summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/battle/skill.conf4
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/clif.c59
-rw-r--r--src/map/map.h10
-rw-r--r--src/map/mercenary.c17
-rw-r--r--src/map/mercenary.h4
-rw-r--r--src/map/skill.c194
-rw-r--r--src/map/skill.h12
8 files changed, 183 insertions, 119 deletions
diff --git a/conf/battle/skill.conf b/conf/battle/skill.conf
index ea1d56cc2..82a1c0159 100644
--- a/conf/battle/skill.conf
+++ b/conf/battle/skill.conf
@@ -18,7 +18,7 @@
// Note 1: Value is a config switch (on/off, yes/no or 1/0)
// Note 2: Value is in percents (100 means 100%)
// Note 3: Value is a bit field. If no description is given,
-// assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun)
+// assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun, 16: Mercenary)
//--------------------------------------------------------------
// The rate of time it takes to cast a spell (Note 2, 0 = No casting time)
@@ -72,7 +72,7 @@ skillrange_by_distance: 14
// Should the equipped weapon's range override the skill's range defined in the skill_db for most weapon-based skills? (Note 3)
// NOTE: Skills affected by this option are those whose range in the skill_db are negative. Note that unless monster_ai&0x400 is
// set, the range of all skills is 9 for monsters.
-skillrange_from_weapon: 14
+skillrange_from_weapon: 30
// Should a check on the caster's status be performed in all skill attacks?
// When set to yes, meteors, storm gust and any other ground skills will have
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 {