From 3d23d29e1f63a526338a35a05d384b7571f12553 Mon Sep 17 00:00:00 2001 From: zephyrus Date: Wed, 3 Sep 2008 13:32:38 +0000 Subject: - Starting Mercenary Skill implementation. - MS_BASH Completed. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13189 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 2 + src/map/clif.c | 59 +++++++++++----- src/map/map.h | 10 +-- src/map/mercenary.c | 17 ++++- src/map/mercenary.h | 4 ++ src/map/skill.c | 194 ++++++++++++++++++++++++++++------------------------ src/map/skill.h | 12 ++-- 7 files changed, 181 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 518c52ad2..1140c6640 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1120,6 +1120,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo { //Hit skill modifiers //It is proven that bonus is applied on final hitrate, not hit. case SM_BASH: + case MS_BASH: hitrate += hitrate * 5 * skill_lv / 100; break; case SM_MAGNUM: @@ -1309,6 +1310,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo switch( skill_num ) { case SM_BASH: + case MS_BASH: skillratio += 30*skill_lv; break; case SM_MAGNUM: diff --git a/src/map/clif.c b/src/map/clif.c index f1f1417fc..f6014fe3a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9172,30 +9172,50 @@ static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_sess { int lv; - if (!hd) + if( !hd ) return; - - if (skillnotok_hom(skillnum, hd)) //[orn] + if( skillnotok_hom(skillnum, hd) ) return; - - if (hd->bl.id != target_id && - skill_get_inf(skillnum)&INF_SELF_SKILL) - target_id = hd->bl.id; //What good is it to mess up the target in self skills? Wished I knew... [Skotlex] - - if (hd->ud.skilltimer != -1) { - if (skillnum != SA_CASTCANCEL) - return; - } else if (DIFF_TICK(tick, hd->ud.canact_tick) < 0) + if( hd->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL ) + target_id = hd->bl.id; + if( hd->ud.skilltimer != -1 ) + { + if( skillnum != SA_CASTCANCEL ) return; + } + else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) return; lv = merc_hom_checkskill(hd, skillnum); - if (skilllv > lv) + if( skilllv > lv ) skilllv = lv; - - if (skilllv) + if( skilllv ) unit_skilluse_id(&hd->bl, target_id, skillnum, skilllv); } +static void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, int target_id) +{ + int lv; + + if( !md ) + return; + if( skillnotok_mercenary(skillnum, md) ) + return; + if( md->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL ) + target_id = md->bl.id; + if( md->ud.skilltimer != INVALID_TIMER ) + { + if( skillnum != SA_CASTCANCEL ) return; + } + else if( DIFF_TICK(tick, md->ud.canact_tick) < 0 ) + return; + + lv = mercenary_checkskill(md, skillnum); + if( skilllv > lv ) + skilllv = lv; + if( skilllv ) + unit_skilluse_id(&md->bl, target_id, skillnum, skilllv); +} + /*========================================== * スキル使用(ID指定) *------------------------------------------*/ @@ -9216,11 +9236,18 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if (tmp&INF_GROUND_SKILL || !tmp) return; //Using a ground/passive skill on a target? WRONG. - if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL) { + if( skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL ) + { clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id); return; } + if( skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE+MAX_MERCSKILL ) + { + clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skillnum, skilllv, target_id); + return; + } + // Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex] sd->idletime = last_tick; diff --git a/src/map/map.h b/src/map/map.h index 92011827b..4a8be92ed 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -172,11 +172,11 @@ enum bl_type { BL_MOB = 0x002, BL_PET = 0x004, BL_HOM = 0x008, - BL_ITEM = 0x010, - BL_SKILL = 0x020, - BL_NPC = 0x040, - BL_CHAT = 0x080, - BL_MER = 0x100, + BL_MER = 0x010, + BL_ITEM = 0x020, + BL_SKILL = 0x040, + BL_NPC = 0x080, + BL_CHAT = 0x100, BL_ALL = 0xFFF, }; diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 0c6e03b6b..566aab6c1 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -314,7 +314,10 @@ int merc_data_received(struct s_mercenary *merc, bool flag) void mercenary_damage(struct mercenary_data *md, struct block_list *src, int hp, int sp) { - clif_mercenary_updatestatus(md->master, SP_HP); + if( hp ) + clif_mercenary_updatestatus(md->master, SP_HP); + if( sp ) + clif_mercenary_updatestatus(md->master, SP_SP); } void mercenary_heal(struct mercenary_data *md, int hp, int sp) @@ -357,6 +360,18 @@ int mercenary_kills(struct mercenary_data *md) return 0; } +int mercenary_checkskill(struct mercenary_data *md, int skill_id) +{ + int i = skill_id - MC_SKILLBASE; + + if( !md || !md->db ) + return 0; + if( md->db->skill[i].id == skill_id ) + return md->db->skill[i].lv; + + return 0; +} + int read_mercenarydb(void) { FILE *fp; diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 21cdf9245..826133660 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -34,6 +34,8 @@ struct mercenary_data { struct map_session_data *master; int contract_timer; + + char blockskill[MAX_SKILL]; }; bool merc_class(int class_); @@ -57,6 +59,8 @@ int mercenary_get_calls(struct mercenary_data *md); int mercenary_set_calls(struct mercenary_data *md, int value); int mercenary_kills(struct mercenary_data *md); +int mercenary_checkskill(struct mercenary_data *md, int skill_id); + int do_init_mercenary(void); #endif /* _MERCENARY_H_ */ diff --git a/src/map/skill.c b/src/map/skill.c index b75245a98..5409d3cb4 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -18,6 +18,7 @@ #include "status.h" #include "pet.h" #include "homunculus.h" +#include "mercenary.h" #include "mob.h" #include "npc.h" #include "battle.h" @@ -390,11 +391,10 @@ int skillnotok (int skillid, struct map_session_data *sd) return (map[m].flag.noskill); } -// [orn] - skill ok to cast? and when? //homunculus -int skillnotok_hom (int skillid, struct homun_data *hd) +int skillnotok_hom(int skillid, struct homun_data *hd) { int i = skill_get_index(skillid); - nullpo_retr (1, hd); + nullpo_retr(1,hd); if (i == 0) return 1; // invalid skill id @@ -406,6 +406,19 @@ int skillnotok_hom (int skillid, struct homun_data *hd) return skillnotok(skillid, hd->master); } +int skillnotok_mercenary(int skillid, struct mercenary_data *md) +{ + int i = skill_get_index(skillid); + nullpo_retr(1,md); + + if( i == 0 ) + return 1; // Invalid Skill ID + if( md->blockskill[i] > 0 ) + return 1; + + return skillnotok(skillid, md->master); +} + struct s_skill_unit_layout* skill_get_unit_layout (int skillid, int skilllv, struct block_list* src, int x, int y) { int pos = skill_get_unit_layout_type(skillid,skilllv); @@ -1943,117 +1956,122 @@ int skill_guildaura_sub (struct block_list *bl, va_list ap) } /*========================================== - * [orn] - * Checks that you have the requirements for casting a skill for homunculus. + * Checks that you have the requirements for casting a skill for homunculus/mercenary. * Flag: * &1: finished casting the skill (invoke hp/sp/item consumption) * &2: picked menu entry (Warp Portal, Teleport and other menu based skills) *------------------------------------------*/ -static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv, int type) +static int skill_check_condition_mercenary(struct block_list *bl, int skill, int lv, int type) { struct status_data *status; - TBL_PC * sd; - int i,j,hp,sp,hp_rate,sp_rate,state,mhp ; + struct map_session_data *sd; + int i, j, hp, sp, hp_rate, sp_rate, state, mhp; int itemid[10],amount[ARRAYLENGTH(itemid)],index[ARRAYLENGTH(itemid)]; - - nullpo_retr(0, hd); - sd = hd->master; - if (lv <= 0) return 0; + if( lv < 1 || lv > MAX_SKILL_LEVEL ) + return 0; + nullpo_retr(0,bl); - status = &hd->battle_status; + switch( bl->type ) + { + case BL_HOM: sd = ((TBL_HOM*)bl)->master; break; + case BL_MER: sd = ((TBL_MER*)bl)->master; break; + } - //Code speedup, rather than using skill_get_* over and over again. - j = skill_get_index(skill); - if( j == 0 ) - return 0; - if( lv < 1 || lv > MAX_SKILL_LEVEL ) + status = status_get_status_data(bl); + if( (j = skill_get_index(skill)) == 0 ) return 0; - for(i = 0; i < 10; i++) { + // Requeriments + for( i = 0; i < ARRAYLENGTH(itemid); i++ ) + { itemid[i] = skill_db[j].itemid[i]; amount[i] = skill_db[j].amount[i]; } - hp = skill_db[j].hp[lv-1]; sp = skill_db[j].sp[lv-1]; hp_rate = skill_db[j].hp_rate[lv-1]; sp_rate = skill_db[j].sp_rate[lv-1]; state = skill_db[j].state; - mhp = skill_db[j].mhp[lv-1]; - if(mhp > 0) - hp += (status->max_hp * mhp)/100; - if(hp_rate > 0) - hp += (status->hp * hp_rate)/100; + if( (mhp = skill_db[j].mhp[lv-1]) > 0 ) + hp += (status->max_hp * mhp) / 100; + if( hp_rate > 0 ) + hp += (status->hp * hp_rate) / 100; else - hp += (status->max_hp * (-hp_rate))/100; - if(sp_rate > 0) - sp += (status->sp * sp_rate)/100; + hp += (status->max_hp * (-hp_rate)) / 100; + if( sp_rate > 0 ) + sp += (status->sp * sp_rate) / 100; else - sp += (status->max_sp * (-sp_rate))/100; + sp += (status->max_sp * (-sp_rate)) / 100; - switch(skill) { // Check for cost reductions due to skills & SCs - case HFLI_SBR44: - if(hd->homunculus.intimacy <= 200) - return 0; - break; - case HVAN_EXPLOSION: - if(hd->homunculus.intimacy < (unsigned int)battle_config.hvan_explosion_intimate) - return 0; - break; + if( bl->type == BL_HOM ) + { // Intimacy Requeriments + struct homun_data *hd = BL_CAST(BL_HOM, bl); + switch( skill ) + { + case HFLI_SBR44: + if( hd->homunculus.intimacy <= 200 ) + return 0; + break; + case HVAN_EXPLOSION: + if( hd->homunculus.intimacy < (unsigned int)battle_config.hvan_explosion_intimate ) + return 0; + break; + } } - if(!(type&2)){ - if( hp>0 && status->hp <= (unsigned int)hp) { - clif_skill_fail(sd,skill,2,0); + if( !(type&2) ) + { + if( hp > 0 && status->hp <= (unsigned int)hp ) + { + clif_skill_fail(sd, skill, 2, 0); return 0; } - if( sp>0 && status->sp < (unsigned int)sp) { - clif_skill_fail(sd,skill,1,0); + if( sp > 0 && status->sp <= (unsigned int)sp ) + { + clif_skill_fail(sd, skill, 1, 0); return 0; } } - if (!type) //States are only checked on begin casting. - switch(state) { - case ST_MOVE_ENABLE: - if(!unit_can_move(&hd->bl)) { - clif_skill_fail(sd,skill,0,0); - return 0; + if( !type ) + switch( state ) + { + case ST_MOVE_ENABLE: + if( !unit_can_move(bl) ) + { + clif_skill_fail(sd, skill, 0, 0); + return 0; + } + break; } - break; - } - - if(!(type&1)) + if( !(type&1) ) return 1; - // Check items and reduce required amounts - for( i = 0; i < ARRAYLENGTH(itemid); ++i ) + // Check item existences + for( i = 0; i < ARRAYLENGTH(itemid); i++ ) { index[i] = -1; - if(itemid[i] <= 0) - continue;// no item - - index[i] = pc_search_inventory(sd,itemid[i]); - if(index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i]) + if( itemid[i] < 1 ) continue; // No item + index[i] = pc_search_inventory(sd, itemid[i]); + if( index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i] ) { - clif_skill_fail(sd,skill,0,0); + clif_skill_fail(sd, skill, 0, 0); return 0; } } // Consume items - for( i = 0; i < ARRAYLENGTH(itemid); ++i ) + for( i = 0; i < ARRAYLENGTH(itemid); i++ ) { - if(index[i] >= 0) - pc_delitem(sd,index[i],amount[i],0); + if( index[i] >= 0 ) pc_delitem(sd, index[i], amount[i], 0); } - if(type&2) + if( type&2 ) return 1; - if(sp || hp) - status_zap(&hd->bl, hp, sp); + if( sp || hp ) + status_zap(bl, hp, sp); return 1; } @@ -2272,6 +2290,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int switch(skillid) { case SM_BASH: + case MS_BASH: case MC_MAMMONITE: case TF_DOUBLE: case AC_DOUBLE: @@ -5145,7 +5164,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in x = src->x; y = src->y; if (hd) - skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)); + skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv)); if (unit_movepos(src,bl->x,bl->y,0,0)) { clif_skill_nodamage(src,src,skillid,skilllv,1); // Homunc @@ -5197,7 +5216,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv))); if (hd) - skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)); + skill_blockhomun_start(hd, skillid, skill_get_time2(skillid,skilllv)); break; case NPC_DRAGONFEAR: @@ -5251,14 +5270,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in *------------------------------------------*/ int skill_castend_id(int tid, unsigned int tick, int id, intptr data) { - struct block_list* target = NULL; - struct block_list* src = NULL; - struct map_session_data* sd = NULL; - struct homun_data* hd = NULL; //[orn] - struct mob_data* md = NULL; - struct unit_data* ud = NULL; - struct status_change* sc = NULL; - int inf,inf2,flag=0; + struct block_list *target, *src; + struct map_session_data *sd; + struct mob_data *md; + struct unit_data *ud; + struct status_change *sc; + int inf,inf2,flag = 0; src = map_id2bl(id); if( src == NULL ) @@ -5275,7 +5292,6 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data) } sd = BL_CAST(BL_PC, src); - hd = BL_CAST(BL_HOM, src); md = BL_CAST(BL_MOB, src); if( src->prev == NULL ) { @@ -5400,12 +5416,12 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data) break; } - if(sd && !skill_check_condition(sd,ud->skillid, ud->skilllv,1)) - break; - - if(hd && !skill_check_condition_hom(hd,ud->skillid, ud->skilllv,1)) //[orn] + if( sd && !skill_check_condition(sd, ud->skillid, ud->skilllv,1) ) break; + if( (src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1) ) + break; + if (ud->state.running && ud->skillid == TK_JUMPKICK) flag = 1; @@ -5498,15 +5514,13 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data) { struct block_list* src = map_id2bl(id); int maxcount; - struct map_session_data *sd = NULL; - struct homun_data *hd = NULL; //[orn] + struct map_session_data *sd; struct unit_data *ud = unit_bl2ud(src); - struct mob_data *md = NULL; + struct mob_data *md; nullpo_retr(0, ud); sd = BL_CAST(BL_PC , src); - hd = BL_CAST(BL_HOM, src); md = BL_CAST(BL_MOB, src); if( src->prev == NULL ) { @@ -5578,7 +5592,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data) if(sd && !skill_check_condition(sd,ud->skillid, ud->skilllv, 1)) break; - if(hd && !skill_check_condition_hom(hd,ud->skillid, ud->skilllv, 1)) //[orn] + if( (src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skillid, ud->skilllv, 1) ) break; if(md) { @@ -10510,7 +10524,7 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick) return add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid); } -int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr data) //[orn] +int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr data) //[orn] { struct homun_data *hd = (TBL_HOM*) map_id2bl(id); if (data <= 0 || data >= MAX_SKILL) @@ -10520,7 +10534,7 @@ int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr data) //[orn] return 1; } -int skill_blockmerc_start(struct homun_data *hd, int skillid, int tick) //[orn] +int skill_blockhomun_start(struct homun_data *hd, int skillid, int tick) //[orn] { nullpo_retr (-1, hd); @@ -10533,7 +10547,7 @@ int skill_blockmerc_start(struct homun_data *hd, int skillid, int tick) //[orn] return -1; } hd->blockskill[skillid] = 1; - return add_timer(gettick()+tick,skill_blockmerc_end,hd->bl.id,skillid); + return add_timer(gettick() + tick, skill_blockhomun_end, hd->bl.id, skillid); } diff --git a/src/map/skill.h b/src/map/skill.h index 5b583406d..34ce889b8 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -311,8 +311,10 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce // ステ?タス異常 int skill_enchant_elemental_end(struct block_list *bl, int type); int skillnotok(int skillid, struct map_session_data *sd); -int skillnotok_hom (int skillid, struct homun_data *hd) ; //[orn] -int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap); //[orn] +int skillnotok_hom(int skillid, struct homun_data *hd); +int skillnotok_mercenary(int skillid, struct mercenary_data *md); + +int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap); // アイテム作成 int skill_can_produce_mix( struct map_session_data *sd, int nameid, int trigger, int qty); @@ -324,8 +326,9 @@ int skill_arrow_create( struct map_session_data *sd,int nameid); int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skilllv,unsigned int tick,int flag); + int skill_blockpc_start (struct map_session_data*,int,int); // [celest] -int skill_blockmerc_start (struct homun_data*,int,int); //[orn] +int skill_blockhomun_start (struct homun_data*,int,int); //[orn] // スキル攻?一括?理 int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc,struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); @@ -1009,7 +1012,7 @@ enum e_skill { HVAN_CHAOTIC, HVAN_INSTRUCT, HVAN_EXPLOSION, - /* + MS_BASH = 8201, MS_MAGNUM, MS_BOWLINGBASH, @@ -1047,7 +1050,6 @@ enum e_skill { MER_SCAPEGOAT, MER_LEXDIVINA, MER_ESTIMATION, - */ }; enum { -- cgit v1.2.3-60-g2f50