// TMW2 Script.
// Authors:
// Jesusalva
// Description:
// Util functions
/////////////////////////////////////////////////////////////////////////////////
// Delete item ID on inventories, storages, guild storages and carts. Also affects mails.
// WARNING, irreversible and dangerous!
// DelItemFromEveryPlayer( ID )
function script DelItemFromEveryPlayer {
if (getarg(0, -1) < 0)
return;
query_sql("DELETE FROM `inventory` WHERE `nameid`="+getarg(0));
query_sql("DELETE FROM `cart_inventory` WHERE `nameid`="+getarg(0));
query_sql("DELETE FROM `storage` WHERE `nameid`="+getarg(0));
query_sql("DELETE FROM `guild_storage` WHERE `nameid`="+getarg(0));
query_sql("DELETE FROM `rodex_items` WHERE `nameid`="+getarg(0));
query_sql("DELETE FROM `auction` WHERE `nameid`="+getarg(0));
return;
}
// Delete an acc_reg entry from all players. Full arrays only. Affect num and str db.
// WARNING, irreversible and dangerous!
// DelAccRegFromEveryPlayer( KEY )
function script DelAccRegFromEveryPlayer {
if (getarg(0, "error") == "error")
return;
query_sql("DELETE FROM `acc_reg_num_db` WHERE `key`='"+getarg(0)+"'");
query_sql("DELETE FROM `acc_reg_str_db` WHERE `key`='"+getarg(0)+"'");
return;
}
// Delete a quest entry from all players. This includes all counters. Use with caution.
// WARNING, irreversible and dangerous!
// DelQuestFromEveryPlayer( ID )
function script DelQuestFromEveryPlayer {
if (getarg(0, -1) < 0)
return;
query_sql("DELETE FROM `quest` WHERE `quest_id`="+getarg(0));
return;
}
// Transforms an item in something else.
// ReplaceItemFromEveryPlayer( OldID, NewID )
function script ReplaceItemFromEveryPlayer {
if (getarg(0, -1) < 0)
return;
debugmes("* Server update: %d item was replaced by %d", getarg(0), getarg(1));
query_sql("UPDATE `inventory` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
query_sql("UPDATE `cart_inventory` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
query_sql("UPDATE `storage` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
query_sql("UPDATE `guild_storage` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
query_sql("UPDATE `rodex_items` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
query_sql("UPDATE `auction` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
return;
}
/////////////////////////////////////////////////////////////////////////////////
// Returns Nard reputation for discounts
// Currently ranges from 0 to 16.
function script nard_reputation {
.@nr=0; // Base reputation
// Valon Quest (+1 rep)
if (getq(CandorQuest_Trainer) >= 14)
.@nr=.@nr+1;
// Zegas Quest (+1 rep)
if (getq(CandorQuest_Barrel) >= 4)
.@nr=.@nr+1;
// Hide And Seek Quest (+1 rep)
if (getq(CandorQuest_HAS) >= 4)
.@nr=.@nr+1;
// Sailors Quest (+1 rep)
if (getq(CandorQuest_Sailors) >= 3)
.@nr=.@nr+1;
// Sailors Quest, part 2 (+1 rep)
if (getq(CandorQuest_SailorCure) >= 1)
.@nr=.@nr+1;
// Vincent Quest (+1 rep)
if (getq(CandorQuest_Vincent) >= 2)
.@nr=.@nr+1;
// Tolchi Quest (+1 rep)
if (getq(CandorQuest_Tolchi) >= 4)
.@nr=.@nr+1;
// Maya Quest (+1 rep)
if (getq(CandorQuest_Maya) >= 4)
.@nr=.@nr+1;
// Rosen Quest (+1 rep)
if (getq(CandorQuest_Rosen) >= 3)
.@nr=.@nr+1;
// Ship Crew Quests
// Dan Quest (+1 rep)
if (getq(ShipQuests_Dan) >= 3)
.@nr=.@nr+1;
// Chef Gado Quest (+1 rep)
if (getq(ShipQuests_ChefGado) >= 2)
.@nr=.@nr+1;
// Peter Quest (+1 rep)
if (getq(ShipQuests_Peter) >= 7)
.@nr=.@nr+1;
// Tulimshar Quests
// Swezanne Quest (+1 rep)
if (getq(TulimsharQuest_Swezanne) >= 1)
.@nr=.@nr+1;
// Sailors Quest (+1 rep)
if (getq(TulimsharQuest_Sailors) >= 2)
.@nr=.@nr+1;
// Hasan Quest (+1 rep)
if (getq(TulimsharQuest_Hasan) >= 5)
.@nr=.@nr+1;
// Dausen Quest (+1 rep)
if (getq(TulimsharQuest_WaterForGuard) >= 3)
.@nr=.@nr+1;
//debugmes "Reputation: "+str(.@nr);
return .@nr;
}
// Returns reputation based on quests completion for discounts. Returns 0~100 int.
// Takes one argument (PC_DEST$). Grep for "getarg".
function script reputation {
.@nr=0; // Base reputation
// Tulimshar Quests (14 points)
if (getarg(0) == "Tulim") {
// Eugene Quest (+1 rep)
if (getq(TulimsharQuests_Fishman) >= 2)
.@nr=.@nr+1;
// Sarah Quest (+1 rep)
if (getq(TulimsharQuest_Sarah) >= 1)
.@nr=.@nr+1;
// Dausen Quest (+1 rep)
if (getq(TulimsharQuest_WaterForGuard) >= 3)
.@nr=.@nr+1;
// Swezanne Quest (+1 rep)
if (getq(TulimsharQuest_Swezanne) >= 1)
.@nr=.@nr+1;
// Silvia Quest (+1 rep)
if (getq(TulimsharQuest_Lifestone) >= 2)
.@nr=.@nr+1;
/*
// Eisten Quest (+1 rep)
if (getq(TulimsharQuest_Eistein) >= 6)
.@nr=.@nr+1;
*/
// Hasan Quest (+1 rep)
if (getq(TulimsharQuest_Hasan) >= 5)
.@nr=.@nr+1;
// Devoir Quest (+1 rep)
if (getq(TulimsharQuest_Devoir) >= 1)
.@nr=.@nr+1;
// Sailors Quest (+1 rep)
if (getq(TulimsharQuest_Sailors) >= 2)
.@nr=.@nr+1;
// Zarkor Quest (+1 rep)
if (getq(TulimsharQuest_DarkInvocator) >= 7)
.@nr=.@nr+1;
// Anwar Quest (+1 rep)
if (getq(TulimsharQuest_AnwarField) >= 10)
.@nr=.@nr+1;
// Neko Quest (+1 rep)
if (getq(TulimsharQuest_Neko) >= 2)
.@nr=.@nr+1;
// Tycoon Quest (+1 rep)
if (getq(MineQuest_Tycoon) >= 15)
.@nr=.@nr+1;
// Dracoula Quest (+1 rep)
if (getq(MineQuest_Dracoula) >= 1)
.@nr=.@nr+1;
// Caelum Quest (+1 rep)
if (getq(MineQuest_Caelum) >= 2)
.@nr=.@nr+1;
// Veteran Officer Quest (+1 rep)
if (getq(TulimsharQuest_WoodenSword) >= 2)
.@nr=.@nr+1;
// TULIMSHAR Magical Forumula
.@nr=.@nr*100/15;
// Hurnscald Quests (9 points)
} else if (getarg(0) == "Hurns") {
// Alan Quest (+1 rep)
if (getq(HurnscaldQuest_ForestBow) >= 2)
.@nr=.@nr+1;
// Gwendolyn Quest (+1 rep)
if (getq(HurnscaldQuest_HarkEye) >= 6)
.@nr=.@nr+1;
// Celestia Quest (+1 rep)
if (getq(HurnscaldQuest_TeaParty) >= 2)
.@nr=.@nr+1;
/*
// Yeti King Quest (+1 rep)
// Please note that if you challenge it again and lose, it'll reset
if (getq(HurnscaldQuest_Celestia) == 6)
.@nr=.@nr+1;
*/
// Farmers Quest (+1 rep)
if (getq(HurnscaldQuest_Farmers) >= 5)
.@nr=.@nr+1;
// Helena Quest (+1 rep)
if (getq(HurnscaldQuest_Bandits) >= 8)
.@nr=.@nr+1;
// Injuried Mouboo Quest (+1 rep)
if (getq(HurnscaldQuest_InjuriedMouboo) >= 2)
.@nr=.@nr+1;
// Blood Donor Quest (+1 rep)
if (getq(HurnscaldQuest_BloodDonor) >= 1)
.@nr=.@nr+1;
// Woody Quest (+1 rep)
if (getq(HurnscaldQuest_Woody) >= 5)
.@nr=.@nr+1;
// Lieutenant Quest (+1 rep)
if (getq(HurnscaldQuest_Lieutenant) >= 10)
.@nr=.@nr+1;
// HURNSCALD Magical Forumula
.@nr=.@nr*100/9;
// Land Of Fire Quests (5 points)
} else if (getarg(0) == "LoF") {
// The EPISODE
//// Tea For Two (+1 rep)
if (getq(LoFQuest_EPISODE) >= 2)
.@nr=.@nr+1;
//// Early Christmas (+1 rep)
if (getq(LoFQuest_EPISODE) >= 6)
.@nr=.@nr+1;
// George Quest (+1 rep)
if (getq(LoFQuest_George) >= 3)
.@nr=.@nr+1;
// Fairy Quest (+1 rep)
if (getq(LoFQuest_Fairy) >= 3)
.@nr=.@nr+1;
// Pet Detective Quest (+1 rep)
if (getq(LoFQuest_Pets) >= 1)
.@nr=.@nr+1;
// LAND OF FIRE Magical Forumula
.@nr=.@nr*100/5;
// Nivalis Quests (2 points)
} else if (getarg(0) == "Nival") {
// Nivalis Well Quest (+1 rep)
if (getq(NivalisQuest_Well) >= 2)
.@nr=.@nr+1;
// Nivalis Cindy Quest (+1 rep)
if (getq(NivalisQuest_Cindy) >= 5)
.@nr=.@nr+1;
// NIVALIS Magical Forumula
.@nr=.@nr*100/2;
// Halinarzo Quests (5 points)
} else if (getarg(0) == "Halin") {
// Foxhound Famine Quest (+1 rep)
if (getq(HalinarzoQuest_Foxhound) >= 6)
.@nr=.@nr+1;
// Charles Quest (+1 rep)
if (getq(HalinarzoQuest_TraderKing) >= 2)
.@nr=.@nr+1;
// Joaquim & Yumi Quest (+1 rep)
if (getq(HalinarzoQuest_SickWife) >= 5)
.@nr=.@nr+1;
// Life Delight Quest (+1 rep)
if (getq(HalinarzoQuest_LifeDelight) >= 2)
.@nr=.@nr+1;
// Sawis Quest (+1 rep)
if (getq(HalinarzoQuest_Sawis) >= 2)
.@nr=.@nr+1;
// HALINARZO Magical Forumula
.@nr=.@nr*100/5;
// Frostia Quests (2 points)
} else if (getarg(0) == "Frostia") {
// Rescue Yeti Quest (+1 rep)
if (getq(NivalisQuest_Well) >= 2)
.@nr=.@nr+1;
// Rescue Cindy Quest (+1 rep)
if (getq(NivalisQuest_Cindy) >= 5)
.@nr=.@nr+1;
// FROSTIA Magical Forumula
.@nr=.@nr*100/2;
// Candor Quests (9 points)
} else if (getarg(0) == "Candor") {
// Valon Quest (+1 rep)
if (getq(CandorQuest_Trainer) >= 14)
.@nr=.@nr+1;
// Zegas Quest (+1 rep)
if (getq(CandorQuest_Barrel) >= 4)
.@nr=.@nr+1;
// Hide And Seek Quest (+1 rep)
if (getq(CandorQuest_HAS) >= 4)
.@nr=.@nr+1;
// Sailors Quest (+1 rep)
if (getq(CandorQuest_Sailors) >= 3)
.@nr=.@nr+1;
// Sailors Quest, part 2 (+1 rep)
if (getq(CandorQuest_SailorCure) >= 1)
.@nr=.@nr+1;
// Vincent Quest (+1 rep)
if (getq(CandorQuest_Vincent) >= 2)
.@nr=.@nr+1;
// Tolchi Quest (+1 rep)
if (getq(CandorQuest_Tolchi) >= 4)
.@nr=.@nr+1;
// Maya Quest (+1 rep)
if (getq(CandorQuest_Maya) >= 4)
.@nr=.@nr+1;
// Rosen Quest (+1 rep)
if (getq(CandorQuest_Rosen) >= 3)
.@nr=.@nr+1;
// CANDOR Magical Forumula
.@nr=.@nr*100/9;
// Final
}
//debugmes "Reputation: "+str(.@nr);
return .@nr;
}
// Returns time for ship travel.
// Can be modified by a factor.
function script nard_time {
// Estimates time to move by ship from LOCATION$ to getarg(0)
// From Candor
if (LOCATION$ == "Candor") {
if (getarg(0) == "Tulim")
return 22000;
}
// From Tulimshar
if (LOCATION$ == "Tulim") {
if (getarg(0) == "Candor")
return 22000;
if (getarg(0) == "Hurns")
return 28000;
if (getarg(0) == "Nival")
return 52000;
}
// From Hurnscald
if (LOCATION$ == "Hurns") {
if (getarg(0) == "Candor")
return 22000;
if (getarg(0) == "Tulim")
return 28000;
if (getarg(0) == "Nival")
return 28000;
}
// From Nivalis
if (LOCATION$ == "Nival") {
if (getarg(0) == "Candor")
return 46000;
if (getarg(0) == "Tulim")
return 52000;
if (getarg(0) == "Hurns")
return 28000;
}
// Error
debugmes "ERROR, INVALID LOCATION AND DESTINATION";
debugmes l("@@ -> @@", LOCATION$, getarg(0));
dispbottom l("An error on your travel time happened. Please report.");
return INT_MAX;
}
// Determines if player is still in range.
// eg.
// if (reachable(.x, .y, .distance)) {
function script reachable {
.@x=getarg(0);
.@y=getarg(1);
.@z=getarg(2);
getmapxy(.@mp$, .@xp, .@yp, 0);
if (distance(.@x, .@y, .@xp, .@yp) <= .@z)
return 1;
else
return 0;
}
// Determines if party exp sharing is enabled
// ( Party ID )
function script party_expon {
.@nb = query_sql("SELECT exp FROM `party` WHERE party_id="+escape_sql(getarg(0))+" LIMIT 2", .@value);
return .@value[0];
}
// Prepare Mana Stone
// mstone( lvl )
function script mstone {
// Fill variable
.@v=getarg(0);
// Determine how much stats you need, this is based on players
// and change based on $Global Variables
.int=10;
.lvl=15;
.jlv=10;
return (
MAGIC_LVL == .@v &&
readparam(bInt) >= $MANA_BINT+(.int*.@v) &&
BaseLevel >= $MANA_BLVL+(.lvl*.@v) &&
JobLevel >= $MANA_JLVL+(.jlv*.@v) &&
readparam(Sp) == readparam(MaxSp));
}
// Gets how many subclasses were actually filled
// total_subclass( )
function script total_subclass {
.@i=0;
if (MAGIC_SUBCLASS & CL_PALADIN)
.@i+=1;
if (MAGIC_SUBCLASS & CL_TANKER)
.@i+=1;
if (MAGIC_SUBCLASS & CL_BERSERKER)
.@i+=1;
if (MAGIC_SUBCLASS & CL_RANGER)
.@i+=1;
if (MAGIC_SUBCLASS & CL_SNIPER)
.@i+=1;
if (MAGIC_SUBCLASS & CL_WIZARD)
.@i+=1;
if (MAGIC_SUBCLASS & CL_SAGE)
.@i+=1;
if (MAGIC_SUBCLASS & CL_PRIEST)
.@i+=1;
return .@i;
}
// Gets how many subclasses were actually allowed
// max_subclass()
function script max_subclass {
return (MAGIC_LVL/2);
}
// Gets subclass current degree
// degree_subclass()
function script degree_subclass {
return (MAGIC_LVL/2)+(MAGIC_LVL%2);
}
// Returns true if a skill can be leveled up, based on degree_subclass().
// sk_canlvup( sk )
function script sk_canlvup {
if (getskilllv(getarg(0)) <= degree_subclass())
return 1;
return 0;
}
// Level up a skill in 1 level
// sk_lvup( sk )
function script sk_lvup {
.@lvl=getskilllv(getarg(0));
getexp 0, 50*(.@lvl+1);
addtoskill(getarg(0),.@lvl+1,0);
return;
}
// Returns the intelligence cost based on skill level
// sk_intcost( sk )
function script sk_intcost {
.@cost=(getskilllv(getarg(0))+1)*17;
if (readparam(bInt) >= .@cost)
return 1;
return 0;
}
// Returns a value defining your current magic control (affects success ratio, higher is better)
// A value of '5' means perfect control, and a value of '0' means overwhelm.
// abizit()
function script abizit {
.@base=(MAGIC_LVL**3);
return min(MAGIC_EXP/.@base, 5);
}
// Returns, based on a 1-5 range, the title for both thief and merc ranks
// thiefrank() / mercrank()
function script thiefrank {
switch (THIEF_RANK) {
case 5: return l("Bandit Lord");
case 4: return l("Assassin");
case 3: return l("Rogue");
case 2: return l("Bandit");
case 1: return l("Thief");
default: return l("Error");
}
}
function script mercrank {
switch (MERC_RANK) {
case 5: return l("Constable");
case 4: return l("Guardian");
case 3: return l("Merchant");
case 2: return l("Trader");
case 1: return l("Fair Person");
default: return l("Error");
}
}
// gettimeparam(GETTIME_X)
// Returns the number of seconds/minutes/hours/days/months/years since 01/01/1970
function script gettimeparam {
.@p=getarg(0, GETTIME_MINUTE);
// Seconds
.@t=gettimetick(2);
if (.@p == GETTIME_SECOND)
return .@t;
// Minutes (default)
.@t=.@t/60;
if (.@p == GETTIME_MINUTE)
return .@t;
// Hours
.@t=.@t/60;
if (.@p == GETTIME_HOUR)
return .@t;
// Days
.@t=.@t/24;
if (.@p == GETTIME_DAYOFMONTH)
return .@t;
// Months (estimative)
.@t=.@t/30;
if (.@p == GETTIME_MONTH)
return .@t;
// Years (estimative, unused, fallback)
.@t=.@t/12;
return .@t;
}
// Something went wrong and must be reported (I tried to keep a syntax close to 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_PLEASEREPORT)
dispbottom("Please take a screenshot and report this bug, explaining how it happened.");
if (.@gf & RB_ISFATAL) {
if (.@gf & RB_SPEECH) {
mesc l("This error is fatal."), 1;
close;
}
if (.@gf & RB_DISPBOTTOM)
dispbottom("This error is fatal, we stop execution.");
if (.@gf & RB_DEBUGMES)
debugmes("[Error] The error is fatal.");
end;
}
return getarg(2, 0);
}
// Upon entering a town
// EnterTown( LocName )
function script EnterTown {
// Fill variable
.@v$=getarg(0);
// Validade variable, see npc/000-1/exit.txt first
setarray .@locs$, "Candor", "Tulim", "Halin", "Hurns", "LoF", "Lilit", "Nival", "Frostia";
if (array_find(.@locs$, .@v$) < 0)
return Exception("Invalid location passed to EnterTown: "+.@v$);
LOCATION$=.@v$;
return;
}