summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormalufett <malufett.eat.my.binaries@gmail.com>2013-08-26 18:02:40 +0800
committermalufett <malufett.eat.my.binaries@gmail.com>2013-08-26 18:02:40 +0800
commitcccc5bc9256b196b1f4e9ad881838ad32c8b3424 (patch)
tree4567d16e2293781ed5611be54bfbff48e173ca76 /src
parent04139592739a69aafe6cffb0ec52f65d50efb1fa (diff)
downloadhercules-cccc5bc9256b196b1f4e9ad881838ad32c8b3424.tar.gz
hercules-cccc5bc9256b196b1f4e9ad881838ad32c8b3424.tar.bz2
hercules-cccc5bc9256b196b1f4e9ad881838ad32c8b3424.tar.xz
hercules-cccc5bc9256b196b1f4e9ad881838ad32c8b3424.zip
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 <malufett.eat.my.binaries@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/map/atcommand.c10
-rw-r--r--src/map/battle.c257
-rw-r--r--src/map/clif.c75
-rw-r--r--src/map/itemdb.c8
-rw-r--r--src/map/itemdb.h2
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/mob.c19
-rw-r--r--src/map/mob.h2
-rw-r--r--src/map/script.c2
-rw-r--r--src/map/skill.c30
-rw-r--r--src/map/status.c10
-rw-r--r--src/map/status.h2
-rw-r--r--src/map/unit.c7
13 files changed, 238 insertions, 188 deletions
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 <item/mob name>.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