diff options
Diffstat (limited to 'kon')
| -rw-r--r-- | kon/konrmfield.c | 62 | ||||
| -rw-r--r-- | kon/konrmfield.h | 11 |
2 files changed, 71 insertions, 2 deletions
diff --git a/kon/konrmfield.c b/kon/konrmfield.c index 92401de..f4c741d 100644 --- a/kon/konrmfield.c +++ b/kon/konrmfield.c @@ -51,6 +51,9 @@ static int roll(kon_rmField_t *field, int n) return n > 0 ? (int)(field->seed % (uint32_t)n) : 0; } +static void makeEncounterCount(kon_rmField_t *field); +static int canEncounter(const kon_rmField_t *field); + static int dirX(int dir) { return dir == 6 ? 1 : dir == 4 ? -1 : 0; @@ -466,6 +469,7 @@ int kon_rmFieldInit(kon_rmField_t *field, const kon_rmMap_t *map, const kon_rmTi chars[KON_RM_PLAYER].active = 1; chars[KON_RM_PLAYER].trigger = 0; kon_rmFieldRefresh(field); + makeEncounterCount(field); return 0; } @@ -565,7 +569,11 @@ void kon_rmFieldUpdate(kon_rmField_t *field) if (e->active && e->trigger == 3 && !field->busy) start(field, i); } - if (wasMoving && !moving(p) && !field->busy) startAt(field, p->x, p->y, 0x06, 0); + if (wasMoving && !moving(p) && !field->busy && startAt(field, p->x, p->y, 0x06, 0) == 0 && canEncounter(field)) { + int progress = kon_rmHasFlag(field->map, field->tileset, p->x, p->y, KON_RM_FLAG_BUSH) ? 4 : 2; + + field->encounterCount -= field->encounterHalf ? progress / 2 : progress; + } } /*** the player ***/ @@ -602,6 +610,58 @@ int kon_rmFieldAction(kon_rmField_t *field) return n > 0; } +/*** fights ***/ + +static void makeEncounterCount(kon_rmField_t *field) +{ + int n = field->map->encounterStep; + + if (n < 0) n = 0; + if (n > 100000) n = 100000; + field->encounterCount = (roll(field, n) + roll(field, n) + 1) * 2; +} + +static int canEncounter(const kon_rmField_t *field) +{ + return !field->encounterNone && !field->chars[KON_RM_PLAYER].routeForced; +} + +int kon_rmFieldEncounter(kon_rmField_t *field) +{ + const kon_rmMap_t *map; + long long sum = 0, value; + int i, region; + + if (!field || !field->chars || field->busy || field->encounterCount > 0) return 0; + map = field->map; + makeEncounterCount(field); + if (!canEncounter(field) || !map->encounters) return 0; + region = kon_rmRegion(map, field->chars[KON_RM_PLAYER].x, field->chars[KON_RM_PLAYER].y); + for (i = 0; i < map->encounterCount; i++) { + const kon_rmEncounter_t *e = &map->encounters[i]; + int k, inRegion = e->regionCount <= 0; + + for (k = 0; k < e->regionCount && e->regions; k++) { + if (e->regions[k] == region) inRegion = 1; + } + if (inRegion && e->weight > 0) sum += e->weight; + } + if (sum <= 0) return 0; + value = roll(field, sum > 2147483647 ? 2147483647 : (int)sum); + for (i = 0; i < map->encounterCount; i++) { + const kon_rmEncounter_t *e = &map->encounters[i]; + int k, inRegion = e->regionCount <= 0; + + for (k = 0; k < e->regionCount && e->regions; k++) { + if (e->regions[k] == region) inRegion = 1; + } + if (!inRegion || e->weight <= 0) continue; + value -= e->weight; + if (value < 0) return e->troopId > 0 ? e->troopId : 0; + } + return 0; +} + /*** events that start ***/ int kon_rmFieldNextStart(kon_rmField_t *field, int *eventId, int *pageIndex) diff --git a/kon/konrmfield.h b/kon/konrmfield.h index d2b358f..17a44fd 100644 --- a/kon/konrmfield.h +++ b/kon/konrmfield.h @@ -76,10 +76,12 @@ typedef struct kon_rmField { int count; uint32_t seed; int busy; /* set it while a script that stops the player is running */ - int steps; /* the steps of the player, count them for encounters and take them back to 0 */ + int steps; /* the steps of the player so far, for the game to use as it likes */ int thisEvent; /* the id of the event whose script is running, for the commands that mean "this event". set it before you run one */ int waitIndex; /* the character a script waits for, -1 for none */ int transferPending; + int encounterCount; /* what is left until the next fight, in halves of a step */ + int encounterHalf, encounterNone; /* set them to halve the steps that count, or to stop fights altogether */ kon_rmTransfer_t transfer; /* both can stay NULL. the first is how a route that turns a switch on or off reaches your game, the second says whether @@ -111,6 +113,13 @@ int kon_rmFieldPlayerStep(kon_rmField_t *field, int dir, int dash); /* the action button: an event on the player's tile or in front of it, or behind a counter. returns 1 when one starts */ int kon_rmFieldAction(kon_rmField_t *field); +/*** fights ***/ + +/* the random fights of the map: every step of the player counts down, a bush counts twice, and when it runs out a troop is picked + from the map's list by weight, only the ones whose regions include the one the player stands in. returns the troop id once, + or 0 for no fight. call it when no script is running. nothing starts while the player is walking a forced route */ +int kon_rmFieldEncounter(kon_rmField_t *field); + /*** events that start ***/ /* the next event that wants its script to run, lowest first: the touched or talked to, and the autorun ones. call it when no |
