From cccc5bc9256b196b1f4e9ad881838ad32c8b3424 Mon Sep 17 00:00:00 2001 From: malufett Date: Mon, 26 Aug 2013 18:02:40 +0800 Subject: Fixed Bug#7584 -Where HW_SOULDRAIN should work only in single target. Fixed Bug#7670 -Where PA_GOSPEL is not working properly. Fixed Bug#7668 -Bonus 'bLongAtkRate' is not working properly. Fixed Bug#7512 -Bonus 'bCritAtkRate' is not working properly. Fixed Bug#7515 -Fixed MO_EXTREMITYFIST animation. -Fixed RE armor/weapon storage tab positioning. -Fixed HW_MAGICPOWER cast time. -Fixed '/item' '/monster' aegis command where it not working properly in some item names or monsters. -Added NC_DISJOINT cast time hidden modifier. -Updated RE ATK for post damage modifier. Signed-off-by: malufett --- db/pre-re/skill_db.txt | 2 +- db/re/skill_cast_db.txt | 2 +- db/re/skill_db.txt | 2 +- src/map/atcommand.c | 10 +- src/map/battle.c | 257 ++++++++++++++++++++++++------------------------ src/map/clif.c | 75 ++++++++++---- src/map/itemdb.c | 8 +- src/map/itemdb.h | 2 +- src/map/map.c | 2 +- src/map/mob.c | 19 ++-- src/map/mob.h | 2 +- src/map/script.c | 2 +- src/map/skill.c | 30 +++--- src/map/status.c | 10 +- src/map/status.h | 2 +- src/map/unit.c | 7 ++ 16 files changed, 241 insertions(+), 191 deletions(-) diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index 54b891c51..ec7a8bdbc 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -179,7 +179,7 @@ 133,0,0,0,0,0,0,5,0,no,0,0,0,weapon,0, AS_LEFT,Lefthand Mastery 134,0,0,0,0,0,0,10,0,no,0,0,0,weapon,0, AS_KATAR,Katar Mastery 135,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0, AS_CLOAKING,Cloaking -136,-1,8,1,-1,0,0,10,8,no,0,0,0,weapon,0, AS_SONICBLOW,Sonic Blow +136,-1,8,1,-1,0,0,10,-8,no,0,0,0,weapon,0, AS_SONICBLOW,Sonic Blow 137,3:4:5:6:7,6,1,-1,0x2,1,5,1,no,0,0,0,weapon,0,AS_GRIMTOOTH,Grimtooth 138,1,6,16,5,0x1,0,10,1,no,0,0x400,0,weapon,0, AS_ENCHANTPOISON,Enchant Poison 139,0,6,4,0,0,0,10,1,no,0,0,0,weapon,0, AS_POISONREACT,Poison React diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index 95eec064a..63b1267f3 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -554,7 +554,7 @@ //-- HW_MAGICCRASHER 365,300,300,0,0,0,0,0 //-- HW_MAGICPOWER -366,0,0,0,30000,0,0,0 +366,0,0,0,30000,0,0,700 //========================================== diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 27224719d..4b01cb34e 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -179,7 +179,7 @@ 133,0,0,0,0,0,0,5,0,no,0,0,0,weapon,0, AS_LEFT,Lefthand Mastery 134,0,0,0,0,0,0,10,0,no,0,0,0,weapon,0, AS_KATAR,Katar Mastery 135,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0, AS_CLOAKING,Cloaking -136,-1,8,1,-1,0,0,10,8,no,0,0,0,weapon,0, AS_SONICBLOW,Sonic Blow +136,-1,8,1,-1,0,0,10,-8,no,0,0,0,weapon,0, AS_SONICBLOW,Sonic Blow 137,3:4:5:6:7,6,1,-1,0x2,1,5,1,no,0,0,0,weapon,0,AS_GRIMTOOTH,Grimtooth 138,1,6,16,5,0x1,0,10,1,no,0,0x400,0,weapon,0, AS_ENCHANTPOISON,Enchant Poison 139,0,6,4,0,0,0,10,1,no,0,0,0,weapon,0, AS_POISONREACT,Poison React diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 587a3e12f..4a4487c3b 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3397,7 +3397,7 @@ ACMD(idsearch) sprintf(atcmd_output, msg_txt(77), item_name); // The reference result of '%s' (name: id): clif->message(fd, atcmd_output); - match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name); + match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name, 0); if (match > MAX_SEARCH) { sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, match); clif->message(fd, atcmd_output); @@ -6660,7 +6660,7 @@ ACMD(mobinfo) mob_array[0] = mob_db(i); count = 1; } else - count = mobdb_searchname_array(mob_array, MAX_SEARCH, message); + count = mobdb_searchname_array(mob_array, MAX_SEARCH, message, 0); if (!count) { clif->message(fd, msg_txt(40)); // Invalid monster ID or name. @@ -7206,7 +7206,7 @@ ACMD(iteminfo) return false; } if ((item_array[0] = itemdb->exists(atoi(message))) == NULL) - count = itemdb->search_name_array(item_array, MAX_SEARCH, message); + count = itemdb->search_name_array(item_array, MAX_SEARCH, message, 0); if (!count) { clif->message(fd, msg_txt(19)); // Invalid item ID or name. @@ -7257,7 +7257,7 @@ ACMD(whodrops) return false; } if ((item_array[0] = itemdb->exists(atoi(message))) == NULL) - count = itemdb->search_name_array(item_array, MAX_SEARCH, message); + count = itemdb->search_name_array(item_array, MAX_SEARCH, message, 0); if (!count) { clif->message(fd, msg_txt(19)); // Invalid item ID or name. @@ -7308,7 +7308,7 @@ ACMD(whereis) mob_array[0] = mob_db(i); count = 1; } else - count = mobdb_searchname_array(mob_array, MAX_SEARCH, message); + count = mobdb_searchname_array(mob_array, MAX_SEARCH, message, 0); if (!count) { clif->message(fd, msg_txt(40)); // Invalid monster ID or name. diff --git a/src/map/battle.c b/src/map/battle.c index 285b177c3..45fa87bc6 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1083,10 +1083,10 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ } } } - +#ifndef RENEWAL if( wflag&BF_LONG ) cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100; - +#endif if( (cflag&1) && cardfix_ != 1000 ) damage = damage * cardfix_ / 1000; else if( cardfix != 1000 ) @@ -1374,7 +1374,7 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_ } int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){ - int i, addedratio; + int i; struct status_change *sc, *tsc; struct map_session_data *sd, *tsd; struct status_data *status, *tstatus; @@ -1389,8 +1389,6 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block status = iStatus->get_status_data(src); tstatus = iStatus->get_status_data(target); - addedratio = skillratio - 100; - switch(attack_type){ case BF_MAGIC: switch(skill_id){ @@ -1828,7 +1826,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 30 * skill_lv; break; case AS_SONICBLOW: - skillratio += -50 + 5 * skill_lv; + skillratio += 300 + 40 * skill_lv; break; case TF_SPRINKLESAND: skillratio += 30; @@ -2507,13 +2505,30 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += -100 + 100 * skill_lv; break; } - if( sc && sc->data[SC_EDP] ){ - skillratio -= addedratio; - if( skill_id == AS_SONICBLOW || - skill_id == GC_COUNTERSLASH || - skill_id == GC_CROSSIMPACT ) - skillratio >>= 1; - skillratio += addedratio; + //Skill damage modifiers that stack linearly + if(sc && skill_id != PA_SACRIFICE){ + if( sc->data[SC_EDP] ){ + if( skill_id == AS_SONICBLOW || + skill_id == GC_COUNTERSLASH || + skill_id == GC_CROSSIMPACT ) + skillratio >>= 1; + } + if(sc->data[SC_OVERTHRUST]) + skillratio += sc->data[SC_OVERTHRUST]->val3; + if(sc->data[SC_OVERTHRUSTMAX]) + skillratio += sc->data[SC_OVERTHRUSTMAX]->val2; + if(sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER]) +#ifndef RENEWAL + skillratio += 100; +#else + skillratio += 200; + if( sc->data[SC_TRUESIGHT] ) + skillratio += 2*sc->data[SC_TRUESIGHT]->val1; + if( sc->data[SC_LKCONCENTRATION] ) + skillratio += sc->data[SC_LKCONCENTRATION]->val2; + if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 ) + skillratio += skillratio * (10 + 2 * i) / 100; +#endif } } if( skillratio < 1 ) @@ -4536,10 +4551,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(sd) { if (sd->bonus.atk_rate) ATK_ADDRATE(sd->bonus.atk_rate); - -#ifndef RENEWAL if(flag.cri && sd->bonus.crit_atk_rate) ATK_ADDRATE(sd->bonus.crit_atk_rate); +#ifndef RENEWAL if(sd->status.party_id && (temp=pc->checkskill(sd,TK_POWER)) > 0){ if( (i = party_foreachsamemap(party->sub_count, sd, 0)) > 1 ) // exclude the player himself [Inkfish] @@ -4551,23 +4565,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } //End default case } //End switch(skill_id) - //Skill damage modifiers that stack linearly - if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 ) - skillratio += skillratio * (13 + 2 * i) / 100; - if(sc && skill_id != PA_SACRIFICE) - { - if(sc->data[SC_OVERTHRUST]) - skillratio += sc->data[SC_OVERTHRUST]->val3; - if(sc->data[SC_OVERTHRUSTMAX]) - skillratio += sc->data[SC_OVERTHRUSTMAX]->val2; - if(sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER]) - skillratio += 100; -#ifdef RENEWAL - if( sc->data[SC_TRUESIGHT] ) - skillratio += 2*sc->data[SC_TRUESIGHT]->val1; - if( sc->data[SC_LKCONCENTRATION] ) - skillratio += sc->data[SC_LKCONCENTRATION]->val2; -#endif + if( sc && skill_id != PA_SACRIFICE ){ if( sc->data[SC_UNLIMIT] && wd.flag&BF_LONG ) ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 ); } @@ -4577,109 +4575,101 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_ADD( 30 * tsc->data[SC_DARKCROW]->val1 ); } - if( !skill_id ) - { - ATK_RATE(skillratio); - } - else - { - #ifdef RENEWAL - if( sd && skill_id == NJ_KUNAI ){ - flag.tdef = 1; - ATK_ADD( sd->bonus.arrow_atk ); - } + if( sd && skill_id == NJ_KUNAI ){ + flag.tdef = 1; + ATK_ADD( sd->bonus.arrow_atk ); + } #endif - switch(skill_id){ + switch(skill_id){ #ifdef RENEWAL - case NJ_TATAMIGAESHI: - ATK_RATE(200); - case LK_SPIRALPIERCE: - case ML_SPIRALPIERCE: // [malufett] - if( skill_id != NJ_TATAMIGAESHI ){ - short index = sd?sd->equip_index[EQI_HAND_R]:0; - GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) ); - wd.damage = wd.damage * 70 / 100; - n_ele = true; - - if (sd && index >= 0 && - sd->inventory_data[index] && - sd->inventory_data[index]->type == IT_WEAPON) - ATK_ADD(sd->inventory_data[index]->weight * 7 / 100); + case NJ_TATAMIGAESHI: + ATK_RATE(200); + case LK_SPIRALPIERCE: + case ML_SPIRALPIERCE: // [malufett] + if( skill_id != NJ_TATAMIGAESHI ){ + short index = sd?sd->equip_index[EQI_HAND_R]:0; + GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) ); + wd.damage = wd.damage * 70 / 100; + n_ele = true; + + if (sd && index >= 0 && + sd->inventory_data[index] && + sd->inventory_data[index]->type == IT_WEAPON) + ATK_ADD(sd->inventory_data[index]->weight * 7 / 100); - switch (tstatus->size) { - case SZ_SMALL: //Small: 115% - ATK_RATE(115); - break; - case SZ_BIG: //Large: 85% - ATK_RATE(85); - } - wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon); + switch (tstatus->size) { + case SZ_SMALL: //Small: 115% + ATK_RATE(115); + break; + case SZ_BIG: //Large: 85% + ATK_RATE(85); } + wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon); + } #endif - default: - ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); - } + default: + ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); + } //Constant/misc additions from skills - switch (skill_id) { + switch (skill_id) { #ifdef RENEWAL - case HW_MAGICCRASHER: - ATK_ADD(battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage / 5); - break; + case HW_MAGICCRASHER: + ATK_ADD(battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage / 5); + break; #else - case MO_EXTREMITYFIST: - ATK_ADD(250 + 150*skill_lv); - break; + case MO_EXTREMITYFIST: + ATK_ADD(250 + 150*skill_lv); + break; #endif - case TK_DOWNKICK: - case TK_STORMKICK: - case TK_TURNKICK: - case TK_COUNTER: - case TK_JUMPKICK: - //TK_RUN kick damage bonus. - if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST) - ATK_ADD(10*pc->checkskill(sd, TK_RUN)); - break; - case GS_MAGICALBULLET: + case TK_DOWNKICK: + case TK_STORMKICK: + case TK_TURNKICK: + case TK_COUNTER: + case TK_JUMPKICK: + //TK_RUN kick damage bonus. + if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST) + ATK_ADD(10*pc->checkskill(sd, TK_RUN)); + break; + case GS_MAGICALBULLET: #ifndef RENEWAL - ATK_ADD( iStatus->get_matk(src, 2) ); + ATK_ADD( iStatus->get_matk(src, 2) ); #else - ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage ); - flag.tdef = 1; + ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage ); + flag.tdef = 1; #endif #ifndef RENEWAL - case NJ_SYURIKEN: - ATK_ADD(4*skill_lv); + case NJ_SYURIKEN: + ATK_ADD(4*skill_lv); #endif - break; - case GC_COUNTERSLASH: - ATK_ADD( status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4 ); - break; - case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) - ATK_ADD( skill_lv * 240 + iStatus->get_lv(target) * 40 ); - if( sc && sc->data[SC_COMBOATTACK] - && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40) - ATK_ADD( skill_lv * 500 + iStatus->get_lv(target) * 40 ); - break; - case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)] - ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str); - if( tsd && tsd->weight ){ - ATK_ADD( (tsd->weight/10) * sstatus->dex / 120 ); - }else{ - ATK_ADD( iStatus->get_lv(target) * 50 ); //mobs - } - break; - case KO_SETSUDAN: - if( tsc && tsc->data[SC_SOULLINK] ){ - ATK_ADDRATE(200*tsc->data[SC_SOULLINK]->val1); - status_change_end(target,SC_SOULLINK,INVALID_TIMER); - } - break; - case KO_MAKIBISHI: - wd.damage = 20 * skill_lv; - break; - } + break; + case GC_COUNTERSLASH: + ATK_ADD( status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4 ); + break; + case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) + ATK_ADD( skill_lv * 240 + iStatus->get_lv(target) * 40 ); + if( sc && sc->data[SC_COMBOATTACK] + && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40) + ATK_ADD( skill_lv * 500 + iStatus->get_lv(target) * 40 ); + break; + case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)] + ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str); + if( tsd && tsd->weight ){ + ATK_ADD( (tsd->weight/10) * sstatus->dex / 120 ); + }else{ + ATK_ADD( iStatus->get_lv(target) * 50 ); //mobs + } + break; + case KO_SETSUDAN: + if( tsc && tsc->data[SC_SOULLINK] ){ + ATK_ADDRATE(200*tsc->data[SC_SOULLINK]->val1); + status_change_end(target,SC_SOULLINK,INVALID_TIMER); + } + break; + case KO_MAKIBISHI: + wd.damage = 20 * skill_lv; + break; } #ifndef RENEWAL //Div fix. @@ -4747,6 +4737,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if( sd ) { if (skill_id && (i = pc->skillatk_bonus(sd, skill_id))) ATK_ADDRATE(i); + #ifdef RENEWAL + if( wflag&BF_LONG ) + ATK_ADDRATE(sd->bonus.long_attack_atk_rate); + #endif if( (i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 && (tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) ) ATK_ADDRATE(-i); @@ -4826,6 +4820,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list #endif ATK_ADD(20*lv); } + + if( !skill_id ) { + if( sc->data[SC_ENCHANTBLADE] ) { + //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt + i = ( sc->data[SC_ENCHANTBLADE]->val1 * 20 + 100 ) * iStatus->get_lv(src) / 150 + status_get_int(src); + i = i - iStatus->get_total_mdef(target) + iStatus->get_matk(src, 2); + if( i ) + ATK_ADD(i); + } + if( sc->data[SC_GIANTGROWTH] && rnd()%100 < 15 ) + ATK_ADDRATE(200); // Triple Damage + } + } #ifndef RENEWAL //Refine bonus @@ -4852,7 +4859,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon); #else if( sd && flag.cri ) - ATK_ADDRATE(sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate : 40); + ATK_ADDRATE(40); #endif } //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks else if(wd.div_ < 0) //Since the attack missed... @@ -4999,12 +5006,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list hp = 2*hp/100; //2% hp loss per hit status_zap(src, hp, 0); } - if( !skill_id ) { - if( sc->data[SC_ENCHANTBLADE] ) { // it also works with bear hands..intended in official - //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt - ATK_ADD(( sc->data[SC_ENCHANTBLADE]->val1 * 20 + 100 ) * iStatus->get_lv(src) / 150 + status_get_int(src)); - } - } status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER); } @@ -5241,7 +5242,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i } } } else { - if (sd && sd->bonus.long_weapon_damage_return){ + if (sd && sd->bonus.long_weapon_damage_return){ NORMALIZE_RDAMAGE(damage * sd->bonus.long_weapon_damage_return / 100); *delay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); } @@ -5516,8 +5517,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t }else status_change_end(src,SC_SPELLFIST,INVALID_TIMER); } - if( sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 ) - wd.damage *= 3; // Triple Damage if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){ pc->delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME); diff --git a/src/map/clif.c b/src/map/clif.c index 847c426e5..fad10be92 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -61,7 +61,14 @@ struct clif_interface clif_s; //Converts item type in case of pet eggs. static inline int itemtype(int type) { - return ( type == IT_PETEGG ) ? IT_WEAPON : type; + switch( type ){ +#if PACKETVER >= 20080827 + case IT_WEAPON: return IT_ARMOR; + case IT_ARMOR: +#endif + case IT_PETEGG: return IT_WEAPON; + default: return type; + } } @@ -4217,7 +4224,7 @@ void clif_storageitemadded(struct map_session_data* sd, struct item* i, int inde WFIFOW(fd, 2) = index+1; // index WFIFOL(fd, 4) = amount; // amount WFIFOW(fd, 8) = ( view > 0 ) ? view : i->nameid; // id - WFIFOB(fd,10) = itemdb_type(i->nameid); //type + WFIFOB(fd,10) = itemtype(itemdb_type(i->nameid)); //type WFIFOB(fd,11) = i->identify; //identify flag WFIFOB(fd,12) = i->attribute; // attribute WFIFOB(fd,13) = i->refine; //refine @@ -13323,33 +13330,61 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) /// /item /monster (CZ_ITEM_CREATE). -/// Request to make items or spawn monsters. +/// Request to execute GM commands. +/// usage: +/// /item n - summon n monster or acquire n item/s +/// /item money - grants 2147483647 zenies +/// /item whereisboss - locate boss mob in current map.(not yet implemented) +/// /item regenboss_n t - regenerate n boss monster by t millisecond.(not yet implemented) +/// /item onekillmonster - toggle an ability to kill mobs in one hit.(not yet implemented) +/// /item bossinfo - display the information of a boss monster in current map.(not yet implemented) +/// /item cap_n - capture n monster as pet.(not yet implemented) +/// /item agitinvest - reset current global agit investments.(not yet implemented) /// 013f .24B void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) { - char *monster_item_name; - struct mob_db *mob_data; - struct item_data *item_data; + int i, count; + char *item_monster_name; + struct item_data *item_array[10]; + struct mob_db *mob_array[10]; char command[NAME_LENGTH+10]; - monster_item_name = (char*)RFIFOP(fd,2); - monster_item_name[NAME_LENGTH-1] = '\0'; + item_monster_name = (char*)RFIFOP(fd,2); + item_monster_name[NAME_LENGTH-1] = '\0'; - if( (item_data=itemdb->search_name(monster_item_name)) != NULL - && strcmp(item_data->name, monster_item_name) != 0 ) { // It only accepts aegis name - if( item_data->type == IT_WEAPON || item_data->type == IT_ARMOR ) // nonstackable - snprintf(command, sizeof(command)-1, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand->at_symbol, item_data->nameid); - else - snprintf(command, sizeof(command)-1, "%citem %d 20", atcommand->at_symbol, item_data->nameid); - atcommand->parse(fd, sd, command, 1); - return; + if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ){ + for(i = 0; i < count; i++){ + if( item_array[i] && strcmp(item_array[i]->name, item_monster_name) == 0 )// It only accepts aegis name + break; + } + + if( i < count ){ + if( item_array[i]->type == IT_WEAPON || item_array[i]->type == IT_ARMOR ) // nonstackable + snprintf(command, sizeof(command)-1, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand->at_symbol, item_array[i]->nameid); + else + snprintf(command, sizeof(command)-1, "%citem %d 20", atcommand->at_symbol, item_array[i]->nameid); + atcommand->parse(fd, sd, command, 1); + return; + } } - if( (mob_data=mob_db(mobdb_searchname(monster_item_name))) - && strcmp(mob_data->sprite, monster_item_name) != 0 ) { // It only accepts sprite name - snprintf(command, sizeof(command)-1, "%cmonster %s", atcommand->at_symbol, mob_data->name); + + if( strcmp("money", item_monster_name) == 0 ){ + snprintf(command, sizeof(command)-1, "%czeny %d", atcommand->at_symbol, INT_MAX); atcommand->parse(fd, sd, command, 1); return; } + + if( (count=mobdb_searchname_array(mob_array, 10, item_monster_name, 1)) > 0){ + for(i = 0; i < count; i++){ + if( mob_array[i] && strcmp(mob_array[i]->sprite, item_monster_name) == 0 ) // It only accepts sprite name + break; + } + + if( i < count ){ + snprintf(command, sizeof(command)-1, "%cmonster %s", atcommand->at_symbol, mob_array[i]->sprite); + atcommand->parse(fd, sd, command, 1); + } + } } @@ -17325,7 +17360,7 @@ void clif_status_change2(struct block_list *bl, int tid, enum send_target target p.index = type; p.AID = tid; p.state = 1; - p.Left = -1;// officially its 9999 but -1 is a explicit "no-duration" which behaves best [Ind/Hercules] + p.Left = 9999; p.val1 = val1; p.val2 = val2; p.val3 = val3; diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 431ee3135..fcd4ccbc1 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -102,8 +102,11 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap) /*========================================== * Founds up to N matches. Returns number of matches [Skotlex] + * search flag : + * 0 - approximate match + * 1 - exact match *------------------------------------------*/ -int itemdb_searchname_array(struct item_data** data, int size, const char *str) { +int itemdb_searchname_array(struct item_data** data, int size, const char *str, int flag) { struct item_data* item; int i; int count=0; @@ -115,7 +118,8 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str) if( item == NULL ) continue; - if( stristr(item->jname,str) || stristr(item->name,str) ) + if( (!flag && (stristr(item->jname,str) || stristr(item->name,str))) || + (flag && (strcmp(item->jname,str) == 0 || strcmp(item->name,str) == 0)) ) { if( count < size ) data[count] = item; diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 45d4311e1..126ba6334 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -303,7 +303,7 @@ struct itemdb_interface { /* */ struct item_data* (*name2id) (const char *str); struct item_data* (*search_name) (const char *name); - int (*search_name_array) (struct item_data** data, int size, const char *str); + int (*search_name_array) (struct item_data** data, int size, const char *str, int flag); struct item_data* (*load)(int nameid); struct item_data* (*search)(int nameid); int (*parse_dbrow) (char** str, const char* source, int line, int scriptopt); diff --git a/src/map/map.c b/src/map/map.c index 5753fbc1d..d3d7ac65d 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -368,7 +368,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) // status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure... status_change_end(bl, SC_NJ_TATAMIGAESHI, INVALID_TIMER); status_change_end(bl, SC_MAGICROD, INVALID_TIMER); - if (sc->data[SC_PROPERTYWALK] && + if (sc && sc->data[SC_PROPERTYWALK] && sc->data[SC_PROPERTYWALK]->val3 >= skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) status_change_end(bl,SC_PROPERTYWALK,INVALID_TIMER); } else if (bl->type == BL_NPC) diff --git a/src/map/mob.c b/src/map/mob.c index b181c9b7b..291f04267 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -110,17 +110,24 @@ int mobdb_searchname(const char *str) return 0; } -static int mobdb_searchname_array_sub(struct mob_db* mob, const char *str) +static int mobdb_searchname_array_sub(struct mob_db* mob, const char *str, int flag) { if (mob == mob_dummy) return 1; if(!mob->base_exp && !mob->job_exp && mob->spawn[0].qty < 1) return 1; // Monsters with no base/job exp and no spawn point are, by this criteria, considered "slave mobs" and excluded from search results - if(stristr(mob->jname,str)) + if( !flag ){ + if(stristr(mob->jname,str)) + return 0; + if(stristr(mob->name,str)) + return 0; + return strcmpi(mob->jname,str); + } + if(strcmp(mob->jname,str) == 0) return 0; - if(stristr(mob->name,str)) + if(strcmp(mob->name,str) == 0) return 0; - return strcmpi(mob->jname,str); + return strcmp(mob->sprite,str); } /*========================================== @@ -194,7 +201,7 @@ void mvptomb_destroy(struct mob_data *md) { /*========================================== * Founds up to N matches. Returns number of matches [Skotlex] *------------------------------------------*/ -int mobdb_searchname_array(struct mob_db** data, int size, const char *str) +int mobdb_searchname_array(struct mob_db** data, int size, const char *str, int flag) { int count = 0, i; struct mob_db* mob; @@ -202,7 +209,7 @@ int mobdb_searchname_array(struct mob_db** data, int size, const char *str) mob = mob_db(i); if (mob == mob_dummy || mob_is_clone(i) ) //keep clones out (or you leak player stats) continue; - if (!mobdb_searchname_array_sub(mob, str)) { + if (!mobdb_searchname_array_sub(mob, str, flag)) { if (count < size) data[count] = mob; count++; diff --git a/src/map/mob.h b/src/map/mob.h index 34e5a81c0..137e33ee7 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -245,7 +245,7 @@ struct item_drop_list { struct mob_db* mob_db(int class_); int mobdb_searchname(const char *str); -int mobdb_searchname_array(struct mob_db** data, int size, const char *str); +int mobdb_searchname_array(struct mob_db** data, int size, const char *str, int flag); int mobdb_checkid(const int id); struct view_data* mob_get_viewdata(int class_); diff --git a/src/map/script.c b/src/map/script.c index 9e88714fe..bad40b948 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -14684,7 +14684,7 @@ BUILDIN(searchitem) if ((items[0] = itemdb->exists(atoi(itemname)))) count = 1; else { - count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname); + count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname, 0); if (count > MAX_SEARCH) count = MAX_SEARCH; } diff --git a/src/map/skill.c b/src/map/skill.c index a4070e92f..c7c0cfcd3 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -870,7 +870,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint #ifndef RENEWAL case WZ_FROSTNOVA: #endif - sc_start(bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv)); + if( !sc_start(bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv)) + && sd && skill_id == MG_FROSTDIVER ) + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; #ifdef RENEWAL @@ -1702,7 +1704,8 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1 return 1; } - +//Early declaration +static int skill_area_temp[8]; /* Splitted off from skill->additional_effect, which is never called when the * attack skill kills the enemy. Place in this function counter status effects * when using skills (eg: Asura's sp regen penalty, or counter-status effects @@ -1783,9 +1786,13 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * !(skill->get_inf(skill_id)&(INF_GROUND_SKILL|INF_SELF_SKILL)) && (rate=pc->checkskill(sd,HW_SOULDRAIN))>0 ){ //Soul Drain should only work on targetted spells [Skotlex] - if (pc_issit(sd)) pc->setstand(sd); //Character stuck in attacking animation while 'sitting' fix. [Skotlex] - clif->skill_nodamage(src,bl,HW_SOULDRAIN,rate,1); - iStatus->heal(src, 0, iStatus->get_lv(bl)*(95+15*rate)/100, 2); + if( pc_issit(sd) ) pc->setstand(sd); //Character stuck in attacking animation while 'sitting' fix. [Skotlex] + if( skill->get_nk(skill_id)&NK_SPLASH && skill_area_temp[1] != bl->id ) + ; + else{ + clif->skill_nodamage(src,bl,HW_SOULDRAIN,rate,1); + iStatus->heal(src, 0, iStatus->get_lv(bl)*(95+15*rate)/100, 2); + } } if( sd && iStatus->isdead(bl) ) { @@ -2045,8 +2052,6 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int } return where?1:0; } -//Early declaration -static int skill_area_temp[8]; /*========================================================================= Used to knock back players, monsters, traps, etc - 'count' is the number of squares to knock back @@ -3688,8 +3693,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint if( (mbl == src || (!map_flag_gvg(src->m) && !map[src->m].flag.battleground) ) && // only NJ_ISSEN don't have slide effect in GVG unit_movepos(src, mbl->x+x, mbl->y+y, 1, 1) ) { clif->slide(src, src->x, src->y); - //uncomment this if you want to remove MO_EXTREMITYFIST glitchy walking effect. [malufett] - //clif->fixpos(src); + clif->fixpos(src); + clif->spiritball(src); } } break; @@ -4884,7 +4889,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) if (unit_movepos(src, src->x+x, src->y+y, 1, 1)) { //Display movement + animation. clif->slide(src,src->x,src->y); - clif->skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skill_id, ud->skill_lv, 5); + clif->spiritball(src); } clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); } @@ -8153,7 +8158,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui int rate = 45 + 5 * skill_lv; if( rnd()%100 < rate ){ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); - iMap->foreachinrange(skill_area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id); + iMap->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id); }else if( sd ) // Failure on Rate clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } @@ -9311,7 +9316,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui 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, skill_lv, skill->get_time(skill_id, skill_lv)); @@ -13899,8 +13903,6 @@ int skill_vfcastfix (struct block_list *bl, double time, uint16 skill_id, uint16 if (sc && sc->count && !(skill->get_castnodex(skill_id, skill_lv)&2) ) { // All variable cast additive bonuses must come first - if ( sc->data[SC_MAGICPOWER] && !( sd && time == 0 && sd->skillitem == skill_id )) - time += 700; if (sc->data[SC_SLOWCAST]) VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2); if (sc->data[SC_FROSTMISTY]) diff --git a/src/map/status.c b/src/map/status.c index 64a107b42..2d68bf28e 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -514,7 +514,7 @@ void initChangeTables(void) { 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(MH_STYLE_CHANGE , SC_STYLE_CHANGE); set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_S , SI_RG_CCONFINE_S , SCB_NONE ); set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_M , SI_RG_CCONFINE_M , SCB_FLEE ); @@ -8193,9 +8193,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val val4 = tick / 10000; tick_time = 10000; // [GodLesZ] tick time break; - case SC_GIANTGROWTH: - val2 = 10; // Triple damage success rate. - break; /** * Arch Bishop **/ @@ -10924,9 +10921,9 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) return 0; } -#ifdef RENEWAL int status_get_total_def(struct block_list *src){ return iStatus->get_status_data(src)->def2 + (short)iStatus->get_def(src); } int status_get_total_mdef(struct block_list *src){ return iStatus->get_status_data(src)->mdef2 + (short)status_get_mdef(src); } +#ifdef RENEWAL int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag){ int min = 0, max = 0, dstr; float strdex_bonus, variance; @@ -11073,13 +11070,12 @@ int status_change_clear_buffs (struct block_list* bl, int type) if( type&3 && !(iStatus->get_sc_type(i)&SC_BUFF) && !(iStatus->get_sc_type(i)&SC_DEBUFF) ) continue; - if( !(type&3) ){ + if( type < 3 ){ if( type&1 && !(iStatus->get_sc_type(i)&SC_BUFF) ) continue; if( type&2 && !(iStatus->get_sc_type(i)&SC_DEBUFF) ) continue; } - switch (i) { case SC_DEEP_SLEEP: case SC_FROSTMISTY: diff --git a/src/map/status.h b/src/map/status.h index cae91849e..d5a40e356 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1871,9 +1871,9 @@ struct status_interface { #ifdef RENEWAL unsigned short (*base_matk) (const struct status_data* status, int level); int (*get_weapon_atk) (struct block_list *src, struct weapon_atk *watk, int flag); +#endif int (*get_total_mdef) (struct block_list *src); int (*get_total_def) (struct block_list *src); -#endif int (*get_matk) (struct block_list *src, int flag); diff --git a/src/map/unit.c b/src/map/unit.c index 22c7165e4..d3f72421d 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1327,6 +1327,13 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui } } break; + case NC_DISJOINT: + if( target->type == BL_PC ){ + struct mob_data *md; + if( (md = iMap->id2md(target->id)) && md->master_id != src->id ) + casttime <<= 1; + } + break; } // moved here to prevent Suffragium from ending if skill fails -- cgit v1.2.3-70-g09d2