summaryrefslogtreecommitdiff
path: root/npc/functions
diff options
context:
space:
mode:
Diffstat (limited to 'npc/functions')
-rw-r--r--npc/functions/npcmovegraph.txt207
1 files changed, 207 insertions, 0 deletions
diff --git a/npc/functions/npcmovegraph.txt b/npc/functions/npcmovegraph.txt
new file mode 100644
index 00000000..0a0e29c7
--- /dev/null
+++ b/npc/functions/npcmovegraph.txt
@@ -0,0 +1,207 @@
+// Evol functions.
+// Authors:
+// Travolta
+// Description:
+// Moving npc utility functions (graph-based)
+// Variables:
+// none
+
+function script initmovegraph {
+ deletearray getvariableofnpc(.movegraphcmd$, strnpcinfo(3));
+ deletearray getvariableofnpc(.movegraphlabels$, strnpcinfo(3));
+ deletearray getvariableofnpc(.movegraphweight, strnpcinfo(3));
+ deletearray getvariableofnpc(.moveposy, strnpcinfo(3));
+ deletearray getvariableofnpc(.moveposx, strnpcinfo(3));
+ .@cnt = 0;
+
+ for (.@f = 0; .@f < getargcount(); .@f = .@f + 3)
+ {
+ set getvariableofnpc(.movegraphlabels$[.@cnt], strnpcinfo(3)), getarg(.@f);
+ set getvariableofnpc(.moveposx[.@cnt], strnpcinfo(3)), getarg(.@f + 1);
+ set getvariableofnpc(.moveposy[.@cnt], strnpcinfo(3)), getarg(.@f + 2);
+ .@cnt ++;
+ }
+ return;
+}
+
+function script findmovegraphlabel {
+ if (!getargcount())
+ return -1;
+ .@arg$ = getarg(0);
+ for (.@i = 0; .@i < getarraysize(getvariableofnpc(.movegraphlabels$, strnpcinfo(3))); .@i++)
+ {
+ if (getvariableofnpc(.movegraphlabels$[.@i], strnpcinfo(3)) == .@arg$)
+ return .@i;
+ }
+
+ return -1;
+}
+
+/* setmovegraphcmd(fromPositionLabel,toPositionLabel,moveChanceWeight,postCommand, ...);
+ * This function manipulates NPC moving graph. Before calling it, make sure
+ * `initmovegraph' was called. The function accepts multiplier of 4 parameters:
+ * fromPositionLabel, toPositionLabel -- starting and ending position of NPC move
+ * moveChanceWeight -- positive integer, represents the cnance of moving in given direction
+ * postCommand -- either "moveon" (start moving to next location straight after arriving from
+ * fromPositionLabel to toPositionLabel) or a semicolon-separated set of commands
+ * ("wait 3", "emote 5" etc, see `execmovecmd') that will be executed after arrival.
+ * The commands don't have to end with ";moveon", it's executed in the end by default.
+ */
+function script setmovegraphcmd {
+ .@size = getarraysize(getvariableofnpc(.moveposx, strnpcinfo(3)));
+
+ for (.@f = 0; .@f < getargcount(); .@f = .@f + 4)
+ {
+ .@from = findmovegraphlabel(getarg(.@f));
+ .@to = findmovegraphlabel(getarg(.@f + 1));
+ .@weight = getarg(.@f + 2);
+ .@cmd$ = getarg(.@f + 3);
+ .@index = .@from * .@size + .@to; // emulation of 2d array
+ set getvariableofnpc(.movegraphcmd$[.@index], strnpcinfo(3)), .@cmd$;
+ set getvariableofnpc(.movegraphweight[.@index], strnpcinfo(3)), .@weight;
+ }
+ return;
+}
+
+function script execmovecmd {
+
+ explode(.@cmd$, getarg(0), " ");
+
+ if (.@cmd$[0] == "moveon")
+ {
+ return 0;
+ }
+ else if (.@cmd$[0] == "dir")
+ {
+ setnpcdir atoi(.@cmd$[1]);
+ }
+ else if (.@cmd$[0] == "wait")
+ {
+ set getvariableofnpc(.waitticks, strnpcinfo(3)), atoi(.@cmd$[1]);
+ }
+ else if (.@cmd$[0] == "emote")
+ {
+ unitemote getnpcid(0), atoi(.@cmd$[1]);
+ }
+ else if (.@cmd$[0] == "class")
+ {
+ setnpcdisplay strnpcinfo(3), atoi(.@cmd$[1]);
+ }
+ else if (.@cmd$[0] == "warp")
+ {
+ .@pos = findmovegraphlabel(.@cmd$[1]);
+ if (.@pos > 0)
+ {
+ movenpc strnpcinfo(3), getvariableofnpc(.moveposx[.@pos], strnpcinfo(3)), getvariableofnpc(.moveposy[.@pos], strnpcinfo(3));
+ set getvariableofnpc(.movepos, strnpcinfo(3)), .@pos;
+ }
+ else
+ {
+ debugmes "execmovecmd: unknown WARP destination label: " + .@cmd$[1];
+ }
+ }
+ else if (.@cmd$[0] == "call")
+ {
+ switch (getarraysize(.@cmd$))
+ {
+ case 1:
+ debugmes "execmovecmd: CALL command needs some parameters";
+ return -1;
+ case 2:
+ callfunc .@cmd$[1];
+ break;
+ case 3:
+ callfunc .@cmd$[1], .@cmd$[2];
+ break;
+ case 4:
+ default:
+ callfunc .@cmd$[1], .@cmd$[2], .@cmd$[3];
+ break;
+ }
+ }
+ else if (.@cmd$[0] == "speed")
+ {
+ npcspeed atoi(.@cmd$[1]);
+ }
+ else
+ {
+ debugmes "Unknown move graph cmd: " + .@cmd$[0];
+ }
+ return 1;
+}
+
+function script getnextmovecmd {
+ .@cmds$ = getvariableofnpc(.nextcmd$, strnpcinfo(3));
+ .@firstCmd$ = .@cmds$;
+ .@restCmd$ = "moveon";
+ .@index = strpos(.@cmds$, ";");
+ if (.@index >= 0)
+ {
+ .@firstCmd$ = substr(.@cmds$, 0, .@index - 1);
+ .@restCmd$ = substr(.@cmds$, .@index + 1, getstrlen(.@cmds$) - 1);
+ }
+ // debugmes "firstCmd = " + .@firstCmd$ + " restCmd = " + .@restCmd$;
+ set getvariableofnpc(.nextcmd$, strnpcinfo(3)), .@restCmd$;
+ return strip(.@firstCmd$);
+}
+
+function script movetonextpoint {
+ .@wait = getvariableofnpc(.waitticks, strnpcinfo(3));
+ if (.@wait > 0)
+ {
+ .@wait --;
+ set getvariableofnpc(.waitticks, strnpcinfo(3)), .@wait;
+ return;
+ }
+ .@nextcmd$ = getnextmovecmd;
+ if (.@nextcmd$ != "moveon")
+ {
+ execmovecmd(.@nextcmd$);
+ return;
+ }
+
+ // choose a random path from all possible paths
+ .@size = getarraysize(getvariableofnpc(.moveposx, strnpcinfo(3)));
+ .@cur = 0;
+ .@pos = getvariableofnpc(.movepos, strnpcinfo(3));
+ .@weight_sum = 0;
+
+ for (.@i = 0; .@i < .@size; .@i++)
+ {
+ .@cmd$ = getvariableofnpc(.movegraphcmd$[.@pos * .@size + .@i], strnpcinfo(3));
+ if (.@cmd$ != "")
+ {
+ setarray .@nextpos[.@cur], .@i;
+ setarray .@weights[.@cur], getvariableofnpc(.movegraphweight[.@pos * .@size + .@i], strnpcinfo(3));
+ .@weight_sum += .@weights[.@cur];
+ .@cur++;
+ }
+ }
+ // pick a random number based on weight_sum
+ .@rnd = rand(.@weight_sum);
+ .@k = -1; .@weight_sum = 0;
+ while (.@rnd >= .@weight_sum)
+ {
+ .@k++;
+ .@weight_sum += .@weights[.@k];
+ }
+ .@next_idx = .@nextpos[.@k];
+ .@next_x = getvariableofnpc(.moveposx[.@next_idx], strnpcinfo(3));
+ .@next_y = getvariableofnpc(.moveposy[.@next_idx], strnpcinfo(3));
+ .@nextcmd$ = getvariableofnpc(.movegraphcmd$[.@pos * .@size + .@next_idx], strnpcinfo(3));
+ set getvariableofnpc(.nextcmd$, strnpcinfo(3)), .@nextcmd$;
+ set getvariableofnpc(.movepos, strnpcinfo(3)), .@next_idx;
+ npcwalkto .@next_x, .@next_y;
+ return;
+}
+
+function script firstmove {
+ .@nextcmd$ = "moveon";
+ if (getargcount() > 0)
+ .@nextcmd$ = getarg(0);
+ set getvariableofnpc(.movepos, strnpcinfo(3)), 0;
+ set getvariableofnpc(.nextcmd$, strnpcinfo(3)), .@nextcmd$;
+ set getvariableofnpc(.waitticks, strnpcinfo(3)), -1;
+ movetonextpoint;
+ return;
+} \ No newline at end of file