- Mercenary Bonus Status (currently activated each mob kill for testing).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13182 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
zephyrus 2008-09-01 19:23:57 +00:00
parent d6f93d3f2f
commit 3d3946138a
5 changed files with 136 additions and 26 deletions

View File

@ -12398,6 +12398,15 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
case SP_MAXSP: case SP_MAXSP:
WFIFOL(fd,4) = md->battle_status.max_sp; WFIFOL(fd,4) = md->battle_status.max_sp;
break; break;
case SP_MERCFLEE:
WFIFOL(fd,4) = md->battle_status.flee;
break;
case SP_ATK1:
WFIFOL(fd,4) = md->battle_status.rhw.atk + md->battle_status.rhw.atk2;
break;
case SP_HIT:
WFIFOL(fd,4) = md->battle_status.hit;
break;
case SP_MERCKILLS: case SP_MERCKILLS:
WFIFOL(fd,4) = md->mercenary.kill_count; WFIFOL(fd,4) = md->mercenary.kill_count;
break; break;

View File

@ -87,7 +87,7 @@ int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime)
int mercenary_get_lifetime(struct mercenary_data *md) int mercenary_get_lifetime(struct mercenary_data *md)
{ {
const struct TimerData * td; const struct TimerData * td;
if( md == NULL ) if( md == NULL || md->contract_timer == INVALID_TIMER )
return 0; return 0;
td = get_timer(md->contract_timer); td = get_timer(md->contract_timer);
@ -331,6 +331,15 @@ int mercenary_dead(struct mercenary_data *md, struct block_list *src)
return 0; return 0;
} }
int mercenary_killbonus(struct mercenary_data *md)
{
const enum sc_type scs[] = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
int index = rand() % ARRAYLENGTH(scs);
status_change_start(&md->bl, scs[index], 10000, rand()%5, 0, 0, 0, 600000, 0);
return 0;
}
int mercenary_kills(struct mercenary_data *md) int mercenary_kills(struct mercenary_data *md)
{ {
md->mercenary.kill_count++; md->mercenary.kill_count++;
@ -342,6 +351,8 @@ int mercenary_kills(struct mercenary_data *md)
if( md->master ) if( md->master )
clif_mercenary_updatestatus(md->master, SP_MERCKILLS); clif_mercenary_updatestatus(md->master, SP_MERCKILLS);
mercenary_killbonus(md);
return 0; return 0;
} }

View File

@ -1942,8 +1942,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
} }
pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count); pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count);
} }
if( sd->md && (md->level > sd->status.base_level / 2) )
mercenary_kills(sd->md);
} }
// filter out entries not eligible for exp distribution // filter out entries not eligible for exp distribution
@ -2324,8 +2322,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
{ {
case BL_PET: sd = ((TBL_PET*)src)->msd; break; case BL_PET: sd = ((TBL_PET*)src)->msd; break;
case BL_HOM: sd = ((TBL_HOM*)src)->master; break; case BL_HOM: sd = ((TBL_HOM*)src)->master; break;
case BL_MER: sd = ((TBL_MER*)src)->master; break;
} }
if( sd && sd->md && src && src->type != BL_HOM )
mercenary_kills(sd->md);
if( md->npc_event[0] && !md->state.npc_killmonster ) if( md->npc_event[0] && !md->state.npc_killmonster )
{ {
if( sd && battle_config.mob_npc_event_type ) if( sd && battle_config.mob_npc_event_type )

View File

@ -457,6 +457,12 @@ void initChangeTables(void)
StatusIconChangeTable[SC_SPCOST_RATE] = SI_SPCOST_RATE; StatusIconChangeTable[SC_SPCOST_RATE] = SI_SPCOST_RATE;
StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_COMMONSC_RESIST; StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_COMMONSC_RESIST;
StatusIconChangeTable[SC_ARMOR_RESIST] = SI_ARMOR_RESIST; StatusIconChangeTable[SC_ARMOR_RESIST] = SI_ARMOR_RESIST;
// Mercenary Bonus Effects
StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
//Other SC which are not necessarily associated to skills. //Other SC which are not necessarily associated to skills.
StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD; StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
@ -503,8 +509,14 @@ void initChangeTables(void)
StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_PC; StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_PC;
StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_PC; StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_PC;
StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
// Mercenary Bonus Effects
StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
if (!battle_config.display_hallucination) //Disable Hallucination. if( !battle_config.display_hallucination ) //Disable Hallucination.
StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK; StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
} }
@ -3443,6 +3455,8 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk -= watk * 25/100; watk -= watk * 25/100;
if(sc->data[SC_STRIPWEAPON]) if(sc->data[SC_STRIPWEAPON])
watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100; watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
if(sc->data[SC_MERC_ATKUP])
watk += sc->data[SC_MERC_ATKUP]->val2;
return (unsigned short)cap_value(watk,0,USHRT_MAX); return (unsigned short)cap_value(watk,0,USHRT_MAX);
} }
@ -3509,7 +3523,9 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
hit -= 30; hit -= 30;
if(sc->data[SC_INCREASING]) if(sc->data[SC_INCREASING])
hit += 20; // RockmanEXE; changed based on updated [Reddozen] hit += 20; // RockmanEXE; changed based on updated [Reddozen]
if(sc->data[SC_MERC_HITUP])
hit += sc->data[SC_MERC_HITUP]->val2;
return (short)cap_value(hit,1,SHRT_MAX); return (short)cap_value(hit,1,SHRT_MAX);
} }
@ -3548,7 +3564,9 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
if(sc->data[SC_GATLINGFEVER]) if(sc->data[SC_GATLINGFEVER])
flee -= sc->data[SC_GATLINGFEVER]->val4; flee -= sc->data[SC_GATLINGFEVER]->val4;
if(sc->data[SC_SPEED]) if(sc->data[SC_SPEED])
flee += 10 + sc->data[SC_SPEED]->val1 * 10 ; flee += 10 + sc->data[SC_SPEED]->val1 * 10;
if(sc->data[SC_MERC_FLEEUP])
flee += sc->data[SC_MERC_FLEEUP]->val2;
return (short)cap_value(flee,1,SHRT_MAX); return (short)cap_value(flee,1,SHRT_MAX);
} }
@ -3946,6 +3964,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * sc->data[SC_DELUGE]->val2/100; maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
if(sc->data[SC_BERSERK]) if(sc->data[SC_BERSERK])
maxhp += maxhp * 2; maxhp += maxhp * 2;
if(sc->data[SC_MERC_HPUP])
maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
return cap_value(maxhp,1,UINT_MAX); return cap_value(maxhp,1,UINT_MAX);
} }
@ -3959,6 +3979,8 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100; maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
if(sc->data[SC_SERVICE4U]) if(sc->data[SC_SERVICE4U])
maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100; maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
if(sc->data[SC_MERC_SPUP])
maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
return cap_value(maxsp,1,UINT_MAX); return cap_value(maxsp,1,UINT_MAX);
} }
@ -4835,6 +4857,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
} }
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break; break;
case SC_MERC_FLEEUP:
case SC_MERC_ATKUP:
case SC_MERC_HPUP:
case SC_MERC_SPUP:
case SC_MERC_HITUP:
if( bl->type != BL_MER )
return 0; // Stats only for Mercenaries
break;
} }
//Check for BOSS resistances //Check for BOSS resistances
@ -4958,21 +4988,28 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl,SC_BLESSING,-1); status_change_end(bl,SC_BLESSING,-1);
status_change_end(bl,SC_INCREASEAGI,-1); status_change_end(bl,SC_INCREASEAGI,-1);
break; break;
} }
//Check for overlapping fails //Check for overlapping fails
if((sce=sc->data[type])) if( (sce = sc->data[type]) )
{ {
switch (type) switch( type )
{ {
case SC_MERC_FLEEUP:
case SC_MERC_ATKUP:
case SC_MERC_HPUP:
case SC_MERC_SPUP:
case SC_MERC_HITUP:
if( sce->val1 > val1 )
val1 = sce->val1;
break;
case SC_ADRENALINE: case SC_ADRENALINE:
case SC_ADRENALINE2: case SC_ADRENALINE2:
case SC_WEAPONPERFECTION: case SC_WEAPONPERFECTION:
case SC_OVERTHRUST: case SC_OVERTHRUST:
if (sce->val2 > val2) if (sce->val2 > val2)
return 0; return 0;
break; break;
case SC_HPREGEN: case SC_HPREGEN:
case SC_SPREGEN: case SC_SPREGEN:
case SC_BOSSMAPINFO: case SC_BOSSMAPINFO:
@ -5933,6 +5970,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Place here SCs that have no SCB_* data, no skill associated, no ICON //Place here SCs that have no SCB_* data, no skill associated, no ICON
//associated, and yet are not wrong/unknown. [Skotlex] //associated, and yet are not wrong/unknown. [Skotlex]
break; break;
case SC_MERC_FLEEUP:
case SC_MERC_ATKUP:
case SC_MERC_HITUP:
val2 = 15 * val1;
break;
case SC_MERC_HPUP:
case SC_MERC_SPUP:
val2 = 5 * val1;
break;
default: default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 ) if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
{ //Status change with no calc, no icon, and no skill associated...? { //Status change with no calc, no icon, and no skill associated...?
@ -6139,9 +6187,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag&=~SCB_DYE; calc_flag&=~SCB_DYE;
} }
if (vd && pcdb_checkid(vd->class_)) //Only for players sprites, client crashes if they receive this for a mob o.O [Skotlex] if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) ) //Only for players sprites, client crashes if they receive this for a mob o.O [Skotlex]
clif_status_change(bl,StatusIconChangeTable[type],1); clif_status_change(bl,StatusIconChangeTable[type],1);
else if (sd) //Send packet to self otherwise (disguised player?) else if( sd ) //Send packet to self otherwise (disguised player?)
clif_status_load(bl,StatusIconChangeTable[type],1); clif_status_load(bl,StatusIconChangeTable[type],1);
//Don't trust the previous sce assignment, in case the SC ended somewhere between there and here. //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
@ -6170,22 +6218,46 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if(sd && sd->pd) if(sd && sd->pd)
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
if (type==SC_BERSERK) { switch( type )
sce->val2 = 5*status->max_hp/100; {
status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block. case SC_BERSERK:
status_set_sp(bl, 0, 0); //Damage all SP sce->val2 = 5*status->max_hp/100;
} else if (type==SC_CHANGE) //Heal all HP/SP status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
status_percent_heal(bl, 100, 100); status_set_sp(bl, 0, 0); //Damage all SP
break;
if (type==SC_RUN) { case SC_CHANGE:
struct unit_data *ud = unit_bl2ud(bl); status_percent_heal(bl, 100, 100);
if (ud) break;
ud->state.running = unit_run(bl); case SC_RUN:
{
struct unit_data *ud = unit_bl2ud(bl);
if( ud )
ud->state.running = unit_run(bl);
}
break;
case SC_BOSSMAPINFO:
if( boss_md != NULL )
clif_bossmapinfo(sd->fd, boss_md, 0); // First Message
break;
case SC_MERC_HPUP:
clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXHP);
status_percent_heal(bl, 100, 0); // Recover Full HP
break;
case SC_MERC_SPUP:
clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXSP);
status_percent_heal(bl, 0, 100); // Recover Full SP
break;
case SC_MERC_FLEEUP:
clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MERCFLEE);
break;
case SC_MERC_ATKUP:
clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_ATK1);
break;
case SC_MERC_HITUP:
clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_HIT);
break;
} }
if( boss_md != NULL )
clif_bossmapinfo(sd->fd, boss_md, 0); // First Message
return 1; return 1;
} }
/*========================================== /*==========================================

View File

@ -295,6 +295,14 @@ typedef enum sc_type {
SC_DEF_RATE, SC_DEF_RATE,
SC_SPREGEN, SC_SPREGEN,
SC_WALKSPEED, SC_WALKSPEED,
// Mercenary Only Bonus Effects
SC_MERC_FLEEUP,
SC_MERC_ATKUP,
SC_MERC_HPUP,
SC_MERC_SPUP,
SC_MERC_HITUP,
SC_MAX, //Automatically updated max, used in for's to check we are within bounds. SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type; } sc_type;
@ -457,6 +465,14 @@ enum si_type {
//SI_FOODDEX = 274, //Same as 244 //SI_FOODDEX = 274, //Same as 244
//SI_FOODINT = 275, //Same as 245 //SI_FOODINT = 275, //Same as 245
//SI_FOODLUK = 276, //Same as 246 //SI_FOODLUK = 276, //Same as 246
// Mercenary Only
SI_MERC_FLEEUP = 277,
SI_MERC_ATKUP = 278,
SI_MERC_HPUP = 279,
SI_MERC_SPUP = 280,
SI_MERC_HITUP = 281,
SI_SLOWCAST = 282, SI_SLOWCAST = 282,
SI_CRITICALWOUND = 286, SI_CRITICALWOUND = 286,
SI_DEF_RATE = 290, SI_DEF_RATE = 290,