summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c289
1 files changed, 160 insertions, 129 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 728e72a9c..70d2d0219 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -7527,7 +7527,7 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type
}
/**
- * Starts a status change.
+ * Starts a status change with a set remaining time.
*
* @param src Status change source bl.
* @param bl Status change target bl.
@@ -7537,13 +7537,14 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type
* @param val2 Additional value (meaning depends on type).
* @param val3 Additional value (meaning depends on type).
* @param val4 Additional value (meaning depends on type).
- * @param tick Base duration (milliseconds).
+ * @param tick Remaining duration (miliseconds). (if flag doesn't contain SCFLAG_LOADED, it will become the final total_tick)
+ * @param total_tick Base duration (milliseconds).
* @param flag Special flags (@see enum scstart_flag).
*
* @retval 0 if no status change happened.
* @retval 1 if the status change was successfully applied.
*/
-static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+static int status_change_start_sub(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag)
{
struct map_session_data *sd = NULL;
struct status_change* sc;
@@ -7557,7 +7558,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
st = status->get_status_data(bl);
if (type <= SC_NONE || type >= SC_MAX) {
- ShowError("status_change_start: invalid status change (%d)!\n", type);
+ ShowError("status_change_start_sub: invalid status change (%d)!\n", type);
return 0;
}
@@ -7582,10 +7583,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
sd = BL_CAST(BL_PC, bl);
- //Adjust tick according to status resistances
+ //Adjust total_tick according to status resistances
if( !(flag&(SCFLAG_NOAVOID|SCFLAG_LOADED)) ) {
- tick = status->get_sc_def(src, bl, type, rate, tick, flag);
- if( !tick ) return 0;
+ total_tick = status->get_sc_def(src, bl, type, rate, total_tick, flag);
+ if( !total_tick ) return 0;
}
undead_flag = battle->check_undead(st->race, st->def_ele);
@@ -7736,7 +7737,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
if (!opt_flag) return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPSHIELD:
if (val2 == 1) {
@@ -7752,7 +7753,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
}
- if (tick == 1)
+ if (total_tick == 1)
return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPARMOR:
@@ -7765,7 +7766,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPHELM:
if (sd && !(flag&SCFLAG_LOADED)) {
@@ -7777,7 +7778,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_MER_FLEE:
case SC_MER_ATK:
@@ -7831,7 +7832,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if( i < 0 )
return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_TOXIN:
case SC_PARALYSE:
@@ -8001,33 +8002,33 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
if (val4)
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOBERSERK:
if (st->hp < st->max_hp>>2 &&
(!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000);
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CRUCIS:
val2 = 10 + 4*val1; //Def reduction
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
clif->emotion(bl,E_SWT);
break;
case SC_MAXIMIZEPOWER:
- tick_time = val2 = tick>0?tick:60000;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
break;
case SC_EDP: // [Celest]
//Chance to Poison enemies.
@@ -8038,7 +8039,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
#endif
val3 = 50 * (val1 + 1); //Damage increase (+50 +50*lv%)
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
- tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ total_tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
break;
case SC_POISONREACT:
val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
@@ -8068,7 +8069,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SACRIFICE:
val2 = 5; //Lasts 5 hits
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_ENCHANTPOISON:
val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
@@ -8105,12 +8106,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8189,9 +8190,9 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val3 : Brings the skill_lv (merged into val1 here)
//val4 : Partner
if (val1 == CG_MOONLIT)
- clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
+ clif->status_change(bl,SI_MOON,1,total_tick,0, 0, 0);
val1|= (val3<<16);
- val3 = tick/1000; //Tick duration
+ val3 = total_tick/1000; //Tick duration
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_LONGING:
@@ -8228,7 +8229,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// mmocharstatus.manner, each negative point results in 1 minute with this status activated
// This is done this way because the message that the client displays is hardcoded, and only
// shows how many minutes are remaining. [Panikon]
- tick = 60000;
+ total_tick = 60000;
val1 = battle_config.manner_system; //Mute filters.
if (sd)
{
@@ -8238,11 +8239,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STONE:
- val3 = tick/1000; //Petrified HP-damage iterations.
+ val3 = total_tick/1000; //Petrified HP-damage iterations.
if(val3 < 1) val3 = 1;
- tick = val4; //Petrifying time.
+ total_tick = val4; //Petrifying time.
if(val4 > 500) // not with WL_SIENNAEXECRATE
- tick = max(tick, 1000); //Min time
+ total_tick = max(total_tick, 1000); //Min time
calc_flag = 0; //Actual status changes take effect on petrified state.
break;
@@ -8261,7 +8262,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
// fall through
case SC_POISON:
- val3 = tick/1000; //Damage iterations
+ val3 = total_tick/1000; //Damage iterations
if(val3 < 1) val3 = 1;
tick_time = 1000; // [GodLesZ] tick time
//val4: HP damage
@@ -8275,7 +8276,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
clif->emotion(bl,E_WHAT);
break;
case SC_BLOODING:
- val4 = tick/10000;
+ val4 = total_tick/10000;
if (!val4) val4 = 1;
tick_time = 10000; // [GodLesZ] tick time
break;
@@ -8288,7 +8289,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// val2 = seconds between heals
// val4 = total of heals
if (val2 < 1) val2 = 1;
- if ((val4 = tick / (val2 * 1000)) < 1)
+ if ((val4 = total_tick / (val2 * 1000)) < 1)
val4 = 1;
tick_time = val2 * 1000; // [GodLesZ] tick time
break;
@@ -8301,19 +8302,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0; // No need to start SC
}
val1 = boss_md->bl.id;
- if( (val4 = tick/1000) < 1 )
+ if( (val4 = total_tick/1000) < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
}
break;
case SC_HIDING:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
val3 = 0; // unused, previously speed adjustment
val4 = val1+3; //Seconds before SP substraction happen.
break;
case SC_CHASEWALK:
- val2 = tick>0?tick:10000; //Interval at which SP is drained.
+ val2 = total_tick>0?total_tick:10000; //Interval at which SP is drained.
val3 = 35 - 5 * val1; //Speed adjustment.
if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
val3 -= 40;
@@ -8323,8 +8324,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_CLOAKING:
if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
val1 = 10;
- tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000; //SP consumption rate.
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
val3 = 0; // unused, previously walk speed adjustment
//val4&1 signals the presence of a wall.
//val4&2 makes cloak not end on normal attacks [Skotlex]
@@ -8338,7 +8339,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_RUWACH:
case SC_WZ_SIGHTBLASTER:
val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
- val2 = tick/20;
+ val2 = total_tick/20;
tick_time = 20; // [GodLesZ] tick time
break;
@@ -8356,7 +8357,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_DODGE_READY:
case SC_PUSH_CART:
case SC_DAILYSENDMAILCNT:
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOGUARD:
@@ -8372,12 +8373,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if( sd ) {
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8396,7 +8397,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
for (i = 0; i < MAX_PC_DEVOTION; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID);
+ status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,total_tick,SCFLAG_NOAVOID);
}
}
}
@@ -8409,8 +8410,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
val2 = 12; //SP cost
val4 = 10000; //Decrease at 10secs intervals.
- val3 = tick/val4;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ val3 = total_tick/val4;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
tick_time = val4; // [GodLesZ] tick time
break;
case SC_PARRYING:
@@ -8428,21 +8429,21 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_BERSERK:
if( val3 == SC__BLOODYLUST )
- sc_start(src,bl,(sc_type)val3,100,val1,tick);
+ sc_start(src,bl,(sc_type)val3,100,val1,total_tick);
if (!val3 && (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4))
- sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick);
+ sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, total_tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
if (!val4) val4 = 10000; //Val4 holds damage interval
- val3 = tick/val4; //val3 holds skill duration
+ val3 = total_tick/val4; //val3 holds skill duration
tick_time = val4; // [GodLesZ] tick time
break;
case SC_GOSPEL:
if(val4 == BCT_SELF) {
// self effect
- val2 = tick/10000;
+ val2 = total_tick/10000;
tick_time = 10000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
}
@@ -8506,12 +8507,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_SWORDREJECT:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_MEMORIZE:
val2 = 5; //Memorized casts.
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_GRAVITATION:
@@ -8565,11 +8566,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
if (src2 && sc2) {
if (!sce2) //Start lock on caster.
- sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
+ sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,total_tick+1000);
else { //Increase count of locked enemies and refresh time.
(sce2->val2)++;
timer->delete(sce2->timer, status->change_timer);
- sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
+ sce2->timer = timer->add(timer->gettick()+total_tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
}
} else //Status failed.
return 0;
@@ -8605,13 +8606,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val4: TK: Combo time
struct unit_data *ud = unit->bl2ud(bl);
if( ud && (!val3 || val3 == 2) ) {
- tick += 300 * battle_config.combo_delay_rate/100;
- ud->attackabletime = timer->gettick()+tick;
+ total_tick += 300 * battle_config.combo_delay_rate/100;
+ ud->attackabletime = timer->gettick()+total_tick;
if( !val3 )
- unit->set_walkdelay(bl, timer->gettick(), tick, 1);
+ unit->set_walkdelay(bl, timer->gettick(), total_tick, 1);
}
val3 = 0;
- val4 = tick;
+ val4 = total_tick;
break;
}
case SC_EARTHSCROLL:
@@ -8625,7 +8626,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_KAAHI:
val2 = 200*val1; //HP heal
@@ -8640,7 +8641,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_TRICKDEAD:
if (vd) vd->dead_sit = 1;
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CONCENTRATION:
val2 = 2 + val1;
@@ -8658,7 +8659,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
//val2 holds if it was casted on self, or is bonus received from others
val3 = 5*val1; //Power increase
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_ADRENALINE2:
case SC_ADRENALINE:
@@ -8666,13 +8667,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
FALLTHROUGH
case SC_WEAPONPERFECT:
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_LKCONCENTRATION:
val2 = 5*val1; //Batk/Watk Increase
val3 = 10*val1; //Hit Increase
val4 = 5*val1; //Def reduction
- sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 1, total_tick); //Endure effect
break;
case SC_ANGELUS:
val2 = 5*val1; //def increase
@@ -8742,7 +8743,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 12*val1; //mdef2 reduction.
break;
case SC_SKA:
- val2 = tick/1000;
+ val2 = total_tick/1000;
val3 = rnd()%100; //Def changes randomly every second...
tick_time = 1000; // [GodLesZ] tick time
break;
@@ -8755,7 +8756,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
// When renewing status' information
// val3 Return map_index
// val4 return coordinates
- tick = val1>0?1000:250;
+ total_tick = val1>0?1000:250;
if (sd)
{
if (sd->mapindex != val2)
@@ -8790,11 +8791,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SWOO:
if(st->mode&MD_BOSS)
- tick /= 5; //TODO: Reduce skill's duration. But for how long?
+ total_tick /= 5; //TODO: Reduce skill's duration. But for how long?
break;
case SC_SPIDERWEB:
if( bl->type == BL_PC )
- tick /= 2;
+ total_tick /= 2;
break;
case SC_ARMOR:
//NPC_DEFENDER:
@@ -8860,7 +8861,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 10*val1; //% of life to be revived with
break;
case SC_ARMORPROPERTY:
- clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, tick, 0, 0, 0);
+ clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, total_tick, 0, 0, 0);
break;
// case SC_ARMOR_RESIST:
// Mod your resistance against elements:
@@ -8902,11 +8903,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
**/
case SC_FEAR:
val2 = 2;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BURNING:
- val4 = tick / 3000; // Total Ticks to Burn!!
+ val4 = total_tick / 3000; // Total Ticks to Burn!!
tick_time = 3000; // [GodLesZ] tick time
break;
/**
@@ -8920,14 +8921,14 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase
break;
case SC_ABUNDANCE:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
/**
* Arch Bishop
**/
case SC_RENOVATIO:
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000;
break;
case SC_SECRAMENT:
@@ -8938,28 +8939,28 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_WEAPONBLOCKING:
val2 = 10 + 2 * val1; // Chance
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_TOXIN:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_MAGICMUSHROOM:
- val4 = tick / 4000;
+ val4 = total_tick / 4000;
tick_time = 4000; // [GodLesZ] tick time
break;
case SC_PYREXIA:
status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE); // Blind status that last for 30 seconds
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_LEECHESEND:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_OBLIVIONCURSE:
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_CLOAKINGEXCEED:
@@ -8998,7 +8999,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_SUMMON3:
case SC_SUMMON4:
case SC_SUMMON5:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
@@ -9013,19 +9014,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
break;
case SC_STEALTHFIELD_MASTER:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 2000 + (1000 * val1);
break;
case SC_ELECTRICSHOCKER:
case SC_COLD:
case SC_MEIKYOUSISUI:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_CAMOUFLAGE:
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_WUGDASH:
@@ -9036,17 +9037,17 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC__REPRODUCE:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000;
break;
case SC__SHADOWFORM: {
struct map_session_data * s_sd = map->id2sd(val2);
if( s_sd )
s_sd->shadowform_id = bl->id;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9057,7 +9058,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC__INVISIBILITY:
val2 = 50 - 10 * val1; // ASPD
val3 = 200 * val1; // CRITICAL
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC__ENERVATION:
@@ -9099,8 +9100,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC__WEAKNESS:
val2 = 10 * val1;
// bypasses coating protection and MADO
- sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick);
- sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick);
+ sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,total_tick);
+ sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,total_tick);
break;
case SC_GN_CARTBOOST:
if( val1 < 3 )
@@ -9120,7 +9121,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STRIKING:
val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BLOOD_SUCKER:
@@ -9129,7 +9130,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 1;
if(src2)
val3 = 200 + 100 * val1 + status_get_int(src2);
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9150,22 +9151,22 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 5 + 5 * val1;
break;
case SC_SIREN:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_DEEP_SLEEP:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_SIRCLEOFNATURE:
val2 = 40 * val1;//HP recovery
val3 = 4 * val1;//SP drain
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_SONG_OF_MANA:
val3 = 10 + 5 * val2;
- val4 = tick/5000;
+ val4 = total_tick/5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_SATURDAY_NIGHT_FEVER:
@@ -9173,7 +9174,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
if ( val2 < 1000 )
val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech]
val3 = tick/val2;*/
- val3 = tick / 3000;
+ val3 = total_tick / 3000;
tick_time = 3000;// [GodLesZ] tick time
break;
case SC_GLOOMYDAY:
@@ -9209,7 +9210,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_MELODYOFSINK:
val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer.
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000;
break;
case SC_BEYOND_OF_WARCRY:
@@ -9227,13 +9228,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_LG_REFLECTDAMAGE:
val2 = 15 + 5 * val1;
val3 = 25 + 5 * val1; //Number of Reflects
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_FORCEOFVANGUARD:
val2 = 8 + 12 * val1; // Chance
val3 = 5 + 2 * val1; // Max rage counters
- tick = INFINITE_DURATION; //endless duration in the client
+ total_tick = INFINITE_DURATION; //endless duration in the client
break;
case SC_EXEEDBREAK:
if( sd ){
@@ -9256,7 +9257,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_MAGNETICFIELD:
- val3 = tick / 1000;
+ val3 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_INSPIRATION:
@@ -9264,7 +9265,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus
val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus
}
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
break;
@@ -9275,7 +9276,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
break;
case SC_RAISINGDRAGON:
- val3 = tick / 5000;
+ val3 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_GENTLETOUCH_CHANGE:
@@ -9385,7 +9386,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_STONE_SHIELD:
val2 += 5;
val3 += 1000;
- val4 = tick;
+ val4 = total_tick;
tick_time = val3;
break;
case SC_WATER_BARRIER:
@@ -9408,18 +9409,18 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_STOMACHACHE:
val3 = 8; // SP consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_STEAMPACK: // [Frost]
val3 = 100; // HP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
- sc_start(src, bl, SC_ENDURE, 100, 10, tick); // Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 10, total_tick); // Endure effect
break;
case SC_MAGIC_CANDY: // [Frost]
val3 = 90; // SP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
break;
case SC_PROMOTE_HEALTH_RESERCH:
@@ -9458,7 +9459,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = val1 * 2;
FALLTHROUGH
case SC_IZAYOI:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000;
break;
case SC_ZANGETSU:
@@ -9498,12 +9499,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
case SC_ANGRIFFS_MODUS:
val2 = 50 + 20 * val1; //atk bonus
val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
+ val4 = total_tick/1000; // hp/sp reduction timer
tick_time = 1000;
break;
case SC_NEUTRALBARRIER:
- tick_time = tick;
- tick = INFINITE_DURATION;
+ tick_time = total_tick;
+ total_tick = INFINITE_DURATION;
break;
case SC_GOLDENE_FERSE:
val2 = 10 + 10*val1; //max hp bonus
@@ -9532,10 +9533,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
if(sc->data[SC_NEEDLE_OF_PARALYZE])
- sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ sc_start(src, bl, SC_ENDURE, 100, val1, total_tick); //start endure for same duration
break;
case SC_STYLE_CHANGE: //[Lighta] need real info
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
else val2 = MH_MD_FIGHTING;
break;
@@ -9543,12 +9544,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
status_percent_heal(bl,100,0);
val2 = 7 - val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_KINGS_GRACE:
val2 = 3 + val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_TELEKINESIS_INTENSE:
val2 = 10 * val1;
@@ -9561,7 +9562,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val2 = 5 * val1;
val3 = (20 * val1) + 80;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_DARKCROW:
val2 = 30 * val1;
@@ -9572,7 +9573,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_SPRITEMABLE:
case SC_ALL_RIDING:
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_FLASHCOMBO:
/**
@@ -9585,7 +9586,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
* Summoner
*/
case SC_FRESHSHRIMP:
- val4 = tick / (10000 - ((val1 - 1) * 1000));
+ val4 = total_tick / (10000 - ((val1 - 1) * 1000));
tick_time = 10000 - ((val1 - 1) * 1000);
if (val4 <= 0) // Prevents a negeative value from happening
val4 = 0;
@@ -9601,7 +9602,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
break;
case SC_BITESCAR:
val2 = 2 * val1; // MHP% damage
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000;
break;
case SC_SHRIMP:
@@ -9612,7 +9613,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
val3 = 25 * val1; // Move speed reduction
break;
default:
- if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, tick, flag)) {
+ if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag)) {
return 0;
}
}
@@ -9682,13 +9683,15 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
}
#endif
- if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type]))
- clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
+ if (!(flag & SCFLAG_LOADED))
+ tick = total_tick; // When starting a new SC (not loading), its remaining duration is the same as the total
+ if(!(flag & SCFLAG_NOICON) && !(flag & SCFLAG_LOADED && status->dbs->DisplayType[type]))
+ clif->status_change_sub(bl, status->dbs->IconChangeTable[type], 1, tick, total_tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0);
/**
* used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
**/
- if( tick_time )
+ if(tick_time)
tick = tick_time;
//Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
@@ -9704,6 +9707,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
sce->val2 = val2;
sce->val3 = val3;
sce->val4 = val4;
+ sce->total_tick = total_tick;
if (tick >= 0) {
sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
@@ -9812,7 +9816,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 1;
}
-static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag)
{
Assert_retr(false, type >= SC_NONE && type < SC_MAX);
if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) {
@@ -9823,6 +9827,28 @@ static bool status_change_start_unknown_sc(struct block_list *src, struct block_
return false;
}
+/**
+ * Starts a status change in its full duration.
+ *
+ * @param src Status change source bl.
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ * @param rate Base success rate. 1 means 0.01%, 10000 means 100%.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ * @param tick Base duration (milliseconds).
+ * @param flag Special flags (@see enum scstart_flag).
+ *
+ * @retval 0 if no status change happened.
+ * @retval 1 if the status change was successfully applied.
+ */
+static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+{
+ return status->change_start_sub(src, bl, type, rate, val1, val2, val3, val4, 0, tick, flag);
+}
+
static void status_change_start_display(struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4)
{
Assert_retv(type >= SC_NONE && type < SC_MAX);
@@ -10201,7 +10227,7 @@ static void status_change_start_stop_action(struct block_list *bl, enum sc_type
switch (type) {
case SC_VACUUM_EXTREME:
if (!map_flag_gvg(bl->m))
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
break;
case SC_FREEZE:
case SC_STUN:
@@ -10754,9 +10780,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
struct status_data *st;
struct view_data *vd;
int opt_flag=0, calc_flag;
-#ifdef ANTI_MAYAP_CHEAT
bool invisible = false;
-#endif
nullpo_ret(bl);
@@ -10811,10 +10835,8 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
status->display_remove(sd,type);
}
-#ifdef ANTI_MAYAP_CHEAT
- if (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE))
+ if ((sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) != 0)
invisible = true;
-#endif
vd = status->get_viewdata(bl);
calc_flag = status->dbs->ChangeFlagTable[type];
@@ -11441,6 +11463,12 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
}
#endif
+ // update HP bar when becoming visible again
+ if (invisible && (sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) == 0) {
+ if (sd != NULL && battle_config.party_hp_mode == 0 && sd->status.party_id != 0)
+ clif->party_hp(sd);
+ }
+
if (calc_flag&SCB_DYE) { //Restore DYE color
if (vd && !vd->cloth_color && sce->val4)
clif->changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
@@ -13351,10 +13379,12 @@ static void status_read_job_db(void)
int i = 0;
struct config_t job_db_conf;
struct config_setting_t *jdb = NULL;
+ char config_filename[256];
+
#ifdef RENEWAL_ASPD
- const char *config_filename = "db/re/job_db.conf";
+ libconfig->format_db_path(DBPATH_RE"job_db.conf", config_filename, sizeof(config_filename));
#else
- const char *config_filename = "db/pre-re/job_db.conf";
+ libconfig->format_db_path(DBPATH_PRE"job_db.conf", config_filename, sizeof(config_filename));
#endif
if (!libconfig->load_file(&job_db_conf, config_filename))
@@ -13645,6 +13675,7 @@ void status_defaults(void)
status->get_sc_def = status_get_sc_def;
status->change_start = status_change_start;
+ status->change_start_sub = status_change_start_sub;
status->change_end_ = status_change_end_;
status->kaahi_heal_timer = kaahi_heal_timer;
status->change_timer = status_change_timer;