summaryrefslogtreecommitdiff
path: root/npc
diff options
context:
space:
mode:
Diffstat (limited to 'npc')
-rwxr-xr-xnpc/functions/clear_vars.txt107
-rw-r--r--npc/functions/main.txt572
-rwxr-xr-xnpc/scripts.conf1
3 files changed, 573 insertions, 107 deletions
diff --git a/npc/functions/clear_vars.txt b/npc/functions/clear_vars.txt
index 76ab7bf7..35c05a4c 100755
--- a/npc/functions/clear_vars.txt
+++ b/npc/functions/clear_vars.txt
@@ -75,110 +75,3 @@ L_EventClear:
return;
}
-function script mapexit {
- debugmes "TRYING TO MAPEXIT IS DEPRECATED";
- return;
-}
-
-function script npcaction {
- debugmes "Deprecated unitaction (did you mean npcsit; or whatever?)";
- return;
-}
-
-function script gmlog {
- logmes(getarg(0), LOGMES_ATCOMMAND);
- return;
-}
-
-function script getx {
- getmapxy(.@m$, .@x, .@y, 0);
- return .@x;
-}
-
-function script gety {
- getmapxy(.@m$, .@x, .@y, 0);
- return .@y;
-}
-
-function script getnpcx {
- return .x;
-}
-
-function script getnpcy {
- return .y;
-}
-
-function script title {
- setnpcdialogtitle getarg(0);
- return;
-}
-
-function script camera {
- if (getarg(0, "") != "")
- setcamnpc getarg(0);
- else
- restorecam;
- return;
-}
-
-function script mapmask {
- setmapmask getmapname(), getarg(0);
- return;
-}
-
-function script getmask {
- return getmapmask(getmapname());
-}
-
-// isin( map, x1, y1, {[x2, y2][radius]} )
-function script isin {
- if (getmapxy(.@mapName$, .@xpos, .@ypos, 0) != 0)
- return false;
- if (.@mapName$ != getarg(0))
- return false;
-
- if (getarg(4,-1) < 0) {
- // Radius Based
- if (.@xpos >= getarg(1)-getarg(3) && .@xpos <= getarg(1)+getarg(3) && .@ypos >= getarg(2)-getarg(3) && .@ypos <= getarg(2)+getarg(3))
- return true;
- } else {
- // Coordinate based
- if (.@xpos >= getarg(1) && .@xpos <= getarg(3) && .@ypos >= getarg(2) && .@ypos <= getarg(4))
- return true;
- }
- return false;
-}
-
-// isat( map, x, y )
-function script isat {
- return isin(getarg(0), getarg(1), getarg(2), 0);
-}
-
-function script mesn {
- if (getargcount() > 0) {
- .@s$ = "[" + getarg(0) + "]";
- } else {
- .@s$ = "[" + strnpcinfo(1) + "]";
- }
- mes .@s$;
- return;
-}
-
-// maptimer("<map>", <tick>, "<npc>::<event>")
-function script maptimer {
- .@c = getunits(BL_PC, .@players, false, getarg(0));
- for (.@i = 0; .@i < .@c; .@i++) {
- addtimer(getarg(1), getarg(2), .@players[.@i]);
- }
- return .@i;
-}
-
-// areatimer("<map>", <x1>, <y1>, <x2>, <y2>, <tick>, "<npc>::<event>")
-function script areatimer {
- .@c = getunits(BL_PC, .@players, false, getarg(0), getarg(1), getarg(2), getarg(3), getarg(4));
- for (.@i = 0; .@i < .@c; .@i++) {
- addtimer(getarg(5), getarg(6), .@players[.@i]);
- }
- return .@i;
-}
-
diff --git a/npc/functions/main.txt b/npc/functions/main.txt
new file mode 100644
index 00000000..5fb9e9e7
--- /dev/null
+++ b/npc/functions/main.txt
@@ -0,0 +1,572 @@
+// TMW2 Script
+// Evol functions.
+// Authors:
+// 4144
+// Travolta
+// gumi
+// Jesusalva
+// Description:
+// Built-in essential functions.
+
+function script menuimage {
+ return getarg(0) + "|" + getarg(1);
+}
+
+function script dnext {
+ if (@dnext >= GSET_LONGMENU_DENSITY) {
+ @dnext=0;
+ next;
+ } else {
+ @dnext+=1;
+ }
+ return;
+}
+
+function script menuaction {
+ return "[" + getarg(0) + "]";
+}
+
+function script setq1 {
+ // Quest, val1 , val2 , val3 , time
+ setq getarg(0), getarg(1), getq2(getarg(0)), getq3(getarg(0)), getqtime(getarg(0));
+ return;
+}
+
+function script setq2 {
+ // Quest, val1 , val2 , val3 , time
+ setq getarg(0), getq(getarg(0)), getarg(1), getq3(getarg(0)), getqtime(getarg(0));
+ return;
+}
+
+function script setq3 {
+ // Quest, val1 , val2 , val3 , time
+ setq getarg(0), getq(getarg(0)), getq2(getarg(0)), getarg(1), getqtime(getarg(0));
+ return;
+}
+
+function script setqtime {
+ // Quest, val1 , val2 , val3 , time
+ setq getarg(0), getq(getarg(0)), getq2(getarg(0)), getq3(getarg(0)), getarg(1);
+ return;
+}
+
+function script mesn {
+ if (getargcount() > 0) {
+ .@s$ = "[" + getarg(0) + "]";
+ } else {
+ .@s$ = "[" + strnpcinfo(1) + "]";
+ }
+ mes .@s$;
+ return;
+}
+
+function script mesq {
+ mes "\"" + getarg(0)+ "\"";
+ return;
+}
+
+function script g {
+ return Sex == 0 ? getarg(0) : getarg(1);
+}
+
+function script b {
+ return "##B" + getarg(0) + "##b";
+}
+
+function script col {
+ .@color = getarg(1,9);
+ if (.@color < 0) .@color = 0;
+ if (.@color > 9) .@color = 9;
+ return "##" + .@color + getarg(0) + "##0";
+}
+
+function script adddefaultskills {
+ if (getskilllv(NV_BASIC) < 6) {
+ skill NV_BASIC, 6, 0;
+ }
+ if (getskilllv(TMW2_FAKESKILL) < 1) {
+ skill TMW2_FAKESKILL, 1, 0;
+ }
+ if (getskilllv(TMW2_FAKESKILL2) < 1) {
+ skill TMW2_FAKESKILL2, 1, 0;
+ }
+ return;
+}
+
+function script addremovemapmask {
+ setmapmask getarg(0), (getmapmask(getarg(0)) | (getarg(1) + getarg(2))) ^ getarg(2);
+ return;
+}
+
+function script mesc {
+ mes col(getarg(0),getarg(1,9));
+ return;
+}
+
+function script get_race {
+ .@g=getarg(0, Class);
+ return l($@allraces$[.@g]);
+}
+
+// tutmes (message, {header=Tutorial, headerfirst=True})
+function script tutmes {
+ .@header$=getarg(1, l("TUTORIAL"));
+ .@showheader=getarg(2, true);
+ .@tcol=9; // Tutorial color code
+
+ if (TUTORIAL) {
+ dnext;
+ if (.@showheader) {
+ mesf(".:: %s ::.", .@header$);
+ mesc getarg(0), .@tcol;
+ } else {
+ mesc .@header$+": "+getarg(0), .@tcol;
+ }
+ }
+ return;
+}
+
+// Function to show narrator text. Accepts string args.
+// If first arg is a number N, then it represents bit flags.
+// Bit flags :
+// 0x1 -- blank line at beginning
+// 0x2 -- blank line at the end
+// 0x4 -- use last "next;"
+// 0x8 -- don't use first "mesn;"
+function script narrator {
+ .@start = 0;
+ .@argc = getargcount();
+ .@flags = 0;
+
+ if (.@argc > 1 && !isstr(getarg(0)))
+ {
+ .@start = 1;
+ .@flags = getarg(0);
+ }
+
+ if (.@flags & 0x1)
+ mes "";
+
+ if (!(.@flags & 0x8))
+ mesn l("Narrator");
+
+ for (.@i = .@start; .@i < .@argc; .@i++)
+ {
+ mes col(getarg(.@i), 9);
+ if (.@i < .@argc - 1)
+ next;
+ }
+
+ if (.@flags & 0x4)
+ next;
+ else if (.@flags & 0x2)
+ mes "";
+
+ return;
+}
+
+// Function to show NPC speech. Accepts string args.
+// If first arg is a number N, then it represents bit flags.
+// Bit flags :
+// 0x1 -- blank line at beginning
+// 0x2 -- blank line at the end
+// 0x4 -- use last "next;"
+// 0x8 -- don't use first "mesn;"
+function script speech {
+ .@start = 0;
+ .@argc = getargcount();
+ .@flags = 0;
+
+ if (.@argc > 1 && !isstr(getarg(0)))
+ {
+ .@start = 1;
+ .@flags = getarg(0);
+ }
+
+ if (.@flags & 0x1)
+ mes "";
+
+ if (!(.@flags & 0x8))
+ mesn;
+
+ for (.@i = .@start; .@i < .@argc; .@i++)
+ {
+ mesq getarg(.@i);
+
+ if (.@i < .@argc - 1)
+ next;
+ }
+
+ if (.@flags & 0x4)
+ next;
+ else if (.@flags & 0x2)
+ mes "";
+
+ return;
+}
+
+// Show debug message if .debug variable of NPC is set to 1
+function script npcdebug {
+ if (getvariableofnpc(.debug, strnpcinfo(3)))
+ debugmes strnpcinfo(3) + ": " + getarg(0);
+ return;
+}
+
+function script askyesno {
+ return select(menuaction(l("Yes")),
+ menuaction(l("No")));
+}
+
+// Argument:
+// 0 Quest variable
+// 1 Current value
+// 2 Next value
+function script compareandsetq {
+ if (getq(getarg(0)) == getarg(1))
+ {
+ setq getarg(0), getarg(2);
+ return true;
+ }
+ return false;
+}
+
+// Use a delay to prevent spams from NPC that display text without the
+// use of (a) close/next function(s).
+// Argument:
+// 0 Text to display
+// 1 Lock delay (default = 1)
+// 2 Message function: (default = 0)
+// 0 = npctalk3
+// 1 = npctalk
+// 2 = message
+// TODO: Use temp player var, because NPC var affect other players
+function script npctalkonce {
+ // lock mechanism
+ switch (getarg(2, 0))
+ {
+ case 1:
+ if (gettimetick(2) <= getvariableofnpc(.talk_lock, strnpcinfo(NPC_NAME_UNIQUE)))
+ return false;
+ set(getvariableofnpc(.talk_lock, strnpcinfo(NPC_NAME_UNIQUE)), gettimetick(2) + getarg(1, 1));
+ break;
+ default:
+ if (gettimetick(2) <= @NPC_TALK_LOCK[getnpcid()])
+ return false;
+ @NPC_TALK_LOCK[getnpcid()] = gettimetick(2) + getarg(1, 1);
+ }
+
+ // talk mechanism
+ switch (getarg(2, 0))
+ {
+ case 0: npctalk3(getarg(0)); break;
+ case 1: npctalk(getarg(0)); break;
+ case 2: message(strcharinfo(0), getarg(0));
+ }
+
+ return true;
+}
+
+// Randomizer functions
+/////////////////////////////////////////////
+
+// pseudo-fix randomness
+// rand2( min, max )
+function script rand2 {
+ if (getargcount() == 2) {
+ .@min=getarg(0)*100;
+ .@max=getarg(1)*100+99;
+ } else {
+ .@min=0;
+ .@max=getarg(0)*100-1;
+ }
+ return rand(.@min, .@max)/100;
+}
+
+// returns one argument randomly
+// any( <arg>{, ...<arg>} )
+function script any {
+ return getarg(rand2(getargcount()));
+}
+
+// returns any member of the array
+// any_of( <array> )
+function script any_of {
+ return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand2(getarraysize(getarg(0)) - getarrayindex(getarg(0))));
+}
+
+function script die {
+ if ($HARDCORE) {
+ @grace=true;
+ percentheal -100, -100;
+ //setparam(Hp, 1);
+ //warp "000-1", 22, 22;
+ //end; // MUST be end; to mimic official behavior
+ } else {
+ percentheal -100, -100;
+ }
+ return;
+}
+
+// TMW2 Custom Functions
+/////////////////////////////////////////////
+
+// Function meant to be used by Main Storyline Quest
+// msObjective ( condition , message )
+function script msObjective {
+ if (getarg(0))
+ mesc getarg(1), 2;
+ else
+ mesc getarg(1), 9;
+ return;
+}
+
+function script getmap {
+ if (getmapxy(.@mapName$, .@xpos, .@ypos, getarg(0,0)) != 0)
+ return false;
+ // TODO: Maybe use getmapname() instead of getmapxy?
+ return .@mapName$;
+}
+
+// isin( map, x1, y1, {[x2, y2][radius]} )
+function script isin {
+ if (getmapxy(.@mapName$, .@xpos, .@ypos, 0) != 0)
+ return false;
+ if (.@mapName$ != getarg(0))
+ return false;
+
+ if (getarg(4,-1) < 0) {
+ // Radius Based
+ if (.@xpos >= getarg(1)-getarg(3) && .@xpos <= getarg(1)+getarg(3) && .@ypos >= getarg(2)-getarg(3) && .@ypos <= getarg(2)+getarg(3))
+ return true;
+ } else {
+ // Coordinate based
+ if (.@xpos >= getarg(1) && .@xpos <= getarg(3) && .@ypos >= getarg(2) && .@ypos <= getarg(4))
+ return true;
+ }
+ return false;
+}
+
+// Clear output of getinventorylist()
+// delinventorylist()
+function script delinventorylist {
+ deletearray @inventorylist_id;
+ deletearray @inventorylist_amount;
+ deletearray @inventorylist_equip;
+ deletearray @inventorylist_refine;
+ deletearray @inventorylist_identify;
+ deletearray @inventorylist_attribute;
+ deletearray @inventorylist_card1;
+ deletearray @inventorylist_card2;
+ deletearray @inventorylist_card3;
+ deletearray @inventorylist_card4;
+ deletearray @inventorylist_expire;
+ deletearray @inventorylist_bound;
+ @inventorylist_count=0;
+ return;
+}
+
+// Get some acc id, even if offline
+// ( Name )
+function script gf_accid {
+ .@nb = query_sql("SELECT `account_id` FROM `char` WHERE `name`='"+escape_sql(getarg(0))+"' LIMIT 1", .@value);
+ return .@value[0];
+}
+
+// Get some char id, even if offline
+// ( Name )
+function script gf_charnameid {
+ .@nb = query_sql("SELECT `char_id` FROM `char` WHERE `name`='"+escape_sql(getarg(0))+"' LIMIT 1", .@value);
+ return .@value[0];
+}
+
+// Get some char name from char ID, even if offline
+// ( Name )
+function script gf_charname {
+ .@nb = query_sql("SELECT `name` FROM `char` WHERE `char_id`="+escape_sql(getarg(0))+" LIMIT 1", .@value$);
+ return .@value$[0];
+}
+
+// Get some char ID from account ID, even if offline
+// ( Name )
+function script gf_charid {
+ .@nb = query_sql("SELECT `char_id` FROM `char` WHERE `account_id`="+escape_sql(getarg(0))+" LIMIT 1", .@value$);
+ return .@value$[0];
+}
+
+// Request pincode and validate it. Use any non-4-digits code to cancel. Failure will dc you.
+// Returns 1 if pin check is OK.
+function script validatepin {
+ if (#FIRST_TIME < 2) {
+ mesc l("ERROR: You must set a PinCode to make use of this function."), 1;
+ return 0;
+ }
+ mesc l("Please insert your pincode."), 1;
+ mesc l("WARNING: If you insert wrong pincode, you'll be disconnected.");
+ mesc l("Use @@ to cancel.", "##B-1##b");
+ mes "";
+ input .@pin$;
+ if (getstrlen(.@pin$) != 4)
+ return 0;
+ query_sql("SELECT userid FROM `login` WHERE account_id="+escape_sql(getcharid(3))+" AND pincode='"+escape_sql(.@pin$)+"' LIMIT 2", .@value$);
+ if (getarraysize(.@value$) != 1) {
+ atcommand "@kick "+strcharinfo(0);
+ return 0;
+ }
+ // Enforce some cooldown to prevent an eventual exploit/abuse
+ sleep2(rand2(150, 400));
+ mesc l("Thanks, @@. We just wanted to be sure it was you.", .@value$[0]);
+ mes "";
+ return true;
+}
+
+// Something went wrong and must be reported (named after raise Exception in python)
+// Exception( BugID, {Flags{, Return Code}} )
+function script Exception {
+ // Fill variable
+ .@msg$=getarg(0);
+ .@gf=getarg(1,RB_DEFAULT);
+
+ if (.@gf & RB_DISPBOTTOM)
+ dispbottom("ERROR: "+.@msg$);
+
+ if (.@gf & RB_DEBUGMES)
+ debugmes("[Warning] "+.@msg$);
+
+ if (.@gf & RB_SPEECH)
+ mesc("ERROR, REPORT ME! "+.@msg$, 1);
+
+ if (.@gf & RB_IRCBROADCAST)
+ channelmes("#world", "Error in script: "+.@msg$);
+
+ if (.@gf & RB_GLOBALANNOUNCE)
+ announce("Error in script: "+.@msg$, bc_all);
+
+ if (.@gf & RB_PLEASEREPORT) {
+ if (.@gf & RB_DISPBOTTOM)
+ dispbottom("Please take a screenshot and report this bug, explaining how it happened.");
+
+ if (.@gf & RB_SPEECH)
+ mesc("Please take a screenshot and report this bug, explaining how it happened."), 1;
+ }
+
+ if (.@gf & RB_ISFATAL) {
+ if (.@gf & RB_DISPBOTTOM)
+ dispbottom("This error is fatal, we stop execution.");
+
+ if (.@gf & RB_DEBUGMES)
+ debugmes("[Error] The error is fatal.");
+
+ if (.@gf & RB_SPEECH) {
+ mesc l("This error is fatal, we stop execution."), 1;
+ close;
+ }
+ end;
+ }
+
+ return getarg(2, 0);
+
+}
+
+// Linking functions
+/////////////////////////////////////////////
+function script getquestlink {
+ return "[@@q" + getarg(0) + "|@@]";
+}
+
+function script getmonsterlink {
+ return "[@@m" + getarg(0) + "|@@]";
+}
+
+function script getpetlink {
+ return "[@@p" + getarg(0) + "|@@]";
+}
+
+function script getmercenarylink {
+ return "[@@M" + getarg(0) + "|@@]";
+}
+
+function script gethomunculuslink {
+ return "[@@h" + getarg(0) + "|@@]";
+}
+
+// Legacy functions
+/////////////////////////////////////////////
+function script mapexit {
+ debugmes "TRYING TO MAPEXIT IS DEPRECATED";
+ return;
+}
+
+function script npcaction {
+ debugmes "Deprecated unitaction (did you mean npcsit; or whatever?)";
+ return;
+}
+
+function script gmlog {
+ logmes(getarg(0), LOGMES_ATCOMMAND);
+ return;
+}
+
+function script getx {
+ getmapxy(.@m$, .@x, .@y, 0);
+ return .@x;
+}
+
+function script gety {
+ getmapxy(.@m$, .@x, .@y, 0);
+ return .@y;
+}
+
+function script getnpcx {
+ return .x;
+}
+
+function script getnpcy {
+ return .y;
+}
+
+function script title {
+ setnpcdialogtitle getarg(0);
+ return;
+}
+
+function script camera {
+ if (getarg(0, "") != "")
+ setcamnpc getarg(0);
+ else
+ restorecam;
+ return;
+}
+
+function script mapmask {
+ setmapmask getmapname(), getarg(0);
+ return;
+}
+
+function script getmask {
+ return getmapmask(getmapname());
+}
+
+// isat( map, x, y )
+function script isat {
+ return isin(getarg(0), getarg(1), getarg(2), 0);
+}
+
+//////////////////////////////////////////////////////////////////////
+// maptimer("<map>", <tick>, "<npc>::<event>")
+function script maptimer {
+ .@c = getunits(BL_PC, .@players, false, getarg(0));
+ for (.@i = 0; .@i < .@c; .@i++) {
+ addtimer(getarg(1), getarg(2), .@players[.@i]);
+ }
+ return .@i;
+}
+
+// areatimer("<map>", <x1>, <y1>, <x2>, <y2>, <tick>, "<npc>::<event>")
+function script areatimer {
+ .@c = getunits(BL_PC, .@players, false, getarg(0), getarg(1), getarg(2), getarg(3), getarg(4));
+ for (.@i = 0; .@i < .@c; .@i++) {
+ addtimer(getarg(5), getarg(6), .@players[.@i]);
+ }
+ return .@i;
+}
+
diff --git a/npc/scripts.conf b/npc/scripts.conf
index 42864beb..568123ff 100755
--- a/npc/scripts.conf
+++ b/npc/scripts.conf
@@ -1,3 +1,4 @@
+"npc/functions/main.txt",
"npc/functions/clear_vars.txt",
"npc/functions/banker.txt",