diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/script.c | 17 | ||||
-rw-r--r-- | src/map/skill.c | 5 | ||||
-rw-r--r-- | src/map/status.c | 44 | ||||
-rw-r--r-- | src/map/status.h | 3 |
4 files changed, 61 insertions, 8 deletions
diff --git a/src/map/script.c b/src/map/script.c index cf1ae0c17..1571d7d5d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7553,7 +7553,22 @@ int buildin_setcastledata(struct script_state *st) case 23: case 24: case 25: - gc->guardian[index-18].hp = value; break; + gc->guardian[index-18].hp = value; + if (gc->guardian[index-18].id) + { //Update this mob's HP. + struct block_list *bl = map_id2bl(gc->guardian[index-18].id); + if (!bl) + { //Wrong target? + gc->guardian[index-18].id = 0; + break; + } + if (value < 1) { + status_kill(bl); + break; + } + status_set_hp(bl, value, 0); + } + break; default: return 0; } guild_castledatasave(gc->castle_id,index,value); diff --git a/src/map/skill.c b/src/map/skill.c index 3749ce6d2..266e1201c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5200,9 +5200,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } sp1 = sstatus->sp; sp2 = tstatus->sp; - //TODO: Will this work correctly once sp1/sp2 go above INT_MAX? - status_heal(src, 0, (signed int)(sp2-sp1), 3); - status_heal(bl, 0, (signed int)(sp1-sp2), 3); + status_set_sp(src, sp2, 3); + status_set_sp(bl, sp1, 3); clif_skill_nodamage(src,bl,skillid,skilllv,1); } break; diff --git a/src/map/status.c b/src/map/status.c index 39034a9b7..971bc3f88 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -495,6 +495,42 @@ int status_getrefinebonus(int lv,int type) return 0; } +//Sets HP to given value. Flag is the flag passed to status_heal in case +//final value is higher than current (use 2 to make a healing effect display +//on players) It will always succeed (overrides Berserk block), but it can't kill. +int status_set_hp(struct block_list *bl, unsigned int hp, int flag) +{ + struct status_data *status; + if (hp < 1) return 0; + status = status_get_status_data(bl); + if (status == &dummy_status) + return 0; + + if (hp > status->max_hp) hp = status->max_hp; + if (hp == status->hp) return 0; + if (hp > status->hp) + return status_heal(bl, hp - status->hp, 0, 1|flag); + return status_zap(bl, status->hp - hp, 0); +} + +//Sets SP to given value. Flag is the flag passed to status_heal in case +//final value is higher than current (use 2 to make a healing effect display +//on players) +int status_set_sp(struct block_list *bl, unsigned int sp, int flag) +{ + struct status_data *status; + + status = status_get_status_data(bl); + if (status == &dummy_status) + return 0; + + if (sp > status->max_sp) sp = status->max_sp; + if (sp == status->sp) return 0; + if (sp > status->sp) + return status_heal(bl, 0, sp - status->sp, 1|flag); + return status_zap(bl, 0, status->sp - sp); +} + //Inflicts damage on the target with the according walkdelay. //If flag&1, damage is passive and does not triggers cancelling status changes. //If flag&2, fail if target does not has enough to substract. @@ -504,8 +540,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s struct status_data *status; struct status_change *sc; - if(sp && target->type != BL_PC && target->type != BL_HOMUNCULUS) //[orn] - sp = 0; //Only players and Homunculus get SP damage. + if(sp && !(target->type&BL_CONSUME)) + sp = 0; //Not a valid SP target. if (hp < 0) { //Assume absorbed damage. status_heal(target, -hp, 0, 1); @@ -5548,7 +5584,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if (type==SC_BERSERK) { sc->data[type].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_percent_damage(NULL, bl, 0, 100); //Damage all SP + status_set_sp(bl, 0, 0); //Damage all SP } if (type==SC_RUN) { @@ -5822,7 +5858,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) case SC_BERSERK: //If val2 is removed, no HP penalty (dispelled?) [Skotlex] if(status->hp > 100 && sc->data[type].val2) - status_zap(bl, status->hp-100, 0); + status_set_hp(bl, 100, 0); if(sc->data[SC_ENDURE].timer != -1) status_change_end(bl, SC_ENDURE, -1); break; diff --git a/src/map/status.h b/src/map/status.h index d41e08b25..a15a6c0d7 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -532,6 +532,9 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe //Instant kill with no drops/exp/etc
//
#define status_kill(bl) status_percent_damage(NULL, bl, 100, 0)
+//Used to set the hp/sp of an object to an absolute value (can't kill)
+int status_set_hp(struct block_list *bl, unsigned int hp, int flag);
+int status_set_sp(struct block_list *bl, unsigned int sp, int flag);
int status_heal(struct block_list *bl,int hp,int sp, int flag);
int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp);
|