Bladeren bron

Merge branch 'rathena/master'

Cydh Ramdh 11 jaren geleden
bovenliggende
commit
f756d7e249

+ 1 - 1
db/re/item_combo_db.txt

@@ -138,7 +138,7 @@
 2479:2580:2890:15042,{ bonus bAspd,2; bonus2 bSkillAtk,"RA_ARROWSTORM",50; bonus bLongAtkRate,30; bonus3 bAutoSpell,"AC_DOUBLE",(getskilllv("AC_DOUBLE") < 3)?3:getskilllv("AC_DOUBLE"),20; }
 2480:2581:2891:15043,{ bonus bMaxHPRate,15; bonus bFlee2,20; bonus2 bSkillAtk,"RA_CLUSTERBOMB",20; bonus bLongAtkRate,-30; bonus bAspd,-7; }
 2483:2586:15046,{ bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; }
-2484:2587:15047,{ bonus bDex,5; bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; }
+2484:2586:15047,{ bonus bDex,5; bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; }
 2485:2587:15048,{ bonus bInt,5; bonus bMdef,10; bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; }
 2518:2648:2649:5126,{ bonus bInt,5; bonus bMdef,11; bonus bMaxSPrate,20; bonus bNoCastCancel,0; bonus bVariableCastrate,25; }
 2519:2650:2651:5127,{ bonus bStr,2; bonus bLuk,9; bonus bCritical,13; bonus bBaseAtk,18; bonus bFlee2,13; }

+ 4 - 4
db/re/item_db.txt

@@ -2579,12 +2579,12 @@
 4571,Gertie_Card,Gertie Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "RG_CLOSECONFINE",1; },{},{}
 4572,Randel_Card,Randel Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "CR_AUTOGUARD",3; },{},{}
 4573,Trentini_Card,Trentini Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; if(BaseJob==Job_Dancer) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;} },{},{}
-4574,General_Daehyon_Card,General Daehyon Card,6,20,,10,,,,,,,,2,,,,,{ if((getiteminfo(getequipid(EQI_HAND_R),14) == 3) || (getiteminfo(getequipid(EQI_HAND_R),14) == 4)) { bonus bBaseAtk,100; } },{},{}
-4575,Armed_Guard_Soheon_Card,Armed Guard Soheon Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,10; if(getiteminfo(getequipid(EQI_HAND_R),14) == 1) { if(getrefine()>=10) { bonus bAspd,1; } if(getrefine()>=14) { bonus bAspd,1; } } },{},{}
+4574,General_Daehyon_Card,General Daehyon Card,6,20,,10,,,,,,,,2,,,,,{ if((getiteminfo(getequipid(EQI_HAND_R),11) == 3) || (getiteminfo(getequipid(EQI_HAND_R),11) == 4)) { bonus bBaseAtk,100; } },{},{}
+4575,Armed_Guard_Soheon_Card,Armed Guard Soheon Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,10; if(getiteminfo(getequipid(EQI_HAND_R),11) == 1) { if(getrefine()>=10) { bonus bAspd,1; } if(getrefine()>=14) { bonus bAspd,1; } } },{},{}
 4576,Gioia_Card,Gioia Card,6,20,,10,,,,,,,,4,,,,,{ bonus2 bMagicAtkEle,4,100; bonus2 bMagicAtkEle,8,100; bonus2 bSubEle,0,-30; bonus2 bSubEle,1,-30; bonus2 bSubEle,2,-30; bonus2 bSubEle,3,-30; bonus2 bSubEle,4,-30; bonus2 bSubEle,5,-30; bonus2 bSubEle,6,-30; bonus2 bSubEle,7,-30; bonus2 bSubEle,8,-30; bonus2 bSubEle,9,-30; },{},{}
 4577,Elvira_Card,Elvira Card,6,20,,10,,,,,,,,136,,,,,{ bonus2 bMagicAtkEle,4,20; bonus2 bMagicAtkEle,8,20; },{},{}
 4578,Angry_Student_Pyuriel_Card,Angry Student Pyuriel Card,6,20,,10,,,,,,,,2,,,,,{ bonus bCritAtkRate,30; bonus2 bSubRace,0,-10; bonus2 bSubRace,1,-10; bonus2 bSubRace,2,-10; bonus2 bSubRace,3,-10; bonus2 bSubRace,4,-10; bonus2 bSubRace,5,-10; bonus2 bSubRace,6,-10; bonus2 bSubRace,7,-10; bonus2 bSubRace,8,-10; bonus2 bSubRace,9,-10; },{},{}
-4579,Warrior_Lola_Card,Warrior Lola Card,6,20,,10,,,,,,,,2,,,,,{ if(getiteminfo(getequipid(EQI_HAND_R),14) == 8) { bonus bBaseAtk,20; bonus bCritical,10; } bonus bBaseAtk,getrefine(); bonus bCritical,getrefine(); },{},{}
+4579,Warrior_Lola_Card,Warrior Lola Card,6,20,,10,,,,,,,,2,,,,,{ if(getiteminfo(getequipid(EQI_HAND_R),11) == 8) { bonus bBaseAtk,20; bonus bCritical,10; } bonus bBaseAtk,getrefine(); bonus bCritical,getrefine(); },{},{}
 4580,Dark_Guardian_Kades_Card,Dark Guardian Kades Card,6,20,,10,,,,,,,,4,,,,,{ bonus2 bSubEle,1,50; bonus2 bSubEle,2,50; bonus2 bSubEle,3,50; bonus2 bSubEle,4,50; bonus2 bSubEle,7,50; bonus2 bSubEle,9,50; bonus2 bSubEle,6,-100; bonus2 bSubEle,8,-100; },{},{}
 4581,Rudo_Card,Rudo Card,6,20,,10,,,,,,,,64,,,,,{ /* TODO: { heal 0,-40; bonus_script "{ bonus bAgi,44; }",3,15,0; sc_start SC_SpeedUp1,3000,0; } */},{},{}
 4582,Bungisngis_Card,Bungisngis Card,6,20,,10,,,,,,,,769,,,,,{ bonus bMaxHPrate,(getrefine()/2); },{},{}
@@ -2612,7 +2612,7 @@
 4604,Realized_Corruption_Root_Card,Realized Corruption Root Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,30; bonus5 bAutoSpellWhenHit,"NPC_WIDESTONE",2,70,BF_WEAPON,0; bonus5 bAutoSpellWhenHit,"NPC_WIDESLEEP",2,70,BF_WEAPON,0; bonus5 bAutoSpellWhenHit,"NPC_WIDECURSE",2,70,BF_WEAPON,0; },{},{}
 4605,Agony_Of_Royal_Knight_Card,Agony Of Royal Knight Card,6,20,,10,,,,,,,,16,,,,,{ bonus bMaxHPrate,-44; bonus bHPGainValue,200+10*getrefine(); },{},{}
 4606,Grudge_of_Royal_Knight_Card,Grudge of Royal Knight Card,6,20,,10,,,,,,,,4,,,,,{ bonus bMaxSPrate,-44; bonus bSPGainValue,20+(getrefine()/2); },{},{ heal 0,-444; }
-4607,Faithful_Manager_Card,Faithful Manager Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,5; bonus bMatk,5; if(getiteminfo(getequipid(EQI_HAND_R),14) == 15) { if(getrefine()>=10) { bonus bBaseAtk,20; bonus bMatk,20; } if(getrefine()>=14) { bonus bBaseAtk,20; bonus bMatk,20; } } },{},{}
+4607,Faithful_Manager_Card,Faithful Manager Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,5; bonus bMatk,5; if(getiteminfo(getequipid(EQI_HAND_R),11) == 15) { if(getrefine()>=10) { bonus bBaseAtk,20; bonus bMatk,20; } if(getrefine()>=14) { bonus bBaseAtk,20; bonus bMatk,20; } } },{},{}
 4608,White_Knight_Card,White Knight Card,6,20,,10,,,,,,,,2,,,,,{ bonus bBaseAtk,15; bonus2 bAddSize,Size_Medium,20; bonus2 bAddSize,Size_Large,20; },{},{}
 4609,Khalitzburg_Knight_Card,Khalitzburg Knight Card,6,20,,10,,,,,,,,32,,,,,{ bonus bDef,20; bonus2 bSubSize,Size_Medium,25; bonus2 bSubSize,Size_Large,25; },{},{}
 

+ 58 - 0
doc/script_commands.txt

@@ -1964,6 +1964,64 @@ with this command when a script is parsed.
 
 ---------------------------------------
 
+*switch (expression);
+
+The switch statement is similar to a series of if statements on the same expression.
+In many occasions, you may want to compare the same variable (or expression)
+with many different values, and execute a different piece of code depending
+on which value it equals to. This is exactly what the switch statement is for.
+
+It is important to understand how the switch statement is executed in order
+to avoid mistakes. The switch statement executes line by line (actually, statement by statement).
+In the beginning, no code is executed. Only when a case statement is found
+with a value that matches the value of the switch expression the case statement(s)
+will to executed. The parser continues to execute the statements until the end
+of the switch block, or the first time it sees a break statement. If you don't
+write a break statement at the end of a case's statement list, the parser will
+go on executing the statements of the following case (fall-through).
+
+Example 1:
+	
+	switch(select("Yes:No")) {
+		case 1:
+			mes "You said yes!";
+			break;
+		case 2:
+			mes "Aww, why?";
+			break;
+	}
+	close;
+
+The example above would work like a menu and would go to the first case if
+the user selects option, otherwise, would go to the second one.
+
+Example 2:
+	
+	switch(getgroupid()) {
+		case 1:
+			mes "Wow, you're super!";
+			break;
+		case 2:
+			mes "A helping hand!";
+			break;
+		case 3:
+			mes "10001010010011";
+			break;
+		case 4:
+			mes "Yes, milord?";
+			break;
+		default:
+			mes "Hello there!";
+			break;		
+	}
+
+The example above would print a message depending on the player's groupid.
+If there is no statement declared for the corresponding groupid, the script
+would use the 'default' statement that applies to rest of possible values,
+similar to 'else' in the if-else statement.
+
+---------------------------------------
+
 *while (<condition>) <statement>;
 
 This is probably the simplest and most frequently used loop structure. The 'while' 

+ 2 - 2
npc/battleground/kvm/kvm_enter.txt

@@ -49,7 +49,7 @@ bat_room,164,178,5	script	KVM Mercenary Officer#1	418,{
 		if (BaseLevel > 79)  warp "bat_room",169,223;
 		else if (BaseLevel < 60) warp "bat_room",197,223;
 		else warp "bat_room",225,223;
-		close;
+		end;
 	case 2:
 		mes "[Guillaume Mercenary Officer]";
 		mes "We will win!";
@@ -149,7 +149,7 @@ bat_room,164,121,1	script	KVM Mercenary Officer#2	414,{
 		if (BaseLevel > 79) warp "bat_room",169,207;
 		else if (BaseLevel < 60) warp "bat_room",197,207;
 		else warp "bat_room",225,207;
-		close;
+		end;
 	case 2:
 		mes "[Croix Mercenary Officer]";
 		mes "We will win!";

+ 3 - 3
npc/re/guild/invest_main.txt

@@ -224,7 +224,7 @@ function	script	F_Invest_Abyss	{
 	}
 }
 
-// Script Core
+// Script Core :: agit_fund
 //============================================================
 prt_gld,1,1,0	script	#fund_master	844,{
 	end;
@@ -1252,7 +1252,7 @@ L_Enter:
 	}
 }
 
-// Item Investments
+// Item Investments :: tooja_namis
 //============================================================
 malangdo,218,126,4	script	Cat Paw Merchants Notice	857,{
 	mes "<< Cat Paw Merchants Notice >>";
@@ -1458,7 +1458,7 @@ OnTouch:
 	end;
 }
 
-// Investment Rewards
+// Investment Rewards :: tooja_japanki
 //============================================================
 malangdo,215,119,4	script	Thanks Ticket Machine	564,{
 	if (MaxWeight - Weight < 4500 || checkweight(1201,1) == 0) {

+ 2 - 0
npc/re/merchants/advanced_refiner.txt

@@ -18,6 +18,8 @@
 //= 1.0 Added Malangdo Refiner "Holink". [Euphy]
 //============================================================
 
+// Main NPC :: mal_jerun
+//============================================================
 malangdo,221,174,6	script	Holink#mal_cash	559,{
 	disable_items;
 	mes "[Holink]";

+ 2 - 0
npc/re/merchants/alchemist.txt

@@ -14,6 +14,8 @@
 //=     Updated dialogue to match the official script.
 //============================================================ 
 
+// Main NPC :: craft_book_alche_skill_npc
+//============================================================
 alde_alche,31,186,3	script	Craft Book Merchant#alde	883,{
 	mes "[Craft Book Merchant]";
 	mes "Welcome.";

+ 2 - 0
npc/re/merchants/blessed_refiner.txt

@@ -17,6 +17,8 @@
 //= 1.0 First version. [Euphy]
 //============================================================
 
+// Main NPC :: new_smelting612
+//============================================================
 -	script	::BlacksmithDister	-1,{
 	disable_items;
 	mes "[Blacksmith Dister]";

File diff suppressed because it is too large
+ 3 - 4
npc/re/merchants/cash_trader-idRO.txt


+ 2 - 0
npc/re/merchants/diamond.txt

@@ -18,6 +18,8 @@
 //= 1.5 Added This Version History (#15429)
 //============================================================
 
+// Main NPC :: diamond
+//============================================================
 -	script	RareDiamondMerchant	58,{
 
 	set .@npc$, "[Rare Diamond Merchant]";

+ 2 - 0
npc/re/merchants/enchan_upg.txt

@@ -14,6 +14,8 @@
 //= 1.1 Standardizing, grammar and bug fixes. [Euphy]
 //============================================================
 
+// Main NPC :: 201105_luk_enc
+//============================================================
 prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 	disable_items;
 	if (checkweight(1201,1) == 0) {

+ 1 - 0
npc/re/merchants/flute.txt

@@ -15,6 +15,7 @@
 //= 1.2 Added Wolf Flute trader, optimized. [Euphy]
 //= 1.2a Fixed some conditions. [Euphy]
 //============================================================ 
+
 // Falcon Flute :: falcon_flute
 //============================================================
 -	script	Falcon Flute Trader::fflute	-1,{

+ 2 - 2
npc/re/merchants/hd_refiner.txt

@@ -18,7 +18,7 @@
 //= 1.0 First version. [Euphy]
 //============================================================
 
-// Blacksmith Mighty Hammer (+7~9)
+// Blacksmith Mighty Hammer (+7~9) :: cash_smelting79
 //============================================================
 -	script	::MightyHammer	-1,{
 	disable_items;
@@ -153,7 +153,7 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 // iRO NPC locations:
 // payon,174,133,4	duplicate(MightyHammer)	Mighty Hammer#im	826
 
-// Basta (+10 and up)
+// Basta (+10 and up) :: cash_smelting
 //============================================================
 -	script	::Basta	-1,{
 	disable_items;

+ 2 - 0
npc/re/merchants/quivers.txt

@@ -19,6 +19,8 @@
 //= 1.1 Updated to match the official scripts. [Euphy]
 //============================================================
 
+// Mora :: ep14_1_tre
+//============================================================
 mora,106,117,3	script	Quiver Maker#mora	516,{
 	if (checkweight(1201,1) == 0) {
 		mes "[Quiver Maker]";

+ 4 - 4
sql-files/item_db_re.sql

@@ -2610,12 +2610,12 @@ REPLACE INTO `item_db_re` VALUES (4570,'Flamel_Card','Flamel Card',6,20,NULL,10,
 REPLACE INTO `item_db_re` VALUES (4571,'Gertie_Card','Gertie Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "RG_CLOSECONFINE",1;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4572,'Randel_Card','Randel Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "CR_AUTOGUARD",3;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4573,'Trentini_Card','Trentini Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; if(BaseJob==Job_Dancer) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;}',NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (4574,'General_Daehyon_Card','General Daehyon Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'if((getiteminfo(getequipid(EQI_HAND_R),14) == 3) || (getiteminfo(getequipid(EQI_HAND_R),14) == 4)) { bonus bBaseAtk,100; }',NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (4575,'Armed_Guard_Soheon_Card','Armed Guard Soheon Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,10; if(getiteminfo(getequipid(EQI_HAND_R),14) == 1) { if(getrefine()>=10) { bonus bAspd,1; } if(getrefine()>=14) { bonus bAspd,1; } }',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (4574,'General_Daehyon_Card','General Daehyon Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'if((getiteminfo(getequipid(EQI_HAND_R),11) == 3) || (getiteminfo(getequipid(EQI_HAND_R),11) == 4)) { bonus bBaseAtk,100; }',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (4575,'Armed_Guard_Soheon_Card','Armed Guard Soheon Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,10; if(getiteminfo(getequipid(EQI_HAND_R),11) == 1) { if(getrefine()>=10) { bonus bAspd,1; } if(getrefine()>=14) { bonus bAspd,1; } }',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4576,'Gioia_Card','Gioia Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus2 bMagicAtkEle,4,100; bonus2 bMagicAtkEle,8,100; bonus2 bSubEle,0,-30; bonus2 bSubEle,1,-30; bonus2 bSubEle,2,-30; bonus2 bSubEle,3,-30; bonus2 bSubEle,4,-30; bonus2 bSubEle,5,-30; bonus2 bSubEle,6,-30; bonus2 bSubEle,7,-30; bonus2 bSubEle,8,-30; bonus2 bSubEle,9,-30;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4577,'Elvira_Card','Elvira Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,136,NULL,NULL,NULL,NULL,'bonus2 bMagicAtkEle,4,20; bonus2 bMagicAtkEle,8,20;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4578,'Angry_Student_Pyuriel_Card','Angry Student Pyuriel Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bCritAtkRate,30; bonus2 bSubRace,0,-10; bonus2 bSubRace,1,-10; bonus2 bSubRace,2,-10; bonus2 bSubRace,3,-10; bonus2 bSubRace,4,-10; bonus2 bSubRace,5,-10; bonus2 bSubRace,6,-10; bonus2 bSubRace,7,-10; bonus2 bSubRace,8,-10; bonus2 bSubRace,9,-10;',NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (4579,'Warrior_Lola_Card','Warrior Lola Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'if(getiteminfo(getequipid(EQI_HAND_R),14) == 8) { bonus bBaseAtk,20; bonus bCritical,10; } bonus bBaseAtk,getrefine(); bonus bCritical,getrefine();',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (4579,'Warrior_Lola_Card','Warrior Lola Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'if(getiteminfo(getequipid(EQI_HAND_R),11) == 8) { bonus bBaseAtk,20; bonus bCritical,10; } bonus bBaseAtk,getrefine(); bonus bCritical,getrefine();',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4580,'Dark_Guardian_Kades_Card','Dark Guardian Kades Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus2 bSubEle,1,50; bonus2 bSubEle,2,50; bonus2 bSubEle,3,50; bonus2 bSubEle,4,50; bonus2 bSubEle,7,50; bonus2 bSubEle,9,50; bonus2 bSubEle,6,-100; bonus2 bSubEle,8,-100;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4581,'Rudo_Card','Rudo Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,64,NULL,NULL,NULL,NULL,'/* TODO: { heal 0,-40; bonus_script "{ bonus bAgi,44; }",3,15,0; sc_start SC_SpeedUp1,3000,0; } */',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4582,'Bungisngis_Card','Bungisngis Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,769,NULL,NULL,NULL,NULL,'bonus bMaxHPrate,(getrefine()/2);',NULL,NULL);
@@ -2643,7 +2643,7 @@ REPLACE INTO `item_db_re` VALUES (4603,'Corruption_Root_Card','Corruption Root C
 REPLACE INTO `item_db_re` VALUES (4604,'Realized_Corruption_Root_Card','Realized Corruption Root Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,30; bonus5 bAutoSpellWhenHit,"NPC_WIDESTONE",2,70,BF_WEAPON,0; bonus5 bAutoSpellWhenHit,"NPC_WIDESLEEP",2,70,BF_WEAPON,0; bonus5 bAutoSpellWhenHit,"NPC_WIDECURSE",2,70,BF_WEAPON,0;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4605,'Agony_Of_Royal_Knight_Card','Agony Of Royal Knight Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16,NULL,NULL,NULL,NULL,'bonus bMaxHPrate,-44; bonus bHPGainValue,200+10*getrefine();',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4606,'Grudge_of_Royal_Knight_Card','Grudge of Royal Knight Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bMaxSPrate,-44; bonus bSPGainValue,20+(getrefine()/2);',NULL,'heal 0,-444;');
-REPLACE INTO `item_db_re` VALUES (4607,'Faithful_Manager_Card','Faithful Manager Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,5; bonus bMatk,5; if(getiteminfo(getequipid(EQI_HAND_R),14) == 15) { if(getrefine()>=10) { bonus bBaseAtk,20; bonus bMatk,20; } if(getrefine()>=14) { bonus bBaseAtk,20; bonus bMatk,20; } }',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (4607,'Faithful_Manager_Card','Faithful Manager Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,5; bonus bMatk,5; if(getiteminfo(getequipid(EQI_HAND_R),11) == 15) { if(getrefine()>=10) { bonus bBaseAtk,20; bonus bMatk,20; } if(getrefine()>=14) { bonus bBaseAtk,20; bonus bMatk,20; } }',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4608,'White_Knight_Card','White Knight Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bBaseAtk,15; bonus2 bAddSize,Size_Medium,20; bonus2 bAddSize,Size_Large,20;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (4609,'Khalitzburg_Knight_Card','Khalitzburg Knight Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,32,NULL,NULL,NULL,NULL,'bonus bDef,20; bonus2 bSubSize,Size_Medium,25; bonus2 bSubSize,Size_Large,25;',NULL,NULL);
 

+ 3 - 0
src/map/map.c

@@ -1646,6 +1646,9 @@ int map_quit(struct map_session_data *sd) {
 		return 0;
 	}
 
+	if (sd->expiration_tid != INVALID_TIMER)
+		delete_timer(sd->expiration_tid, pc_expiration_timer);
+
 	if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
 		npc_timerevent_quit(sd);
 

+ 68 - 8
src/map/pc.c

@@ -62,8 +62,10 @@ static unsigned int level_penalty[3][CLASS_MAX][MAX_LEVEL*2+1];
 // h-files are for declarations, not for implementations... [Shinomori]
 struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
 // timer for night.day implementation
-int day_timer_tid;
-int night_timer_tid;
+int day_timer_tid = INVALID_TIMER;
+int night_timer_tid = INVALID_TIMER;
+
+int pc_expiration_tid = INVALID_TIMER;
 
 struct fame_list smith_fame_list[MAX_FAME_LIST];
 struct fame_list chemist_fame_list[MAX_FAME_LIST];
@@ -1033,6 +1035,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	sd->invincible_timer = INVALID_TIMER;
 	sd->npc_timer_id = INVALID_TIMER;
 	sd->pvp_timer = INVALID_TIMER;
+	sd->expiration_tid = INVALID_TIMER;
 
 #ifdef SECURE_NPCTIMEOUT
 	// Initialize to defaults/expected
@@ -1138,12 +1141,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 				clif_displaymessage(sd->fd, motd_text[i]);
 		}
 
-		// message of the limited time of the account
-		if (expiration_time != 0) { // don't display if it's unlimited or unknow value
-			char tmpstr[1024];
-			strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(sd,501), localtime(&expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
-			clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
-		}
+		if (expiration_time != 0)
+			sd->expiration_time = expiration_time;
 
 		/**
 		 * Fixes login-without-aura glitch (the screen won't blink at this point, don't worry :P)
@@ -1345,6 +1344,15 @@ int pc_reg_received(struct map_session_data *sd)
 		clif_parse_LoadEndAck(sd->fd, sd);
 	}
 
+	if (sd->expiration_time != 0) { // don't display if it's unlimited or an unknown value
+		time_t exp_time = sd->expiration_time;
+		char tmpstr[1024];
+			strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(sd,501), localtime(&sd->expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
+			clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
+		
+		pc_expire_check(sd);
+	}
+
 	return 1;
 }
 
@@ -10501,6 +10509,56 @@ void pc_damage_log_clear(struct map_session_data *sd, int id)
 	}
 }
 
+int pc_expiration_timer(int tid, unsigned int tick, int id, intptr_t data) {
+	struct map_session_data *sd = map_id2sd(id);
+
+	if( !sd ) return 0;
+
+	sd->expiration_tid = INVALID_TIMER;
+
+	if( sd->fd )
+		clif_authfail_fd(sd->fd,10);
+
+	map_quit(sd);
+
+	return 0;
+}
+
+/* this timer exists only when a character with a expire timer > 24h is online */
+/* it loops thru online players once an hour to check whether a new < 24h is available */
+int pc_global_expiration_timer(int tid, unsigned int tick, int id, intptr_t data) {
+	struct s_mapiterator* iter;
+	struct map_session_data* sd;
+
+	iter = mapit_getallusers();
+
+	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+		if( sd->expiration_time )
+			pc_expire_check(sd);
+
+	mapit_free(iter);
+
+  return 0;
+}
+
+void pc_expire_check(struct map_session_data *sd) {  
+	/* ongoing timer */
+	if( sd->expiration_tid != INVALID_TIMER )
+		return;
+
+	/* not within the next 24h, enable the global check */
+	if( sd->expiration_time > (time(NULL) + ((60 * 60) * 24)) ) {
+
+		/* global check not running, enable */
+		if( pc_expiration_tid == INVALID_TIMER ) /* Starts in 1h, repeats every hour */
+			pc_expiration_tid = add_timer_interval(gettick() + ((1000 * 60) * 60), pc_global_expiration_timer, 0, 0, ((1000 * 60) * 60));
+
+		return;
+	}
+
+	sd->expiration_tid = add_timer(gettick() + (unsigned int)(sd->expiration_time - time(NULL)) * 1000, pc_expiration_timer, sd->bl.id, 0);
+}
+
 /**
 * Deposit some money to bank
 * @param sd
@@ -10734,6 +10792,8 @@ void do_init_pc(void) {
 	add_timer_func_list(pc_follow_timer, "pc_follow_timer");
 	add_timer_func_list(pc_endautobonus, "pc_endautobonus");
 	add_timer_func_list(pc_talisman_timer, "pc_talisman_timer");
+	add_timer_func_list(pc_global_expiration_timer, "pc_global_expiration_timer");
+	add_timer_func_list(pc_expiration_timer, "pc_expiration_timer");
 
 	add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
 

+ 11 - 0
src/map/pc.h

@@ -587,8 +587,15 @@ struct map_session_data {
 		int16 icon;
 		int tid;
 	} bonus_script[MAX_PC_BONUS_SCRIPT];
+
+	/* Expiration Timer ID */
+	int expiration_tid;
+	time_t expiration_time;
 };
 
+/* Global Expiration Timer ID */
+extern int pc_expiration_tid;
+
 enum weapon_type {
 	W_FIST,	//Bare hands
 	W_DAGGER,	//1
@@ -831,6 +838,10 @@ int pc_checkskill(struct map_session_data *sd,uint16 skill_id);
 short pc_checkequip(struct map_session_data *sd,int pos);
 bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
 
+int pc_expiration_timer(int tid, unsigned int tick, int id, intptr_t data);
+int pc_global_expiration_timer(int tid, unsigned tick, int id, intptr_t data);
+void pc_expire_check(struct map_session_data *sd);
+
 int pc_calc_skilltree(struct map_session_data *sd);
 int pc_calc_skilltree_normalize_job(struct map_session_data *sd);
 void pc_clean_skilltree(struct map_session_data *sd);

Some files were not shown because too many files changed in this diff