-Add Homon-S skills, 1st implementation (all done except Eleanors)

--Upd Skill conf to set land-limit for homonculus by default (ground skill limit)
--Mv MH_HEILIGE_STANGE and MH_ANGRIFFS_MODUS skill from Eleanor to Bayeri

-Enforce all zeny transaction to use pc_payzeny and pc_getzeny handlers, (auto log and clif)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16914 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
glighta 2012-11-12 00:06:25 +00:00
parent e1a327c223
commit 752776e4cc
27 changed files with 1149 additions and 807 deletions

View File

@ -144,7 +144,7 @@ player_cloak_check_type: 1
monster_cloak_check_type: 4
// Can't place unlimited land skills at the same time (Note 3)
land_skill_limit: 1
land_skill_limit: 9
//Determines which kind of skill-failed messages should be sent:
// 1 - Disable all skill-failed messages.

View File

@ -95,6 +95,8 @@
6049,8031,5,0,0,0,0,0,0,0,0,0,0 //MH_STAHL_HORN
6049,8032,5,0,0,0,0,0,0,0,0,0,0 //MH_GOLDENE_FERSE
6049,8033,5,0,0,0,0,0,0,0,0,0,0 //MH_STEINWAND
6049,8034,5,0,0,0,0,0,0,0,0,0,0 //MH_HEILIGE_STANGE
6049,8035,5,0,0,0,0,0,0,0,0,0,0 //MH_ANGRIFFS_MODUS
//Sera
6050,8018,5,0,0,0,0,0,0,0,0,0,0 //MH_SUMMON_LEGION
6050,8019,5,0,0,0,0,0,0,0,0,0,0 //MH_NEEDLE_OF_PARALYZE
@ -111,8 +113,6 @@
6052,8028,5,0,0,0,0,0,0,0,0,0,0 //MH_SONIC_CRAW
6052,8029,5,0,0,0,0,0,0,0,0,0,0 //MH_SILVERVEIN_RUSH
6052,8030,5,0,0,0,0,0,0,0,0,0,0 //MH_MIDNIGHT_FRENZY
6052,8034,5,0,0,0,0,0,0,0,0,0,0 //MH_HEILIGE_STANGE
6052,8035,5,0,0,0,0,0,0,0,0,0,0 //MH_ANGRIFFS_MODUS
6052,8036,5,0,0,0,0,0,0,0,0,0,0 //MH_TINDER_BREAKER
6052,8037,5,0,0,0,0,0,0,0,0,0,0 //MH_CBC
6052,8038,5,0,0,0,0,0,0,0,0,0,0 //MH_EQC

View File

@ -1722,23 +1722,23 @@
//==========================================
//-- MH_SUMMON_LEGION
8018,2000,0,0,0,20000:30000:40000:50000:60000,0,400:600:800:1000:1200
8018,1600:1400:1200:1000:800,0,0,20000:30000:40000:50000:60000,0,0,400:600:800:1000:1200
//-- MH_NEEDLE_OF_PARALYZE
8019,1500,0,0,0,0,0,500:400:300:200:100
8019,1000:1100:1200:1300:1400,0,0,12000:14000:16000:18000:20000,0,0,500:400:300:200:100
//-- MH_POISON_MIST
8020,1000:1200:1400:1600:1800,0,0,0,12000:14000:16000:18000:20000,0,500
8020,500:700:900:1100:1300,0,0,12000:14000:16000:18000:20000,4000:6000:8000:10000:12000,0,500
//-- MH_PAIN_KILLER
8021,2000,0,0,0,20000:30000:40000:50000:60000,0,1000:800:600:400:200
8021,1000:1200:1400:1600:1800,0,0,20000:30000:40000:50000:60000,0,0,1000:800:600:400:200
//-- MH_LIGHT_OF_REGENE
8022,1600:1400:1200:1000:800,0,0,0,360000:420000:480000:540000:600000,0,1600:1400:1200:1000:800
8022,1600:1400:1200:1000:800,0,0,360000:420000:480000:540000:600000,0,0,1600:1400:1200:1000:800
//-- MH_OVERED_BOOST
8023,1000,0,0,0,30000:45000:60000:75000:90000,0,200:300:400:500:600
8023,800:700:600:500:400,0,0,30000:45000:60000:75000:90000,0,0,200:300:400:500:600
//-- MH_ERASER_CUTTER
8024,1000:1500:2000:2500:3000,0,0,0,0,0,0
8024,1000:1500:2000:2500:3000,0,0,0,0,0,-1
//-- MH_XENO_SLASHER
8025,2000:3000:4000:5000:6000,0,0,0,500,0,500
8025,1500:2500:3500:4500:5500,0,0,500,0,0,500
//-- MH_SILENT_BREEZE
8026,2000,0,0,0,9000:12000:15000:18000:21000,0,1000:800:600:400:200
8026,2000,0,0,9000:12000:15000:18000:21000,0,0,1000:800:600:400:200
//-- MH_STYLE_CHANGE
//8027,0,0,0,0,0,0,0
//-- MH_SONIC_CRAW
@ -1748,15 +1748,15 @@
//-- MH_MIDNIGHT_FRENZY
//8030,0,0,0,0,0,0,0
//-- MH_STAHL_HORN
8031,1000,0,0,0,0,0,200:400:600:800:1000
8031,800:600:400:200:0,0,0,5000,0,0,200:400:600:800:1000
//-- MH_GOLDENE_FERSE
8032,1000:1200:1400:1600:1800,0,0,0,30000:45000:60000:75000:90000,0,0
8032,1000:1200:1400:1600:1800,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_STEINWAND
8033,1000,0,0,0,30000:45000:60000:75000:90000,0,0
8033,1000,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_HEILIGE_STANGE
8034,2000,0,0,0,0,0,1800:1600:1400:1200:1000
//-- MH_ANGRIFFS_MODUS
8035,200:400:600:800:1000,0,0,0,30000:45000:60000:75000:90000,0,0
8035,200:400:600:800:1000,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_TINDER_BREAKER
//8036,0,0,0,0,0,0,0
//-- MH_CBC
@ -1764,15 +1764,15 @@
//-- MH_EQC
//8038,0,0,0,0,0,0,0
//-- MH_MAGMA_FLOW
8039,4000,0,0,0,30000:45000:60000:75000:90000,0,2000:1500:1000:500:0
8039,2000:2500:3000:3500:4000,0,0,30000:45000:60000:75000:90000,0,0,2000:1500:1000:500:-1
//-- MH_GRANITIC_ARMOR
8040,6000:5500:5000:4500:4000,0,0,0,0,0,1000
8040,6000:5500:5000:4500:4000,0,0,60000,0,0,1000
//-- MH_LAVA_SLIDE
8041,6000:5500:5000:4500:4000,0,0,0,12000:14000:16000:18000:20000,0,1000
8041,6000:5500:5000:4500:4000,0,0,12000:14000:16000:18000:20000,0,0,1000
//-- MH_PYROCLASTIC
8042,6000:5500:5000:4500:4000,0,0,0,60000:90000:120000:150000:180000,0,1000
8042,5000:4500:4000:3500:3000,0,0,60000:90000:120000:150000:180000,0,0,1000
//-- MH_VOLCANIC_ASH
8043,5000:4500:4000:3500:3000,0,0,0,12000:14000:16000:18000:20000,0,1000
8043,5000:4500:4000:3500:3000,0,0,12000:14000:16000:18000:20000,0,0,1000
//===== Mercenary Skills ===================
//-- MS_MAGNUM

View File

@ -1075,30 +1075,30 @@
8015,0,0,0,0,0x1,0,5,0,no,0,0,0,none,0, HVAN_INSTRUCT,Instruct
8016,4,6,4,-1,0xD2,4,3,1,no,0,0,0,misc,0, HVAN_EXPLOSION,Bio Explosion
//
8018,9,6,1,0,0x1,0,5,1,no,0,0,0,none,0, MH_SUMMON_LEGION,Summon Legion
8018,9,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_SUMMON_LEGION,Summon Legion
8019,5,6,1,5,0,0,5,1,no,0,0,0,weapon,0, MH_NEEDLE_OF_PARALYZE,Needle of Paralyze
8020,5,6,2,5,0,0,5,1,no,0,0,1,weapon,0, MH_POISON_MIST,Nevoa Venenosa
8020,5,6,2,5,0,0,5,1,no,0,0,1,weapon,0, MH_POISON_MIST,Poison Mist
8021,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0, MH_PAIN_KILLER,Pain Killer
8022,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_LIGHT_OF_REGENE,Light of Regene
8023,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_OVERED_BOOST,Overed Boost
8024,7,6,1,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_ERASER_CUTTER,Corte Ilusório
8024,7,6,1,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_ERASER_CUTTER,Eraser Cutter
8025,7,6,2,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_XENO_SLASHER,Xeno Slasher
8026,5:5:7:7:9,6,16,0,0x1,0,5,1,no,0,0,0,magic,0, MH_SILENT_BREEZE,Silent Breeze
8027,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, MH_STYLE_CHANGE,Style Change
8028,1,8,1,0,0,0,5,1,no,0,0,0,weapon,0, MH_SONIC_CRAW,Sonic Claw
8029,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_SILVERVEIN_RUSH,Silver Bain Rush
8030,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_MIDNIGHT_FRENZY,Midnight Frenzy
8031,5:6:7:8:9,6,1,0,0,0,5,1,no,0,0,0,weapon,3, MH_STAHL_HORN,Chifre de Aço
8032,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_GOLDENE_FERSE,Ferraduras de Ouro
8031,5:6:7:8:9,6,1,0,0,0,5,1,no,0,0,0,weapon,3, MH_STAHL_HORN,Steel Horn
8032,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_GOLDENE_FERSE,Golden Heel
8033,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_STEINWAND,Stone Wall
8034,9,6,1,6,0x2,1:1:1:1:2,5,1,no,0,0,0,magic,0, MH_HEILIGE_STANGE,Holy Pole
8035,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_ANGRIFFS_MODUS,Modo de Ataque
8035,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_ANGRIFFS_MODUS,Attack Mode
8036,3:4:5:6:7,6,1,0,0,0,5,1,no,0,0,0,weapon,0, MH_TINDER_BREAKER,Tinder Breaker
8037,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_CBC,Continual Break Combo
8038,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_EQC,Eternal Quick Combo
8039,0,6,4,3,0x2,1:1:1:2:2,5,1,no,0,0,0,weapon,0, MH_MAGMA_FLOW,Magma Flow
8040,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, MH_GRANITIC_ARMOR,Granitic Armor
8041,7,6,2,3,0x2,0,5,1,no,0,0,1,weapon,0, MH_LAVA_SLIDE,Deslizamento de Lava
8041,7,6,2,3,0x2,0,5,1,no,0,0,1,weapon,0, MH_LAVA_SLIDE,Lava Slide
8042,0,6,4,3,0x1,0,5,1,no,0,0,0,none,0, MH_PYROCLASTIC,Pyroclastic
8043,7,6,2,0,0x1,0,5,1,no,0,0,3,none,0, MH_VOLCANIC_ASH,Volcanic Ash

View File

@ -163,8 +163,8 @@
8020,0xf5, , 0, 3,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST
8033,0x7e, , 0, 0, -1,all, 0x003 //MH_STEINWAND
8025,0x86, , 0, 2:2:3:3:4,1000,enemy, 0x018 //MH_XENO_SLASHER
8041,0xf6, , 1:1:2:2:3, 0,1000,enemy, 0x018 //MH_LAVA_SLIDE
8043,0xf7, , 0, 1,1000,enemy, 0x018 //MH_VOLCANIC_ASH
8041,0xf6, , 1:1:2:2:3, 0,2000,enemy, 0x01A //MH_LAVA_SLIDE
8043,0xf7, , 1, 0,-1,enemy, 0x2018 //MH_VOLCANIC_ASH
8208,0x86, , 0, 2,1000,enemy, 0x080 //MA_SHOWER
8209,0x90, , 0, 1,1000,enemy, 0x006 //MA_SKIDTRAP

View File

@ -2196,7 +2196,7 @@ ACMD_FUNC(killmonster)
if ((map_id = map_mapname2mapid(map_name)) < 0)
map_id = sd->bl.m;
}
drop_flag = strcmp(command+1, "killmonster2");
map_foreachinmap(atkillmonster_sub, map_id, BL_MOB, -drop_flag);
@ -2533,25 +2533,7 @@ ACMD_FUNC(zeny)
clif_displaymessage(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>).
return -1;
}
new_zeny = sd->status.zeny + zeny;
if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow
new_zeny = MAX_ZENY;
else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow
new_zeny = 0;
if (new_zeny != sd->status.zeny) {
sd->status.zeny = new_zeny;
clif_updatestatus(sd, SP_ZENY);
clif_displaymessage(fd, msg_txt(176)); // Current amount of zeny changed.
} else {
if (zeny < 0)
clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
else
clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
return -1;
}
pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL);
return 0;
}
@ -3393,7 +3375,7 @@ ACMD_FUNC(spiritball)
if( sd->spiritball > 0 )
pc_delspiritball(sd, sd->spiritball, 1);
sd->spiritball = number;
clif_spiritball(sd);
clif_spiritball(&sd->bl);
// no message, player can look the difference
return 0;

View File

@ -367,6 +367,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
if( tsc->data[SC_ASH]) damage += damage/2; //150%
break;
case ELE_HOLY:
if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2;
@ -482,7 +483,14 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT )
{
struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
int skill_id = sc->data[SC_SAFETYWALL]->val2;
if (group) {
if(skill_id == MH_STEINWAND){
if (--group->val2<=0)
skill_delunitgroup(group);
d->dmg_lv = ATK_BLOCK;
return 0;
}
/**
* in RE, SW possesses a lifetime equal to 3 times the caster's health
**/
@ -730,6 +738,16 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
//Reduction: 6% + 6% every 20%
damage -= damage * 6 * (1+per) / 100;
}
if(sc->data[SC_GRANITIC_ARMOR]){
damage -= damage * sc->data[SC_GRANITIC_ARMOR]->val2/100;
}
if(sc->data[SC_PAIN_KILLER]){
damage -= damage * sc->data[SC_PAIN_KILLER]->val3/100;
}
if((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) ){
skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
}
/**
* In renewal steel body reduces all incoming damage by 1/10
**/
@ -787,6 +805,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
if (sc->data[SC_STYLE_CHANGE] && rnd() % 100 < 50) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) hom_addspiritball(hd, 10); //add a sphere
}
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
status_change_spread(bl, src); // Deadly infect attacked side
@ -846,6 +868,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
status_change_spread(src, bl);
if (sc->data[SC_STYLE_CHANGE] && rnd() % 100 < 50) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) hom_addspiritball(hd, 10);
}
}
if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
@ -1480,6 +1506,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
break;
}
if (!(nk & NK_NO_ELEFIX) && !n_ele)
if (src->type == BL_HOM)
n_ele = true; //skill is "not elemental"
if (sc && sc->data[SC_GOLDENE_FERSE] && ((!skill_num && (rnd() % 100 < sc->data[SC_GOLDENE_FERSE]->val4)) || skill_num == MH_STAHL_HORN)) {
s_ele = s_ele_ = ELE_HOLY;
n_ele = false;
}
if(!skill_num)
{ //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2)
if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0)
@ -1818,7 +1852,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skillratio += sc->data[SC_OVERTHRUST]->val3;
if(sc->data[SC_MAXOVERTHRUST])
skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
if(sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
skillratio += 100;
if(sc->data[SC_ZENKAI] && sstatus->rhw.ele == sc->data[SC_ZENKAI]->val2 )
skillratio += sc->data[SC_ZENKAI]->val1 * 2;
@ -2564,12 +2598,18 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case KO_BAKURETSU:
skillratio = 50 * skill_lv * (sd?pc_checkskill(sd,NJ_TOBIDOUGU):10);
break;
case MH_NEEDLE_OF_PARALYZE:
skillratio += 600 + 100 * skill_lv;
break;
case MH_STAHL_HORN:
skillratio += 500 + 100 * skill_lv;
skillratio += 400 + 100 * skill_lv;
break;
case MH_LAVA_SLIDE:
skillratio = 70 * skill_lv;
break;
case MH_MAGMA_FLOW:
skillratio += -100 + 100 * skill_lv;
break;
}
ATK_RATE(skillratio);
@ -2686,6 +2726,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
ATK_ADDRATE(sc->data[SC_EDP]->val3);
}
}
if(sc->data[SC_STYLE_CHANGE]){
TBL_HOM *hd = BL_CAST(BL_HOM,src);
if (hd) ATK_ADD(hd->spiritball * 3);
}
}
switch (skill_num) {
@ -3890,10 +3935,19 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += 1100;
break;
case MH_ERASER_CUTTER:
if (skill_lv >= 3)
skillratio += 800 + 200 * skill_lv ;
else
skillratio += 500 + 400 * skill_lv;
if(skill_lv%2) skillratio += 400; //600:800:1000
else skillratio += 700; //1000:1200
skillratio += 100 * skill_lv;
break;
case MH_XENO_SLASHER:
if(skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700
else skillratio += 400 + 100 * skill_lv; //700:900
break;
case MH_HEILIGE_STANGE:
skillratio += 400 + 250 * skill_lv;
break;
case MH_POISON_MIST:
skillratio += 100 * skill_lv;
break;
}
@ -4403,7 +4457,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
if( sd ) {
if ( md.damage > sd->status.zeny )
md.damage = sd->status.zeny;
pc_payzeny(sd, md.damage);
pc_payzeny(sd, md.damage,LOG_TYPE_STEAL,NULL);
}
break;
}

View File

@ -366,17 +366,14 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
zeny = amount*pl_sd->buyingstore.items[listidx].price;
// log
log_zeny(sd, LOG_TYPE_BUYING_STORE, pl_sd, zeny);
// move item
pc_additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE);
pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
pl_sd->buyingstore.items[listidx].amount-= amount;
// pay up
pc_payzeny(pl_sd, zeny);
pc_getzeny(sd, zeny);
pc_payzeny(pl_sd, zeny, LOG_TYPE_BUYING_STORE, sd);
pc_getzeny(sd, zeny, LOG_TYPE_BUYING_STORE, pl_sd);
pl_sd->buyingstore.zenylimit-= zeny;
// notify clients

View File

@ -1356,7 +1356,7 @@ int clif_spawn(struct block_list *bl)
TBL_PC *sd = ((TBL_PC*)bl);
int i;
if (sd->spiritball > 0)
clif_spiritball(sd);
clif_spiritball(&sd->bl);
if(sd->state.size==SZ_BIG) // tiny/big players [Valaris]
clif_specialeffect(bl,423,AREA);
else if(sd->state.size==SZ_MEDIUM)
@ -5440,12 +5440,12 @@ void clif_GlobalMessage(struct block_list* bl, const char* message) {
char buf[100];
int len;
nullpo_retv(bl);
if(!message)
return;
len = strlen(message)+1;
if( len > sizeof(buf)-8 ) {
ShowWarning("clif_GlobalMessage: Truncating too long message '%s' (len=%d).\n", message, len);
len = sizeof(buf)-8;
@ -5465,7 +5465,7 @@ void clif_GlobalMessage(struct block_list* bl, const char* message) {
void clif_MainChatMessage(const char* message) {
uint8 buf[200];
int len;
if(!message)
return;
@ -6896,20 +6896,27 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd)
clif_send(buf, packet_len(0x1cf), src, AREA);
}
/*==========================================
* Server tells clients nearby 'sd' (and himself) to display 'sd->spiritball' number of spiritballs on 'sd'
* Notifies clients in an area of an object's spirits.
* 01d0 <id>.L <amount>.W (ZC_SPIRITS)
* 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
*------------------------------------------*/
void clif_spiritball(struct block_list *bl) {
unsigned char buf[16];
TBL_PC *sd = BL_CAST(BL_PC,bl);
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
/// Notifies clients in an area of an object's spirits.
/// 01d0 <id>.L <amount>.W (ZC_SPIRITS)
/// 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
void clif_spiritball(struct map_session_data *sd)
{
unsigned char buf[8];
nullpo_retv(bl);
nullpo_retv(sd);
WBUFW(buf,0)=0x1d0;
WBUFL(buf,2)=sd->bl.id;
WBUFW(buf,6)=sd->spiritball;
clif_send(buf,packet_len(0x1d0),&sd->bl,AREA);
WBUFW(buf, 0) = 0x1d0;
WBUFL(buf, 2) = bl->id;
WBUFW(buf, 6) = 0; //init to 0
switch(bl->type){
case BL_PC: WBUFW(buf, 6) = sd->spiritball; break;
case BL_HOM: WBUFW(buf, 6) = hd->spiritball; break;
}
clif_send(buf, packet_len(0x1d0), bl, AREA);
}
@ -8205,7 +8212,7 @@ void clif_message(struct block_list* bl, const char* msg) {
unsigned short msg_len = strlen(msg) + 1;
uint8 buf[256];
nullpo_retv(bl);
if( msg_len > sizeof(buf)-8 ) {
ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
msg_len = sizeof(buf)-8;
@ -8215,7 +8222,7 @@ void clif_message(struct block_list* bl, const char* msg) {
WBUFW(buf,2) = msg_len + 8;
WBUFL(buf,4) = bl->id;
safestrncpy((char*)WBUFP(buf,8), msg, msg_len);
clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
}
@ -14220,8 +14227,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
pc_delitem(sd, sd->auction.index, sd->auction.amount, 1, 6, LOG_TYPE_AUCTION);
sd->auction.amount = 0;
log_zeny(sd, LOG_TYPE_AUCTION, sd, -zeny);
pc_payzeny(sd, zeny);
pc_payzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
}
}
@ -14265,8 +14271,7 @@ void clif_parse_Auction_bid(int fd, struct map_session_data *sd)
else if ( CheckForCharServer() ) // char server is down (bugreport:1138)
clif_Auction_message(fd, 0); // You have failed to bid into the auction
else {
log_zeny(sd, LOG_TYPE_AUCTION, sd, -bid);
pc_payzeny(sd, bid);
pc_payzeny(sd, bid, LOG_TYPE_AUCTION, NULL);
intif_Auction_bid(sd->status.char_id, sd->status.name, auction_id, bid);
}
}

View File

@ -454,7 +454,7 @@ void clif_skillunit_update(struct block_list* bl);
void clif_autospell(struct map_session_data *sd,int skilllv);
void clif_devotion(struct block_list *src, struct map_session_data *tsd);
void clif_spiritball(struct map_session_data *sd);
void clif_spiritball(struct block_list *bl);
void clif_combo_delay(struct block_list *bl,int wait);
void clif_bladestop(struct block_list *src, int dst_id, int active);
void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target target);

View File

@ -408,7 +408,7 @@ int guild_created(int account_id,int guild_id)
sd->status.guild_id=guild_id;
clif_guild_created(sd,0);
if(battle_config.guild_emperium_check)
pc_delitem(sd,pc_search_inventory(sd,714),1,0,0,LOG_TYPE_CONSUME); // <20>G<EFBFBD><47><EFBFBD>y<EFBFBD><79><EFBFBD>E<EFBFBD><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pc_delitem(sd,pc_search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption
return 0;
}

View File

@ -81,6 +81,46 @@ int hom_class2mapid(int hom_class)
}
}
int hom_addspiritball(TBL_HOM *hd, int max) {
nullpo_ret(hd);
if (max > MAX_SKILL_LEVEL)
max = MAX_SKILL_LEVEL;
if (hd->spiritball < 0)
hd->spiritball = 0;
if (hd->spiritball && hd->spiritball >= max) {
hd->spiritball = max;
}
else
hd->spiritball++;
clif_spiritball(&hd->bl);
return 0;
}
int hom_delspiritball(TBL_HOM *hd, int count, int type) {
nullpo_ret(hd);
if (hd->spiritball <= 0) {
hd->spiritball = 0;
return 0;
}
if (count <= 0)
return 0;
if (count > MAX_SKILL_LEVEL)
count = MAX_SKILL_LEVEL;
if (count > hd->spiritball)
count = hd->spiritball;
hd->spiritball -= count;
if (!type)
clif_spiritball(&hd->bl);
return 0;
}
void merc_damage(struct homun_data *hd) {
clif_hominfo(hd->master,hd,0);
}

View File

@ -45,6 +45,8 @@ struct homun_data {
int hungry_timer; //[orn]
unsigned int exp_next;
char blockskill[MAX_SKILL]; // [orn]
int spiritball; //for homun S [lighta]
};
#define HOM_EVO 0x100 //256
@ -112,4 +114,7 @@ void merc_hom_init_timers(struct homun_data * hd);
void merc_skill_reload(void);
void merc_reload(void);
int hom_addspiritball(TBL_HOM *hd, int max);
int hom_delspiritball(TBL_HOM *hd, int count, int type);
#endif /* _HOMUNCULUS_H_ */

View File

@ -50,7 +50,7 @@ extern int char_fd; // inter server Fd used for char_fd
#define inter_fd char_fd // alias
//-----------------------------------------------------------------
// Send to inter server
// Send to inter server
int CheckForCharServer(void)
{
@ -417,7 +417,7 @@ int intif_request_partyinfo(int party_id, int char_id)
return 0;
}
// Request to add a member to party
// Request to add a member to party
int intif_party_addmember(int party_id,struct party_member *member)
{
if (CheckForCharServer())
@ -460,11 +460,11 @@ int intif_party_leave(int party_id,int account_id, int char_id)
return 0;
}
// Request keeping party for new map ??
// Request keeping party for new map ??
int intif_party_changemap(struct map_session_data *sd,int online)
{
int m, mapindex;
if (CheckForCharServer())
return 0;
if(!sd)
@ -487,7 +487,7 @@ int intif_party_changemap(struct map_session_data *sd,int online)
return 1;
}
// Request breaking party
// Request breaking party
int intif_break_party(int party_id)
{
if (CheckForCharServer())
@ -687,7 +687,7 @@ int intif_guild_change_memberinfo(int guild_id,int account_id,int char_id,
return 0;
}
// Request a change of Guild title
// Request a change of Guild title
int intif_guild_position(int guild_id,int idx,struct guild_position *p)
{
if (CheckForCharServer())
@ -702,7 +702,7 @@ int intif_guild_position(int guild_id,int idx,struct guild_position *p)
return 0;
}
// Request an update of Guildskill skillnum
// Request an update of Guildskill skillnum
int intif_guild_skillup(int guild_id, int skill_num, int account_id, int max)
{
if( CheckForCharServer() )
@ -857,7 +857,7 @@ int intif_homunculus_requestdelete(int homun_id)
// Wisp/Page reception // rewritten by [Yor]
int intif_parse_WisMessage(int fd)
{
{
struct map_session_data* sd;
char *wisp_source;
char name[NAME_LENGTH];
@ -881,7 +881,7 @@ int intif_parse_WisMessage(int fd)
sd->ignore[i].name[0] != '\0' &&
strcmp(sd->ignore[i].name, wisp_source) != 0
; i++);
if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0')
{ //Ignored
intif_wis_replay(id, 2);
@ -913,7 +913,7 @@ static int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va)
char *wisp_name;
char *message;
int len;
if (!pc_has_permission(sd, permission))
return 0;
wisp_name = va_arg(va, char*);
@ -1006,7 +1006,7 @@ int intif_parse_LoadGuildStorage(int fd)
struct guild_storage *gstor;
struct map_session_data *sd;
int guild_id;
guild_id = RFIFOL(fd,8);
if(guild_id <= 0)
return 1;
@ -1426,7 +1426,7 @@ int intif_parse_questlog(int fd)
sd->quest_index[i] = quest_search_db(sd->quest_log[i].quest_id);
if( sd->quest_index[i] < 0 )
{
{
ShowError("intif_parse_questlog: quest %d not found in DB.\n",sd->quest_log[i].quest_id);
sd->avail_quests--;
sd->num_quests--;
@ -1786,7 +1786,7 @@ static void intif_parse_Auction_results(int fd)
int intif_Auction_register(struct auction_data *auction)
{
int len = sizeof(struct auction_data) + 4;
if( CheckForCharServer() )
return 0;
@ -1795,7 +1795,7 @@ int intif_Auction_register(struct auction_data *auction)
WFIFOW(inter_fd,2) = len;
memcpy(WFIFOP(inter_fd,4), auction, sizeof(struct auction_data));
WFIFOSET(inter_fd,len);
return 1;
}
@ -1827,8 +1827,7 @@ static void intif_parse_Auction_register(int fd)
clif_Auction_message(sd->fd, 4);
pc_additem(sd, &auction.item, auction.item.amount, LOG_TYPE_AUCTION);
log_zeny(sd, LOG_TYPE_AUCTION, sd, zeny);
pc_getzeny(sd, zeny);
pc_getzeny(sd, zeny, LOG_TYPE_AUCTION,NULL);
}
}
@ -1925,8 +1924,7 @@ static void intif_parse_Auction_bid(int fd)
clif_Auction_message(sd->fd, result);
if( bid > 0 )
{
log_zeny(sd, LOG_TYPE_AUCTION, sd, bid);
pc_getzeny(sd, bid);
pc_getzeny(sd, bid, LOG_TYPE_AUCTION,NULL);
}
if( result == 1 )
{ // To update the list, display your buy list
@ -2041,10 +2039,10 @@ int intif_parse_mercenary_saved(int fd)
int intif_elemental_create(struct s_elemental *ele)
{
int size = sizeof(struct s_elemental) + 4;
if( CheckForCharServer() )
return 0;
WFIFOHEAD(inter_fd,size);
WFIFOW(inter_fd,0) = 0x307c;
WFIFOW(inter_fd,2) = size;
@ -2062,7 +2060,7 @@ int intif_parse_elemental_received(int fd)
ShowError("intif: create elemental data size error %d != %d\n", sizeof(struct s_elemental), len);
return 0;
}
elemental_data_received((struct s_elemental*)RFIFOP(fd,5), RFIFOB(fd,4));
return 0;
}
@ -2071,7 +2069,7 @@ int intif_elemental_request(int ele_id, int char_id)
{
if (CheckForCharServer())
return 0;
WFIFOHEAD(inter_fd,10);
WFIFOW(inter_fd,0) = 0x307d;
WFIFOL(inter_fd,2) = ele_id;
@ -2084,7 +2082,7 @@ int intif_elemental_delete(int ele_id)
{
if (CheckForCharServer())
return 0;
WFIFOHEAD(inter_fd,6);
WFIFOW(inter_fd,0) = 0x307e;
WFIFOL(inter_fd,2) = ele_id;
@ -2096,17 +2094,17 @@ int intif_parse_elemental_deleted(int fd)
{
if( RFIFOB(fd,2) != 1 )
ShowError("Elemental data delete failure\n");
return 0;
}
int intif_elemental_save(struct s_elemental *ele)
{
int size = sizeof(struct s_elemental) + 4;
if( CheckForCharServer() )
return 0;
WFIFOHEAD(inter_fd,size);
WFIFOW(inter_fd,0) = 0x307f;
WFIFOW(inter_fd,2) = size;
@ -2119,7 +2117,7 @@ int intif_parse_elemental_saved(int fd)
{
if( RFIFOB(fd,2) != 1 )
ShowError("Elemental data save failure\n");
return 0;
}
@ -2127,18 +2125,18 @@ void intif_request_accinfo( int u_fd, int aid, int group_id, char* query ) {
WFIFOHEAD(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
WFIFOW(inter_fd,0) = 0x3007;
WFIFOL(inter_fd,2) = u_fd;
WFIFOL(inter_fd,6) = aid;
WFIFOL(inter_fd,10) = group_id;
safestrncpy(WFIFOP(inter_fd,14), query, NAME_LENGTH);
WFIFOSET(inter_fd,2 + 4 + 4 + 4 + NAME_LENGTH);
return;
}
void intif_parse_MessageToFD(int fd) {
int u_fd = RFIFOL(fd,4);
@ -2151,9 +2149,9 @@ void intif_parse_MessageToFD(int fd) {
safestrncpy(msg, (char*)RFIFOP(fd,12), RFIFOW(fd,2) - 12);
clif_displaymessage(u_fd,msg);
}
}
return;
}
@ -2250,7 +2248,7 @@ int intif_parse(int fd)
case 0x387c: intif_parse_elemental_received(fd); break;
case 0x387d: intif_parse_elemental_deleted(fd); break;
case 0x387e: intif_parse_elemental_saved(fd); break;
case 0x3880: intif_parse_CreatePet(fd); break;
case 0x3881: intif_parse_RecvPetData(fd); break;
case 0x3882: intif_parse_SavePetOk(fd); break;

View File

@ -48,9 +48,7 @@ int mail_removezeny(struct map_session_data *sd, short flag)
if (flag && sd->mail.zeny > 0)
{ //Zeny send
log_zeny(sd, LOG_TYPE_MAIL, sd, -sd->mail.zeny);
sd->status.zeny -= sd->mail.zeny;
pc_payzeny(sd,sd->mail.zeny,LOG_TYPE_MAIL, NULL);
}
sd->mail.zeny = 0;
clif_updatestatus(sd, SP_ZENY);
@ -59,10 +57,10 @@ int mail_removezeny(struct map_session_data *sd, short flag)
}
unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
if( pc_istrading(sd) )
return 1;
if( idx == 0 ) { // Zeny Transfer
if( amount < 0 || !pc_can_give_items(sd) )
return 1;
@ -88,7 +86,7 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
sd->mail.index = idx;
sd->mail.nameid = sd->status.inventory[idx].nameid;
sd->mail.amount = amount;
return 0;
}
}
@ -96,7 +94,7 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg)
{
int n;
nullpo_retr(false,sd);
nullpo_retr(false,msg);
@ -140,8 +138,7 @@ void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item
if( zeny > 0 )
{ //Zeny receive
log_zeny(sd, LOG_TYPE_MAIL, sd, zeny);
pc_getzeny(sd, zeny);
pc_getzeny(sd, zeny,LOG_TYPE_MAIL, NULL);
}
}
@ -170,13 +167,9 @@ void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg)
if( msg->zeny > 0 )
{
//Zeny receive (due to failure)
log_zeny(sd, LOG_TYPE_MAIL, sd, msg->zeny);
sd->status.zeny += msg->zeny;
clif_updatestatus(sd, SP_ZENY);
pc_getzeny(sd,msg->zeny,LOG_TYPE_MAIL, NULL); //Zeny receive (due to failure)
}
clif_Mail_send(sd->fd, true);
}

View File

@ -2290,7 +2290,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
}
}
if(zeny) // zeny from mobs [Valaris]
pc_getzeny(tmpsd[i], zeny);
pc_getzeny(tmpsd[i], zeny, LOG_TYPE_PICKDROP_MONSTER, NULL);
}
}
@ -2430,7 +2430,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
if( sd->bonus.get_zeny_num && rnd()%100 < sd->bonus.get_zeny_rate ) {
i = sd->bonus.get_zeny_num > 0 ? sd->bonus.get_zeny_num : -md->level * sd->bonus.get_zeny_num;
if (!i) i = 1;
pc_getzeny(sd, 1+rnd()%i);
pc_getzeny(sd, 1+rnd()%i, LOG_TYPE_OTHER, NULL);
}
}

View File

@ -199,7 +199,7 @@ int npc_enable(const char* name, int flag)
} else
clif_changeoption(&nd->bl);
if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
map_foreachinarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd );
return 0;
@ -302,7 +302,7 @@ int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char
/**
* Exec name (NPC events) on player or global
* Do on all NPC when called with foreach
* Do on all NPC when called with foreach
* @see DBApply
*/
int npc_event_doall_sub(DBKey key, DBData *data, va_list ap)
@ -411,22 +411,22 @@ int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
case 6: day = "Sat"; break;
default:day = ""; break;
}
sprintf(buf,"OnMinute%02d",t->tm_min);
c += npc_event_doall(buf);
sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min);
c += npc_event_doall(buf);
sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min);
c += npc_event_doall(buf);
}
if (t->tm_hour != ev_tm_b.tm_hour) {
sprintf(buf,"OnHour%02d",t->tm_hour);
c += npc_event_doall(buf);
}
if (t->tm_mday != ev_tm_b.tm_mday) {
sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday);
c += npc_event_doall(buf);
@ -539,13 +539,13 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data)
sd->npc_timer_id = INVALID_TIMER;
else
nd->u.scr.timerid = INVALID_TIMER;
ers_free(timer_event_ers, ted);
}
// Run the script
run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
nd->u.scr.rid = old_rid; // Attached-rid should be restored anyway.
if( sd )
{ // Restore previous data, only if this timer is a player-attached one.
@ -564,7 +564,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
unsigned int tick = gettick();
struct map_session_data *sd = NULL; //Player to whom script is attached.
struct timer_event_data *ted;
nullpo_ret(nd);
// Check if there is an OnTimer Event
@ -584,7 +584,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
}
else if( nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick )
return 0;
if (j < nd->u.scr.timeramount)
{
// Arrange for the next event
@ -606,7 +606,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
}
else if (!sd)
{
nd->u.scr.timertick = tick;
nd->u.scr.timertick = tick;
}
return 0;
@ -627,7 +627,7 @@ int npc_timerevent_stop(struct npc_data* nd)
ShowError("npc_timerevent_stop: Attached player not found!\n");
return 1;
}
tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
if( *tid == INVALID_TIMER && (sd || !nd->u.scr.timertick) ) // Nothing to stop
return 0;
@ -700,7 +700,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
nd->u.scr.rid = sd->bl.id;
nd->u.scr.timertick = gettick();
nd->u.scr.timer = ted->time;
//Execute label
run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
@ -855,7 +855,7 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
xs = nd->u.scr.xs;
ys = nd->u.scr.ys;
if( sd->bl.m != nd->bl.m ||
if( sd->bl.m != nd->bl.m ||
sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
pc_ishiding(sd) || leavemap )
@ -1012,7 +1012,7 @@ int npc_check_areanpc(int flag, int m, int x, int y, int range)
y0 = max(y-range, 0);
x1 = min(x+range, map[m].xs-1);
y1 = min(y+range, map[m].ys-1);
//First check for npc_cells on the range given
i = 0;
for (ys = y0; ys <= y1 && !i; ys++) {
@ -1106,7 +1106,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
{
char buffer[200];
char time[10];
strftime(time, sizeof(time), "%H:%M", localtime(&nd->u.tomb.kill_time));
// TODO: Find exact color?
@ -1117,7 +1117,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
snprintf(buffer, sizeof(buffer), msg_txt(659), time);
clif_scriptmes(sd, nd->bl.id, buffer);
clif_scriptmes(sd, nd->bl.id, msg_txt(660));
snprintf(buffer, sizeof(buffer), msg_txt(661), nd->u.tomb.killer_name[0] ? nd->u.tomb.killer_name : "Unknown");
@ -1128,7 +1128,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
/*==========================================
* NPC 1st call when clicking on npc
* Do specific action for NPC type (openshop, run scripts...)
* Do specific action for NPC type (openshop, run scripts...)
*------------------------------------------*/
int npc_click(struct map_session_data* sd, struct npc_data* nd)
{
@ -1179,7 +1179,7 @@ int npc_scriptcont(struct map_session_data* sd, int id)
nd?(char*)nd->name:"'Unknown NPC'", (int)id);
return 1;
}
if(id != fake_nd->bl.id) { // Not item script
if ((npc_checknear(sd,map_id2bl(id))) == NULL){
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
@ -1218,7 +1218,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL)
return 1;
if (nd->subtype!=SHOP) {
ShowError("no such shop npc : %d\n",id);
if (sd->npc_id == id)
@ -1459,7 +1459,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
int nameid, amount, value;
// find this entry in the shop's sell list
ARR_FIND( 0, nd->u.shop.count, j,
ARR_FIND( 0, nd->u.shop.count, j,
item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
);
@ -1515,11 +1515,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
if( pc_inventoryblank(sd) < new_ )
return 3; // Not enough space to store items
//Logs (S)hopping Zeny [Lupus]
log_zeny(sd, LOG_TYPE_NPC, sd, -(int)z);
//Logs
pc_payzeny(sd,(int)z);
pc_payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
for( i = 0; i < n; ++i )
{
@ -1584,7 +1580,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
script_cleararray_pc(sd, card_slot, (void*)0);
}
// save list of to be sold items
for( i = 0; i < n; i++ )
{
@ -1598,7 +1594,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
for( j = 0; j < MAX_SLOTS; j++ )
{// store each of the cards from the equipment in the array
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
@ -1691,11 +1687,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
if( z > MAX_ZENY )
z = MAX_ZENY;
//Logs (S)hopping Zeny [Lupus]
log_zeny(sd, LOG_TYPE_NPC, sd, (int)z);
//Logs
pc_getzeny(sd, (int)z);
pc_getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
@ -1793,13 +1785,13 @@ int npc_unload(struct npc_data* nd, bool single) {
if( nd->path && nd->path != npc_last_ref ) {
npd = strdb_get(npc_path_db, nd->path);
}
if( npd && --npd->references == 0 ) {
strdb_remove(npc_path_db, nd->path);/* remove from db */
aFree(nd->path);/* remove now that no other instances exist */
}
}
if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
aFree(nd->u.shop.shop_item);
else if( nd->subtype == SCRIPT ) {
@ -1809,7 +1801,7 @@ int npc_unload(struct npc_data* nd, bool single) {
if( single )
ev_db->foreach(ev_db,npc_unload_ev,nd->exname); //Clean up all events related
iter = mapit_geteachpc();
iter = mapit_geteachpc();
for( bl = (struct block_list*)mapit_first(iter); mapit_exists(iter); bl = (struct block_list*)mapit_next(iter) ) {
struct map_session_data *sd = ((TBL_PC*)bl);
if( sd && sd->npc_timer_id != INVALID_TIMER ) {
@ -1823,13 +1815,13 @@ int npc_unload(struct npc_data* nd, bool single) {
delete_timer(sd->npc_timer_id, npc_timerevent);
sd->npc_timer_id = INVALID_TIMER;
}
}
}
mapit_free(iter);
if (nd->u.scr.timerid != INVALID_TIMER) {
const struct TimerData *td = NULL;
td = get_timer(nd->u.scr.timerid);
if (td && td->data)
if (td && td->data)
ers_free(timer_event_ers, (void*)td->data);
delete_timer(nd->u.scr.timerid, npc_timerevent);
}
@ -1988,20 +1980,20 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta
ShowDebug("other npc in '%s' :\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n",dnd->path, dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y);
safestrncpy(nd->exname, newname, sizeof(nd->exname));
}
if( npc_last_path != filepath ) {
struct npc_path_data * npd = NULL;
if( !(npd = strdb_get(npc_path_db,filepath) ) ) {
CREATE(npd, struct npc_path_data, 1);
strdb_put(npc_path_db, filepath, npd);
CREATE(npd->path, char, strlen(filepath)+1);
safestrncpy(npd->path, filepath, strlen(filepath)+1);
npd->references = 0;
}
nd->path = npd->path;
npd->references++;
@ -2122,7 +2114,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
/// Parses a shop/cashshop npc.
static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
{
//TODO: could be rewritten to NOT need this temp array [ultramage]
//TODO: could be rewritten to NOT need this temp array [ultramage]
#define MAX_SHOPITEM 100
struct npc_item_list items[MAX_SHOPITEM];
char *p;
@ -2144,7 +2136,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
ShowError("npc_parse_shop: Invalid shop definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
return strchr(start,'\n');// skip and continue
}
m = map_mapname2mapid(mapname);
}
@ -2464,17 +2456,17 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
if( runOnInit ) {
char evname[EVENT_NAME_LENGTH];
struct event_data *ev;
snprintf(evname, ARRAYLENGTH(evname), "%s::OnInit", nd->exname);
if( ( ev = (struct event_data*)strdb_get(ev_db, evname) ) ) {
//Execute OnInit
run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
}
}
return end;
}
@ -2630,7 +2622,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
int npc_duplicate4instance(struct npc_data *snd, int m) {
char newname[NAME_LENGTH];
if( map[m].instance_id == 0 )
return 1;
@ -2858,9 +2850,9 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c
// split atcmd parameters based on spaces
i = 0;
j = 0;
temp = (char*)aMalloc(strlen(message) + 1);
while( message[i] != '\0' ) {
if( message[i] == ' ' && k < 127 ) {
temp[j] = '\0';
@ -3108,7 +3100,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
if (w4 && !strcmpi(w4, "off"))
state = 0; //Disable mapflag rather than enable it. [Skotlex]
if (!strcmpi(w3, "nosave")) {
char savemap[32];
int savex, savey;
@ -3556,7 +3548,7 @@ void npc_read_event_script(void)
ShowWarning("npc_read_event_script: too many occurences of event '%s'!\n", config[i].event_name);
break;
}
if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 )
{
script_event[i].event[count] = ed;
@ -3576,14 +3568,14 @@ void npc_read_event_script(void)
void npc_clear_pathlist(void) {
struct npc_path_data *npd = NULL;
DBIterator *path_list = db_iterator(npc_path_db);
DBIterator *path_list = db_iterator(npc_path_db);
/* free all npc_path_data filepaths */
for( npd = dbi_first(path_list); dbi_exists(path_list); npd = dbi_next(path_list) ) {
if( npd->path )
aFree(npd->path);
}
dbi_destroy(path_list);
}
@ -3596,12 +3588,12 @@ int npc_reload(void) {
struct block_list* bl;
npc_clear_pathlist();
db_clear(npc_path_db);
db_clear(npcname_db);
db_clear(ev_db);
//Remove all npcs/mobs. [Skotlex]
iter = mapit_geteachiddb();
@ -3662,20 +3654,20 @@ int npc_reload(void) {
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
do_final_instance();
for( i = 0; i < ARRAYLENGTH(instance); ++i )
instance_init(instance[i].instance_id);
//Re-read the NPC Script Events cache.
npc_read_event_script();
/* refresh guild castle flags on both woe setups */
npc_event_doall("OnAgitInit");
npc_event_doall("OnAgitInit2");
//Execute the OnInit event for freshly loaded npcs. [Skotlex]
ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
// Execute rest of the startup events if connected to char-server. [Lance]
if(!CheckForCharServer()){
ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
@ -3689,7 +3681,7 @@ bool npc_unloadfile( const char* path ) {
DBIterator * iter = db_iterator(npcname_db);
struct npc_data* nd = NULL;
bool found = false;
for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) {
if( nd->path && strcasecmp(nd->path,path) == 0 ) {
found = true;
@ -3697,12 +3689,12 @@ bool npc_unloadfile( const char* path ) {
npc_unload(nd, true);
}
}
dbi_destroy(iter);
if( found ) /* refresh event cache */
npc_read_event_script();
return found;
}
@ -3712,7 +3704,7 @@ void do_clear_npc(void) {
}
/*==========================================
* Destructor
* Destructor
*------------------------------------------*/
int do_final_npc(void) {
npc_clear_pathlist();
@ -3770,15 +3762,15 @@ int do_init_npc(void)
//Stock view data for normal npcs.
memset(&npc_viewdb, 0, sizeof(npc_viewdb));
npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
for( i = 1; i < MAX_NPC_CLASS; i++ )
for( i = 1; i < MAX_NPC_CLASS; i++ )
npc_viewdb[i].class_ = i;
ev_db = strdb_alloc((DBOptions)(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA),2*NAME_LENGTH+2+1);
npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH);
npc_path_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,80);
timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
// process all npc files
ShowStatus("Loading NPCs...\r");
for( file = npc_src_files; file != NULL; file = file->next ) {
@ -3822,6 +3814,6 @@ int do_init_npc(void)
fake_nd->u.scr.timerid = INVALID_TIMER;
map_addiddb(&fake_nd->bl);
// End of initialization
return 0;
}

View File

@ -36,7 +36,7 @@ static unsigned long party_booking_nextid = 1;
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
/*==========================================
* Fills the given party_member structure according to the sd provided.
* Fills the given party_member structure according to the sd provided.
* Used when creating/adding people to a party. [Skotlex]
*------------------------------------------*/
static void party_fill_member(struct party_member* member, struct map_session_data* sd, unsigned int leader)
@ -254,7 +254,7 @@ int party_recv_info(struct party* sp, int char_id)
int added_count = 0;
int i;
int member_id;
nullpo_ret(sp);
p = (struct party_data*)idb_get(party_db, sp->party_id);
@ -336,7 +336,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
struct party_data *p;
int i;
nullpo_ret(sd);
if( ( p = party_search(sd->status.party_id) ) == NULL )
@ -357,7 +357,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
clif_party_inviteack(sd, (tsd?tsd->status.name:""), 3);
return 0;
}
// confirm whether the account has the ability to invite before checking the player
if( !pc_has_permission(sd, PC_PERM_PARTY) || (tsd && !pc_has_permission(tsd, PC_PERM_PARTY)) ) {
clif_displaymessage(sd->fd, msg_txt(81)); // "Your GM level doesn't authorize you to preform this action on the specified player."
@ -386,7 +386,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
clif_party_inviteack(sd,tsd->status.name,0);
return 0;
}
tsd->party_invite=sd->status.party_id;
tsd->party_invite_account=sd->status.account_id;
@ -588,7 +588,7 @@ int party_broken(int party_id)
p = party_search(party_id);
if( p == NULL )
return 0;
if( p->instance_id )
{
instance[p->instance_id].party_id = 0;
@ -650,7 +650,7 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts
}
if( map[sd->bl.m].flag.partylock )
{
{
clif_displaymessage(sd->fd, msg_txt(287));
return false;
}
@ -714,7 +714,7 @@ int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short m
m->lv = lv;
//Check if they still exist on this map server
p->data[i].sd = party_sd_check(party_id, account_id, char_id);
clif_party_info(p,NULL);
return 0;
}
@ -741,7 +741,7 @@ void party_send_movemap(struct map_session_data *sd)
if (sd->fd) { // synchronize minimap positions with the rest of the party
for(i=0; i < MAX_PARTY; i++) {
if (p->data[i].sd &&
if (p->data[i].sd &&
p->data[i].sd != sd &&
p->data[i].sd->bl.m == sd->bl.m)
{
@ -765,7 +765,7 @@ int party_send_logout(struct map_session_data *sd)
if(!sd->status.party_id)
return 0;
intif_party_changemap(sd,0);
p=party_search(sd->status.party_id);
if(!p) return 0;
@ -775,7 +775,7 @@ int party_send_logout(struct map_session_data *sd)
memset(&p->data[i], 0, sizeof(p->data[0]));
else
ShowError("party_send_logout: Failed to locate member %d:%d in party %d!\n", sd->status.account_id, sd->status.char_id, p->party.party_id);
return 1;
}
@ -823,7 +823,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in
default:
return 0; //Unknown case?
}
for(i=0;i<MAX_PARTY;i++){
if ((p_sd = p->data[i].sd) == NULL)
continue;
@ -949,7 +949,7 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
pc_gainexp(sd[i], src, base_exp, job_exp, false);
if (zeny) // zeny from mobs [Valaris]
pc_getzeny(sd[i],zeny);
pc_getzeny(sd[i],zeny,LOG_TYPE_OTHER,NULL);
}
return 0;
}
@ -973,7 +973,7 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
if( (psd = p->data[i].sd) == NULL || sd->bl.m != psd->bl.m || pc_isdead(psd) || (battle_config.idle_no_share && pc_isidle(psd)) )
continue;
if (pc_additem(psd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))
continue; //Chosen char can't pick up loot.
@ -1008,7 +1008,7 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
}
}
if (!target) {
if (!target) {
target = sd; //Give it to the char that picked it up
if ((i=pc_additem(sd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)))
return i;
@ -1036,7 +1036,7 @@ int party_sub_count(struct block_list *bl, va_list ap)
if (sd->state.autotrade)
return 0;
if (battle_config.idle_no_share && pc_isidle(sd))
return 0;
@ -1052,9 +1052,9 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
struct block_list *list[MAX_PARTY];
int blockcount=0;
int total = 0; //Return value.
nullpo_ret(sd);
if((p=party_search(sd->status.party_id))==NULL)
return 0;
@ -1073,11 +1073,11 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
(psd->bl.x<x0 || psd->bl.y<y0 ||
psd->bl.x>x1 || psd->bl.y>y1 ) )
continue;
list[blockcount++]=&psd->bl;
list[blockcount++]=&psd->bl;
}
map_freeblock_lock();
for(i=0;i<blockcount;i++)
{
va_list ap;
@ -1120,7 +1120,7 @@ void party_booking_register(struct map_session_data *sd, short level, short mapi
clif_PartyBookingRegisterAck(sd, 2);
return;
}
memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH);
pb_ad->starttime = (int)time(NULL);
pb_ad->p_detail.level = level;
@ -1141,10 +1141,10 @@ void party_booking_update(struct map_session_data *sd, short* job)
struct party_booking_ad_info *pb_ad;
pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id);
if( pb_ad == NULL )
return;
pb_ad->starttime = (int)time(NULL);// Update time.
for(i=0;i<PARTY_BOOKING_JOBS;i++)
@ -1162,9 +1162,9 @@ void party_booking_search(struct map_session_data *sd, short level, short mapid,
struct party_booking_ad_info* result_list[PARTY_BOOKING_RESULTS];
bool more_result = false;
DBIterator* iter = db_iterator(party_booking_db);
memset(result_list, 0, sizeof(result_list));
for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) )
{
if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level)))

View File

@ -171,7 +171,7 @@ static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data
memmove(sd->spirit_timer+i, sd->spirit_timer+i+1, (sd->spiritball-i)*sizeof(int));
sd->spirit_timer[sd->spiritball] = INVALID_TIMER;
clif_spiritball(sd);
clif_spiritball(&sd->bl);
return 0;
}
@ -206,7 +206,7 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max)
if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD )
clif_millenniumshield(sd,sd->spiritball);
else
clif_spiritball(sd);
clif_spiritball(&sd->bl);
return 0;
}
@ -245,7 +245,7 @@ int pc_delspiritball(struct map_session_data *sd,int count,int type)
if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD )
clif_millenniumshield(sd,sd->spiritball);
else
clif_spiritball(sd);
clif_spiritball(&sd->bl);
}
return 0;
}
@ -3586,7 +3586,7 @@ int pc_inventoryblank(struct map_session_data *sd)
/*==========================================
* attempts to remove zeny from player (sd)
*------------------------------------------*/
int pc_payzeny(struct map_session_data *sd,int zeny)
int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
nullpo_ret(sd);
@ -3602,6 +3602,8 @@ int pc_payzeny(struct map_session_data *sd,int zeny)
sd->status.zeny -= zeny;
clif_updatestatus(sd,SP_ZENY);
if(!tsd) tsd = sd;
log_zeny(sd, type, tsd, -zeny);
if( zeny > 0 && sd->state.showzeny ) {
char output[255];
sprintf(output, "Removed %dz.", zeny);
@ -3700,8 +3702,9 @@ void pc_getcash(struct map_session_data *sd, int cash, int points)
/*==========================================
* Attempts to give zeny to player (sd)
* tsd (optional) from who for log (if null take sd)
*------------------------------------------*/
int pc_getzeny(struct map_session_data *sd,int zeny)
int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
nullpo_ret(sd);
@ -3717,6 +3720,8 @@ int pc_getzeny(struct map_session_data *sd,int zeny)
sd->status.zeny += zeny;
clif_updatestatus(sd,SP_ZENY);
if(!sd) tsd = sd;
log_zeny(sd, type, tsd, zeny);
if( zeny > 0 && sd->state.showzeny ) {
char output[255];
sprintf(output, "Gained %dz.", zeny);
@ -4569,8 +4574,7 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
{
int amount = md->level*10 + rnd()%100;
log_zeny(sd, LOG_TYPE_STEAL, sd, amount);
pc_getzeny(sd, amount);
pc_getzeny(sd, amount, LOG_TYPE_STEAL, NULL);
md->state.steal_coin_flag = 1;
return 1;
}
@ -6449,8 +6453,10 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
pet_unlocktarget(sd->pd);
}
if( sd->status.hom_id > 0 && battle_config.homunculus_auto_vapor )
merc_hom_vaporize(sd, 0);
if (sd->status.hom_id > 0){
if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE])
merc_hom_vaporize(sd, 0);
}
if( sd->md )
merc_delete(sd->md, 3); // Your mercenary soldier has ran away.
@ -6646,7 +6652,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
{
base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
if(base_penalty)
pc_payzeny(sd, base_penalty);
pc_payzeny(sd, base_penalty, LOG_TYPE_OTHER, NULL); //@TODO that type suck
}
}

View File

@ -74,7 +74,7 @@ struct s_addeffectonskill {
unsigned char target;
};
struct s_add_drop {
struct s_add_drop {
short id, group;
int race, rate;
};
@ -165,7 +165,7 @@ struct map_session_data {
int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
struct mmo_charstatus status;
struct registry save_reg;
struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
short equip_index[14];
unsigned int weight,max_weight;
@ -216,7 +216,7 @@ struct map_session_data {
unsigned int cansendmail_tick; // [Mail System Flood Protection]
unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
unsigned int bloodylust_tick; // bloodylust player timer [out/in re full-heal protection]
struct {
short nameid;
unsigned int tick;
@ -226,7 +226,7 @@ struct map_session_data {
short disguise; // [Valaris]
struct weapon_data right_weapon, left_weapon;
// here start arrays to be globally zeroed at the beginning of status_calc_pc()
int param_bonus[6],param_equip[6]; //Stores card/equipment bonuses.
int subele[ELE_MAX];
@ -350,7 +350,7 @@ struct map_session_data {
struct script_regstr *regstr;
int trade_partner;
struct {
struct {
struct {
short index, amount;
} item[10];
@ -464,7 +464,7 @@ struct map_session_data {
unsigned short *id;/* array of combo ids */
unsigned char count;
} combos;
/**
* Guarantees your friend request is legit (for bugreport:4629)
**/
@ -533,7 +533,7 @@ enum ammo_type {
//Equip position constants
enum equip_pos {
EQP_HEAD_LOW = 0x0001,
EQP_HEAD_LOW = 0x0001,
EQP_HEAD_MID = 0x0200, //512
EQP_HEAD_TOP = 0x0100, //256
EQP_HAND_R = 0x0002,
@ -559,7 +559,7 @@ enum equip_pos {
/// Equip positions that use a visible sprite
#if PACKETVER < 20110111
#define EQP_VISIBLE EQP_HELM
#else
#else
#define EQP_VISIBLE (EQP_HELM|EQP_GARMENT|EQP_COSTUME)
#endif
@ -608,7 +608,7 @@ enum equip_index {
#define pc_is50overweight(sd) ( (sd)->weight*100 >= (sd)->max_weight*battle_config.natural_heal_weight_rate )
#define pc_is90overweight(sd) ( (sd)->weight*10 >= (sd)->max_weight*9 )
#define pc_maxparameter(sd) ( ((((sd)->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO) || (sd)->class_&JOBL_THIRD ? ((sd)->class_&JOBL_BABY ? battle_config.max_baby_third_parameter : battle_config.max_third_parameter) : ((sd)->class_&JOBL_BABY ? battle_config.max_baby_parameter : battle_config.max_parameter)) )
/**
/**
* Ranger
**/
#define pc_iswug(sd) ( (sd)->sc.option&OPTION_WUG )
@ -649,7 +649,7 @@ enum equip_index {
#define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
#define pc_leftside_def(sd) ((sd)->battle_status.def)
#define pc_rightside_def(sd) ((sd)->battle_status.def2)
#define pc_rightside_def(sd) ((sd)->battle_status.def2)
#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef)
#define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) )
#endif
@ -695,9 +695,9 @@ int pc_memo(struct map_session_data* sd, int pos);
int pc_checkadditem(struct map_session_data*,int,int);
int pc_inventoryblank(struct map_session_data*);
int pc_search_inventory(struct map_session_data *sd,int item_id);
int pc_payzeny(struct map_session_data*,int);
int pc_payzeny(struct map_session_data*,int, enum e_log_pick_type type, struct map_session_data*);
int pc_additem(struct map_session_data*,struct item*,int,e_log_pick_type);
int pc_getzeny(struct map_session_data*,int);
int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_session_data*);
int pc_delitem(struct map_session_data*,int,int,int,short,e_log_pick_type);
// Special Shop System

File diff suppressed because it is too large Load Diff

View File

@ -615,6 +615,22 @@ int skillnotok_hom(int skillid, struct homun_data *hd)
if (hd->blockskill[i] > 0)
return 1;
switch(skillid){
case MH_LIGHT_OF_REGENE:
if(hd->homunculus.intimacy <= 750) //if not cordial
return 1;
break;
case MH_OVERED_BOOST:
if(hd->homunculus.hunger <= 1) //if we starving
return 1;
case MH_GOLDENE_FERSE: //can be used with angriff
if(hd->sc.data[SC_ANGRIFFS_MODUS])
return 1;
case MH_ANGRIFFS_MODUS:
if(hd->sc.data[SC_GOLDENE_FERSE])
return 1;
break;
}
//Use master's criteria.
return skillnotok(skillid, hd->master);
@ -796,17 +812,18 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
sc_start(src,SC_COMBO, 15, TK_TURNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
else if(sc->data[SC_READYCOUNTER])
{ //additional chance from SG_FRIEND [Komurka]
else if (sc->data[SC_READYCOUNTER]) { //additional chance from SG_FRIEND [Komurka]
rate = 20;
if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
sc_start4(src,SC_COMBO, rate, TK_COUNTER, bl->id,0,0,
sc_start2(src, SC_COMBO, rate, TK_COUNTER, bl->id,
(2000 - 4*sstatus->agi - 2*sstatus->dex));
}
}
if(sc && sc->data[SC_PYROCLASTIC] && (rnd() % 1000 <= sstatus->luk * 10 / 3 + 1) )
skill_castend_pos2(src, bl->x, bl->y, BS_HAMMERFALL,sc->data[SC_PYROCLASTIC]->val1, tick, 0);
}
if (sc) {
@ -1350,18 +1367,21 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case EL_TYPOON_MIS:
sc_start(bl,SC_SILENCE,10*skilllv,skilllv,skill_get_time(skillid,skilllv));
break;
case MH_LAVA_SLIDE:
sc_start4(bl,SC_BURNING,10*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
break;
case MH_STAHL_HORN:
sc_start(bl,SC_STUN,(20 + 4 * skilllv),skilllv,skill_get_time2(skillid,skilllv));
break;
case KO_JYUMONJIKIRI: // needs more info
sc_start(bl,SC_JYUMONJIKIRI,25,skilllv,skill_get_time(skillid,skilllv));
break;
case KO_MAKIBISHI:
sc_start(bl, SC_STUN, 100, skilllv, skill_get_time2(skillid,skilllv));
break;
case MH_LAVA_SLIDE:
if (tsc && !tsc->data[SC_BURNING]) sc_start4(bl, SC_BURNING, 10 * skilllv, skilllv, 1000, src->id, 0, skill_get_time(skillid, skilllv));
break;
case MH_STAHL_HORN:
sc_start(bl, SC_STUN, (20 + 4 * (skilllv-1)), skilllv, skill_get_time(skillid, skilllv));
break;
case MH_NEEDLE_OF_PARALYZE:
sc_start(bl, SC_PARALYSIS, 40 + (5*skilllv), skilllv, skill_get_time(skillid, skilllv));
break;
}
if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai)
@ -2787,10 +2807,11 @@ static int skill_check_unit_range_sub (struct block_list *bl, va_list ap)
g_skillid = unit->group->skill_id;
switch (skillid) {
case MH_STEINWAND:
case MG_SAFETYWALL:
case AL_PNEUMA:
case SC_MAELSTROM:
if(g_skillid != MG_SAFETYWALL && g_skillid != AL_PNEUMA && g_skillid != SC_MAELSTROM)
if(g_skillid != MH_STEINWAND && g_skillid != MG_SAFETYWALL && g_skillid != AL_PNEUMA && g_skillid != SC_MAELSTROM)
return 0;
break;
case AL_WARP:
@ -3483,7 +3504,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case WM_SEVERE_RAINSTORM_MELEE:
case WM_GREAT_ECHO:
case GN_SLINGITEM_RANGEMELEEATK:
case MH_STAHL_HORN:
case KO_JYUMONJIKIRI:
case KO_SETSUDAN:
case KO_KAIHOU:
@ -3720,7 +3740,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case SO_VARETYR_SPEAR:
case GN_CART_TORNADO:
case GN_CARTCANNON:
case MH_LAVA_SLIDE:
case KO_HAPPOKUNAI:
case KO_HUUMARANKA:
case KO_MUCHANAGE:
@ -4528,6 +4547,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
break;
//recursive homon skill
case MH_MAGMA_FLOW:
case MH_XENO_SLASHER:
case MH_HEILIGE_STANGE:
if(flag & 1)
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
else {
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
}
break;
case MH_STAHL_HORN:
case MH_NEEDLE_OF_PARALYZE:
skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
break;
case 0:/* no skill - basic/normal attack */
if(sd) {
if (flag & 3){
@ -4545,11 +4579,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
break;
default:
if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
} else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
0, abs(skill_get_num(skillid, skilllv)),
skillid, skilllv, skill_get_hit(skillid));
@ -4660,6 +4690,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
case MH_STEINWAND: {
struct block_list *s_src = battle_get_master(src);
short ret;
if(!skill_check_unit_range(src, src->x, src->y, skillid, skilllv)) //prevent reiteration
ret = skill_castend_pos2(src,src->x,src->y,skillid,skilllv,tick,flag); //cast on homon
if(s_src && !skill_check_unit_range(s_src, s_src->x, s_src->y, skillid, skilllv))
ret |= skill_castend_pos2(s_src,s_src->x,s_src->y,skillid,skilllv,tick,flag); //cast on master
if (hd)
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
return ret;
}
break;
default:
//Skill is actually ground placed.
if (src == bl && skill_get_unit_id(skillid,0))
@ -4961,7 +5003,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case SA_FORTUNE:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
if(sd) pc_getzeny(sd,status_get_lv(bl)*100);
if(sd) pc_getzeny(sd,status_get_lv(bl)*100,LOG_TYPE_OTHER,NULL);
break;
case SA_TAMINGMONSTER:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@ -7213,12 +7255,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
}
break;
case MH_STAHL_HORN:
if (sd) {
if( skillid == MH_GOLDENE_FERSE )
clif_skill_fail(sd,skillid,USESKILL_FAIL_CONDITION,0);
}
break;
case HAMI_CASTLE: //[orn]
if(rnd()%100 < 20*skilllv && src != bl)
{
@ -7370,7 +7407,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case RK_IGNITIONBREAK:
case LG_EARTHDRIVE:
case MH_LAVA_SLIDE:
clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
i = skill_get_splash(skillid,skilllv);
if( skillid == LG_EARTHDRIVE ) {
@ -8830,12 +8866,98 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_nodamage_id);
}
break;
case MH_SILENT_BREEZE: {
struct status_change *ssc = status_get_sc(src);
struct block_list *m_bl = battle_get_master(src);
const enum sc_type scs[] = {
SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
};
int heal;
if(tsc){
for (i = 0; i < ARRAYLENGTH(scs); i++) {
if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
status_change_start(bl, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
}
heal = status_get_matk_min(src)*4;
status_heal(bl, heal, 0, 7);
//now inflict silence on everyone
if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun
status_change_start(src, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
if(m_bl){
struct status_change *msc = status_get_sc(m_bl);
if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master
status_change_start(m_bl, SC_SILENCE, 100, skilllv, 0,0,0, skill_get_time(skillid, skilllv),1|2|8);
}
if (hd)
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
case MH_OVERED_BOOST:
if (hd){
struct block_list *s_bl = battle_get_master(src);
if(hd->homunculus.hunger>50) //reduce hunger
hd->homunculus.hunger = hd->homunculus.hunger/2;
else
hd->homunculus.hunger = min(1,hd->homunculus.hunger);
if(s_bl && s_bl->type==BL_PC){
status_set_sp(s_bl,status_get_max_sp(s_bl)/2,0); //master drain 50% sp
clif_send_homdata(((TBL_PC *)s_bl), SP_HUNGRY, hd->homunculus.hunger); //refresh hunger info
sc_start(s_bl, type, 100, skilllv, skill_get_time(skillid, skilllv)); //gene bonus
}
sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
case MH_GRANITIC_ARMOR:
case MH_PYROCLASTIC: {
struct block_list *s_bl = battle_get_master(src);
if(s_bl) sc_start2(s_bl, type, 100, skilllv, hd->homunculus.level, skill_get_time(skillid, skilllv)); //start on master
sc_start2(bl, type, 100, skilllv, hd->homunculus.level, skill_get_time(skillid, skilllv));
if (hd) skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
case MH_LIGHT_OF_REGENE:
if(hd){
hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
if(sd) clif_send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
}
//don't break need to start status and start block timer
case MH_STYLE_CHANGE:
case MH_MAGMA_FLOW:
case MH_PAIN_KILLER:
sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv));
if (hd)
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
break;
case MH_SUMMON_LEGION:
{
int summons[5] = {1004, 1303, 1303, 1994, 1994};
int qty[5] = {3 , 3 , 4 , 4 , 5};
struct mob_data *md;
int i;
for(i=0; i<qty[skilllv - 1]; i++){ //easy way
md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), summons[skilllv - 1], "", SZ_SMALL, AI_ATTACK);
if (md) {
md->master_id = src->id;
if (md->deletetimer != INVALID_TIMER)
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer(gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
mob_spawn(md); //Now it is ready for spawning.
sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_ASSIST, 0, 60000);
}
}
if (hd)
skill_blockhomun_start(hd, skillid, skill_get_cooldown(skillid, skilllv));
}
break;
default:
if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
} else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
map_freeblock_unlock();
return 1;
@ -9548,11 +9670,15 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
case SO_WATER_INSIGNIA:
case SO_WIND_INSIGNIA:
case SO_EARTH_INSIGNIA:
case MH_POISON_MIST:
case KO_HUUMARANKA:
case KO_MUCHANAGE:
case KO_BAKURETSU:
case KO_ZENKAI:
case MH_LAVA_SLIDE:
case MH_VOLCANIC_ASH:
case MH_POISON_MIST:
case MH_STEINWAND:
case MH_XENO_SLASHER:
flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
skill_unitsetting(src,skillid,skilllv,x,y,0);
@ -10018,15 +10144,12 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
for( i = 0; i < (skilllv+2); i++ ) {
x = src->x - 1 + rnd()%3;
y = src->y - 1 + rnd()%3;
skill_unitsetting(src,skillid,skilllv,x,y,0);
skill_unitsetting(src,skillid,skilllv,x,y,0);
}
break;
default:
if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
} else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
return 1;
}
@ -10335,6 +10458,9 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
sc = status_get_sc(src); // for traps, firewall and fogwall - celest
switch( skillid ) {
case MH_STEINWAND:
val2 = 4 + skilllv; //nb of attack blocked
break;
case MG_SAFETYWALL:
#ifdef RENEWAL
/**
@ -10841,7 +10967,7 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
break;
case UNT_SAFETYWALL:
if (!sce)
sc_start4(bl,type,100,sg->skill_lv,sg->group_id,sg->group_id,0,sg->limit);
sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
break;
case UNT_PNEUMA:
@ -10991,6 +11117,11 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
break;
case UNT_VOLCANIC_ASH:
if (!sce)
sc_start(bl, SC_ASH, 50, sg->skill_lv, skill_get_time(MH_VOLCANIC_ASH, sg->skill_lv)); //50% chance
break;
case UNT_GD_LEADERSHIP:
case UNT_GD_GLORYWOUNDS:
case UNT_GD_SOULCOLD:
@ -11703,6 +11834,16 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
sg->limit = DIFF_TICK(tick, sg->tick);
sg->unit_id = UNT_USED_TRAPS;
break;
case UNT_LAVA_SLIDE:
skill_attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
if(++sg->val1 > 4) //after 5 stop hit and destroy me
sg->limit = DIFF_TICK(tick, sg->tick);
break;
case UNT_POISON_MIST:
skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
status_change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
break;
}
if (bl->type == BL_MOB && ss != bl)
@ -11807,6 +11948,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
//your own. Let's pray that scenario is pretty unlikely and noone will complain too much about it.
status_change_end(bl, SC_DANCING, INVALID_TIMER);
}
case MH_STEINWAND:
case MG_SAFETYWALL:
case AL_PNEUMA:
case SA_VOLCANO:
@ -13139,7 +13281,7 @@ int skill_consume_requirement( struct map_session_data *sd, short skill, short l
req.zeny = 0; //Zeny is reduced on skill_attack.
if( sd->status.zeny < req.zeny )
req.zeny = sd->status.zeny;
pc_payzeny(sd,req.zeny);
pc_payzeny(sd,req.zeny,LOG_TYPE_OTHER,NULL); //@Need proper type
}
}
@ -13489,6 +13631,8 @@ int skill_castfix_sc (struct block_list *bl, int time)
if (sc && sc->count) {
if (sc->data[SC_SLOWCAST])
time += time * sc->data[SC_SLOWCAST]->val2 / 100;
if (sc->data[SC_PARALYSIS])
time += sc->data[SC_PARALYSIS]->val3;
if (sc->data[SC_SUFFRAGIUM]) {
time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);

View File

@ -491,6 +491,26 @@ void initChangeTables(void) {
set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF );
set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
// Homunculus S
add_sc(MH_STAHL_HORN, SC_STUN);
set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
add_sc( MH_STEINWAND, SC_SAFETYWALL );
add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
add_sc(MH_LAVA_SLIDE, SC_BURNING);
set_sc(MH_NEEDLE_OF_PARALYZE, SC_PARALYSIS, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
add_sc(MH_POISON_MIST, SC_BLIND);
set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
add_sc( MER_CRASH , SC_STUN );
set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
add_sc( MS_MAGNUM , SC_WATK_ELEMENT );
@ -728,13 +748,6 @@ void initChangeTables(void) {
set_sc_with_vfx( OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
add_sc( MH_STAHL_HORN , SC_STUN );
set_sc( MH_ANGRIFFS_MODUS , SC_ANGRIFFS_MODUS , SI_ANGRIFFS_MODUS , SCB_BATK|SCB_WATK|SCB_DEF|SCB_FLEE );
set_sc( MH_GOLDENE_FERSE , SC_GOLDENE_FERSE , SI_GOLDENE_FERSE , SCB_SPEED|SCB_FLEE|SCB_ATK_ELE );
add_sc( MH_LAVA_SLIDE , SC_BURNING );
add_sc( MH_POISON_MIST , SC_BLIND );
set_sc( MH_ERASER_CUTTER , SC_ERASER_CUTTER , SI_BLANK , SCB_NONE );
// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
@ -1034,6 +1047,9 @@ void initChangeTables(void) {
StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOCAST;
StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
//Homon S
StatusChangeStateTable[SC_PARALYSIS] |= SCS_NOMOVE;
}
static void initDummyData(void)
@ -1294,9 +1310,17 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
return hp+sp;
}
if( target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*)target)->state.rebirth )
{// Ensure the monster has not already rebirthed before doing so.
if(target->type == BL_PC){
TBL_PC *sd = BL_CAST(BL_PC,target);
TBL_HOM *hd = sd->hd;
if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,10*hd->sc.data[SC_LIGHT_OF_REGENE]->val1,0));
status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
return hp + sp;
}
}
if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) {// Ensure the monster has not already rebirthed before doing so.
status_revive(target, sc->data[SC_REBIRTH]->val2, 0);
status_change_clear(target,0);
((TBL_MOB*)target)->state.rebirth = 1;
@ -3254,6 +3278,7 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c
#ifdef RENEWAL_ASPD
static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag);
#endif
static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int);
static unsigned int status_calc_maxhp(struct block_list *,struct status_change *,unsigned int);
static unsigned int status_calc_maxsp(struct block_list *,struct status_change *,unsigned int);
static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element);
@ -3809,10 +3834,10 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(status->aspd_rate != 1000) // absolute percentage modifier
amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
#endif
//fixed value added
//@TODO move FIGHTINGSPIRIT in fix_aspd
if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
amotion = status_calc_fix_aspd(bl, sc, amotion);
status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
status->adelay = 2*status->amotion;
@ -3826,6 +3851,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(status->aspd_rate != 1000)
amotion = amotion*status->aspd_rate/1000;
amotion = status_calc_fix_aspd(bl, sc, amotion);
status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
status->adelay = status->amotion;
@ -3838,6 +3864,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(status->aspd_rate != 1000)
amotion = amotion*status->aspd_rate/1000;
amotion = status_calc_fix_aspd(bl, sc, amotion);
status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
temp = b_status->adelay*status->aspd_rate/1000;
@ -4407,10 +4434,17 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
batk += 70;
if(sc->data[SC_ANGRIFFS_MODUS])
batk += batk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
if( sc->data[SC_ZANGETSU] )
batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_element(bl) == ELE_WATER) //water type
batk /= 2;
}
if(sc->data[SC_PYROCLASTIC])
batk += sc->data[SC_PYROCLASTIC]->val2;
if (sc->data[SC_ANGRIFFS_MODUS])
batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@ -4597,6 +4631,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
hit -= hit * 20 / 100;
if(sc->data[SC_INSPIRATION])
hit += 5 * sc->data[SC_INSPIRATION]->val1;
if (sc->data[SC_ASH])
hit /= 2;
return (short)cap_value(hit,1,SHRT_MAX);
}
@ -4668,14 +4704,18 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
if( sc->data[SC_MARSHOFABYSS] )
flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
if( sc->data[SC_ANGRIFFS_MODUS] )
flee -= flee * sc->data[SC_ANGRIFFS_MODUS]->val3 / 100;
if( sc->data[SC_GOLDENE_FERSE ] )
flee -= flee * sc->data[SC_GOLDENE_FERSE ]->val2 / 100;
#ifdef RENEWAL
if( sc->data[SC_SPEARQUICKEN] )
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
#endif
if (sc->data[SC_ANGRIFFS_MODUS])
flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
if (sc->data[SC_OVERED_BOOST])
flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
if(status_get_element(bl) == ELE_WATER) //water type
flee /= 2;
}
return (short)cap_value(flee,1,SHRT_MAX);
}
@ -4765,7 +4805,11 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_ODINS_POWER])
def -= 20;
if( sc->data[SC_ANGRIFFS_MODUS] )
def -= def * sc->data[SC_ANGRIFFS_MODUS]->val4 / 100;
def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def /= 2;
}
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
}
@ -4823,6 +4867,12 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
if( sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4)
def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def2 /= 2;
}
if (sc->data[SC_PARALYSIS])
def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
#ifdef RENEWAL
return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
@ -5212,6 +5262,28 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
}
#endif
static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) {
if (!sc || !sc->count)
return cap_value(aspd, 0, 2000);
if (!sc->data[SC_QUAGMIRE]) {
if (sc->data[SC_FIGHTINGSPIRIT])
aspd += sc->data[SC_FIGHTINGSPIRIT]->val3;
if ((sc->data[SC_GUST_OPTION]
|| sc->data[SC_BLAST_OPTION]
|| sc->data[SC_WILD_STORM_OPTION])
)
aspd -= 50; // ventus passive = +5 ASPD
if (sc->data[SC_OVERED_BOOST]){
aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
}
// if(sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
// aspd -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) * 4;
}
return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
}
/// Calculates an object's ASPD modifier (alters the base amotion value).
/// Note that the scale of aspd_rate is 1000 = 100%.
static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
@ -5258,9 +5330,6 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
max < sc->data[SC_FLEET]->val2)
max = sc->data[SC_FLEET]->val2;
if( sc->data[SC_GOLDENE_FERSE] && max < sc->data[SC_GOLDENE_FERSE]->val3 )
max = sc->data[SC_GOLDENE_FERSE]->val3;
if(sc->data[SC_ASSNCROS] &&
max < sc->data[SC_ASSNCROS]->val2)
{
@ -5346,6 +5415,10 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
aspd_rate -= sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1 * 10;
if( sc->data[SC_INCASPDRATE] )
aspd_rate -= sc->data[SC_INCASPDRATE]->val1 * 10;
if( sc->data[SC_PAIN_KILLER])
aspd_rate += sc->data[SC_PAIN_KILLER]->val2 * 10;
if( sc->data[SC_GOLDENE_FERSE])
aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
@ -5416,6 +5489,10 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
maxhp += 500;
if (sc->data[SC_ANGRIFFS_MODUS])
maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
if (sc->data[SC_GOLDENE_FERSE])
maxhp += (maxhp * sc->data[SC_GOLDENE_FERSE]->val2) / 100;
return cap_value(maxhp,1,UINT_MAX);
}
@ -5516,8 +5593,8 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
return ELE_GHOST;
if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
return ELE_WATER;
if(sc->data[SC_GOLDENE_FERSE] && rand()%100 < sc->data[SC_GOLDENE_FERSE]->val4)
return ELE_HOLY;
if(sc->data[SC_PYROCLASTIC])
return ELE_FIRE;
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
@ -6118,6 +6195,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
case SC_KYOUGAKU:
tick -= 30*status->int_;
break;
case SC_PARALYSIS:
tick -= 50 * (status->vit + status->luk); //(1000/20);
break;
default:
//Effect that cannot be reduced? Likely a buff.
if (!(rnd()%10000 < rate))
@ -6306,6 +6386,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
undead_flag = battle_check_undead(status->race,status->def_ele);
//Check for inmunities / sc fails
switch (type) {
case SC_ANGRIFFS_MODUS:
case SC_GOLDENE_FERSE:
if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
|| (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
)
return 0;
case SC_STONE:
if(sc->data[SC_POWER_OF_GAIA])
return 0;
@ -6609,6 +6695,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_BURNING: // Place here until we have info about its behavior on Boss-monsters. [pakpil]
case SC_MARSHOFABYSS:
case SC_ADORAMUS:
case SC_PARALYSIS:
// Exploit prevention - kRO Fix
case SC_PYREXIA:
@ -7654,16 +7741,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 3*val1; //Leech chance
val4 = 20; //Leech percent
break;
case SC_ANGRIFFS_MODUS:
val2 = 70 + 30*val1; //atk
val3 = 50 + 20*val1; //flee
val4 = 60 + 20*val1; //def
break;
case SC_GOLDENE_FERSE:
val2 = 20 + 10*val1; //flee
val3 = 10 + 4*val1; //aspd
val4 = 2 + 2*val1; //chance to issue holy-ele attack
break;
case SC_FLEET:
val2 = 30*val1; //Aspd change
val3 = 5+5*val1; //bAtk/wAtk rate change
@ -8318,7 +8395,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_KYOUGAKU:
val2 = 2*val1 + rand()%val1;
clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
break;
case SC_KAGEMUSYA:
val3 = val1 * 2;
@ -8351,6 +8428,41 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
}
break;
case SC_ANGRIFFS_MODUS:
val2 = 50 + 20 * val1; //atk bonus
val3 = 40 + 20 * val1; // Flee reduction.
val4 = tick/1000; // hp/sp reduction timer
tick_time = 1000;
break;
case SC_GOLDENE_FERSE:
val2 = 10 + 10*val1; //max hp bonus
val3 = 6 + 4 * val1; // Aspd Bonus
val4 = 2 + 2 * val1; // Chance of holy attack
break;
case SC_OVERED_BOOST:
val2 = 300 + 40*val1; //flee bonus
val3 = 179 + 2*val1; //aspd bonus
break;
case SC_GRANITIC_ARMOR:
val2 = 2*val1; //dmg reduction
val3 = 6*val1; //dmg on status end
break;
case SC_MAGMA_FLOW:
val2 = 3*val1; //activation chance
break;
case SC_PYROCLASTIC:
val2 += 10*val1; //atk bonus
break;
case SC_PARALYSIS: //[Lighta] need real info
val2 = 2*val1; //def reduction
val3 = 500*val1; //varcast augmentation
break;
case SC_PAIN_KILLER: //[Lighta] need real info
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
if(sc->data[SC_PARALYSIS])
sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
break;
default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
{ //Status change with no calc, no icon, and no skill associated...?
@ -8407,6 +8519,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_NETHERWORLD:
case SC_MEIKYOUSISUI:
case SC_KYOUGAKU:
case SC_PARALYSIS:
unit_stop_walking(bl,1);
break;
case SC_HIDING:
@ -8877,6 +8990,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
vd = status_get_viewdata(bl);
calc_flag = StatusChangeFlagTable[type];
switch(type){
case SC_GRANITIC_ARMOR:{
int dammage = status->max_hp*sce->val3/100;
if(status->hp < dammage) //to not kill him
dammage = status->hp-1;
status_damage(NULL, bl, dammage,0,0,1);
break;
}
case SC_PYROCLASTIC:
if(bl->type == BL_PC)
skill_break_equip(bl,EQP_WEAPON,10000,BCT_SELF);
break;
case SC_WEDDING:
case SC_XMAS:
case SC_SUMMER:
@ -10274,8 +10398,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_WIND_STEP:
case SC_STONE_SHIELD:
case SC_SOLID_SKIN:
if( !status_charge(bl,0,sce->val2) )
{
if( !status_charge(bl,0,sce->val2) ){
struct block_list *s_bl = battle_get_master(bl);
if( s_bl )
status_change_end(s_bl,type+1,INVALID_TIMER);
@ -10286,8 +10409,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
case SC_STOMACHACHE:
if( --(sce->val4) > 0 )
{
if( --(sce->val4) > 0 ){
status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
if( sd && !pc_issit(sd) ) // Force to sit every 10 seconds.
{
@ -10308,8 +10430,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
sc_timer_next(600000 + tick, status_change_timer, bl->id, data);
return 0;
case SC_MEIKYOUSISUI:
if( --(sce->val4) > 0 )
{
if( --(sce->val4) > 0 ){
status_heal(bl, status->max_hp * (sce->val1+1) / 100, status->max_sp * sce->val1 / 100, 0);
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;
@ -10317,12 +10438,17 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_IZAYOI:
case SC_KAGEMUSYA:
if( --(sce->val2) > 0 )
{
if(!status_charge(bl, 0, 1))
break;
if( --(sce->val2) > 0 ){
if(!status_charge(bl, 0, 1)) break;
sc_timer_next(1000+tick, status_change_timer, bl->id, data);
return 0;
}
break;
case SC_ANGRIFFS_MODUS:
if(--(sce->val4) >= 0) { //drain hp/sp
if( !status_charge(bl,100,20) ) break;
sc_timer_next(1000+tick,status_change_timer,bl->id, data);
return 0;
}
break;
}

View File

@ -613,10 +613,6 @@ typedef enum sc_type {
* To increase the maximum value just add another status type before SC_MAXSPELLBOOK (ex. SC_SPELLBOOK7, SC_SPELLBOOK8 and so on)
**/
SC_MAXSPELLBOOK,
/* homun-s */
SC_ANGRIFFS_MODUS,
SC_GOLDENE_FERSE,
SC_ERASER_CUTTER,
/* Max HP & SP */
SC_INCMHP,
SC_INCMSP,
@ -635,6 +631,21 @@ typedef enum sc_type {
SC_ZANGETSU,
SC_GENSOU,
SC_AKAITSUKI,
//homon S
SC_STYLE_CHANGE,
SC_GOLDENE_FERSE,
SC_ANGRIFFS_MODUS,
SC_ERASER_CUTTER,
SC_OVERED_BOOST,
SC_LIGHT_OF_REGENE,
SC_ASH,
SC_GRANITIC_ARMOR,
SC_MAGMA_FLOW,
SC_PYROCLASTIC,
SC_PARALYSIS,
SC_PAIN_KILLER,
#ifdef RENEWAL
SC_EXTREMITYFIST2,
#endif

View File

@ -74,15 +74,15 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
clif_displaymessage(sd->fd, msg_txt(246));
clif_tradestart(sd, 2); // GM is not allowed to trade
return;
}
}
// Players can not request trade from far away, unless they are allowed to use @trade.
if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
(sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) {
clif_tradestart(sd, 0); // too far
return ;
}
target_sd->trade_partner = sd->status.account_id;
sd->trade_partner = target_sd->status.account_id;
clif_traderequest(target_sd, sd->status.name);
@ -106,7 +106,7 @@ void trade_tradeack(struct map_session_data *sd, int type)
if (sd->state.trading || !sd->trade_partner)
return; //Already trading or no partner set.
if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
clif_tradestart(sd, 1); // character does not exist
sd->trade_partner=0;
@ -177,7 +177,7 @@ int impossible_trade_check(struct map_session_data *sd)
int i, index;
nullpo_retr(1, sd);
if(sd->deal.zeny > sd->status.zeny)
{
pc_setglobalreg(sd,"ZENY_HACKER",1);
@ -220,7 +220,7 @@ int impossible_trade_check(struct map_session_data *sd)
} else
// message about the ban
strcpy(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled).
intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
return 1;
}
@ -257,7 +257,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
n = sd->deal.item[trade_i].index;
if (amount > inventory[n].amount)
return 0; //qty Exploit?
data = itemdb_search(inventory[n].nameid);
i = MAX_INVENTORY;
if (itemdb_isstackable2(data)) { //Stackable item.
@ -272,7 +272,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
break;
}
}
if (i == MAX_INVENTORY) {// look for an empty slot.
for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
if (i == MAX_INVENTORY)
@ -439,7 +439,7 @@ void trade_tradeok(struct map_session_data *sd)
if(sd->state.deal_locked || !sd->state.trading)
return;
if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
trade_tradecancel(sd);
return;
@ -470,7 +470,7 @@ void trade_tradecancel(struct map_session_data *sd)
clif_tradecancelled(sd);
return;
}
for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
if (!sd->deal.item[trade_i].amount)
continue;
@ -498,7 +498,7 @@ void trade_tradecancel(struct map_session_data *sd)
target_sd->deal.item[trade_i].index = 0;
target_sd->deal.item[trade_i].amount = 0;
}
if (target_sd->deal.zeny) {
clif_updatestatus(target_sd, SP_ZENY);
target_sd->deal.zeny = 0;
@ -525,9 +525,9 @@ void trade_tradecommit(struct map_session_data *sd)
trade_tradecancel(sd);
return;
}
sd->state.deal_locked = 2;
if (tsd->state.deal_locked < 2)
return; //Not yet time for trading.
@ -547,7 +547,7 @@ void trade_tradecommit(struct map_session_data *sd)
trade_tradecancel(sd);
return;
}
// trade is accepted and correct.
for( trade_i = 0; trade_i < 10; trade_i++ )
{
@ -580,37 +580,28 @@ void trade_tradecommit(struct map_session_data *sd)
if( sd->deal.zeny || tsd->deal.zeny )
{
sd->status.zeny += tsd->deal.zeny - sd->deal.zeny;
tsd->status.zeny += sd->deal.zeny - tsd->deal.zeny;
//Logs Zeny (T)rade [Lupus]
if( sd->deal.zeny )
log_zeny(tsd, LOG_TYPE_TRADE, sd, sd->deal.zeny);
if( tsd->deal.zeny )
log_zeny(sd, LOG_TYPE_TRADE, tsd, tsd->deal.zeny);
pc_getzeny(sd,tsd->deal.zeny - sd->deal.zeny,LOG_TYPE_TRADE, tsd);
pc_getzeny(tsd,sd->deal.zeny - tsd->deal.zeny,LOG_TYPE_TRADE, sd);
sd->deal.zeny = 0;
tsd->deal.zeny = 0;
clif_updatestatus(sd, SP_ZENY);
clif_updatestatus(tsd, SP_ZENY);
}
sd->state.deal_locked = 0;
sd->trade_partner = 0;
sd->state.trading = 0;
tsd->state.deal_locked = 0;
tsd->trade_partner = 0;
tsd->state.trading = 0;
clif_tradecompleted(sd, 0);
clif_tradecompleted(tsd, 0);
// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
if (save_settings&1)
{
chrif_save(sd,0);
chrif_save(sd,0);
chrif_save(tsd,0);
}
}

View File

@ -1249,6 +1249,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
case RA_WUGDASH:
if (sc && sc->data[SC_WUGDASH])
casttime = -1;
break;
}
// moved here to prevent Suffragium from ending if skill fails

View File

@ -59,7 +59,7 @@ void vending_vendinglistreq(struct map_session_data* sd, int id)
{ // GM is not allowed to trade
clif_displaymessage(sd->fd, msg_txt(246));
return;
}
}
sd->vended_id = vsd->vender_id; // register vending uid
@ -139,11 +139,11 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
clif_buyvending(sd, idx, amount, 2); // you can not buy, because overweight
return;
}
//Check to see if cart/vend info is in sync.
if( vending[j].amount > vsd->status.cart[idx].amount )
vending[j].amount = vsd->status.cart[idx].amount;
// if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples).
// here, we check cumulative amounts
if( vending[j].amount < amount )
@ -152,7 +152,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity
return;
}
vending[j].amount -= amount;
switch( pc_checkadditem(sd, vsd->status.cart[idx].nameid, amount) ) {
@ -168,13 +168,10 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
}
}
//Logs (V)ending Zeny [Lupus]
log_zeny(vsd, LOG_TYPE_VENDING, sd, (int)z);
pc_payzeny(sd, (int)z);
pc_payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
if( battle_config.vending_tax )
z -= z * (battle_config.vending_tax/10000.);
pc_getzeny(vsd, (int)z);
pc_getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
for( i = 0; i < count; i++ )
{
@ -202,7 +199,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
{
if( vsd->vending[i].amount == 0 )
continue;
if( cursor != i ) // speedup
{
vsd->vending[cursor].index = vsd->vending[i].index;
@ -236,18 +233,18 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
}
static int vending_checknearnpc_sub(struct block_list* bl, va_list args) {
struct npc_data *nd = (struct npc_data*)bl;
if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) )
return 0;
return 1;
}
bool vending_checknearnpc(struct block_list * bl) {
if( battle_config.min_npc_vending_distance > 0 &&
map_foreachinrange(vending_checknearnpc_sub,bl, battle_config.min_npc_vending_distance, BL_NPC) )
return true;
return false;
}
/*==========================================
@ -287,8 +284,8 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
return;
}
// filter out invalid items
i = 0;
for( j = 0; j < count; j++ )