diff options
Diffstat (limited to 'npc/functions/main.txt')
-rw-r--r-- | npc/functions/main.txt | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/npc/functions/main.txt b/npc/functions/main.txt new file mode 100644 index 00000000..d072ff60 --- /dev/null +++ b/npc/functions/main.txt @@ -0,0 +1,750 @@ +// 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) < 7) { + skill NV_BASIC, 7, 0; + } + if (getskilllv(TMW2_FAKESKILL) < 1) { + skill TMW2_FAKESKILL, 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; +} + +// Returns if a map is on PVP Mode or Not +// ispvpmap( {mapid} ) +function script ispvpmap { + .@mapa$=getarg(0, getmapname()); + return (getmapflag(.@mapa$, mf_pvp) || getmapflag(.@mapa$, mf_pvp_noparty) || getmapflag(.@mapa$, mf_pvpnoguild)); +} + +// 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); +} + +// mescordialog(text, color, {dialog=1}) +function script mescordialog { + if (getarg(2, true)) + mesc getarg(0), getarg(1); + else + dispbottom col(getarg(0), getarg(1)); + return; +} + +// Delayed healing. Takes 3~5 seconds. Variates with Vit up to +100%. +// The vit can have an additional 20% bonus as well. +function script itheal { + .@bas=getarg(0); + .@vit=readbattleparam(getcharid(3), UDT_VIT); + .@vit=cap_value(.@vit-1, 0, 100); + if (getargcount() > 2) + .@tim=getarg(3); + else + .@tim=rand2(3,5); + .@min=.@bas*(100+.@vit)/100; + .@max=.@bas*(100+.@vit*120/100)/100; + // Now divide the HP values by the time + .@min=max(1, .@min/.@tim); + .@max=max(1, .@max/.@tim); + callfunc("SC_Bonus", .@tim, SC_S_LIFEPOTION, .@min, .@max); + if (getarg(1,0) > 0) + heal 0, getarg(1, 0); + return; +} + +// sqldate({day variation, month variation}) +function script sqldate { + .@d=gettime(GETTIME_DAYOFMONTH)+getarg(0, 0); + .@m=gettime(GETTIME_MONTH)+getarg(1, 0); + .@y=gettime(GETTIME_YEAR); + // Overflow prevention + if (.@d <= 0) { + .@d=1; + } + while (.@m > 12) { + .@y+=1; + .@m-=12; + } + while (.@m < 1) { + .@y-=1; + .@m+=12; + } + .@strdate$=sprintf("%04d-%02d-%02d %02d:%02d:%02d", .@y, .@m, .@d, gettime(GETTIME_HOUR), gettime(GETTIME_MINUTE), gettime(GETTIME_SECOND)); + return .@strdate$; +} + +// Makes a monster aggro +// set_aggro( monster{, mode=MD_AGGRESSIVE} ) +function script set_aggro { + .@m=getarg(0); + .@x=getarg(1, MD_AGGRESSIVE); + .@op=getunitdata(.@m, UDT_MODE); + .@op=.@op|.@x; + setunitdata(.@m, UDT_MODE, .@op); + return; +} + +// Special function which makes a date as a number +// numdate( - ) +function script numdate { + .@strdate$=sprintf("%04d%02d%02d", gettime(GETTIME_YEAR), gettime(GETTIME_MONTH), gettime(GETTIME_DAYOFMONTH)); + // Debug payload + if ($@OVERRIDE_NUMDATE) + return $@OVERRIDE_NUMDATE; + return atoi(.@strdate$); +} + +// json_encode( {varname, varvalue}, {varname 2, varvalue 2}... ) +// returns string +function script json_encode { + if (getargcount() < 2 || getargcount() % 2 != 0) + return Exception("json_encode arguments must be paired"); + + .@json$="{"; + .@tab=true; + + // For arguments + for (.@i=0;.@i < getargcount(); .@i++) { + // Close previous item + if (.@tab) + .@tab=false; + else + .@json$+=","; + + // Input variable name + .@json$+="\""+getarg(.@i)+"\": "; + + // Input variable value + if (isstr(getarg(.@i+1))) + .@json$+="\""+getarg(.@i+1)+"\""; + else + .@json$+=getarg(.@i+1); + + // Advance + .@i++; + } + + // Close the JSON + .@json$+="}"; + return .@json$; +} + + +// api_send( code, data ) +// sends to API +function script api_send { + .@cde=getarg(0); + .@fm$=escape_sql(getarg(1)); + query_sql("INSERT INTO `api_export` (`type`, `data`) VALUES ('"+.@cde+"', \""+.@fm$+"\")"); + return; +} + +// 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 destroy { + disablenpc strnpcinfo(0); + return; +} + +function script npcaction { + debugmes "Deprecated unitaction (did you mean npcsit; or whatever?)"; + .@a=getarg(0, 0); + if (.@a == 9) + clear; + 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 { + sendmapmask getarg(0); + return; +} + +function script getmask { + return 1; //getmapmask(getmapname()); // TODO: Return original map masks +} + +// isat( map, x, y ) +function script isat { + return isin(getarg(0), getarg(1), getarg(2), 0); +} + +function script if_then_else { + return (getarg(0) ? getarg(1) : getarg(2)); +} + +function script misceffect { + // or SELF + something + return specialeffect(getarg(0), AREA, getarg(1, strnpcinfo(0))); +} + +function script fakenpcname { + if (getargcount() > 2) + setnpcdisplay(getarg(0), getarg(1), getarg(2)); + else + setnpcdisplay(getarg(0), getarg(1)); + return; +} + +function script npcwarp { + if (getargcount() > 2) + .@id=getnpcid(getarg(3)); + else + .@id=getnpcid(); + + getmapxy(.@m$, .@x, .@y, UNITTYPE_NPC, strnpcinfo(0, "", .@id)); + unitwarp(.@id, .@m$, getarg(0), getarg(1)); + return; +} + +function script get { + return getvariableofnpc(getarg(0), getarg(1)); +} + +function script sc_check { + return getstatus(getarg(0), getarg(1, 0)); +} + +function script wgm { + charcommand("@request "+getarg(0)); + return; +} + +function script registercmd { + // Remove "@" from command start + .@cmd$=getarg(1); + if (charat(.@cmd$, 0) == "@") + delchar(.@cmd$, 0); + bindatcmd getarg(0), .@cmd$, getarg(2, 0); + return; +} + +function script iscollision { + return checknpccell(getarg(0), getarg(1), getarg(2), cell_chkpass); +} + +function script readparam2 { + return readbattleparam(getcharid(3), getarg(0)); +} + +function script updateskill { + skill getarg(0), getarg(1), 0; + return; +} + +function script learnskill { + if (getskilllv(getarg(0)) < getarg(1, 1)) + skill getarg(0), getarg(1, 1), 0; + return; +} + |