summaryrefslogtreecommitdiff
path: root/kon
diff options
context:
space:
mode:
Diffstat (limited to 'kon')
-rw-r--r--kon/konrmfield.c62
-rw-r--r--kon/konrmfield.h11
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