diff options
-rw-r--r-- | src/map/clif.c | 9 | ||||
-rw-r--r-- | src/map/mercenary.c | 13 | ||||
-rw-r--r-- | src/map/mob.c | 6 | ||||
-rw-r--r-- | src/map/status.c | 120 | ||||
-rw-r--r-- | src/map/status.h | 16 |
5 files changed, 137 insertions, 27 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index b5c749531..f03264557 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12398,6 +12398,15 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type) case SP_MAXSP: WFIFOL(fd,4) = md->battle_status.max_sp; 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: WFIFOL(fd,4) = md->mercenary.kill_count; break; diff --git a/src/map/mercenary.c b/src/map/mercenary.c index b06cf89bb..36d67b52e 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -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) { const struct TimerData * td; - if( md == NULL ) + if( md == NULL || md->contract_timer == INVALID_TIMER ) return 0; td = get_timer(md->contract_timer); @@ -331,6 +331,15 @@ int mercenary_dead(struct mercenary_data *md, struct block_list *src) 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) { md->mercenary.kill_count++; @@ -342,6 +351,8 @@ int mercenary_kills(struct mercenary_data *md) if( md->master ) clif_mercenary_updatestatus(md->master, SP_MERCKILLS); + mercenary_killbonus(md); + return 0; } diff --git a/src/map/mob.c b/src/map/mob.c index 6d340b14a..309b47000 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -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); } - if( sd->md && (md->level > sd->status.base_level / 2) ) - mercenary_kills(sd->md); } // 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_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( sd && battle_config.mob_npc_event_type ) diff --git a/src/map/status.c b/src/map/status.c index eb8e3b3f1..58a320849 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -457,6 +457,12 @@ void initChangeTables(void) StatusIconChangeTable[SC_SPCOST_RATE] = SI_SPCOST_RATE; StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_COMMONSC_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. StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD; @@ -503,8 +509,14 @@ void initChangeTables(void) StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_PC; StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_PC; StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; - - if (!battle_config.display_hallucination) //Disable Hallucination. + // 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. 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; if(sc->data[SC_STRIPWEAPON]) 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); } @@ -3509,7 +3523,9 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change hit -= 30; if(sc->data[SC_INCREASING]) 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); } @@ -3548,7 +3564,9 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change if(sc->data[SC_GATLINGFEVER]) flee -= sc->data[SC_GATLINGFEVER]->val4; 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); } @@ -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; if(sc->data[SC_BERSERK]) 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); } @@ -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; if(sc->data[SC_SERVICE4U]) 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); } @@ -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 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 @@ -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_INCREASEAGI,-1); break; - } //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_ADRENALINE2: case SC_WEAPONPERFECTION: case SC_OVERTHRUST: if (sce->val2 > val2) return 0; - break; + break; case SC_HPREGEN: case SC_SPREGEN: 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 //associated, and yet are not wrong/unknown. [Skotlex] 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: if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 ) { //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; } - 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); - 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); //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) pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing - if (type==SC_BERSERK) { - 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. - status_set_sp(bl, 0, 0); //Damage all SP - } else if (type==SC_CHANGE) //Heal all HP/SP - status_percent_heal(bl, 100, 100); - - if (type==SC_RUN) { - struct unit_data *ud = unit_bl2ud(bl); - if (ud) - ud->state.running = unit_run(bl); + switch( type ) + { + case SC_BERSERK: + 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. + status_set_sp(bl, 0, 0); //Damage all SP + break; + case SC_CHANGE: + status_percent_heal(bl, 100, 100); + break; + 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; } /*========================================== diff --git a/src/map/status.h b/src/map/status.h index 8d9940b0f..ae26c499e 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -295,6 +295,14 @@ typedef enum sc_type { SC_DEF_RATE, SC_SPREGEN, 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_type; @@ -457,6 +465,14 @@ enum si_type { //SI_FOODDEX = 274, //Same as 244 //SI_FOODINT = 275, //Same as 245 //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_CRITICALWOUND = 286, SI_DEF_RATE = 290, |