- JK_JOINTBEAT as described in:

http://www.ragnainfo.net/wiki/index.php/Vital_Strike
  Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
  Reported by zaibach in http://www.eathena.ws/board/index.php?s=&showtopic=93873&view=findpost&p=727844

Note: this should be reviewed by Skotlex or someone that knows this part of the code.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9609 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
FlavioJS 2007-01-03 05:07:58 +00:00
parent 215762fe8c
commit 00c558490a
7 changed files with 169 additions and 138 deletions

View File

@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/01/03
* JK_JOINTBEAT as described in:
http://www.ragnainfo.net/wiki/index.php/Vital_Strike
Although not clear, it's being assumed that the 2x damage is only for the
break neck ailment. [FlavioJS]
* Modified the useless error message in atcommand_effect.
* Silenced the debug message in socket.c that's been freaking people out.
* Added support for text/comments at the end of monster spawn lines (<tab> required)

View File

@ -1027,9 +1027,6 @@ static struct Damage battle_calc_weapon_attack(
{
if (tsc->data[SC_SLEEP].timer!=-1 )
cri <<=1;
if(tsc->data[SC_JOINTBEAT].timer != -1 &&
tsc->data[SC_JOINTBEAT].val2 == 5) // Always take crits with Neck broken by Joint Beat [DracoRPG]
flag.cri=1;
}
switch (skill_num)
{
@ -2082,6 +2079,10 @@ static struct Damage battle_calc_weapon_attack(
{ //Breaker's int-based damage (a misc attack?)
struct Damage md = battle_calc_misc_attack(src, target, skill_num, skill_lv, wflag);
wd.damage += md.damage;
} else if( skill_num == LK_JOINTBEAT && wflag&BREAK_NECK ) {
//##TODO should this be here?[FlavioJS]
// Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
wd.damage *= 2; // 2x damage when breaking neck
}
if (wd.damage || wd.damage2) {
@ -3003,7 +3004,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
else if (sc && sc->data[SC_SACRIFICE].timer != -1)
return skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,sc->data[SC_SACRIFICE].val1,tick,0);
wd = battle_calc_weapon_attack(src,target, 0, 0,0);
wd = battle_calc_weapon_attack(src, target, 0, 0, flag);
if (sd && sd->state.arrow_atk) //Consume arrow.
battle_consume_ammo(sd, 0, 0);

View File

@ -95,7 +95,7 @@ int clif_additem(struct map_session_data*,int,int,int); //self
int clif_delitem(struct map_session_data*,int,int); //self
int clif_updatestatus(struct map_session_data*,int); //self
int clif_changestatus(struct block_list*,int,int); //area
int clif_damage(struct block_list *,struct block_list *,unsigned int,int,int,int,int,int,int); // area
int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2); // area
#define clif_takeitem(src,dst) clif_damage(src,dst,0,0,0,0,0,1,0)
int clif_changelook(struct block_list *,int,int); // area
void clif_changetraplook(struct block_list *bl,int val); // area

View File

@ -1134,7 +1134,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
sc_start(bl,SC_FREEZE,(3*skilllv+35),skilllv,skill_get_time2(skillid,skilllv));
break;
case HT_FLASHER:
case HT_FLASHER:
sc_start(bl,SC_BLIND,(10*skilllv+30),skilllv,skill_get_time2(skillid,skilllv));
break;
@ -1275,11 +1275,15 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
if (!(battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON))
sc_start(bl, SC_BLEEDING,50, skilllv, skill_get_time2(skillid,skilllv));
break;
/*
case LK_JOINTBEAT:
sc_start(bl,SkillStatusChangeTable(skillid),(5*skilllv+5),skilllv,skill_get_time2(skillid,skilllv));
{
int flag = 0;
//##TODO how should this be done? the ailment has to be calculated before because it also affects the damage [FlavioJS]
sc_start2(bl,SkillStatusChangeTable(skillid),(5*skilllv+5),skilllv,flag&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
break;
}
*/
case ASC_METEORASSAULT:
//Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*SkillLV% chance.
switch(rand()%3) {
@ -1470,7 +1474,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
mob_class_change(dstmd,class_);
}
return 0;
}
@ -2743,7 +2746,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case LK_AURABLADE:
case LK_SPIRALPIERCE:
case LK_HEADCRUSH:
case LK_JOINTBEAT:
case CG_ARROWVULCAN:
case HW_MAGICCRASHER:
case ITM_TOMAHAWK:
@ -2775,6 +2777,20 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
case LK_JOINTBEAT: // decide the ailment first (affects attack damage and effect)
switch( rand()%6 ){
case 0: flag |= BREAK_ANKLE; break;
case 1: flag |= BREAK_WRIST; break;
case 2: flag |= BREAK_KNEE; break;
case 3: flag |= BREAK_SHOULDER; break;
case 4: flag |= BREAK_WAIST; break;
case 5: flag |= BREAK_NECK; break;
}
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
//##TODO this is a quick&dirty hack. How do I pass the selected ailment to skill_additional_effect? [FlavioJS]
sc_start2(bl,SkillStatusChangeTable(skillid),(5*skilllv+5),skilllv,flag&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
break;
case MO_COMBOFINISH:
if (!(flag&1) && sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_MONK)
{ //Becomes a splash attack when Soul Linked.

View File

@ -765,7 +765,6 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
if (!(flag&1) && sc && sc->data[SC_BERSERK].timer!=-1)
hp = 0;
if((unsigned int)hp > status->max_hp - status->hp)
hp = status->max_hp - status->hp;
}
@ -3341,7 +3340,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += batk * 3;
if(sc->data[SC_BLOODLUST].timer!=-1)
batk += batk * sc->data[SC_BLOODLUST].val2/100;
if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2==4)
if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2&BREAK_WAIST)
batk -= batk * 25/100;
if(sc->data[SC_CURSE].timer!=-1)
batk -= batk * 25/100;
@ -3580,10 +3579,9 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
if(sc->data[SC_PROVOKE].timer!=-1)
def2 -= def2 * sc->data[SC_PROVOKE].val4/100;
if(sc->data[SC_JOINTBEAT].timer!=-1){
if(sc->data[SC_JOINTBEAT].val2==3)
def2 -= def2 * 50/100;
else if(sc->data[SC_JOINTBEAT].val2==4)
def2 -= def2 * 25/100;
def2 -= def2 *
( ( sc->data[SC_JOINTBEAT].val2&BREAK_SHOULDER ? 50 : 0 )
+ ( sc->data[SC_JOINTBEAT].val2&BREAK_WAIST ? 25 : 0 ) );
}
if(sc->data[SC_FLING].timer!=-1)
def2 -= def2 * (sc->data[SC_FLING].val3)/100;
@ -3679,11 +3677,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
speed = speed * 100/75;
if(sc->data[SC_JOINTBEAT].timer!=-1) {
if (sc->data[SC_JOINTBEAT].val2 == 0)
speed = speed * 100/50;
else
if (sc->data[SC_JOINTBEAT].val2 == 2)
speed = speed * 100/70;
speed = speed * ( 100
- ( sc->data[SC_JOINTBEAT].val2&BREAK_ANKLE ? 50 : 0 )
- ( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE ? 30 : 0 ));
}
if(sc->data[SC_CLOAKING].timer!=-1)
speed = speed * 100 /(
@ -3794,9 +3790,9 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
// if(sc->data[SC_BLEEDING].timer != -1)
// aspd_rate += 250;
if(sc->data[SC_JOINTBEAT].timer!=-1) {
if (sc->data[SC_JOINTBEAT].val2 == 1)
if( sc->data[SC_JOINTBEAT].val2&BREAK_WRIST )
aspd_rate += 250;
else if (sc->data[SC_JOINTBEAT].val2 == 2)
if( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE )
aspd_rate += 100;
}
@ -5250,9 +5246,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
val3 = 4*val2; //movement speed % increase is 4 times that
break;
case SC_JOINTBEAT: // Random break [DracoRPG]
val2 = rand()%6; //Type of break -> [0,5]
if (val2 == 5) sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(StatusSkillChangeTable[type],val1));
case SC_JOINTBEAT:
val2 |= sc->data[SC_JOINTBEAT].val2; // stackable ailments
if( val2&BREAK_NECK )
sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(StatusSkillChangeTable[type],val1));
break;
case SC_BERSERK:
@ -6309,6 +6306,9 @@ int status_change_end( struct block_list* bl , int type,int tid )
status_set_hp(bl, 10, 0);
status_set_sp(bl, 10, 0);
break;
case SC_JOINTBEAT:
sc->data[type].val2 = 0; // Clear stackable ailments
break;
}
opt_flag = 1;

View File

@ -402,6 +402,15 @@ enum {
SI_ACCURACY = 210
};
// JOINTBEAT stackable ailments
#define BREAK_ANKLE 0x01 // MoveSpeed reduced by 50%
#define BREAK_WRIST 0x02 // ASPD reduced by 25%
#define BREAK_KNEE 0x04 // MoveSpeed reduced by 30%, ASPD reduced by 10%
#define BREAK_SHOULDER 0x08 // DEF reduced by 50%
#define BREAK_WAIST 0x10 // DEF reduced by 25%, ATK reduced by 25%
#define BREAK_NECK 0x20 // current attack does 2x damage, inflicts 'bleeding' for 30 seconds
#define BREAK_FLAGS ( BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK )
extern int current_equip_item_index;
extern int current_equip_card_id;
@ -611,6 +620,7 @@ int status_get_sc_def(struct block_list *bl, int type);
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
#define sc_start(bl, type, rate, val1, tick) status_change_start(bl,type,100*(rate),val1,0,0,0,tick,0)
#define sc_start2(bl, type, rate, val1, val2, tick) status_change_start(bl,type,100*(rate),val1,val2,0,0,tick,0)
#define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) status_change_start(bl,type,100*(rate),val1,val2,val3,val4,tick,0)
int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);