// TMW2 scripts.
// Authors:
// Jesusalva
// TMW Org.
// Description:
// HUB functions (Login, Logout, Death)
// HUB_Login ()
function script HUB_Login {
getmapxy(.@mapa$, .@a,.@b, 0);
// Login on Blue Sage Workshop/Library
if (.@mapa$ == "020-7-1") {
addtimer(1000, "#BlueSageHUB::OnCycle");
}
// Random Treasure cleaning
if (CLEANUP < gettimetick(2)-CHEST_WAITTIME)
deletearray RNGTREASURE_DATE;
return;
}
// HUB_Logout ( {dead} )
function script HUB_Logout {
.@dead=getarg(0, false);
getmapxy(.@mapa$, .@a,.@b, 0);
// Vanished on Cindy Cave
if (.@mapa$ == "021-4" && strcharinfo(0) == $@CINDY_HERO$) {
donpcevent("Cindy#Outside::OnReckless");
recovery(getcharid(3));
warp any("010-1", "010-2"), 0, 0;
percentheal -100, -100;
sc_start2 SC_POISON, 1, 90, 10000;
heal -1, -1;
} else if (.@mapa$ == "021-4") {
.@pl = getmapusers("021-4")-1;
if (.@pl < 1)
donpcevent("Cindy#Outside::OnCleanUp");
recovery(getcharid(3));
warp "Save", 0, 0;
}
// Logout while donating blood
if (getq(HurnscaldQuest_BloodDonor) == 2) {
slide 35, 28;
setpcblock(PCBLOCK_ATTACK|PCBLOCK_SKILL|PCBLOCK_USEITEM|PCBLOCK_MOVE, false);
setq HurnscaldQuest_BloodDonor, 0, gettimetick(2)+3600; // one hour penalty
}
// Logout/Death on Nard's ship hold
if (compare(.@mapa$, "002-2") || compare(.@mapa$,"nard")) {
setq2 ShipQuests_Peter, 0;
setq3 ShipQuests_Peter, -1;
}
// Logout on botcheck area
if (compare(.@mapa$,"botcheck") && !.@dead) {
if (!is_staff())
atcommand "@jail "+strcharinfo(0);
}
// Died on Terranite Cave where exp penalty is lower
if (.@mapa$ == "015-6" && .@dead) {
@deathpenalty_override=2;
@deathpenalty_realvalue=readparam(BaseExp);
@deathpenalty_realvaljob=readparam(JobExp);
}
// Died or logged out at Tulimshar Arena (FIXME)
if (compare(.@mapa$, "ARENA")) {
if ('UDTf) {
'UDTf=0;
killmonster(getmap(), instance_npcname("Arnea#003-13")+"::OnGladius");
deltimer(instance_npcname("Arnea#003-13")+"::OnVerify");
}
}
// Died or logged during Bandit Lord fight
if (.@mapa$ == "015-2") {
if (isin("015-2", 228, 227, 282, 280))
killmonster("015-2", "#BanditLordDen::OnLordDeath");
}
// Died or logged out on Blue Sage House
if (.@mapa$ == "020-7-1") {
callfunc("BSClearNest", @nestid);
}
// Died or logged out on Player Story 5 - Forgotten Throne Room
if (compare(.@mapa$, "hmc")) {
if (@instid > 0)
.@n$=instance_npcname("#Core02331", @instid);
else
.@n$=instance_npcname("#Core02331");
deltimer(.@n$+"::OnW01");
deltimer(.@n$+"::OnW02");
deltimer(.@n$+"::OnE07");
deltimer(.@n$+"::OnE08");
deltimer(.@n$+"::OnE09");
deltimer(.@n$+"::OnE10");
deltimer(.@n$+"::OnE11");
deltimer(.@n$+"::OnE12");
killmonsterall(getmap());
}
// Died or logged out on Player Story 6 - Forgotten Shrine
if (compare(.@mapa$, "brb3")) {
//.@n$=instance_npcname("#Core02331");
.@q=getq(LoFQuest_Barbara);
// Reset quest to: Forgotten Chamber Puzzle incomplete
if (.@q < 4) {
setq1 LoFQuest_Barbara, 1;
setq3 LoFQuest_Barbara, 1;
dispbottom col(l("WARNING: You died at Forgotten Shrine and the Shrine defense triggered."), 1);
dispbottom col(l("WARNING: Your progress on the quest was lost!"), 1);
}
}
// Died or logged out during Sagratha Fight
if (compare(.@mapa$, "sgt2")) {
setq1 HurnscaldQuest_Sagratha, 3;
setq3 HurnscaldQuest_Sagratha, 0;
}
// First death produces a warning message
if (PC_DIE_COUNTER <= 1 && .@dead) {
dispbottom l("Dying outside a town square will cause EXP loss.");
}
// If you were travelling and died/logged out, cleaning is needed
if (@timer_navio_running) {
@timer_navio_running=0;
// Logged out? Correct your position to inside the ship
// Of course, this is messy... But still better than Save Point
if (!.@dead) {
if (compare(.@mapa$, "016-"))
warp "016-1", 28, 27;
else if (compare(.@mapa$, "002-"))
warp "002-1", 55, 40;
else
warp "Save", 0, 0;
}
}
// Crazyfefe hot fix
if (.@dead) {
// It was PK
if (killerrid > 2000000 && killerrid < 2100000) {
// PVP flag was off
/*
if (!getmapflag(.@mapa$, mf_pvp) && !getmapflag(.@mapa$, mf_pvp_noparty) && !getmapflag(.@mapa$, mf_pvpnoguild)) {
recovery(getcharid(3));
warp .@mapa$, .@a, .@b;
percentheal 100, 100;
dispbottom l("REVENGE TIME!");
.@trueid=getcharid(3);
//detachrid();
attachrid(killerrid);
setpcblock(PCBLOCK_ATTACK|PCBLOCK_SKILL|PCBLOCK_USEITEM|PCBLOCK_COMMANDS, true);
sc_start SC_WALKSPEED,120000,50;
sc_end SC_CASH_PLUSEXP;
sc_end SC_OVERLAPEXPUP;
sc_start SC_OVERLAPEXPUP, 300000, -20;
dispbottom l("For cowardingly killing in a \"secure\" area, you will be severely punished.");
//Karma+=1;
sc_start SC_STUN, 15000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK;
addtimer(15000, "#mobptsys::OnUnlock");
percentheal -88, -100;
detachrid();
attachrid(.@trueid);
}
*/
HONOR+=1;
}
}
// This allows code to override death penalty, just once:
// @deathpenalty_override
// Valid values: 1- No penalty. 2- Halved penalty.
// You must also set: @deathpenalty_realvalue and @deathpenalty_realvaljob
if (@deathpenalty_override && .@dead) {
if (is_staff())
debugmes("Old values: %d %d Current Values: %d %d", @deathpenalty_realvalue, @deathpenalty_realvaljob, readparam(BaseExp), readparam(JobExp));
addtimer(300, "#QuirinoHUB::OnNoPenaltyCommand");
}
// Register logout time
if (!.@dead)
CLEANUP=gettimetick(2);
return;
}
// HUB_SkillInvoke ( )
function script HUB_SkillInvoke {
// TODO: Detect what was script-cast and what was player-case. Then, readd RB_IRCBROADCAST
// If you can't do this: You can't do this
if (getskilllv(@skillId) < @skillLv)
Exception("System ERROR, HSI."+@skillId+" INVALID CAST (got "+@skillLv+" expected "+getskilllv(@skillId)+", sub-LC."+(getcharid(3)-2000000)+")", RB_DEBUGMES|RB_ISFATAL);
// Record to database
skillInvoke[@skillId] = skillInvoke[@skillId] + 1;
// Script-based skills
switch (@skillId) {
case TMW2_FAKESKILL:
atcommand("@refresh");
break;
case TMW2_MPREGEN:
SK_mpregen();
break;
case TMW2_FAKESKILL2:
//CMD_lang(); next; closeclientdialog;
CMD_toevent();
break;
case TMW2_CRAFT:
//case NV_BASIC:
//case TMW2_ANCIENTLANGUAGES:
//case TMW2_SPEECH:
UserCtrlPanel();
break;
case TMW2_ZARKOR:
SK_zarkor();
break;
case TMW2_PARUM:
SK_parum();
break;
case TMW2_KALMURK:
SK_summon(Maggot, 2, any(1,2));
break;
case TMW2_LIMERIZER:
SK_summon(any(GreenSlime,AzulSlime,RedSlime,AngryYellowSlime), 2, any(3,4));
break;
case TMW2_HALHISS:
.@mobId=Snake;
if (abizit() > 3 &&
GHMEMO[GHQ_GetQuestIDByMonsterID(MountainSnake)] >= 10000 &&
rand2(1,3) == 2)
{
.@mobId=MountainSnake;
}
SK_summon(.@mobId, 4, any(3,4));
break;
case TMW2_KALWULF:
SK_summon(Wolvern, 4, any(3,4));
break;
case TMW2_FAIRYKINGDOM:
// TODO: Allow Pixie summoning
SK_summon(any(FireFairy, EarthFairy, WaterFairy, WindFairy, PoisonFairy), 4, any(3,4));
break;
case TMW2_KALBOO:
SK_summon(Mouboo, 4, any(2,3));
break;
case TMW2_KALSPIKE:
SK_summon(PoisonSpikyMushroom, 4, any(2,3));
break;
// Special exception
case TMW2_TRANSMIGRATION:
doevent("sk#mkpot::OnCall");
break;
}
// Debug
if ($@GM_OVERRIDE || debug)
debugmes "Cast skill %d on level %d", @skillId, @skillLv;
return;
}
// When you kill a player, some special care is needed
// Only a few maps will give you experience for PK: Tulimshar's Guards Arena,
// Frostia Imperial PVP Arena, Call Of Dusty, Arena Quirino Voraz.
// HUB_PvP ( ) - killedrid must be set
function script HUB_PvP {
// Update global PK count
$PLAYERS_KILLED+=1;
// Prepare local variables
.@atk=get_BR(getcharid(3));
.@def=get_BR(killedrid);
.@honor=calc_HR(.@atk, .@def);
.@m$=getmap();
// This is an official PVP Map
if (ispvpmap(.@m$)) {
// Honorable Death
if (.@honor) {
HONOR+=.@honor;
} else {
// Dishonorable... But... Legit?
if (is_bandit(killedrid)) {
HONOR+=1;
} else {
// Did the defensor cheat? (within Level+30% rule)
if (BaseLevel < readparam(BaseLevel, killedrid)*13/10)
HONOR+=1; // Ehhhhhh............ Well.
else
HONOR+=.@honor; // It's negative.
}
}
// It was a duel!
} else {
// Honorable Duel: HONOR +30%
if (.@honor)
HONOR+=max(1, .@honor*3/10);
else
HONOR+=1;
// ^ Dishonorable duel, but was a duel!
}
// Report about honor
dispbottom l("%d vs %d: Honor (%d)", .@atk, .@def, .@honor);
// TODO: Start using readparam2() to read if the opponent was worthy
// That is, read total attack, defense, HP, evasion and hit chance
// And compare with your own readparam2(), then use a % and a table
// based on your (assassin's) level.
.@bxp=readparam(BaseLevel, killedrid);
.@jxp=readparam(JobLevel, killedrid);
if (compare(.@m$, "001-8")) {
// Quirino Voraz PVP Arena
// You get 5 times killed player level, and 1 time job level
getexp .@bxp*5, .@jxp;
} else if (compare(.@m$, "ARENA") || compare(.@m$, "003-13")) {
// Tulimshar Duel Arena
// You get 3 times killed player level, and 2 times job level
getexp .@bxp*3, .@jxp*2;
} else if (compare(.@m$, "001-10")) {
// Call Of Dusty
// You get 3 times killed player level, and 3 times job level
getexp .@bxp*3, .@jxp*3;
} else if (compare(.@m$, "001-10-1")) {
// Call Of Dusty Boss Room
// You _may_ get a Bottled Dusty at random, but dead player status affect
.@bagistr=(readparam2(bAgi, killedrid)*2)+readparam2(bDex, killedrid);
//.@b2=readparam(MaxHp, killedrid);
if (.@bagistr > 20)
if (rand2(0,250) < readparam2(bLuk)+readparam2(bLuk, killedrid))
getitem BottledDust, any(1,1,2);
} else {
// Anywhere else
// You get 0.5 times killed player level, and 0 times job level
getexp (.@bxp/2), 0;
}
return;
}