diff options
author | L0ne_W0lf <L0ne_W0lf@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2011-08-27 03:25:00 +0000 |
---|---|---|
committer | L0ne_W0lf <L0ne_W0lf@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2011-08-27 03:25:00 +0000 |
commit | 1fe2e1773b9a7218fe5e39c4d2116194216b6986 (patch) | |
tree | 31a19349a7c55280bd21eeab4831fc0b838678bc /src/map/status.c | |
parent | a2ec62d8f24cbc11dcb646712c4c16a5cf897372 (diff) | |
download | hercules-1fe2e1773b9a7218fe5e39c4d2116194216b6986.tar.gz hercules-1fe2e1773b9a7218fe5e39c4d2116194216b6986.tar.bz2 hercules-1fe2e1773b9a7218fe5e39c4d2116194216b6986.tar.xz hercules-1fe2e1773b9a7218fe5e39c4d2116194216b6986.zip |
- Implemented first version of Archbishop skills. Preliminary version, see doc/3rd_job_notes.txt for details/bugs/issues with skills.
- Implemented fixed cast time, old cast time mechanics no longer available. Added bFixedCastRate used for reducing fixed cast time mechanic.
Cast time calculations probably still needs work, as the cast rate reductions are probably additive and multiplicative as they used to be.
- As a result, skill_delayfix_sc() has been removed, status effects that modify cast time are now calculated DURING cast time, not after.
- Implemented skill cooldown in skill_cast_db.txt. Known issue is that the cooldowns should save on logout/server shutdown/etc.
- Implemented new heal calculation and started work on MATK. Added bWeaponMatk, and bEquipmentMatk for use with new MATK mechanic.
- Removed custom features and their config settings: delay_dependon_dex, delay_dependon_agi, castrate_dex_scale.
- Increased max_def to 9999 for now, as that is by default the largest defense increase found in the Renewal database (Ahura_mazdah, GM item)
- Added shield aspd reduction from job_db1.txt-- Not 100% sure on this one yet. Should be considered a WIP.
- Modified updatestatus(), to display information more in line with the client's status window.
- Updated some calculations in status_calc_misc to match renewal, needs a lot of work still.
- ST_CHASEWALK and HP_BASILICA no longer have 0 cast time while being canceled.
* Implemented 'Boss' Decrease AGI, like 'Boss' Heal - editable in skill.conf
* clif_skill_fail() now accepts a new parameter, to be used in later messages.
* status_change_start() now stores tick as duration upon being called, which fixes timers calling the function from showing negative durations.
* Implemented skill ALL_PARTYFLEE. 1 level, increases party member flee by 10.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/renewal@14941 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 196 |
1 files changed, 166 insertions, 30 deletions
diff --git a/src/map/status.c b/src/map/status.c index 37dad30b9..8294d4873 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -35,7 +35,7 @@ #include <stdlib.h> #include <memory.h> #include <string.h> - +#include <math.h> //Regen related flags. enum e_regen @@ -52,6 +52,7 @@ static int hp_coefficient2[CLASS_COUNT]; static int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1]; static int sp_coefficient[CLASS_COUNT]; static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89] +static int shield_aspd_base[CLASS_COUNT]; static int refinebonus[MAX_REFINE_BONUS][3]; // ΈB{[iXe[u(refine_db.txt) int percentrefinery[5][MAX_REFINE+1]; // ΈB¬χ¦(refine_db.txt) static int atkmods[3][MAX_WEAPON_TYPE]; // νATKTCYC³(size_fix.txt) @@ -399,7 +400,7 @@ void initChangeTables(void) set_sc( CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED ); set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE ); - //set_sc( ALL_PARTYFLEE , SC_INCFLEE , SI_PARTYFLEE , SCB_NONE ); + set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_FLEE ); set_sc( CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE ); set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE ); @@ -412,6 +413,19 @@ void initChangeTables(void) add_sc( SA_ELEMENTGROUND , SC_ELEMENTALCHANGE ); add_sc( SA_ELEMENTWIND , SC_ELEMENTALCHANGE ); + set_sc( AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED ); + add_sc( AB_CLEMENTIA , SC_BLESSING ); + add_sc( AB_CANTO , SC_INCREASEAGI ); + add_sc( AB_PRAEFATIO , SC_KYRIE ); + set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP ); + set_sc( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE ); + set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT ); + set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK ); + set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN ); + set_sc( AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_NONE ); + set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE ); + set_sc( AB_SECRAMENT , SC_AB_SECRAMENT , SI_AB_SECRAMENT , SCB_NONE ); + set_sc( HLIF_AVOID , SC_AVOID , SI_BLANK , SCB_SPEED ); set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT ); set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK ); @@ -489,6 +503,7 @@ void initChangeTables(void) StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF; StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK; StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK; + //StatusIconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY; // Causes client to crash when mousing over state icon? //Cash Items StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH; StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH; @@ -560,6 +575,8 @@ void initChangeTables(void) StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL; StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL; + //StatusChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED; + // Cash Items StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR; StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI; @@ -1266,20 +1283,23 @@ int status_check_visibility(struct block_list *src, struct block_list *target) // Basic ASPD value int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status) { - int amotion; + int amotion, shield = 0; // base weapon delay amotion = (sd->status.weapon < MAX_WEAPON_TYPE) ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon : (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield + if (sd->status.shield) + shield = shield_aspd_base[pc_class2idx(sd->status.class_)] * 10; + // percentual delay reduction from stats - amotion-= amotion * (4*status->agi + status->dex)/1000; - + amotion-= ( amotion - shield ) * (4*status->agi + status->dex)/1000; + // raw delay adjustment from bAspd bonus amotion+= sd->aspd_add; - - return amotion; + + return amotion; } static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status) @@ -1334,10 +1354,12 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev status->matk_min = status_base_matk_min(status); status->matk_max = status_base_matk_max(status); - status->hit += level + status->dex; - status->flee += level + status->agi; + status->hit += 175 + status->dex + (unsigned short)floor((double)status->luk/3) + level; //Renewal calclation. + status->flee += 100 + status->agi + level; status->def2 += status->vit; - status->mdef2 += status->int_ + (status->vit>>1); + status->mdef2 += status->mdef; + //Status MATK = floor(Base Level/4 + INT + INT/2 + DEX/5 + LUK/3) + status->status_matk = (unsigned short)floor((double)level/4 + (double)status->int_ + (double)status->int_/2 + (double)status->dex/5 + (double)status->luk/3); if( bl->type&battle_config.enable_critical ) status->cri += status->luk*3 + 10; @@ -1734,6 +1756,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100; sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100; sd->regen.state.block = 0; + sd->fixedcastrate=0; + sd->weapon_matk = 0; + sd->equipment_matk = 0; // zeroed arrays, order follows the order in pc.h. // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo] @@ -1963,7 +1988,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip)); memset(sd->param_bonus, 0, sizeof(sd->param_bonus)); - status->def += (refinedef+50)/100; + status->def += refinedef; //Parse Cards for(i=0;i<EQI_MAX-1;i++) { @@ -2356,6 +2381,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first) sd->dsprate = 0; if(sd->castrate < 0) sd->castrate = 0; + if( sd->fixedcastrate < 0 ) + sd->fixedcastrate = 0; if(sd->delayrate < 0) sd->delayrate = 0; if(sd->hprecov_rate < 0) @@ -2377,6 +2404,17 @@ int status_calc_pc_(struct map_session_data* sd, bool first) sd->magic_addrace[RC_DRAGON]+=skill; sd->subrace[RC_DRAGON]+=skill; } + if( (skill = pc_checkskill(sd, AB_EUCHARISTICA)) > 0 ) + { + sd->right_weapon.addrace[RC_DEMON]+=skill; + sd->right_weapon.addele[ELE_DARK]+=skill; + sd->left_weapon.addrace[RC_DEMON]+=skill; + sd->left_weapon.addele[ELE_DARK]+=skill; + sd->magic_addrace[RC_DEMON]+=skill; + sd->magic_addele[ELE_DARK]+=skill; + sd->subrace[RC_DEMON]+=skill; + sd->subele[ELE_DARK]+=skill; + } if(sc->count){ if(sc->data[SC_CONCENTRATE]) @@ -2976,10 +3014,26 @@ void status_calc_bl_main(struct block_list *bl, enum scb_flag flag) } if(flag&SCB_MATK) { + int wlv = 1, wmatk = 0; + short index = sd->equip_index[EQI_HAND_R]; + //New matk status->matk_min = status_base_matk_min(status); status->matk_max = status_base_matk_max(status); + // iRO Wiki states as of 2011/02/24: + // Status MATK = floor(Base Level/4 + INT + INT/2 + DEX/5 + LUK/3) + status->status_matk = status_get_lv(bl)/4 + status->int_ + status->int_/2 + status->dex/5 + status->luk/3; + wmatk = sd->weapon_matk + sd->battle_status.rhw.atk2 + sd->equipment_matk; + + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) + wlv = sd->inventory_data[index]->wlv; + + // Variance = ± 0.1 * Weapon Level * Base Weapon MATK + // Used in a lot of magical attack calculations still. + status->matk_min = status->status_matk + wmatk; + status->matk_max = status->status_matk + wmatk + (wmatk * wlv / 10); + if( bl->type&BL_PC && sd->matk_rate != 100 ) { //Bonuses from previous matk @@ -3138,7 +3192,10 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first) if(b_status.speed != status->speed) clif_updatestatus(sd,SP_SPEED); if(b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk || b_status.batk != status->batk) + { clif_updatestatus(sd,SP_ATK1); + clif_updatestatus(sd,SP_MATK1); + } if(b_status.def != status->def) clif_updatestatus(sd,SP_DEF1); if(b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2) @@ -3150,13 +3207,15 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first) if(b_status.cri != status->cri) clif_updatestatus(sd,SP_CRITICAL); if(b_status.matk_max != status->matk_max) - clif_updatestatus(sd,SP_MATK1); - if(b_status.matk_min != status->matk_min) - clif_updatestatus(sd,SP_MATK2); - if(b_status.mdef != status->mdef) + { + clif_updatestatus(sd,SP_MATK1); + clif_updatestatus(sd,SP_MATK2); + } + if(b_status.mdef != status->mdef || b_status.mdef2 != status->mdef2) + { clif_updatestatus(sd,SP_MDEF1); - if(b_status.mdef2 != status->mdef2) clif_updatestatus(sd,SP_MDEF2); + } if(b_status.rhw.range != status->rhw.range) clif_updatestatus(sd,SP_ATTACKRANGE); if(b_status.max_hp != status->max_hp) @@ -3285,6 +3344,8 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50) agi = 50; + if(sc->data[SC_ADORAMUS]) + agi -= sc->data[SC_ADORAMUS]->val2; return (unsigned short)cap_value(agi,0,USHRT_MAX); } @@ -3316,6 +3377,8 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang vit += sc->data[SC_MARIONETTE2]->val3&0xFF; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50) vit = 50; + if(sc->data[SC_LAUDAAGNUS]) + vit += sc->data[SC_LAUDAAGNUS]->val2; return (unsigned short)cap_value(vit,0,USHRT_MAX); } @@ -3426,6 +3489,8 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang luk += sc->data[SC_MARIONETTE2]->val4&0xFF; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50) luk = 50; + if(sc->data[SC_LAUDARAMUS]) + luk += sc->data[SC_LAUDARAMUS]->val2; return (unsigned short)cap_value(luk,0,USHRT_MAX); } @@ -3619,6 +3684,8 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change flee -= sc->data[SC_GATLINGFEVER]->val4; if(sc->data[SC_SPEED]) flee += 10 + sc->data[SC_SPEED]->val1 * 10; + if(sc->data[SC_PARTYFLEE]) + flee += sc->data[SC_PARTYFLEE]->val1 * 10; if(sc->data[SC_MERC_FLEEUP]) flee += sc->data[SC_MERC_FLEEUP]->val2; @@ -3826,6 +3893,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha val = max( val, sc->data[SC_SUITON]->val3 ); if( sc->data[SC_SWOO] ) val = max( val, 300 ); + if( sc->data[SC_ADORAMUS] ) + val = max( val, 25 ); if( sd && sd->speed_rate + sd->speed_add_rate > 0 ) // permanent item-based speedup val = max( val, sd->speed_rate + sd->speed_add_rate ); @@ -3858,6 +3927,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha val = max( val, 10 * sc->data[SC_AVOID]->val1 ); if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] ) val = max( val, 75 ); + //if( sc->data[SC_MOVHASTE_INFINITY] ) + // val = max( val, 25 ); //FIXME: official items use a single bonus for this [ultramage] if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup @@ -4026,6 +4097,9 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang if(sc->data[SC_MERC_HPUP]) maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100; + if(sc->data[SC_EPICLESIS]) + maxhp += maxhp * sc->data[SC_EPICLESIS]->val2/100; + return cap_value(maxhp,1,UINT_MAX); } @@ -4581,6 +4655,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti case SC_STONE: case SC_QUAGMIRE: case SC_SUITON: + case SC_ADORAMUS: return 0; } @@ -4599,6 +4674,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti sc_def = 3 +status->int_; break; case SC_DECREASEAGI: + case SC_ADORAMUS: if (sd) tick>>=1; //Half duration for players. case SC_STONE: case SC_FREEZE: @@ -4731,6 +4807,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val struct status_data *status; struct view_data *vd; int opt_flag, calc_flag, undead_flag; + int duration = tick; nullpo_ret(bl); sc = status_get_sc(bl); @@ -4799,7 +4876,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE))) return 0; if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DECREASEAGI] + sc->data[SC_DECREASEAGI] || + sc->data[SC_ADORAMUS] ) return 0; break; @@ -4807,14 +4885,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2))) return 0; if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DECREASEAGI] + sc->data[SC_DECREASEAGI] || + sc->data[SC_ADORAMUS] ) return 0; break; case SC_ONEHAND: case SC_MERC_QUICKEN: case SC_TWOHANDQUICKEN: - if(sc->data[SC_DECREASEAGI]) + if(sc->data[SC_DECREASEAGI] || + sc->data[SC_ADORAMUS]) return 0; case SC_CONCENTRATE: case SC_INCREASEAGI: @@ -4994,6 +5074,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_RICHMANKIM: case SC_ROKISWEIL: case SC_FOGWALL: + case SC_ADORAMUS: return 0; } } @@ -5012,6 +5093,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_INCREASEAGI: status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER); + status_change_end(bl, SC_ADORAMUS, INVALID_TIMER); break; case SC_QUAGMIRE: status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER); @@ -5019,6 +5101,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val status_change_end(bl, SC_WINDWALK, INVALID_TIMER); //Also blocks the ones below... case SC_DECREASEAGI: + case SC_ADORAMUS: status_change_end(bl, SC_CARTBOOST, INVALID_TIMER); //Also blocks the ones below... case SC_DONTFORGETME: @@ -5076,9 +5159,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); break; case SC_CARTBOOST: - if(sc->data[SC_DECREASEAGI]) + if(sc->data[SC_DECREASEAGI] || sc->data[SC_ADORAMUS]) { //Cancel Decrease Agi, but take no further effect [Skotlex] status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER); + status_change_end(bl, SC_ADORAMUS, INVALID_TIMER); return 0; } break; @@ -5227,6 +5311,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val { case SC_DECREASEAGI: case SC_INCREASEAGI: + case SC_ADORAMUS: val2 = 2 + val1; //Agi change break; case SC_ENDURE: @@ -5277,7 +5362,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_KYRIE: val2 = status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb - val3 = (val1 / 2 + 5); //Hits + // val1 determines if status is casued by Kyrie or Praefatio, + // as Praefatio blocks more hits than Kyrie Elesion. + if( !val4 ) + val3 = (val1 / 2 + 5); + else + val3 = 6 + val1; + if( sd ) + val1 = min(val1,pc_checkskill(sd,PR_KYRIE)); // uses kill level to determine barrier health. break; case SC_MAGICPOWER: //val1: Skill lv @@ -6037,6 +6129,31 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_KAIZEL: val2 = 10*val1; //% of life to be revived with break; + case SC_EPICLESIS: + val2 = 5 * val1; // % HP gained * level of Epiclesis cast. + break; + case SC_ORATIO: + val2 = 2 * val1; // % Damage increased by level of Oratio cast. + break; + case SC_LAUDAAGNUS: + case SC_LAUDARAMUS: + val2 = 4+val1; // Bonus status points gained + break; + case SC_RENOVATIO: + val2 = tick / 5000; // Heal every 5 seconds. + tick = 5000; + break; + case SC_EXPIATIO: + val2 = 5*val1; // DEF reduced by 5*Skill Level percent. + break; + case SC_DUPLELIGHT: + val2 = 10+val1*2; //Chance of MELEE proc + val3 = 10+val1*2; //Chance of MAGIC proc + break; + + case SC_AB_SECRAMENT: + val2 = 10*val1; //Fixed cast time reduced by 10*Skill Level + break; // case SC_ARMOR_ELEMENT: // case SC_ARMOR_RESIST: // Mod your resistance against elements: @@ -6288,8 +6405,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_) || 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,tick); + 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] + || (bl->type == BL_MOB && type == SC_ORATIO)) ) // Required to show the proper status for monsters. Possible this may need an overhaul. + clif_status_change(bl,StatusIconChangeTable[type],1,duration); else if( sd ) //Send packet to self otherwise (disguised player?) clif_status_load(bl,StatusIconChangeTable[type],1); @@ -6455,8 +6573,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const return 0; if (tid == INVALID_TIMER) { - if (type == SC_ENDURE && sce->val4) - //Do not end infinite endure. + if( (type == SC_ENDURE /*|| type == SC_MOVHASTE_INFINITY*/ ) && sce->val4 ) + //Do not end infinite endure or speed adjustment. return 0; if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration delete_timer(sce->timer,status_change_timer); @@ -6943,7 +7061,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } //On Aegis, when turning off a status change, first goes the sc packet, then the option packet. - if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) ) + if( vd && ((pcdb_checkid(vd->class_) || bl->type == BL_MER ) + || (bl->type == BL_MOB && type == SC_ORATIO)) ) // Required to remove SI_ORATIO indicator from monsters. clif_status_change(bl,StatusIconChangeTable[type],0,0); else if (sd) clif_status_load(bl,StatusIconChangeTable[type],0); @@ -7345,6 +7464,20 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) return 0; } break; + case SC_RENOVATIO: + if((--sc->data[type]->val2) > 0) { + int heal = status->max_hp * 3 / 100; + if( status->hp + heal > status->max_hp ) + heal = status->max_hp - status->hp; + if(heal > 0) + { + clif_heal(sd->fd,SP_HP,heal); + status_heal(bl, heal, 0, 0); + } + sc_timer_next(5000+tick, status_change_timer, bl->id, data); + return 0; + } + break; } // default for all non-handled control paths is to end the status @@ -7480,6 +7613,7 @@ int status_change_clear_buffs (struct block_list* bl, int type) case SC_STRIPSHIELD: case SC_STRIPARMOR: case SC_STRIPHELM: + case SC_ADORAMUS: if (!(type&2)) continue; break; @@ -7730,6 +7864,7 @@ static bool status_readdb_job1(char* fields[], int columns, int current) { aspd_base[idx][i] = atoi(fields[i+5]); } + shield_aspd_base[idx] = atoi(fields[29]); // Won't take 5+MAX_WEAPON_TYPE+1 return true; } @@ -7792,6 +7927,7 @@ int status_readdb(void) memset(hp_coefficient2, 0, sizeof(hp_coefficient2)); memset(sp_coefficient, 0, sizeof(sp_coefficient)); memset(aspd_base, 0, sizeof(aspd_base)); + memset(shield_aspd_base, 0, sizeof(shield_aspd_base)); // job_db2.txt memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus @@ -7814,10 +7950,10 @@ int status_readdb(void) // read databases // - sv_readdb(db_path, "job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, &status_readdb_job1); - sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2); - sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix); - sv_readdb(db_path, "refine_db.txt", ',', 3+MAX_REFINE+1, 3+MAX_REFINE+1, ARRAYLENGTH(percentrefinery), &status_readdb_refine); + sv_readdb(db_path, "job_db1.txt", ',', 5+MAX_WEAPON_TYPE+1, 5+MAX_WEAPON_TYPE+1, -1, &status_readdb_job1); + sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2); + sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix); + sv_readdb(db_path, "refine_db.txt", ',', 3+MAX_REFINE+1, 3+MAX_REFINE+1, ARRAYLENGTH(percentrefinery), &status_readdb_refine); return 0; } |