diff options
Diffstat (limited to 'npc')
-rwxr-xr-x | npc/functions/clear_vars.txt | 107 | ||||
-rw-r--r-- | npc/functions/main.txt | 572 | ||||
-rwxr-xr-x | npc/scripts.conf | 1 |
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", |