diff options
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 1220 |
1 files changed, 609 insertions, 611 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index 96ade3908..f2154aa22 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4,47 +4,47 @@ #define HERCULES_CORE -#include "../config/core.h" // DBPATH, MAGIC_REFLECTION_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_CAST, VARCAST_REDUCTION() +#include "config/core.h" // DBPATH, MAGIC_REFLECTION_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_CAST, VARCAST_REDUCTION() #include "skill.h" +#include "map/battle.h" +#include "map/battleground.h" +#include "map/chrif.h" +#include "map/clif.h" +#include "map/date.h" +#include "map/elemental.h" +#include "map/guild.h" +#include "map/homunculus.h" +#include "map/intif.h" +#include "map/itemdb.h" +#include "map/log.h" +#include "map/map.h" +#include "map/mercenary.h" +#include "map/mob.h" +#include "map/npc.h" +#include "map/party.h" +#include "map/path.h" +#include "map/pc.h" +#include "map/pet.h" +#include "map/script.h" +#include "map/status.h" +#include "map/unit.h" +#include "common/cbasetypes.h" +#include "common/ers.h" +#include "common/malloc.h" +#include "common/nullpo.h" +#include "common/random.h" +#include "common/showmsg.h" +#include "common/strlib.h" +#include "common/timer.h" +#include "common/utils.h" + #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> -#include "battle.h" -#include "battleground.h" -#include "chrif.h" -#include "clif.h" -#include "date.h" -#include "elemental.h" -#include "guild.h" -#include "homunculus.h" -#include "intif.h" -#include "itemdb.h" -#include "log.h" -#include "map.h" -#include "mercenary.h" -#include "mob.h" -#include "npc.h" -#include "party.h" -#include "path.h" -#include "pc.h" -#include "pet.h" -#include "script.h" -#include "status.h" -#include "unit.h" -#include "../common/cbasetypes.h" -#include "../common/ers.h" -#include "../common/malloc.h" -#include "../common/nullpo.h" -#include "../common/random.h" -#include "../common/showmsg.h" -#include "../common/strlib.h" -#include "../common/timer.h" -#include "../common/utils.h" - #define SKILLUNITTIMER_INTERVAL 100 // ranges reserved for mapping skill ids to skilldb offsets @@ -62,6 +62,7 @@ #endif struct skill_interface skill_s; +struct s_skill_dbs skilldbs; //Since only mob-casted splash skills can hit ice-walls static inline int splash_target(struct block_list* bl) { @@ -99,7 +100,7 @@ int skill_get_index( uint16 skill_id ) { skill_id = MC_SKILLRANGEMIN + skill_id - MC_SKILLBASE; else if( skill_id >= HM_SKILLBASE ) skill_id = HM_SKILLRANGEMIN + skill_id - HM_SKILLBASE; - //[Ind/Hercules] GO GO GO LESS! - http://hercules.ws/board/topic/512-skill-id-processing-overhaul/ + //[Ind/Hercules] GO GO GO LESS! - http://herc.ws/board/topic/512-skill-id-processing-overhaul/ else if( skill_id > 1019 && skill_id < 8001 ) { if( skill_id < 2058 ) // 1020 - 2000 are empty skill_id = 1020 + skill_id - 2001; @@ -121,11 +122,11 @@ int skill_get_index( uint16 skill_id ) { } const char* skill_get_name( uint16 skill_id ) { - return skill->db[skill->get_index(skill_id)].name; + return skill->dbs->db[skill->get_index(skill_id)].name; } const char* skill_get_desc( uint16 skill_id ) { - return skill->db[skill->get_index(skill_id)].desc; + return skill->dbs->db[skill->get_index(skill_id)].desc; } // out of bounds error checking [celest] @@ -138,58 +139,58 @@ void skill_chk(uint16* skill_id) { skill->chk(&(id)); \ if(!(id)) return 0; \ if( (lv) > MAX_SKILL_LEVEL && (var) > 1 ) { \ - int lv2__ = (lv); (lv) = skill->db[(id)].max; \ + int lv2__ = (lv); (lv) = skill->dbs->db[(id)].max; \ return (var) + ((lv2__-(lv))/2);\ } \ return (var);\ } while(0) #define skill_glv(lv) min((lv),MAX_SKILL_LEVEL-1) // Skill DB -int skill_get_hit( uint16 skill_id ) { skill_get (skill->db[skill_id].hit, skill_id); } -int skill_get_inf( uint16 skill_id ) { skill_get (skill->db[skill_id].inf, skill_id); } -int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { skill_get (skill->db[skill_id].element[skill_glv(skill_lv-1)], skill_id); } -int skill_get_nk( uint16 skill_id ) { skill_get (skill->db[skill_id].nk, skill_id); } -int skill_get_max( uint16 skill_id ) { skill_get (skill->db[skill_id].max, skill_id); } -int skill_get_range( uint16 skill_id , uint16 skill_lv ) { skill_get2 (skill->db[skill_id].range[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_splash( uint16 skill_id , uint16 skill_lv ) { skill_get2 ( (skill->db[skill_id].splash[skill_glv(skill_lv-1)]>=0?skill->db[skill_id].splash[skill_glv(skill_lv-1)]:AREA_SIZE), skill_id, skill_lv); } -int skill_get_hp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].hp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_sp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].sp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_hp_rate(uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].hp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_sp_rate(uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].sp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_state(uint16 skill_id) { skill_get (skill->db[skill_id].state, skill_id); } -int skill_get_spiritball(uint16 skill_id, uint16 skill_lv) { skill_get2 (skill->db[skill_id].spiritball[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_itemid(uint16 skill_id, int idx) { skill_get (skill->db[skill_id].itemid[idx], skill_id); } -int skill_get_itemqty(uint16 skill_id, int idx) { skill_get (skill->db[skill_id].amount[idx], skill_id); } -int skill_get_zeny( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].zeny[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_num( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].num[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_cast( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].cast[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_delay( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].delay[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].walkdelay[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_time( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].upkeep_time[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_time2( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].upkeep_time2[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_castdef( uint16 skill_id ) { skill_get (skill->db[skill_id].cast_def_rate, skill_id); } -int skill_get_weapontype( uint16 skill_id ) { skill_get (skill->db[skill_id].weapon, skill_id); } -int skill_get_ammotype( uint16 skill_id ) { skill_get (skill->db[skill_id].ammo, skill_id); } -int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].ammo_qty[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_inf2( uint16 skill_id ) { skill_get (skill->db[skill_id].inf2, skill_id); } -int skill_get_castcancel( uint16 skill_id ) { skill_get (skill->db[skill_id].castcancel, skill_id); } -int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].maxcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].blewcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].mhp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].castnodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ skill_get2 (skill->db[skill_id].delaynodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_type( uint16 skill_id ) { skill_get (skill->db[skill_id].skill_type, skill_id); } -int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill->db[skill_id].unit_id[flag], skill_id); } -int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_interval, skill_id); } -int skill_get_unit_range( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].unit_range[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_unit_target( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_target&BCT_ALL, skill_id); } -int skill_get_unit_bl_target( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_target&BL_ALL, skill_id); } -int skill_get_unit_flag( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_flag, skill_id); } -int skill_get_unit_layout_type( uint16 skill_id ,uint16 skill_lv ){ skill_get2 (skill->db[skill_id].unit_layout_type[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_cooldown( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].cooldown[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_hit( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].hit, skill_id); } +int skill_get_inf( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf, skill_id); } +int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get (skill->dbs->db[skill_id].element[skill_glv(skill_lv-1)], skill_id); } +int skill_get_nk( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].nk, skill_id); } +int skill_get_max( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].max, skill_id); } +int skill_get_range( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].range[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_splash( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 ( (skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]>=0?skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]:AREA_SIZE), skill_id, skill_lv); } +int skill_get_hp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_sp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_hp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_sp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_state(uint16 skill_id) { skill_get (skill->dbs->db[skill_id].state, skill_id); } +int skill_get_spiritball(uint16 skill_id, uint16 skill_lv) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].spiritball[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_itemid(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].itemid[idx], skill_id); } +int skill_get_itemqty(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].amount[idx], skill_id); } +int skill_get_zeny( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].zeny[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_num( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].num[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_cast( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cast[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_delay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delay[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].walkdelay[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_time( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_time2( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time2[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_castdef( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].cast_def_rate, skill_id); } +int skill_get_weapontype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].weapon, skill_id); } +int skill_get_ammotype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].ammo, skill_id); } +int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].ammo_qty[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_inf2( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf2, skill_id); } +int skill_get_castcancel( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].castcancel, skill_id); } +int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].maxcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].blewcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].mhp[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].castnodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delaynodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_type( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].skill_type, skill_id); } +int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill->dbs->db[skill_id].unit_id[flag], skill_id); } +int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_interval, skill_id); } +int skill_get_unit_range( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_range[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_unit_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BCT_ALL, skill_id); } +int skill_get_unit_bl_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BL_ALL, skill_id); } +int skill_get_unit_flag( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_flag, skill_id); } +int skill_get_unit_layout_type( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_layout_type[skill_glv(skill_lv-1)], skill_id, skill_lv); } +int skill_get_cooldown( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cooldown[skill_glv(skill_lv-1)], skill_id, skill_lv); } int skill_get_fixed_cast( uint16 skill_id ,uint16 skill_lv ) { #ifdef RENEWAL_CAST - skill_get2 (skill->db[skill_id].fixed_cast[skill_glv(skill_lv-1)], skill_id, skill_lv); + Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].fixed_cast[skill_glv(skill_lv-1)], skill_id, skill_lv); #else return 0; #endif @@ -223,17 +224,17 @@ int skill_get_casttype (uint16 skill_id) { } int skill_get_casttype2 (uint16 index) { - int inf = skill->db[index].inf; + int inf = skill->dbs->db[index].inf; if (inf&(INF_GROUND_SKILL)) return CAST_GROUND; if (inf&INF_SUPPORT_SKILL) return CAST_NODAMAGE; if (inf&INF_SELF_SKILL) { - if(skill->db[index].inf2&INF2_NO_TARGET_SELF) + if(skill->dbs->db[index].inf2&INF2_NO_TARGET_SELF) return CAST_DAMAGE; //Combo skill. return CAST_NODAMAGE; } - if (skill->db[index].nk&NK_NO_DAMAGE) + if (skill->dbs->db[index].nk&NK_NO_DAMAGE) return CAST_NODAMAGE; return CAST_DAMAGE; } @@ -438,7 +439,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b if( !(sd->sc.data[SC__REPRODUCE]) && ((skill_id >= RK_ENCHANTBLADE && skill_id <= LG_OVERBRAND_PLUSATK) || (skill_id >= RL_GLITTERING_GREED && skill_id <= OB_AKAITSUKI) || (skill_id >= GC_DARKCROW && skill_id <= NC_MAGMA_ERUPTION_DOTDAMAGE))) return 0; // Reproduce will only copy skills according on the list. [Jobbie] - else if( sd->sc.data[SC__REPRODUCE] && !skill->reproduce_db[skill->get_index(skill_id)] ) + else if( sd->sc.data[SC__REPRODUCE] && !skill->dbs->reproduce_db[skill->get_index(skill_id)] ) return 0; return 1; @@ -619,19 +620,19 @@ struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill } if (pos != -1) // simple single-definition layout - return &skill->unit_layout[pos]; + return &skill->dbs->unit_layout[pos]; dir = (src->x == x && src->y == y) ? 6 : map->calc_dir(src,x,y); // 6 - default aegis direction if (skill_id == MG_FIREWALL) - return &skill->unit_layout [skill->firewall_unit_pos + dir]; + return &skill->dbs->unit_layout [skill->firewall_unit_pos + dir]; else if (skill_id == WZ_ICEWALL) - return &skill->unit_layout [skill->icewall_unit_pos + dir]; + return &skill->dbs->unit_layout [skill->icewall_unit_pos + dir]; else if( skill_id == WL_EARTHSTRAIN ) //Warlock - return &skill->unit_layout [skill->earthstrain_unit_pos + dir]; + return &skill->dbs->unit_layout [skill->earthstrain_unit_pos + dir]; ShowError("skill_get_unit_layout: unknown unit layout for skill %d (level %d)\n", skill_id, skill_lv); - return &skill->unit_layout[0]; // default 1x1 layout + return &skill->dbs->unit_layout[0]; // default 1x1 layout } /*========================================== @@ -671,7 +672,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( skill_id != WS_CARTTERMINATION && skill_id != AM_DEMONSTRATION && skill_id != CR_REFLECTSHIELD && skill_id != MS_REFLECTSHIELD && skill_id != ASC_BREAKER ) { // Trigger status effects enum sc_type type; - int i; + int i, flag; for( i = 0; i < ARRAYLENGTH(sd->addeff) && sd->addeff[i].flag; i++ ) { rate = sd->addeff[i].rate; if( attack_type&BF_LONG ) // Any ranged physical attack takes status arrows into account (Grimtooth...) [DracoRPG] @@ -695,13 +696,22 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 } type = sd->addeff[i].id; - temp = skill->get_time2(status->sc2skill(type),7); + + if (sd->addeff[i].duration > 0) { + // Fixed duration + temp = sd->addeff[i].duration; + flag = SCFLAG_FIXEDRATE|SCFLAG_FIXEDTICK; + } else { + // Default duration + temp = skill->get_time2(status->sc2skill(type),7); + flag = SCFLAG_NONE; + } if (sd->addeff[i].flag&ATF_TARGET) - status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE); + status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,flag); if (sd->addeff[i].flag&ATF_SELF) - status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE); + status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,flag); } } @@ -912,9 +922,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case AM_ACIDTERROR: - sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); - if (skill->break_equip(bl, EQP_ARMOR, 100*skill->get_time(skill_id,skill_lv), BCT_ENEMY)) - clif->emotion(bl,E_OMG); + sc_start2(src, bl, SC_BLOODING, (skill_lv * 3), skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); + if ( bl->type == BL_PC && rnd() % 1000 < 10 * skill->get_time(skill_id, skill_lv) ) { + skill->break_equip(bl, EQP_ARMOR, 10000, BCT_ENEMY); + clif->emotion(bl, E_OMG); // emote icon still shows even there is no armor equip. + } break; case AM_DEMONSTRATION: @@ -1356,7 +1368,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; } - if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) { + if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai != AI_NONE) { //Pass heritage to Master for status causing effects. [Skotlex] sd = map->id2sd(md->master_id); src = sd?&sd->bl:src; @@ -2002,7 +2014,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in } if (flag) { sd->status.inventory[j].attribute = 1; - pc->unequipitem(sd, j, 3); + pc->unequipitem(sd, j, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } } clif->equiplist(sd); @@ -2194,7 +2206,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr //Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here. if (sc && sc->data[SC_TRICKDEAD]) return 0; - + if ( skill_id != HW_GRAVITATION ) { + struct status_change *csc = status->get_sc(src); + if(csc && csc->data[SC_GRAVITATION] && csc->data[SC_GRAVITATION]->val3 == BCT_SELF ) + return 0; + } + dmg = battle->calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF); //Skotlex: Adjusted to the new system @@ -2213,9 +2230,11 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr } } - if( dmg.flag&BF_MAGIC && ( (battle_config.eq_single_target_reflectable && (flag&0xFFF) == 1) ) ) { + if( dmg.flag&BF_MAGIC + && (skill_id != NPC_EARTHQUAKE || (battle_config.eq_single_target_reflectable && (flag & 0xFFF) == 1)) ) { /* Need more info cause NPC_EARTHQUAKE is ground type */ // Earthquake on multiple targets is not counted as a target skill. [Inkfish] - if( (dmg.damage || dmg.damage2) && (type = skill->magic_reflect(src, bl, src==dsrc)) ) { + int reflecttype; + if( (dmg.damage || dmg.damage2) && (reflecttype = skill->magic_reflect(src, bl, src==dsrc)) ) { //Magic reflection, switch caster/target struct block_list *tbl = bl; rmdamage = true; @@ -2232,17 +2251,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr /* bugreport:7859 magical reflected zeroes blow count */ dmg.blewcount = 0; //Spirit of Wizard blocks Kaite's reflection - if (type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) { + if (reflecttype == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) { //Consume one Fragment per hit of the casted skill? [Skotlex] - type = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0; - if (type != INDEX_NOT_FOUND) { - if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME); + int consumeitem = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0; + if (consumeitem != INDEX_NOT_FOUND) { + if ( tsd ) pc->delitem(tsd, consumeitem, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); dmg.damage = dmg.damage2 = 0; dmg.dmg_lv = ATK_MISS; sc->data[SC_SOULLINK]->val3 = skill_id; sc->data[SC_SOULLINK]->val4 = dsrc->id; } - } else if( type != 2 ) /* Kaite bypasses */ + } else if( reflecttype != 2 ) /* Kaite bypasses */ additional_effects = false; /** @@ -2255,7 +2274,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr #else // issue:6415 in pre-renewal Kaite reflected the entire damage received // regardless of caster's equipment (Aegis 11.1) - if( dmg.dmg_lv != ATK_MISS && type == 1 ) //Wiz SL canceled and consumed fragment + if( dmg.dmg_lv != ATK_MISS && reflecttype == 1 ) //Wiz SL canceled and consumed fragment #endif { short s_ele = skill->get_ele(skill_id, skill_lv); @@ -2303,14 +2322,13 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr if( damage && sc && sc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){ struct block_list *nbl; nbl = battle->get_enemy_area(bl,bl->x,bl->y,2,BL_CHAR,bl->id); - if( nbl ){ // Only one target is chosen. - int temp = (int)(damage / (float)(10 / skill_lv)); - clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,temp,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6); + if (nbl) { // Only one target is chosen. + clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage * skill_lv / 10,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, BDT_SKILL); } } //Skill hit type - type=(skill_id==0)?5:skill->get_hit(skill_id); + type=(skill_id==0)?BDT_SPLASH:skill->get_hit(skill_id); if(damage < dmg.div_ //Only skills that knockback even when they miss. [Skotlex] @@ -2319,7 +2337,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr if(skill_id == CR_GRANDCROSS||skill_id == NPC_GRANDDARKNESS) { if(battle_config.gx_disptype) dsrc = src; - if(src == bl) type = 4; + if(src == bl) type = BDT_ENDURE; else flag|=SD_ANIMATION; } if(skill_id == NJ_TATAMIGAESHI) { @@ -2425,7 +2443,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr //Display damage. switch( skill_id ) { case PA_GOSPEL: //Should look like Holy Cross [Skotlex] - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, BDT_SPLASH); break; //Skills that need be passed as a normal attack for the client to display correctly. case HVAN_EXPLOSION: @@ -2443,13 +2461,13 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case AS_SPLASHER: if( flag&SD_ANIMATION ) // the surrounding targets - dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, 5); // needs -1 as skill level + dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, BDT_SPLASH); // needs -1 as skill level else // the central target doesn't display an animation - dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, 5); // needs -2(!) as skill level + dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, BDT_SPLASH); // needs -2(!) as skill level break; case WL_HELLINFERNO: case SR_EARTHSHAKER: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,BDT_SKILL); break; case KO_MUCHANAGE: if( dmg.dmg_lv == ATK_FLEE ) @@ -2457,17 +2475,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case WL_SOULEXPANSION: case WL_COMET: case NJ_HUUMA: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,8); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,BDT_MULTIHIT); break; case WL_CHAINLIGHTNING_ATK: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,BDT_SKILL); break; case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND: /* Fall through */ dmg.amotion = status_get_amotion(src) * 2; case LG_OVERBRAND_PLUSATK: - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH); break; case EL_FIRE_BOMB: case EL_FIRE_BOMB_ATK: @@ -2490,29 +2508,29 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case GN_CRAZYWEED_ATK: case KO_BAKURETSU: case NC_MAGMA_ERUPTION: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH); break; case GN_SLINGITEM_RANGEMELEEATK: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,BDT_SKILL); break; case SC_FEINTBOMB: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,BDT_SPLASH); break; case EL_STONE_RAIN: - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?BDT_MULTIHIT:BDT_SPLASH); break; case WM_SEVERE_RAINSTORM_MELEE: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,BDT_SPLASH); break; case WM_REVERBERATION_MELEE: case WM_REVERBERATION_MAGIC: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,BDT_SKILL); break; case WL_TETRAVORTEX_FIRE: case WL_TETRAVORTEX_WATER: case WL_TETRAVORTEX_WIND: case WL_TETRAVORTEX_GROUND: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,BDT_SPLASH); break; case HT_CLAYMORETRAP: case HT_BLASTMINE: @@ -2521,14 +2539,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case RA_CLUSTERBOMB: case RA_FIRINGTRAP: case RA_ICEBOUNDTRAP: - dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5); + dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH); if( dsrc != src ) // avoid damage display redundancy break; case HT_LANDMINE: dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type); break; + case HW_GRAVITATION: + dmg.dmotion = clif->damage(bl, bl, 0, 0, damage, 1, BDT_ENDURE, 0); + break; case WZ_SIGHTBLASTER: - dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5); + dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH); break; case AB_DUPLELIGHT_MELEE: case AB_DUPLELIGHT_MAGIC: @@ -2610,6 +2631,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr tsd->status.skill[cidx].flag = SKILL_FLAG_PLAGIARIZED; clif->addskill(tsd,copy_skill); } else { + int plagiarismlvl; lv = skill_lv; if ( tsd->cloneskill_id ) { idx = skill->get_index(tsd->cloneskill_id); @@ -2621,8 +2643,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr } } - if ((type = pc->checkskill(tsd,RG_PLAGIARISM)) < lv) - lv = type; + if ((plagiarismlvl = pc->checkskill(tsd,RG_PLAGIARISM)) < lv) + lv = plagiarismlvl; tsd->cloneskill_id = copy_skill; pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill); @@ -2693,7 +2715,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr } /* monsters with skill lv higher than MAX_SKILL_LEVEL may get this value beyond the max depending on conditions, we cap to the system's limit */ - if( dsrc && dsrc->type == BL_MOB && skill_lv > MAX_SKILL_LEVEL && dmg.blewcount > 25 ) + if (dsrc->type == BL_MOB && skill_lv > MAX_SKILL_LEVEL && dmg.blewcount > 25) dmg.blewcount = 25; //blown-specific handling @@ -2738,12 +2760,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr ) && check_distance_bl(bl, d_bl, sce->val3) ) { if(!rmdamage){ - clif->damage(d_bl,d_bl, 0, 0, damage, 0, 0, 0); + clif->damage(d_bl,d_bl, 0, 0, damage, 0, BDT_NORMAL, 0); status_fix_damage(NULL,d_bl, damage, 0); } else{ //Reflected magics are done directly on the target not on paladin //This check is only for magical skill. //For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage - clif->damage(bl,bl, 0, 0, damage, 0, 0, 0); + clif->damage(bl,bl, 0, 0, damage, 0, BDT_NORMAL, 0); status_fix_damage(bl,bl, damage, 0); } } @@ -2837,11 +2859,11 @@ void skill_attack_combo2_unknown(int *attack_type, struct block_list* src, struc void skill_attack_display_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage) { if (*flag & SD_ANIMATION && dmg->div_ < 2) //Disabling skill animation doesn't works on multi-hit. - *type = 5; + *type = BDT_SPLASH; if (bl->type == BL_SKILL ) { TBL_SKILL *su = (TBL_SKILL*)bl; if (su->group && skill->get_inf2(su->group->skill_id) & INF2_TRAP) // show damage on trap targets - clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, 5); + clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, BDT_SPLASH); } dmg->dmotion = clif->skill_damage(dsrc, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, *type); } @@ -2890,7 +2912,7 @@ int skill_area_sub(struct block_list *bl, va_list ap) { if(battle->check_target(src,bl,flag) > 0) { // several splash skills need this initial dummy packet to display correctly if (flag&SD_PREAMBLE && skill->area_temp[2] == 0) - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if (flag&(SD_SPLASH|SD_PREAMBLE)) skill->area_temp[2]++; @@ -3065,15 +3087,15 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, // Requirements for( i = 0; i < ARRAYLENGTH(itemid); i++ ) { - itemid[i] = skill->db[idx].itemid[i]; - amount[i] = skill->db[idx].amount[i]; - } - hp = skill->db[idx].hp[lv-1]; - sp = skill->db[idx].sp[lv-1]; - hp_rate = skill->db[idx].hp_rate[lv-1]; - sp_rate = skill->db[idx].sp_rate[lv-1]; - state = skill->db[idx].state; - if( (mhp = skill->db[idx].mhp[lv-1]) > 0 ) + itemid[i] = skill->dbs->db[idx].itemid[i]; + amount[i] = skill->dbs->db[idx].amount[i]; + } + hp = skill->dbs->db[idx].hp[lv-1]; + sp = skill->dbs->db[idx].sp[lv-1]; + hp_rate = skill->dbs->db[idx].hp_rate[lv-1]; + sp_rate = skill->dbs->db[idx].sp_rate[lv-1]; + state = skill->dbs->db[idx].state; + if( (mhp = skill->dbs->db[idx].mhp[lv-1]) > 0 ) hp += (st->max_hp * mhp) / 100; if( hp_rate > 0 ) hp += (st->hp * hp_rate) / 100; @@ -3135,7 +3157,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, // Consume items for (i = 0; i < ARRAYLENGTH(itemid); i++) { if (index[i] != INDEX_NOT_FOUND) - pc->delitem(sd, index[i], amount[i], 0, 1, LOG_TYPE_CONSUME); + pc->delitem(sd, index[i], amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); } if( type&2 ) @@ -3315,7 +3337,7 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { break; case SC_ESCAPE: if( skl->type < 4+skl->skill_lv ){ - clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,5); + clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,BDT_SPLASH); skill->blown(src,src,1,unit->getdir(src),0); skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0); } @@ -3814,9 +3836,16 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 if( dir > 2 && dir < 6 ) y = -i; else if( dir == 7 || dir < 2 ) y = i; else y = 0; - if( (mbl == src || (!map_flag_gvg2(src->m) && !map->list[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) - ) { + if ((mbl == src || (!map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground))) { // only NJ_ISSEN don't have slide effect in GVG + if (!(unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1))) { + // The cell is not reachable (wall, object, ...), move next to the target + if (x > 0) x = -1; + else if (x < 0) x = 1; + if (y > 0) y = -1; + else if (y < 0) y = 1; + + unit->movepos(src, bl->x+x, bl->y+y, 1, 1); + } clif->slide(src, src->x, src->y); clif->fixpos(src); clif->spiritball(src); @@ -3914,7 +3943,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 /* Fall through */ case LG_MOONSLASHER: case MH_XENO_SLASHER: - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; default: break; @@ -3946,7 +3975,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case MS_MAGNUM: if( flag&1 ) { //Damage depends on distance, so add it to flag if it is > 1 - skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|distance_bl(src, bl)); + skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|SD_ANIMATION|distance_bl(src, bl)); } break; @@ -4069,7 +4098,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 break; case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex] //clif->skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/ - clif->damage(src,bl,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack. + clif->damage(src,bl,status_get_amotion(src),0,-1,1,BDT_ENDURE,0); //Display an absorbed damage attack. skill->addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag); break; @@ -4523,7 +4552,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it. } else { map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( sd ) pc->overheat(sd,1); } break; @@ -4542,7 +4571,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 skill->area_temp[5] = y; map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); skill->addtimerskill(src,tick + 800,src->id,x,y,skill_id,skill_lv,0,flag); // To teleport Self - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); } break; case LG_PINPOINTATTACK: @@ -4581,14 +4610,12 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); + status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER); status_change_end(bl, SC_SIREN, INVALID_TIMER); - status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); - status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER); status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER); status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); - status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER); @@ -4602,7 +4629,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); } else{ map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); } break; @@ -4669,7 +4696,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 else { int i = skill->get_splash(skill_id,skill_lv); clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 30 ) map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); else @@ -4679,7 +4706,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case EL_ROCK_CRUSHER: clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 50 ) skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); else @@ -4692,7 +4719,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 else { int i = skill->get_splash(skill_id,skill_lv); clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 30 ) map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); else @@ -4705,7 +4732,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case EL_WIND_SLASH: case EL_STONE_HAMMER: clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); skill->attack(skill->get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -4718,7 +4745,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 type2 = type-1; clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( (esc && esc->data[type2]) || (tsc && tsc->data[type]) ) { elemental->clean_single_effect(ele, skill_id); } @@ -4855,7 +4882,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { if( sd && ud->skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK) ) {// restore original walk speed ud->skilltimer = INVALID_TIMER; - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); } ud->skilltimer = INVALID_TIMER; @@ -5021,7 +5048,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { } if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH) - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); // Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish] @@ -5141,9 +5168,9 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { } } - ud->skill_id = ud->skill_lv = ud->skilltarget = 0; if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick; + ud->skill_id = ud->skill_lv = ud->skilltarget = 0; //You can't place a skill failed packet here because it would be //sent in ALL cases, even cases where skill_check_condition fails //which would lead to double 'skill failed' messages u.u [Skotlex] @@ -5512,10 +5539,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin int abra_skill_id = 0, abra_skill_lv, abra_idx; do { abra_idx = rnd() % MAX_SKILL_ABRA_DB; - abra_skill_id = skill->abra_db[abra_idx].skill_id; + abra_skill_id = skill->dbs->abra_db[abra_idx].skill_id; } while (abra_skill_id == 0 || - skill->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear - rnd()%10000 >= skill->abra_db[abra_idx].per + skill->dbs->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear + rnd()%10000 >= skill->dbs->abra_db[abra_idx].per ); abra_skill_lv = min(skill_lv, skill->get_max(abra_skill_id)); clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); @@ -6081,7 +6108,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } i = 0; - count = (sd)? min(skill_lv,5) : 1; // Mercenary only can Devote owner + count = (sd)? min(skill_lv,MAX_PC_DEVOTION) : 1; // Mercenary only can Devote owner if( sd ) { // Player Devoting Player ARR_FIND(0, count, i, sd->devotion[i] == bl->id ); @@ -6109,22 +6136,17 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case MO_CALLSPIRITS: if(sd) { - int limit = skill_lv; - if( sd->sc.data[SC_RAISINGDRAGON] ) - limit += sd->sc.data[SC_RAISINGDRAGON]->val1; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit); + pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), pc->getmaxspiritball(sd, 0)); } break; case CH_SOULCOLLECT: if(sd) { - int limit = 5, i; - if( sd->sc.data[SC_RAISINGDRAGON] ) - limit += sd->sc.data[SC_RAISINGDRAGON]->val1; + int i, limit = pc->getmaxspiritball(sd, 5); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - for (i = 0; i < limit; i++) - pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit); + for ( i = 0; i < limit; i++ ) + pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), limit); } break; @@ -6146,7 +6168,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin { int sp = 0; if ( dstsd && dstsd->spiritball - && (sd == dstsd || map_flag_vs(src->m) || (sd->duel_group && sd->duel_group == dstsd->duel_group)) + && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) && ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION) ) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen] @@ -6216,7 +6238,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); if( !count && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) ) - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); } break; @@ -6268,7 +6290,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin { //Self Destruction hits everyone in range (allies+enemies) //Except for Summoned Marine spheres on non-versus maps, where it's just enemy. - int targetmask = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))? + int targetmask = ((!md || md->special_state.ai == AI_SPHERE) && !map_flag_vs(src->m))? BCT_ENEMY:BCT_ALL; clif->skill_nodamage(src, src, skill_id, -1, 1); map->delblock(src); //Required to prevent chain-self-destructions hitting back. @@ -6439,7 +6461,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin // custom hack to make the mob display the skill, because these skills don't show the skill use text themselves //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches) char temp[70]; - snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill->db[skill_id].desc); + snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill->dbs->db[skill_id].desc); clif->disp_overhead(&md->bl,temp); } break; @@ -6554,6 +6576,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin status_change_end(bl, SC_STUN, INVALID_TIMER); status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER); } + status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER); //Is this equation really right? It looks so... special. if( battle->check_undead(tstatus->race,tstatus->def_ele) ) { status->change_start(src, bl, SC_BLIND, @@ -6636,7 +6659,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin return 1; } if( sd->skillitem != skill_id ) - status_zap(src,0,skill->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded + status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded } break; @@ -6814,13 +6837,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( sd ) { int x,bonus=100, potion = min(500+skill_lv,505); x = skill_lv%11 - 1; - i = pc->search_inventory(sd,skill->db[skill_id].itemid[x]); - if (i == INDEX_NOT_FOUND || skill->db[skill_id].itemid[x] <= 0) { + i = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[x]); + if (i == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[x] <= 0) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 1; } - if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill->db[skill_id].amount[x]) { + if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill->dbs->db[skill_id].amount[x]) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 1; @@ -6917,44 +6940,24 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } break; case AM_CP_WEAPON: - if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]]) - clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - else { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - return 0; - } - break; - case AM_CP_SHIELD: { - int i; - if(dstsd && (i=dstsd->equip_index[EQI_HAND_L])>=0 && dstsd->inventory_data[i] && - dstsd->inventory_data[i]->type==IT_ARMOR) - clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - else { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - return 0; - } - } - break; + case AM_CP_SHIELD: case AM_CP_ARMOR: - if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_ARMOR]]) - clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - else { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - return 0; - } - break; case AM_CP_HELM: - if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HEAD_TOP]]) - clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - else { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + { + unsigned int equip[] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP }; + int index; + if ( sd && (bl->type != BL_PC || (dstsd && pc->checkequip(dstsd, equip[skill_id - AM_CP_WEAPON]) < 0) || + (dstsd && equip[skill_id - AM_CP_WEAPON] == EQP_SHIELD && pc->checkequip(dstsd, EQP_SHIELD) > 0 + && (index = dstsd->equip_index[EQI_HAND_L]) >= 0 && dstsd->inventory_data[index] + && dstsd->inventory_data[index]->type != IT_ARMOR)) ) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + map->freeblock_unlock(); // Don't consume item requirements return 0; } + clif->skill_nodamage(src, bl, skill_id, skill_lv, + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; + } case AM_TWILIGHT1: if (sd) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -7382,14 +7385,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case WE_MALE: { - int hp_rate = (!skill_lv)? 0:skill->db[skill_id].hp_rate[skill_lv-1]; + int hp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].hp_rate[skill_lv-1]; int gain_hp = tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it cost the caster. [Skotlex] clif->skill_nodamage(src,bl,skill_id,status->heal(bl, gain_hp, 0, 0),1); } break; case WE_FEMALE: { - int sp_rate = (!skill_lv)? 0:skill->db[skill_id].sp_rate[skill_lv-1]; + int sp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].sp_rate[skill_lv-1]; int gain_sp = tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it cost the caster. [Skotlex] clif->skill_nodamage(src,bl,skill_id,status->heal(bl, 0, gain_sp, 0),1); } @@ -7453,15 +7456,15 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin int i; // get back all items used to deploy the trap for( i = 0; i < 10; i++ ) { - if( skill->db[su->group->skill_id].itemid[i] > 0 ) { + if( skill->dbs->db[su->group->skill_id].itemid[i] > 0 ) { int success; struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = skill->db[su->group->skill_id].itemid[i]; + item_tmp.nameid = skill->dbs->db[su->group->skill_id].itemid[i]; item_tmp.identify = 1; - if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) { + if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) { clif->additem(sd,0,0,success); - map->addflooritem(&item_tmp,skill->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); + map->addflooritem(&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } } } @@ -7638,28 +7641,27 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } break; // Full Chemical Protection - case CR_FULLPROTECTION: { - bool iused=false; - int i; - if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]]) { - iused=true; - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTWEAPON,100,skill_lv,skill->get_time(skill_id,skill_lv))); - } if(dstsd && (i=dstsd->equip_index[EQI_HAND_L])>=0 && dstsd->inventory_data[i] && - dstsd->inventory_data[i]->type==IT_ARMOR) { - iused=true; - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTSHIELD,100,skill_lv,skill->get_time(skill_id,skill_lv))); - } if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_ARMOR]]) { - iused=true; - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTARMOR,100,skill_lv,skill->get_time(skill_id,skill_lv))); - } if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HEAD_TOP]]) { - iused=true; - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTHELM,100,skill_lv,skill->get_time(skill_id,skill_lv))); - } if(iused) - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - else { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + case CR_FULLPROTECTION: + { + unsigned int equip[] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP }; + int i, s = 0, skilltime = skill->get_time(skill_id, skill_lv); + for ( i = 0; i < 4; i++ ) { + if ( bl->type != BL_PC || (dstsd && pc->checkequip(dstsd, equip[i]) < 0) ) + continue; + if ( dstsd && equip[i] == EQP_SHIELD ) { + short index = dstsd->equip_index[EQI_HAND_L]; + if ( index >= 0 && dstsd->inventory_data[index] && dstsd->inventory_data[index]->type != IT_ARMOR ) + continue; + } + sc_start(src, bl, (sc_type)(SC_PROTECTWEAPON + i), 100, skill_lv, skilltime); + s++; + } + if ( sd && !s ) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + map->freeblock_unlock(); // Don't consume item requirements return 0; } + clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); } break; @@ -7692,7 +7694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin map->freeblock_unlock(); return 0; } - status_zap(src,0,skill->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish] + status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish] do { int eff = rnd() % 14; if( eff == 5 ) @@ -7713,7 +7715,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case 3: // 1000 damage, random armor destroyed { status_fix_damage(src, bl, 1000, 0); - clif->damage(src,bl,0,0,1000,0,0,0); + clif->damage(src,bl,0,0,1000,0,BDT_NORMAL,0); if( !status->isdead(bl) ) { int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT }; skill->break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY); @@ -7750,14 +7752,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case 10: // 6666 damage, atk matk halved, cursed status_fix_damage(src, bl, 6666, 0); - clif->damage(src,bl,0,0,6666,0,0,0); + clif->damage(src,bl,0,0,6666,0,BDT_NORMAL,0); sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv)); break; case 11: // 4444 damage status_fix_damage(src, bl, 4444, 0); - clif->damage(src,bl,0,0,4444,0,0,0); + clif->damage(src,bl,0,0,4444,0,BDT_NORMAL,0); break; case 12: // stun sc_start(src,bl,SC_STUN,100,skill_lv,5000); @@ -8135,7 +8137,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case LG_EARTHDRIVE: { int splash; - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); splash = skill->get_splash(skill_id,skill_lv); if( skill_id == LG_EARTHDRIVE ) { int dummy = 1; @@ -8316,7 +8318,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case GC_PHANTOMMENACE: { int r; - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); r = skill->get_splash(skill_id, skill_lv); map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR, @@ -8612,7 +8614,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin * Ranger **/ case RA_FEARBREEZE: - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; @@ -8653,7 +8655,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case RA_SENSITIVEKEEN: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY,skill->castend_damage_id); break; /** @@ -8680,7 +8682,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case NC_ANALYZE: - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src,bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))); if( sd ) pc->overheat(sd,1); @@ -8692,7 +8694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( (failure = sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) ) { map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill->castend_damage_id);; - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); if (sd) pc->overheat(sd,1); } clif->skill_nodamage(src,src,skill_id,skill_lv,failure); @@ -8812,7 +8814,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case LG_TRAMPLE: - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->destroy_trap,bl,skill->get_splash(skill_id,skill_lv),BL_SKILL,tick); break; @@ -8850,7 +8852,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin switch( opt ) { case 1: sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER); break; @@ -8877,13 +8879,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin switch( opt ) { case 1: sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER); break; case 2: sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 2000); //Splash AoE Lex Divina - clif->skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id); break; case 3: @@ -8996,7 +8998,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } } else { int count = 0; - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); count = map->forcountinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-characters BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); if( sd ) pc->delspiritball(sd, count, 0); @@ -9006,13 +9008,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case SR_RAISINGDRAGON: - if( sd ) { - short max = 5 + skill_lv; - int i; + if ( sd ) { + int i, max; sc_start(src, bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv)); - for( i = 0; i < max; i++ ) // Don't call more than max available spheres. - pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), max); - clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv))); + clif->skill_nodamage(src, bl, skill_id, skill_lv, + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + max = pc->getmaxspiritball(sd, 0); + for ( i = 0; i < max; i++ ) + pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, skill_lv), max); } break; @@ -9030,7 +9033,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0); } else { - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill->castend_nodamage_id); } break; @@ -9038,12 +9041,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case SR_POWERVELOCITY: if( !dstsd ) break; - if( sd && dstsd->spiritball <= 5 ) { - int i; - for(i = 0; i <= 5; i++) { - pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), i); - pc->delspiritball(sd, sd->spiritball, 0); + if ( sd && (dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER ) { + int i, max = pc->getmaxspiritball(dstsd, 5); + for ( i = 0; i < max; i++ ) { + pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, 1), max); } + pc->delspiritball(sd, sd->spiritball, 0); } clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); break; @@ -9199,7 +9202,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin madnesscheck = map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count); sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)); if ( madnesscheck >= 8 )//The god of madness deals 9999 fixed unreduceable damage when 8 or more enemy players are affected. - status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, 0, 0)); + status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, BDT_NORMAL, 0)); //skill->attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);//To renable when I can confirm it deals damage like this. Data shows its dealt as reflected damage which I don't have it coded like that yet. [Rytech] } else if( sd ) { int rate = sstatus->int_ / 6 + (sd? sd->status.job_level:0) / 5 + skill_lv * 4; @@ -9230,8 +9233,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin int improv_skill_id = 0, improv_skill_lv, improv_idx; do { improv_idx = rnd() % MAX_SKILL_IMPROVISE_DB; - improv_skill_id = skill->improvise_db[improv_idx].skill_id; - } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[improv_idx].per ); + improv_skill_id = skill->dbs->improvise_db[improv_idx].skill_id; + } while( improv_skill_id == 0 || rnd()%10000 >= skill->dbs->improvise_db[improv_idx].per ); improv_skill_lv = 4 + skill_lv; clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); @@ -9335,7 +9338,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; } clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, BDT_SKILL); break; case GM_SANDMAN: @@ -9560,7 +9563,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin elemental->clean_single_effect(ele, skill_id); } else { clif->skill_nodamage(src,src,skill_id,skill_lv,1); - clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( skill_id == EL_WIND_STEP ) // There aren't teleport, just push the master away. skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rnd()%8,0); sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); @@ -9575,7 +9578,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case EL_ZEPHYR: case EL_POWER_OF_GAIA: clif->skill_nodamage(src,src,skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); skill->unitsetting(src,skill_id,skill_lv,bl->x,bl->y,0); break; @@ -9591,7 +9594,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin elemental->clean_single_effect(ele, skill_id); } else { // This not heals at the end. - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); sc_start(src, bl,type,100,src->id,skill->get_time(skill_id,skill_lv)); } @@ -9668,8 +9671,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin clif->skill_nodamage(src, src, skill_id, skill_lv, 1); clif->slide(src, bl->x, bl->y) ; sc_start(src, src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv)); - if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) ) - { + if ( !is_boss(bl) && unit->stop_walking(&sd->bl, STOPWALKING_FLAG_FIXPOS) && unit->movepos(bl, x, y, 0, 0) ) { if( dstsd && pc_issit(dstsd) ) pc->setstand(dstsd); clif->slide(bl, x, y) ; @@ -9692,7 +9694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case KG_KAGEMUSYA: clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; case KG_KAGEHUMI: @@ -9711,7 +9713,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); } if( skill->area_temp[2] == 1 ){ - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); sc_start(src, src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); } } else { @@ -9889,7 +9891,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) if( sd && ud->skilltimer != INVALID_TIMER && ( pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK ) ) {// restore original walk speed ud->skilltimer = INVALID_TIMER; - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); } ud->skilltimer = INVALID_TIMER; @@ -9965,7 +9967,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) src->type, src->id, ud->skill_id, ud->skill_lv, ud->skillx, ud->skilly); if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); @@ -10527,9 +10529,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case CR_SLIMPITCHER: if (sd) { int i = skill_lv%11 - 1; - int j = pc->search_inventory(sd,skill->db[skill_id].itemid[i]); - if (j == INDEX_NOT_FOUND || skill->db[skill_id].itemid[i] <= 0 - || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill->db[skill_id].amount[i] + int j = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[i]); + if (j == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[i] <= 0 + || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill->dbs->db[skill_id].amount[i] ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; @@ -10558,7 +10560,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui } else { int i = skill_lv%11 - 1; struct item_data *item; - i = skill->db[skill_id].itemid[i]; + i = skill->dbs->db[skill_id].itemid[i]; item = itemdb->search(i); script->potion_flag = 1; script->potion_hp = 0; @@ -10661,7 +10663,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case RK_WINDCUTTER: - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); /* Fall through */ case NC_COLDSLOWER: case RK_DRAGONBREATH: @@ -10701,7 +10703,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_GC_POISONINGWEAPON,0); return 0; } - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); skill->unitsetting(src, skill_id, skill_lv, x, y, flag); //status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect. break; @@ -10738,7 +10740,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case RA_DETONATOR: r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->detonator, src->m, x-r, y-r, x+r, y+r, BL_SKILL, src); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; /** * Mechanic @@ -11074,6 +11076,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ * According to data provided in RE, SW life is equal to 3 times caster's health **/ val2 = status_get_max_hp(src) * 3; + val3 = skill_lv+1; #else val2 = skill_lv+1; #endif @@ -11389,7 +11392,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ } break; case NPC_EARTHQUAKE: - clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; default: skill->unitsetting1_unknown(src, &skill_id, &skill_lv, &x, &y, &flag, &val1, &val2, &val3); @@ -11785,7 +11788,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 struct skill_unit_group *sg; struct block_list *ss; TBL_PC* tsd; - struct status_data *tstatus; + struct status_data *tstatus, *bst; struct status_change *tsc, *ssc; struct skill_unit_group_tickset *ts; enum sc_type type; @@ -11809,6 +11812,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 return 0; tstatus = status->get_status_data(bl); + bst = status->get_base_status(bl); type = status->skill2sc(sg->skill_id); skill_id = sg->skill_id; @@ -12346,10 +12350,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 skill->attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0); break; case UNT_NETHERWORLD: - if( !(status_get_mode(bl)&MD_BOSS)) { - if( !(tsc && tsc->data[type]) ){ - sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv)); - } + if ( battle->check_target(&src->bl, bl, BCT_PARTY) == -1 && bl->id != sg->src_id ) { + sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sg->limit = 0; + clif->changetraplook(&src->bl, UNT_USED_TRAPS); + sg->unit_id = UNT_USED_TRAPS; } break; case UNT_THORNS_TRAP: @@ -12420,7 +12425,6 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 hp = tstatus->max_hp * 3 * sg->skill_lv / 100; else hp = tstatus->max_hp * sg->skill_lv / 100; - status->heal(bl, hp, 0, 0); if( tstatus->hp != tstatus->max_hp ) clif->skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0); if( tsc && tsc->data[SC_AKAITSUKI] && hp ) @@ -12457,7 +12461,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 if (tsc && (tsc->data[SC_HALLUCINATIONWALK] || tsc->data[SC_VACUUM_EXTREME])) { return 0; } else { - sg->limit -= 100 * tstatus->str/20; + sg->limit -= 1000 * bst->str/20; sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit); if ( !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !is_boss(bl) ) { @@ -12924,7 +12928,8 @@ int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap) { mob_class=va_arg(ap,int); skill_id=va_arg(ap,int); c=va_arg(ap,int *); - if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill_id == AM_SPHEREMINE?2:skill_id == KO_ZANZOU?4:skill_id == MH_SUMMON_LEGION?1:3) ) + if( md->master_id != src_id + || md->special_state.ai != (skill_id == AM_SPHEREMINE?AI_SPHERE:skill_id == KO_ZANZOU?AI_ZANZOU:skill_id == MH_SUMMON_LEGION?AI_ATTACK:AI_FLORA) ) return 0; //Non alchemist summoned mobs have nothing to do here. if(md->class_==mob_class) (*c)++; @@ -13038,8 +13043,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id sd->itemid = sd->itemindex = -1; if( skill_id == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007] ; //Do not consume item. - else if( sd->status.inventory[i].expire_time == 0 ) - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration + else if( sd->status.inventory[i].expire_time == 0 ) // Rental usable items are not consumed until expiration + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); } return 1; } @@ -13644,7 +13649,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) { char output[128]; sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */ - clif->colormes(sd->fd, COLOR_RED, output); + clif->messagecolor_self(sd->fd, COLOR_RED, output); return 0; } } @@ -14078,7 +14083,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, skill->get_desc(skill_id), require.ammo_qty, itemdb_jname(sd->status.inventory[i].nameid)); - clif->colormes(sd->fd,COLOR_RED,e_msg); + clif->messagecolor_self(sd->fd, COLOR_RED, e_msg); return 0; } if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message @@ -14214,7 +14219,7 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin } if ((n = pc->search_inventory(sd,req.itemid[i])) != INDEX_NOT_FOUND) - pc->delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME); + pc->delitem(sd, n, req.amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); } } @@ -14280,17 +14285,17 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 st = &sd->battle_status; - req.hp = skill->db[idx].hp[skill_lv-1]; - hp_rate = skill->db[idx].hp_rate[skill_lv-1]; + req.hp = skill->dbs->db[idx].hp[skill_lv-1]; + hp_rate = skill->dbs->db[idx].hp_rate[skill_lv-1]; if(hp_rate > 0) req.hp += (st->hp * hp_rate)/100; else req.hp += (st->max_hp * (-hp_rate))/100; - req.sp = skill->db[idx].sp[skill_lv-1]; + req.sp = skill->dbs->db[idx].sp[skill_lv-1]; if((sd->skill_id_old == BD_ENCORE) && skill_id == sd->skill_id_dance) req.sp /= 2; - sp_rate = skill->db[idx].sp_rate[skill_lv-1]; + sp_rate = skill->dbs->db[idx].sp_rate[skill_lv-1]; if(sp_rate > 0) req.sp += (st->sp * sp_rate)/100; else @@ -14318,22 +14323,22 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 req.sp -= req.sp * sc->data[SC_TELEKINESIS_INTENSE]->val2 / 100; } - req.zeny = skill->db[idx].zeny[skill_lv-1]; + req.zeny = skill->dbs->db[idx].zeny[skill_lv-1]; if( sc && sc->data[SC__UNLUCKY] ) req.zeny += sc->data[SC__UNLUCKY]->val1 * 500; - req.spiritball = skill->db[idx].spiritball[skill_lv-1]; + req.spiritball = skill->dbs->db[idx].spiritball[skill_lv-1]; - req.state = skill->db[idx].state; + req.state = skill->dbs->db[idx].state; - req.mhp = skill->db[idx].mhp[skill_lv-1]; + req.mhp = skill->dbs->db[idx].mhp[skill_lv-1]; - req.weapon = skill->db[idx].weapon; + req.weapon = skill->dbs->db[idx].weapon; - req.ammo_qty = skill->db[idx].ammo_qty[skill_lv-1]; + req.ammo_qty = skill->dbs->db[idx].ammo_qty[skill_lv-1]; if (req.ammo_qty) - req.ammo = skill->db[idx].ammo; + req.ammo = skill->dbs->db[idx].ammo; if (!req.ammo && skill_id && skill->isammotype(sd, skill_id)) { //Assume this skill is using the weapon, therefore it requires arrows. @@ -14359,11 +14364,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 continue; break; case AB_ADORAMUS: - if( itemid_isgemstone(skill->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 2) ) + if( itemid_isgemstone(skill->dbs->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 2) ) continue; break; case WL_COMET: - if( itemid_isgemstone(skill->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 0) ) + if( itemid_isgemstone(skill->dbs->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 0) ) continue; break; case GN_FIRE_EXPANSION: @@ -14389,8 +14394,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 } } - req.itemid[i] = skill->db[idx].itemid[i]; - req.amount[i] = skill->db[idx].amount[i]; + req.itemid[i] = skill->dbs->db[idx].itemid[i]; + req.amount[i] = skill->dbs->db[idx].amount[i]; if (itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN) { if (sd->special_state.no_gemstone) { @@ -14432,8 +14437,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 case SO_FIRE_INSIGNIA: case SO_WIND_INSIGNIA: case SO_EARTH_INSIGNIA: - req.itemid[skill_lv-1] = skill->db[idx].itemid[skill_lv-1]; - req.amount[skill_lv-1] = skill->db[idx].amount[skill_lv-1]; + req.itemid[skill_lv-1] = skill->dbs->db[idx].itemid[skill_lv-1]; + req.amount[skill_lv-1] = skill->dbs->db[idx].amount[skill_lv-1]; break; } if (skill_id == NC_REPAIR) { @@ -14737,8 +14742,11 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 fixcast_r = max(fixcast_r, sc->data[SC_DANCE_WITH_WUG]->val4); if( sc->data[SC_SECRAMENT] ) fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2); - if( sd && ( skill_lv = pc->checkskill(sd, WL_RADIUS) ) && (skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) ) - fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + skill_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] % + if (sd && skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) { + int radius_lv = pc->checkskill(sd, WL_RADIUS); + if (radius_lv) + fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + radius_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] % + } // Fixed cast non percentage bonuses if( sc->data[SC_MANDRAGORA] ) fixed += sc->data[SC_MANDRAGORA]->val1 * 500; @@ -15078,7 +15086,7 @@ void skill_repairweapon (struct map_session_data *sd, int idx) { clif->equiplist(target_sd); - pc->delitem(sd,pc->search_inventory(sd,material),1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, pc->search_inventory(sd, material), 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this the correct reason flag? clif->item_repaireffect(sd,idx,0); @@ -15147,7 +15155,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) else per += 5 * ((signed int)sd->status.job_level - 50); - pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag? if (per > rnd() % 1000) { int ep = 0; logs->pick_pc(sd, LOG_TYPE_OTHER, -1, item, ditem); @@ -15155,9 +15163,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) logs->pick_pc(sd, LOG_TYPE_OTHER, 1, item, ditem); if(item->equip) { ep = item->equip; - pc->unequipitem(sd,idx,3); + pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } - clif->delitem(sd,idx,1,0); + clif->delitem(sd, idx, 1, DELITEM_NORMAL); clif->upgrademessage(sd->fd, 0,item->nameid); clif->inventorylist(sd); clif->refine(sd->fd,0,idx,item->refine); @@ -15183,9 +15191,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) } else { item->refine = 0; if(item->equip) - pc->unequipitem(sd,idx,3); + pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); clif->refine(sd->fd,1,idx,item->refine); - pc->delitem(sd,idx,1,0,0, LOG_TYPE_OTHER); + pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); clif->misceffect(&sd->bl,2); clif->emotion(&sd->bl, E_OMG); } @@ -15488,7 +15496,6 @@ int skill_graffitiremover (struct block_list *bl, va_list ap) { struct skill_unit *su=NULL; nullpo_ret(bl); - nullpo_ret(ap); if(bl->type != BL_SKILL) return 0; @@ -15519,7 +15526,6 @@ int skill_detonator(struct block_list *bl, va_list ap) { int unit_id; nullpo_ret(bl); - nullpo_ret(ap); src = va_arg(ap,struct block_list *); if( bl->type != BL_SKILL ) @@ -15725,7 +15731,7 @@ int skill_trap_splash(struct block_list *bl, va_list ap) { skill->blown(src,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),-1,0); break; case UNT_ELECTRICSHOCKER: - clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5); + clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,BDT_SPLASH); break; case UNT_MAGENTATRAP: case UNT_COBALTTRAP: @@ -15912,7 +15918,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) return false; } - status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0); + status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? BDT_MULTIHIT : BDT_NORMAL), 0), 0); /* because damage can cancel it */ if( sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) { @@ -15945,7 +15951,8 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int su->group=group; su->alive=1; su->val1=val1; - su->val2=val2; + su->val2 = val2; + su->prev = 0; idb_put(skill->unit_db, su->bl.id, su); map->addiddb(&su->bl); @@ -16539,7 +16546,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { dissonance = skill->dance_switch(su, 0); - if( su->range >= 0 && group->interval != -1 ) { + if( su->range >= 0 && group->interval != -1 && su->bl.id != su->prev) { if( battle_config.skill_wall_check ) map->foreachinshootrange(skill->unit_timer_sub_onplace, bl, su->range, group->bl_flag, bl,tick); else @@ -16555,6 +16562,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { group->bl_flag= BL_NUL; } } + if ( group->limit == group->interval ) + su->prev = su->bl.id; } if( dissonance ) skill->dance_switch(su, 1); @@ -16795,9 +16804,9 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger, return 0; for(i=0;i<MAX_SKILL_PRODUCE_DB;i++){ - if(skill->produce_db[i].nameid == nameid ){ - if((j=skill->produce_db[i].req_skill)>0 && - pc->checkskill(sd,j) < skill->produce_db[i].req_skill_lv) + if(skill->dbs->produce_db[i].nameid == nameid ){ + if((j=skill->dbs->produce_db[i].req_skill)>0 && + pc->checkskill(sd,j) < skill->dbs->produce_db[i].req_skill_lv) continue; // must iterate again to check other skills that produce it. [malufett] if( j > 0 && sd->menuskill_id > 0 && sd->menuskill_id != j ) continue; // special case @@ -16815,22 +16824,22 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger, if(trigger>=0){ if(trigger>20) { // Non-weapon, non-food item (itemlv must match) - if(skill->produce_db[i].itemlv!=trigger) + if(skill->dbs->produce_db[i].itemlv!=trigger) return 0; } else if(trigger>10) { // Food (any item level between 10 and 20 will do) - if(skill->produce_db[i].itemlv<=10 || skill->produce_db[i].itemlv>20) + if(skill->dbs->produce_db[i].itemlv<=10 || skill->dbs->produce_db[i].itemlv>20) return 0; } else { // Weapon (itemlv must be higher or equal) - if(skill->produce_db[i].itemlv>trigger) + if(skill->dbs->produce_db[i].itemlv>trigger) return 0; } } for (j = 0; j < MAX_PRODUCE_RESOURCE; j++) { - int id = skill->produce_db[i].mat_id[j]; + int id = skill->dbs->produce_db[i].mat_id[j]; if (id <= 0) continue; - if (skill->produce_db[i].mat_amount[j] <= 0) { + if (skill->dbs->produce_db[i].mat_amount[j] <= 0) { if (pc->search_inventory(sd,id) == INDEX_NOT_FOUND) return 0; } else { @@ -16838,7 +16847,7 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger, for(y=0,x=0;y<MAX_INVENTORY;y++) if( sd->status.inventory[y].nameid == id ) x+=sd->status.inventory[y].amount; - if(x<qty*skill->produce_db[i].mat_amount[j]) + if(x<qty*skill->dbs->produce_db[i].mat_amount[j]) return 0; } } @@ -16869,7 +16878,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, qty = 1; if (!skill_id) //A skill can be specified for some override cases. - skill_id = skill->produce_db[idx].req_skill; + skill_id = skill->dbs->produce_db[idx].req_skill; if( skill_id == GC_RESEARCHNEWPOISON ) skill_id = GC_CREATENEWPOISON; @@ -16886,12 +16895,12 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, if (j == INDEX_NOT_FOUND) continue; if( slot[i]==ITEMID_STAR_CRUMB ) { - pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? sc++; } if( slot[i] >= ITEMID_FLAME_HEART && slot[i] <= ITEMID_GREAT_NATURE && ele == 0 ) { static const int ele_table[4]={3,1,4,2}; - pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? ele=ele_table[slot[i]-994]; } } @@ -16908,7 +16917,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, for( i = 0; i < MAX_INVENTORY; i++ ) { if( sd->status.inventory[i].nameid == nameid ) { if( sd->status.inventory[i].amount >= data->stack.amount ) { - clif->msgtable(sd->fd,0x61b); + clif->msgtable(sd, MSG_RUNE_STONE_MAX_AMOUNT); return 0; } else { /** @@ -16926,10 +16935,10 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, for(i=0;i<MAX_PRODUCE_RESOURCE;i++){ int j,id,x; - if( (id=skill->produce_db[idx].mat_id[i]) <= 0 ) + if( (id=skill->dbs->produce_db[idx].mat_id[i]) <= 0 ) continue; num++; - x=( skill_id == RK_RUNEMASTERY ? 1 : qty)*skill->produce_db[idx].mat_amount[i]; + x=( skill_id == RK_RUNEMASTERY ? 1 : qty)*skill->dbs->produce_db[idx].mat_amount[i]; do{ int y=0; j = pc->search_inventory(sd,id); @@ -16937,7 +16946,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, if (j != INDEX_NOT_FOUND) { y = sd->status.inventory[j].amount; if(y>x)y=x; - pc->delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, y, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? } else ShowError("skill_produce_mix: material item error\n"); @@ -17070,8 +17079,8 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, break; case GN_CHANGEMATERIAL: for(i=0; i<MAX_SKILL_PRODUCE_DB; i++) - if( skill->changematerial_db[i].itemid == nameid ){ - make_per = skill->changematerial_db[i].rate * 10; + if( skill->dbs->changematerial_db[i].itemid == nameid ){ + make_per = skill->dbs->changematerial_db[i].rate * 10; break; } break; @@ -17183,7 +17192,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, + 20 * (sd->status.base_level + 1) + 20 * (st->dex + 1) + 100 * (rnd()%(30+5*(sd->cook_mastery/400) - (6+sd->cook_mastery/80)) + (6+sd->cook_mastery/80)) - - 400 * (skill->produce_db[idx].itemlv - 11 + 1) + - 400 * (skill->dbs->produce_db[idx].itemlv - 11 + 1) - 10 * (100 - st->luk + 1) - 500 * (num - 1) - 100 * (rnd()%4 + 1); @@ -17339,11 +17348,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, clif->misceffect(&sd->bl,5); break; default: //Those that don't require a skill? - if( skill->produce_db[idx].itemlv > 10 && skill->produce_db[idx].itemlv <= 20) + if( skill->dbs->produce_db[idx].itemlv > 10 && skill->dbs->produce_db[idx].itemlv <= 20) { //Cooking items. clif->specialeffect(&sd->bl, 608, AREA); if( sd->cook_mastery < 1999 ) - pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5); + pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->dbs->produce_db[idx].itemlv - 11) / 2 ) ) * 5); } break; } @@ -17351,10 +17360,10 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, if ( skill_id == GN_CHANGEMATERIAL && tmp_item.amount) { //Success int j, k = 0; for(i=0; i<MAX_SKILL_PRODUCE_DB; i++) - if( skill->changematerial_db[i].itemid == nameid ){ + if( skill->dbs->changematerial_db[i].itemid == nameid ){ for(j=0; j<5; j++){ - if( rnd()%1000 < skill->changematerial_db[i].qty_rate[j] ){ - tmp_item.amount = qty * skill->changematerial_db[i].qty[j]; + if( rnd()%1000 < skill->dbs->changematerial_db[i].qty_rate[j] ){ + tmp_item.amount = qty * skill->dbs->changematerial_db[i].qty[j]; if((flag = pc->additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) { clif->additem(sd,0,0,flag); map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); @@ -17365,7 +17374,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, break; } if( k ){ - clif->msg_skill(sd,skill_id,0x627); + clif->msgtable_skill(sd, skill_id, MSG_SKILL_SUCCESS); return 1; } } else if (tmp_item.amount) { //Success @@ -17374,7 +17383,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } if( skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY ) - clif->msg_skill(sd,skill_id,0x627); + clif->msgtable_skill(sd, skill_id, MSG_SKILL_SUCCESS); return 1; } } @@ -17433,20 +17442,20 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, clif->additem(sd,0,0,flag); map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } - clif->msg_skill(sd,skill_id,0x628); + clif->msgtable_skill(sd, skill_id, MSG_SKILL_FAILURE); } break; case GN_MAKEBOMB: case GN_S_PHARMACY: case GN_CHANGEMATERIAL: - clif->msg_skill(sd,skill_id,0x628); + clif->msgtable_skill(sd, skill_id, MSG_SKILL_FAILURE); break; default: - if( skill->produce_db[idx].itemlv > 10 && skill->produce_db[idx].itemlv <= 20 ) + if( skill->dbs->produce_db[idx].itemlv > 10 && skill->dbs->produce_db[idx].itemlv <= 20 ) { //Cooking items. clif->specialeffect(&sd->bl, 609, AREA); if( sd->cook_mastery > 0 ) - pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 )); + pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->dbs->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->dbs->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 )); } } } @@ -17464,7 +17473,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid) return 1; for(i=0;i<MAX_SKILL_ARROW_DB;i++) - if(nameid == skill->arrow_db[i].nameid) { + if(nameid == skill->dbs->arrow_db[i].nameid) { index = i; break; } @@ -17472,12 +17481,12 @@ int skill_arrow_create (struct map_session_data *sd, int nameid) if(index < 0 || (j = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND) return 1; - pc->delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? for(i=0;i<MAX_ARROW_RESOURCE;i++) { memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.identify = 1; - tmp_item.nameid = skill->arrow_db[index].cre_id[i]; - tmp_item.amount = skill->arrow_db[index].cre_amount[i]; + tmp_item.nameid = skill->dbs->arrow_db[index].cre_id[i]; + tmp_item.amount = skill->dbs->arrow_db[index].cre_amount[i]; if(battle_config.produce_item_name_input&0x4) { tmp_item.card[0]=CARD0_CREATE; tmp_item.card[1]=0; @@ -17498,7 +17507,7 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) { sc_type type; int chance, i; nullpo_ret(sd); - if( nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) { + if (nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME)) { clif->skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0); return 0; } @@ -17555,15 +17564,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) { nullpo_ret(sd); skill_id = sd->menuskill_val; - if (nameid <= 0 || !itemdb_is_element(nameid) || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND - || !skill_id || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) + if (nameid <= 0 || !itemdb_is_element(nameid) || !skill_id + || (i = pc->search_inventory(sd, nameid)) == INDEX_NOT_FOUND + || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) != 0 ) { clif->skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0); return 0; } // Spawn Position - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this intended to be there twice? x = sd->sc.comet_x; y = sd->sc.comet_y; sd->sc.comet_x = sd->sc.comet_y = 0; @@ -17603,10 +17613,10 @@ int skill_spellbook (struct map_session_data *sd, int nameid) { return 0; } - ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill->spellbook_db[i].nameid == nameid); // Search for information of this item + ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill->dbs->spellbook_db[i].nameid == nameid); // Search for information of this item if( i == MAX_SKILL_SPELLBOOK_DB ) return 0; - if( !pc->checkskill(sd, (skill_id = skill->spellbook_db[i].skill_id)) ) + if( !pc->checkskill(sd, (skill_id = skill->dbs->spellbook_db[i].skill_id)) ) { // User don't know the skill sc_start(&sd->bl, &sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB))); clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0); @@ -17614,7 +17624,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) { } max_preserve = 4 * pc->checkskill(sd, WL_FREEZE_SP) + (status_get_int(&sd->bl) + sd->status.base_level) / 10; - point = skill->spellbook_db[i].point; + point = skill->dbs->spellbook_db[i].point; if( sc && sc->data[SC_READING_SB] ) { if( (sc->data[SC_READING_SB]->val2 + point) > max_preserve ) { @@ -17699,7 +17709,7 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, return 1; } - if( pc->delitem(sd,idx,del_amount,0,1,LOG_TYPE_CONSUME) ) { + if( pc->delitem(sd, idx, del_amount, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME) ) { clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; } @@ -17737,23 +17747,23 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite // Search for objects that can be created. for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) { - if( skill->produce_db[i].itemlv == 26 ) { + if( skill->dbs->produce_db[i].itemlv == 26 ) { p = 0; do { c = 0; // Verification of overlap between the objects required and the list submitted. for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) { - if( skill->produce_db[i].mat_id[j] > 0 ) { + if( skill->dbs->produce_db[i].mat_id[j] > 0 ) { for( k = 0; k < n; k++ ) { int idx = item_list[k*2+0]-2; nameid = sd->status.inventory[idx].nameid; amount = item_list[k*2+1]; if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){ - clif->msg_skill(sd,GN_CHANGEMATERIAL,0x62D); + clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NEED_IDENTIFY); return 0; } - if( nameid == skill->produce_db[i].mat_id[j] && (amount-p*skill->produce_db[i].mat_amount[j]) >= skill->produce_db[i].mat_amount[j] - && (amount-p*skill->produce_db[i].mat_amount[j])%skill->produce_db[i].mat_amount[j] == 0 ) // must be in exact amount + if( nameid == skill->dbs->produce_db[i].mat_id[j] && (amount-p*skill->dbs->produce_db[i].mat_amount[j]) >= skill->dbs->produce_db[i].mat_amount[j] + && (amount-p*skill->dbs->produce_db[i].mat_amount[j])%skill->dbs->produce_db[i].mat_amount[j] == 0 ) // must be in exact amount c++; // match } } @@ -17764,14 +17774,14 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite } while(n == j && c == n); p--; if ( p > 0 ) { - skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->produce_db[i].nameid,0,0,0,p); + skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->dbs->produce_db[i].nameid,0,0,0,p); return 1; } } } if( p == 0) - clif->msg_skill(sd,GN_CHANGEMATERIAL,0x623); + clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NOT_FOUND); return 0; } @@ -17894,6 +17904,9 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) } if( i != cd->cursor ) {/* duplicate, update necessary */ + // Don't do anything if there's already a tick longer than the incoming one + if (DIFF_TICK32(cd->entry[i]->started + cd->entry[i]->duration, now) > tick) + return 0; cd->entry[i]->duration = tick; #if PACKETVER >= 20120604 cd->entry[i]->total = tick; @@ -18077,25 +18090,25 @@ void skill_init_unit_layout (void) //when != it was already cleared during skill_defaults() no need to repeat if( runflag == MAPSERVER_ST_RUNNING ) - memset(skill->unit_layout,0,sizeof(skill->unit_layout)); + memset(skill->dbs->unit_layout, 0, sizeof(skill->dbs->unit_layout)); // standard square layouts go first for (i=0; i<=MAX_SQUARE_LAYOUT; i++) { int size = i*2+1; - skill->unit_layout[i].count = size*size; + skill->dbs->unit_layout[i].count = size*size; for (j=0; j<size*size; j++) { - skill->unit_layout[i].dx[j] = (j%size-i); - skill->unit_layout[i].dy[j] = (j/size-i); + skill->dbs->unit_layout[i].dx[j] = (j%size-i); + skill->dbs->unit_layout[i].dy[j] = (j/size-i); } } // afterwards add special ones pos = i; for (i=0;i<MAX_SKILL_DB;i++) { - if (!skill->db[i].unit_id[0] || skill->db[i].unit_layout_type[0] != -1) + if (!skill->dbs->db[i].unit_id[0] || skill->dbs->db[i].unit_layout_type[0] != -1) continue; - switch (skill->db[i].nameid) { + switch (skill->dbs->db[i].nameid) { case MG_FIREWALL: case WZ_ICEWALL: case WL_EARTHSTRAIN://Warlock @@ -18109,9 +18122,9 @@ void skill_init_unit_layout (void) static const int dy[]={ -2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2}; - skill->unit_layout[pos].count = 21; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 21; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case PR_MAGNUS: { @@ -18123,18 +18136,18 @@ void skill_init_unit_layout (void) -3,-3,-3,-2,-2,-2,-1,-1,-1,-1, -1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3}; - skill->unit_layout[pos].count = 33; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 33; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case MH_POISON_MIST: case AS_VENOMDUST: { static const int dx[] = {-1, 0, 0, 0, 1}; static const int dy[] = { 0,-1, 0, 1, 0}; - skill->unit_layout[pos].count = 5; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 5; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case CR_GRANDCROSS: @@ -18147,9 +18160,9 @@ void skill_init_unit_layout (void) -4,-3,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4}; - skill->unit_layout[pos].count = 29; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 29; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case PF_FOGWALL: { @@ -18157,9 +18170,9 @@ void skill_init_unit_layout (void) -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; static const int dy[] = { -1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}; - skill->unit_layout[pos].count = 15; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 15; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case PA_GOSPEL: { @@ -18173,17 +18186,17 @@ void skill_init_unit_layout (void) -1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3}; - skill->unit_layout[pos].count = 33; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 33; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case NJ_KAENSIN: { static const int dx[] = {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; static const int dy[] = { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2}; - skill->unit_layout[pos].count = 24; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 24; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case NJ_TATAMIGAESHI: { @@ -18198,29 +18211,29 @@ void skill_init_unit_layout (void) static const int dy3[] = { 0, 0, 0, 0, 0, 0,-3,-2,-1, 1, 2, 3}; //lv1 j = 0; - skill->unit_layout[pos].count = 4; - memcpy(skill->unit_layout[pos].dx,dx1,sizeof(dx1)); - memcpy(skill->unit_layout[pos].dy,dy1,sizeof(dy1)); - skill->db[i].unit_layout_type[j] = pos; + skill->dbs->unit_layout[pos].count = 4; + memcpy(skill->dbs->unit_layout[pos].dx,dx1,sizeof(dx1)); + memcpy(skill->dbs->unit_layout[pos].dy,dy1,sizeof(dy1)); + skill->dbs->db[i].unit_layout_type[j] = pos; //lv2/3 j++; pos++; - skill->unit_layout[pos].count = 8; - memcpy(skill->unit_layout[pos].dx,dx2,sizeof(dx2)); - memcpy(skill->unit_layout[pos].dy,dy2,sizeof(dy2)); - skill->db[i].unit_layout_type[j] = pos; - skill->db[i].unit_layout_type[++j] = pos; + skill->dbs->unit_layout[pos].count = 8; + memcpy(skill->dbs->unit_layout[pos].dx,dx2,sizeof(dx2)); + memcpy(skill->dbs->unit_layout[pos].dy,dy2,sizeof(dy2)); + skill->dbs->db[i].unit_layout_type[j] = pos; + skill->dbs->db[i].unit_layout_type[++j] = pos; //lv4/5 j++; pos++; - skill->unit_layout[pos].count = 12; - memcpy(skill->unit_layout[pos].dx,dx3,sizeof(dx3)); - memcpy(skill->unit_layout[pos].dy,dy3,sizeof(dy3)); - skill->db[i].unit_layout_type[j] = pos; - skill->db[i].unit_layout_type[++j] = pos; + skill->dbs->unit_layout[pos].count = 12; + memcpy(skill->dbs->unit_layout[pos].dx,dx3,sizeof(dx3)); + memcpy(skill->dbs->unit_layout[pos].dy,dy3,sizeof(dy3)); + skill->dbs->db[i].unit_layout_type[j] = pos; + skill->dbs->db[i].unit_layout_type[++j] = pos; //Fill in the rest using lv 5. for (;j<MAX_SKILL_LEVEL;j++) - skill->db[i].unit_layout_type[j] = pos; + skill->dbs->db[i].unit_layout_type[j] = pos; //Skip, this way the check below will fail and continue to the next skill. pos++; } @@ -18228,27 +18241,27 @@ void skill_init_unit_layout (void) case GN_WALLOFTHORN: { static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0}; static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2}; - skill->unit_layout[pos].count = 16; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 16; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case EL_FIRE_MANTLE: { static const int dx[] = {-1, 0, 1, 1, 1, 0,-1,-1}; static const int dy[] = { 1, 1, 1, 0,-1,-1,-1, 0}; - skill->unit_layout[pos].count = 8; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + skill->dbs->unit_layout[pos].count = 8; + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; default: ShowError("unknown unit layout at skill %d\n",i); break; } - if (!skill->unit_layout[pos].count) + if (!skill->dbs->unit_layout[pos].count) continue; for (j=0;j<MAX_SKILL_LEVEL;j++) - skill->db[i].unit_layout_type[j] = pos; + skill->dbs->db[i].unit_layout_type[j] = pos; pos++; } @@ -18256,60 +18269,60 @@ void skill_init_unit_layout (void) skill->firewall_unit_pos = pos; for (i=0;i<8;i++) { if (i&1) { - skill->unit_layout[pos].count = 5; + skill->dbs->unit_layout[pos].count = 5; if (i&0x2) { int dx[] = {-1,-1, 0, 0, 1}; int dy[] = { 1, 0, 0,-1,-1}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } else { int dx[] = { 1, 1 ,0, 0,-1}; int dy[] = { 1, 0, 0,-1,-1}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } } else { - skill->unit_layout[pos].count = 3; + skill->dbs->unit_layout[pos].count = 3; if (i%4==0) { int dx[] = {-1, 0, 1}; int dy[] = { 0, 0, 0}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } else { int dx[] = { 0, 0, 0}; int dy[] = {-1, 0, 1}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } } pos++; } skill->icewall_unit_pos = pos; for (i=0;i<8;i++) { - skill->unit_layout[pos].count = 5; + skill->dbs->unit_layout[pos].count = 5; if (i&1) { if (i&0x2) { int dx[] = {-2,-1, 0, 1, 2}; int dy[] = { 2, 1, 0,-1,-2}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } else { int dx[] = { 2, 1 ,0,-1,-2}; int dy[] = { 2, 1, 0,-1,-2}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } } else { if (i%4==0) { int dx[] = {-2,-1, 0, 1, 2}; int dy[] = { 0, 0, 0, 0, 0}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } else { int dx[] = { 0, 0, 0, 0, 0}; int dy[] = {-2,-1, 0, 1, 2}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } } pos++; @@ -18317,15 +18330,15 @@ void skill_init_unit_layout (void) skill->earthstrain_unit_pos = pos; for( i = 0; i < 8; i++ ) { // For each Direction - skill->unit_layout[pos].count = 15; + skill->dbs->unit_layout[pos].count = 15; switch( i ) { case 0: case 1: case 3: case 4: case 5: case 7: { int dx[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; int dy[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; case 2: @@ -18333,8 +18346,8 @@ void skill_init_unit_layout (void) { int dx[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int dy[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; - memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy)); + memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy)); } break; } @@ -18581,36 +18594,36 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->db[idx].nameid = skill_id; - skill->split_atoi(split[1],skill->db[idx].range); - skill->db[idx].hit = atoi(split[2]); - skill->db[idx].inf = atoi(split[3]); - skill->split_atoi(split[4],skill->db[idx].element); - skill->db[idx].nk = (int)strtol(split[5], NULL, 0); - skill->split_atoi(split[6],skill->db[idx].splash); - skill->db[idx].max = atoi(split[7]); - skill->split_atoi(split[8],skill->db[idx].num); + skill->dbs->db[idx].nameid = skill_id; + skill->split_atoi(split[1],skill->dbs->db[idx].range); + skill->dbs->db[idx].hit = atoi(split[2]); + skill->dbs->db[idx].inf = atoi(split[3]); + skill->split_atoi(split[4],skill->dbs->db[idx].element); + skill->dbs->db[idx].nk = (int)strtol(split[5], NULL, 0); + skill->split_atoi(split[6],skill->dbs->db[idx].splash); + skill->dbs->db[idx].max = atoi(split[7]); + skill->split_atoi(split[8],skill->dbs->db[idx].num); if( strcmpi(split[9],"yes") == 0 ) - skill->db[idx].castcancel = 1; + skill->dbs->db[idx].castcancel = 1; else - skill->db[idx].castcancel = 0; - skill->db[idx].cast_def_rate = atoi(split[10]); - skill->db[idx].inf2 = (int)strtol(split[11], NULL, 0); - skill->split_atoi(split[12],skill->db[idx].maxcount); + skill->dbs->db[idx].castcancel = 0; + skill->dbs->db[idx].cast_def_rate = atoi(split[10]); + skill->dbs->db[idx].inf2 = (int)strtol(split[11], NULL, 0); + skill->split_atoi(split[12],skill->dbs->db[idx].maxcount); if( strcmpi(split[13],"weapon") == 0 ) - skill->db[idx].skill_type = BF_WEAPON; + skill->dbs->db[idx].skill_type = BF_WEAPON; else if( strcmpi(split[13],"magic") == 0 ) - skill->db[idx].skill_type = BF_MAGIC; + skill->dbs->db[idx].skill_type = BF_MAGIC; else if( strcmpi(split[13],"misc") == 0 ) - skill->db[idx].skill_type = BF_MISC; + skill->dbs->db[idx].skill_type = BF_MISC; else - skill->db[idx].skill_type = 0; - skill->split_atoi(split[14],skill->db[idx].blewcount); - safestrncpy(skill->db[idx].name, trim(split[15]), sizeof(skill->db[idx].name)); - safestrncpy(skill->db[idx].desc, trim(split[16]), sizeof(skill->db[idx].desc)); - strdb_iput(skill->name2id_db, skill->db[idx].name, skill_id); - script->set_constant2(skill->db[idx].name,(int)skill_id,0); + skill->dbs->db[idx].skill_type = 0; + skill->split_atoi(split[14],skill->dbs->db[idx].blewcount); + safestrncpy(skill->dbs->db[idx].name, trim(split[15]), sizeof(skill->dbs->db[idx].name)); + safestrncpy(skill->dbs->db[idx].desc, trim(split[16]), sizeof(skill->dbs->db[idx].desc)); + strdb_iput(skill->name2id_db, skill->dbs->db[idx].name, skill_id); + script->set_constant2(skill->dbs->db[idx].name,(int)skill_id,0); return true; } @@ -18625,22 +18638,22 @@ bool skill_parse_row_requiredb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->split_atoi(split[1],skill->db[idx].hp); - skill->split_atoi(split[2],skill->db[idx].mhp); - skill->split_atoi(split[3],skill->db[idx].sp); - skill->split_atoi(split[4],skill->db[idx].hp_rate); - skill->split_atoi(split[5],skill->db[idx].sp_rate); - skill->split_atoi(split[6],skill->db[idx].zeny); + skill->split_atoi(split[1],skill->dbs->db[idx].hp); + skill->split_atoi(split[2],skill->dbs->db[idx].mhp); + skill->split_atoi(split[3],skill->dbs->db[idx].sp); + skill->split_atoi(split[4],skill->dbs->db[idx].hp_rate); + skill->split_atoi(split[5],skill->dbs->db[idx].sp_rate); + skill->split_atoi(split[6],skill->dbs->db[idx].zeny); //Which weapon type are required, see doc/item_db for types p = split[7]; for( j = 0; j < 32; j++ ) { int l = atoi(p); if( l == 99 ) { // Any weapon - skill->db[idx].weapon = 0; + skill->dbs->db[idx].weapon = 0; break; } else - skill->db[idx].weapon |= 1<<l; + skill->dbs->db[idx].weapon |= 1<<l; p = strchr(p,':'); if(!p) break; @@ -18652,49 +18665,49 @@ bool skill_parse_row_requiredb(char* split[], int columns, int current) { for( j = 0; j < 32; j++ ) { int l = atoi(p); if( l == 99 ) { // Any ammo type - skill->db[idx].ammo = 0xFFFFFFFF; + skill->dbs->db[idx].ammo = 0xFFFFFFFF; break; } else if( l ) // 0 stands for no requirement - skill->db[idx].ammo |= 1<<l; + skill->dbs->db[idx].ammo |= 1<<l; p = strchr(p,':'); if( !p ) break; p++; } - skill->split_atoi(split[9],skill->db[idx].ammo_qty); - - if( strcmpi(split[10],"hiding") == 0 ) skill->db[idx].state = ST_HIDING; - else if( strcmpi(split[10],"cloaking") == 0 ) skill->db[idx].state = ST_CLOAKING; - else if( strcmpi(split[10],"hidden") == 0 ) skill->db[idx].state = ST_HIDDEN; - else if( strcmpi(split[10],"riding") == 0 ) skill->db[idx].state = ST_RIDING; - else if( strcmpi(split[10],"falcon") == 0 ) skill->db[idx].state = ST_FALCON; - else if( strcmpi(split[10],"cart") == 0 ) skill->db[idx].state = ST_CART; - else if( strcmpi(split[10],"shield") == 0 ) skill->db[idx].state = ST_SHIELD; - else if( strcmpi(split[10],"sight") == 0 ) skill->db[idx].state = ST_SIGHT; - else if( strcmpi(split[10],"explosionspirits") == 0 ) skill->db[idx].state = ST_EXPLOSIONSPIRITS; - else if( strcmpi(split[10],"cartboost") == 0 ) skill->db[idx].state = ST_CARTBOOST; - else if( strcmpi(split[10],"recover_weight_rate") == 0 ) skill->db[idx].state = ST_RECOV_WEIGHT_RATE; - else if( strcmpi(split[10],"move_enable") == 0 ) skill->db[idx].state = ST_MOVE_ENABLE; - else if( strcmpi(split[10],"water") == 0 ) skill->db[idx].state = ST_WATER; - else if( strcmpi(split[10],"dragon") == 0 ) skill->db[idx].state = ST_RIDINGDRAGON; - else if( strcmpi(split[10],"warg") == 0 ) skill->db[idx].state = ST_WUG; - else if( strcmpi(split[10],"ridingwarg") == 0 ) skill->db[idx].state = ST_RIDINGWUG; - else if( strcmpi(split[10],"mado") == 0 ) skill->db[idx].state = ST_MADO; - else if( strcmpi(split[10],"elementalspirit") == 0 ) skill->db[idx].state = ST_ELEMENTALSPIRIT; - else if( strcmpi(split[10],"poisonweapon") == 0 ) skill->db[idx].state = ST_POISONINGWEAPON; - else if( strcmpi(split[10],"rollingcutter") == 0 ) skill->db[idx].state = ST_ROLLINGCUTTER; - else if( strcmpi(split[10],"mh_fighting") == 0 ) skill->db[idx].state = ST_MH_FIGHTING; - else if( strcmpi(split[10],"mh_grappling") == 0 ) skill->db[idx].state = ST_MH_GRAPPLING; - else if( strcmpi(split[10],"peco") == 0 ) skill->db[idx].state = ST_PECO; + skill->split_atoi(split[9],skill->dbs->db[idx].ammo_qty); + + if( strcmpi(split[10],"hiding") == 0 ) skill->dbs->db[idx].state = ST_HIDING; + else if( strcmpi(split[10],"cloaking") == 0 ) skill->dbs->db[idx].state = ST_CLOAKING; + else if( strcmpi(split[10],"hidden") == 0 ) skill->dbs->db[idx].state = ST_HIDDEN; + else if( strcmpi(split[10],"riding") == 0 ) skill->dbs->db[idx].state = ST_RIDING; + else if( strcmpi(split[10],"falcon") == 0 ) skill->dbs->db[idx].state = ST_FALCON; + else if( strcmpi(split[10],"cart") == 0 ) skill->dbs->db[idx].state = ST_CART; + else if( strcmpi(split[10],"shield") == 0 ) skill->dbs->db[idx].state = ST_SHIELD; + else if( strcmpi(split[10],"sight") == 0 ) skill->dbs->db[idx].state = ST_SIGHT; + else if( strcmpi(split[10],"explosionspirits") == 0 ) skill->dbs->db[idx].state = ST_EXPLOSIONSPIRITS; + else if( strcmpi(split[10],"cartboost") == 0 ) skill->dbs->db[idx].state = ST_CARTBOOST; + else if( strcmpi(split[10],"recover_weight_rate") == 0 ) skill->dbs->db[idx].state = ST_RECOV_WEIGHT_RATE; + else if( strcmpi(split[10],"move_enable") == 0 ) skill->dbs->db[idx].state = ST_MOVE_ENABLE; + else if( strcmpi(split[10],"water") == 0 ) skill->dbs->db[idx].state = ST_WATER; + else if( strcmpi(split[10],"dragon") == 0 ) skill->dbs->db[idx].state = ST_RIDINGDRAGON; + else if( strcmpi(split[10],"warg") == 0 ) skill->dbs->db[idx].state = ST_WUG; + else if( strcmpi(split[10],"ridingwarg") == 0 ) skill->dbs->db[idx].state = ST_RIDINGWUG; + else if( strcmpi(split[10],"mado") == 0 ) skill->dbs->db[idx].state = ST_MADO; + else if( strcmpi(split[10],"elementalspirit") == 0 ) skill->dbs->db[idx].state = ST_ELEMENTALSPIRIT; + else if( strcmpi(split[10],"poisonweapon") == 0 ) skill->dbs->db[idx].state = ST_POISONINGWEAPON; + else if( strcmpi(split[10],"rollingcutter") == 0 ) skill->dbs->db[idx].state = ST_ROLLINGCUTTER; + else if( strcmpi(split[10],"mh_fighting") == 0 ) skill->dbs->db[idx].state = ST_MH_FIGHTING; + else if( strcmpi(split[10],"mh_grappling") == 0 ) skill->dbs->db[idx].state = ST_MH_GRAPPLING; + else if( strcmpi(split[10],"peco") == 0 ) skill->dbs->db[idx].state = ST_PECO; /** * Unknown or no state **/ - else skill->db[idx].state = ST_NONE; + else skill->dbs->db[idx].state = ST_NONE; - skill->split_atoi(split[11],skill->db[idx].spiritball); + skill->split_atoi(split[11],skill->dbs->db[idx].spiritball); for( j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++ ) { - skill->db[idx].itemid[j] = atoi(split[12+ 2*j]); - skill->db[idx].amount[j] = atoi(split[13+ 2*j]); + skill->dbs->db[idx].itemid[j] = atoi(split[12+ 2*j]); + skill->dbs->db[idx].amount[j] = atoi(split[13+ 2*j]); } return true; @@ -18707,14 +18720,14 @@ bool skill_parse_row_castdb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->split_atoi(split[1],skill->db[idx].cast); - skill->split_atoi(split[2],skill->db[idx].delay); - skill->split_atoi(split[3],skill->db[idx].walkdelay); - skill->split_atoi(split[4],skill->db[idx].upkeep_time); - skill->split_atoi(split[5],skill->db[idx].upkeep_time2); - skill->split_atoi(split[6],skill->db[idx].cooldown); + skill->split_atoi(split[1],skill->dbs->db[idx].cast); + skill->split_atoi(split[2],skill->dbs->db[idx].delay); + skill->split_atoi(split[3],skill->dbs->db[idx].walkdelay); + skill->split_atoi(split[4],skill->dbs->db[idx].upkeep_time); + skill->split_atoi(split[5],skill->dbs->db[idx].upkeep_time2); + skill->split_atoi(split[6],skill->dbs->db[idx].cooldown); #ifdef RENEWAL_CAST - skill->split_atoi(split[7],skill->db[idx].fixed_cast); + skill->split_atoi(split[7],skill->dbs->db[idx].fixed_cast); #endif return true; } @@ -18726,9 +18739,9 @@ bool skill_parse_row_castnodexdb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->split_atoi(split[1],skill->db[idx].castnodex); + skill->split_atoi(split[1],skill->dbs->db[idx].castnodex); if( split[2] ) // optional column - skill->split_atoi(split[2],skill->db[idx].delaynodex); + skill->split_atoi(split[2],skill->dbs->db[idx].delaynodex); return true; } @@ -18740,37 +18753,37 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16); - skill->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16); - skill->split_atoi(split[3],skill->db[idx].unit_layout_type); - skill->split_atoi(split[4],skill->db[idx].unit_range); - skill->db[idx].unit_interval = atoi(split[5]); - - if( strcmpi(split[6],"noenemy")==0 ) skill->db[idx].unit_target = BCT_NOENEMY; - else if( strcmpi(split[6],"friend")==0 ) skill->db[idx].unit_target = BCT_NOENEMY; - else if( strcmpi(split[6],"party")==0 ) skill->db[idx].unit_target = BCT_PARTY; - else if( strcmpi(split[6],"ally")==0 ) skill->db[idx].unit_target = BCT_PARTY|BCT_GUILD; - else if( strcmpi(split[6],"guild")==0 ) skill->db[idx].unit_target = BCT_GUILD; - else if( strcmpi(split[6],"all")==0 ) skill->db[idx].unit_target = BCT_ALL; - else if( strcmpi(split[6],"enemy")==0 ) skill->db[idx].unit_target = BCT_ENEMY; - else if( strcmpi(split[6],"self")==0 ) skill->db[idx].unit_target = BCT_SELF; - else if( strcmpi(split[6],"sameguild")==0 ) skill->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD; - else if( strcmpi(split[6],"noone")==0 ) skill->db[idx].unit_target = BCT_NOONE; - else skill->db[idx].unit_target = (int)strtol(split[6],NULL,16); - - skill->db[idx].unit_flag = (int)strtol(split[7],NULL,16); - - if (skill->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy) - skill->db[idx].unit_target = BCT_NOENEMY; + skill->dbs->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16); + skill->dbs->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16); + skill->split_atoi(split[3],skill->dbs->db[idx].unit_layout_type); + skill->split_atoi(split[4],skill->dbs->db[idx].unit_range); + skill->dbs->db[idx].unit_interval = atoi(split[5]); + + if( strcmpi(split[6],"noenemy")==0 ) skill->dbs->db[idx].unit_target = BCT_NOENEMY; + else if( strcmpi(split[6],"friend")==0 ) skill->dbs->db[idx].unit_target = BCT_NOENEMY; + else if( strcmpi(split[6],"party")==0 ) skill->dbs->db[idx].unit_target = BCT_PARTY; + else if( strcmpi(split[6],"ally")==0 ) skill->dbs->db[idx].unit_target = BCT_PARTY|BCT_GUILD; + else if( strcmpi(split[6],"guild")==0 ) skill->dbs->db[idx].unit_target = BCT_GUILD; + else if( strcmpi(split[6],"all")==0 ) skill->dbs->db[idx].unit_target = BCT_ALL; + else if( strcmpi(split[6],"enemy")==0 ) skill->dbs->db[idx].unit_target = BCT_ENEMY; + else if( strcmpi(split[6],"self")==0 ) skill->dbs->db[idx].unit_target = BCT_SELF; + else if( strcmpi(split[6],"sameguild")==0 ) skill->dbs->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD; + else if( strcmpi(split[6],"noone")==0 ) skill->dbs->db[idx].unit_target = BCT_NOONE; + else skill->dbs->db[idx].unit_target = (int)strtol(split[6],NULL,16); + + skill->dbs->db[idx].unit_flag = (int)strtol(split[7],NULL,16); + + if (skill->dbs->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy) + skill->dbs->db[idx].unit_target = BCT_NOENEMY; //By default, target just characters. - skill->db[idx].unit_target |= BL_CHAR; - if (skill->db[idx].unit_flag&UF_NOPC) - skill->db[idx].unit_target &= ~BL_PC; - if (skill->db[idx].unit_flag&UF_NOMOB) - skill->db[idx].unit_target &= ~BL_MOB; - if (skill->db[idx].unit_flag&UF_SKILL) - skill->db[idx].unit_target |= BL_SKILL; + skill->dbs->db[idx].unit_target |= BL_CHAR; + if (skill->dbs->db[idx].unit_flag&UF_NOPC) + skill->dbs->db[idx].unit_target &= ~BL_PC; + if (skill->dbs->db[idx].unit_flag&UF_NOMOB) + skill->dbs->db[idx].unit_target &= ~BL_MOB; + if (skill->dbs->db[idx].unit_flag&UF_SKILL) + skill->dbs->db[idx].unit_target |= BL_SKILL; return true; } @@ -18783,14 +18796,14 @@ bool skill_parse_row_producedb(char* split[], int columns, int current) { if( !i ) return false; - skill->produce_db[current].nameid = i; - skill->produce_db[current].itemlv = atoi(split[1]); - skill->produce_db[current].req_skill = atoi(split[2]); - skill->produce_db[current].req_skill_lv = atoi(split[3]); + skill->dbs->produce_db[current].nameid = i; + skill->dbs->produce_db[current].itemlv = atoi(split[1]); + skill->dbs->produce_db[current].req_skill = atoi(split[2]); + skill->dbs->produce_db[current].req_skill_lv = atoi(split[3]); for( x = 4, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_PRODUCE_RESOURCE; x += 2, y++ ) { - skill->produce_db[current].mat_id[y] = atoi(split[x]); - skill->produce_db[current].mat_amount[y] = atoi(split[x+1]); + skill->dbs->produce_db[current].mat_id[y] = atoi(split[x]); + skill->dbs->produce_db[current].mat_amount[y] = atoi(split[x+1]); } return true; @@ -18804,11 +18817,11 @@ bool skill_parse_row_createarrowdb(char* split[], int columns, int current) { if( !i ) return false; - skill->arrow_db[current].nameid = i; + skill->dbs->arrow_db[current].nameid = i; for( x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESOURCE; x += 2, y++ ) { - skill->arrow_db[current].cre_id[y] = atoi(split[x]); - skill->arrow_db[current].cre_amount[y] = atoi(split[x+1]); + skill->dbs->arrow_db[current].cre_id[y] = atoi(split[x]); + skill->dbs->arrow_db[current].cre_amount[y] = atoi(split[x+1]); } return true; @@ -18827,9 +18840,9 @@ bool skill_parse_row_spellbookdb(char* split[], int columns, int current) { if( points < 1 ) ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill->get_name(skill_id)); else { - skill->spellbook_db[current].skill_id = skill_id; - skill->spellbook_db[current].point = points; - skill->spellbook_db[current].nameid = nameid; + skill->dbs->spellbook_db[current].skill_id = skill_id; + skill->dbs->spellbook_db[current].point = points; + skill->dbs->spellbook_db[current].nameid = nameid; return true; } @@ -18857,8 +18870,8 @@ bool skill_parse_row_improvisedb(char* split[], int columns, int current) { ShowError("skill_improvise_db: Maximum amount of entries reached (%d), increase MAX_SKILL_IMPROVISE_DB\n",MAX_SKILL_IMPROVISE_DB); return false; } - skill->improvise_db[current].skill_id = skill_id; - skill->improvise_db[current].per = j; // Still need confirm it. + skill->dbs->improvise_db[current].skill_id = skill_id; + skill->dbs->improvise_db[current].per = j; // Still need confirm it. return true; } @@ -18875,7 +18888,7 @@ bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) { return false; } - skill->magicmushroom_db[current].skill_id = skill_id; + skill->dbs->magicmushroom_db[current].skill_id = skill_id; return true; } @@ -18886,7 +18899,7 @@ bool skill_parse_row_reproducedb(char* split[], int column, int current) { if( !idx ) return false; - skill->reproduce_db[idx] = true; + skill->dbs->reproduce_db[idx] = true; return true; } @@ -18904,9 +18917,9 @@ bool skill_parse_row_abradb(char* split[], int columns, int current) { return false; } - skill->abra_db[current].skill_id = skill_id; - skill->abra_db[current].req_lv = atoi(split[2]); - skill->abra_db[current].per = atoi(split[3]); + skill->dbs->abra_db[current].skill_id = skill_id; + skill->dbs->abra_db[current].req_lv = atoi(split[2]); + skill->dbs->abra_db[current].per = atoi(split[3]); return true; } @@ -18918,8 +18931,8 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) { int x,y; for(x=0; x<MAX_SKILL_PRODUCE_DB; x++){ - if( skill->produce_db[x].nameid == skill_id ) - if( skill->produce_db[x].req_skill == GN_CHANGEMATERIAL ) + if( skill->dbs->produce_db[x].nameid == skill_id ) + if( skill->dbs->produce_db[x].req_skill == GN_CHANGEMATERIAL ) break; } @@ -18933,12 +18946,12 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) { return false; } - skill->changematerial_db[current].itemid = skill_id; - skill->changematerial_db[current].rate = j; + skill->dbs->changematerial_db[current].itemid = skill_id; + skill->dbs->changematerial_db[current].rate = j; for( x = 2, y = 0; x+1 < columns && split[x] && split[x+1] && y < 5; x += 2, y++ ) { - skill->changematerial_db[current].qty[y] = atoi(split[x]); - skill->changematerial_db[current].qty_rate[y] = atoi(split[x+1]); + skill->dbs->changematerial_db[current].qty[y] = atoi(split[x]); + skill->dbs->changematerial_db[current].qty_rate[y] = atoi(split[x+1]); } return true; @@ -18962,21 +18975,12 @@ void skill_readdb(bool minimal) { /* when != it was called during init and this procedure was already performed by skill_defaults() */ if( runflag == MAPSERVER_ST_RUNNING ) { - memset(skill->db,0,sizeof(skill->db) - + sizeof(skill->produce_db) - + sizeof(skill->arrow_db) - + sizeof(skill->abra_db) - + sizeof(skill->magicmushroom_db) - + sizeof(skill->improvise_db) - + sizeof(skill->changematerial_db) - + sizeof(skill->spellbook_db) - + sizeof(skill->reproduce_db) - ); + memset(ZEROED_BLOCK_POS(skill->dbs), 0, ZEROED_BLOCK_SIZE(skill->dbs)); } // load skill databases - safestrncpy(skill->db[0].name, "UNKNOWN_SKILL", sizeof(skill->db[0].name)); - safestrncpy(skill->db[0].desc, "Unknown Skill", sizeof(skill->db[0].desc)); + safestrncpy(skill->dbs->db[0].name, "UNKNOWN_SKILL", sizeof(skill->dbs->db[0].name)); + safestrncpy(skill->dbs->db[0].desc, "Unknown Skill", sizeof(skill->dbs->db[0].desc)); #ifdef ENABLE_CASE_CHECK script->parser_current_file = DBPATH"skill_db.txt"; @@ -19094,6 +19098,8 @@ void skill_defaults(void) { const int skill_deluge_eff[5] = { 5, 9, 12, 14, 15 }; skill = &skill_s; + skill->dbs = &skilldbs; + skill->init = do_init_skill; skill->final = do_final_skill; skill->reload = skill_reload; @@ -19110,18 +19116,10 @@ void skill_defaults(void) { skill->timer_ers = NULL; skill->cd_ers = NULL; skill->cd_entry_ers = NULL; - /* one huge 0, follows skill.h order */ - memset(skill->db,0,sizeof(skill->db) - + sizeof(skill->produce_db) - + sizeof(skill->arrow_db) - + sizeof(skill->abra_db) - + sizeof(skill->magicmushroom_db) - + sizeof(skill->improvise_db) - + sizeof(skill->changematerial_db) - + sizeof(skill->spellbook_db) - + sizeof(skill->reproduce_db) - + sizeof(skill->unit_layout) - ); + + memset(ZEROED_BLOCK_POS(skill->dbs), 0, ZEROED_BLOCK_SIZE(skill->dbs)); + memset(skill->dbs->unit_layout, 0, sizeof(skill->dbs->unit_layout)); + /* */ memcpy(skill->enchant_eff, skill_enchant_eff, sizeof(skill->enchant_eff)); memcpy(skill->deluge_eff, skill_deluge_eff, sizeof(skill->deluge_eff)); |