diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 5 | ||||
-rw-r--r-- | src/map/mercenary.c | 8 | ||||
-rw-r--r-- | src/map/mob.c | 37 | ||||
-rw-r--r-- | src/map/pc.c | 46 | ||||
-rw-r--r-- | src/map/script.c | 6 | ||||
-rw-r--r-- | src/map/status.c | 66 | ||||
-rw-r--r-- | src/map/unit.c | 28 |
7 files changed, 102 insertions, 94 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 4b61c5f74..bf0d3e2da 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3690,9 +3690,8 @@ static int atkillmonster_sub(struct block_list *bl, va_list ap) { if (flag)
status_kill(bl);
- else
- unit_remove_map(&md->bl,1);
-
+ else //FIXME: Eh.. what exactly is the difference here?
+ status_kill(bl);
return 1;
}
void atcommand_killmonster_sub(
diff --git a/src/map/mercenary.c b/src/map/mercenary.c index d6e2c06be..335bd54fa 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -102,14 +102,8 @@ void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp) int merc_dead(struct homun_data *hd, struct block_list *src)
{
//dead lol
- clif_clearchar((struct block_list*)hd,1);
- hd->bl.m = 0;
- hd->bl.x = 0;
- hd->bl.y = 0; //send it somewhere where it doesn't bother us
merc_save(hd);
- clif_clearchar_area(&hd->bl,0);
- map_delblock(&hd->bl);
- return 1;
+ return 3; //Remove it from map.
}
void merc_skillup(struct map_session_data *sd,short skillnum)
diff --git a/src/map/mob.c b/src/map/mob.c index d7442dcdf..929565511 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -883,10 +883,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) bl=map_id2bl(md->master_id); if (!bl || status_isdead(bl)) { //主が死亡しているか見つからない - if(md->special_state.ai) - unit_remove_map(&md->bl, 1); - else - status_kill(&md->bl); + status_kill(&md->bl); return 0; } @@ -921,10 +918,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) } } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) { //Delete the summoned mob if it's in a gvg ground and the master is elsewhere. [Skotlex] - if(md->special_state.ai) - unit_remove_map(&md->bl, 1); - else - status_kill(&md->bl); + status_kill(&md->bl); return 0; } @@ -1695,19 +1689,13 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) } md->state.skillstate = MSS_DEAD; - md->status.hp = 1; //Otherwise skill will be blocked due to being dead! [Skotlex] mobskill_use(md,tick,-1); //On Dead skill. - md->status.hp = 0; if (md->sc.data[SC_KAIZEL].timer != -1) { //Revive in a bit. - mob_unlocktarget(md,tick); - mob_stop_walking(md, 0); - clif_clearchar_area(&md->bl,1); add_timer(gettick()+3000, mob_respawn, md->bl.id, 10*md->sc.data[SC_KAIZEL].val1); //% of life to rebirth with - status_change_end(&md->bl, SC_KAIZEL, -1); map_delblock(&md->bl); - return 0; + return 1; //Return 1 to only clear the object. } map_freeblock_lock(); @@ -2134,9 +2122,24 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance] } if(md->level) md->level=0; + + if(md->deletetimer!=-1) { + delete_timer(md->deletetimer,mob_timer_delete); + md->deletetimer=-1; + } + if(pcdb_checkid(md->vd->class_)) //Player mobs are not removed automatically by the client. + clif_clearchar_delay(tick+3000,&md->bl,0); + + mob_deleteslave(md); + md->last_deadtime=tick; + map_freeblock_unlock(); - unit_remove_map(&md->bl,1); - return 1; + + if(!md->spawn) //Tell status_damage to remove it from memory. + return 5; + + mob_setdelayspawn(md); //Set respawning. + return 3; //Remove from map. } void mob_revive(struct mob_data *md, unsigned int hp) diff --git a/src/map/pc.c b/src/map/pc.c index 2040b5ebf..8f8e6749c 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4432,9 +4432,8 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h int pc_dead(struct map_session_data *sd,struct block_list *src)
{
- int i=0,j=0,resurrect_flag=0,baby_flag=0;
+ int i=0,j=0;
unsigned int tick = gettick();
- struct status_data *status = &sd->battle_status;
if(sd->vender_id)
vending_closevending(sd);
@@ -4458,20 +4457,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if(sd->duel_invite > 0)
duel_reject(sd->duel_invite, sd);
}
-
- //SC data that will be needed later on.
- resurrect_flag = (sd->sc.data[SC_KAIZEL].timer != -1)?sd->sc.data[SC_KAIZEL].val1:0;
- baby_flag = (sd->sc.data[SC_BABY].timer != -1)?1:0;
- pc_stop_attack(sd);
- pc_stop_walking(sd,0);
- unit_skillcastcancel(&sd->bl,0);
- clif_clearchar_area(&sd->bl,1);
pc_setdead(sd);
- skill_unit_move(&sd->bl,tick,4);
- if (battle_config.clear_unit_ondeath)
- skill_clear_unitgroup(&sd->bl); //orn
- status_change_clear(&sd->bl,0);
sd->canregen_tick = tick;
pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter);
@@ -4599,7 +4586,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if(battle_config.death_penalty_type && sd->state.snovice_flag != 4
&& (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
&& !map[sd->bl.m].flag.nopenalty && !map_flag_gvg(sd->bl.m)
- && !baby_flag)
+ && sd->sc.data[SC_BABY].timer == -1)
{
unsigned int base_penalty =0;
if (battle_config.death_penalty_base > 0) {
@@ -4715,27 +4702,28 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) return 1;
}
- if (sd->state.snovice_flag == 4 || resurrect_flag)
+ if (sd->sc.count && sd->sc.data[SC_KAIZEL].timer != -1)
{
clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,1,1);
- pc_setstand(sd);
- status->hp = 1;
- if (sd->state.snovice_flag == 4 ||
- sd->special_state.restart_full_recover) {
+ if(sd->special_state.restart_full_recover)
status_percent_heal(&sd->bl, 100, 100);
- } else { //10% life per each level in Kaizel
- status_percent_heal(&sd->bl, 10*resurrect_flag, 0);
- }
- clif_updatestatus(sd, SP_HP);
- clif_updatestatus(sd, SP_SP);
+ else
+ status_percent_heal(&sd->bl, 10*sd->sc.data[SC_KAIZEL].val1, 0);
+ if(battle_config.pc_invincible_time)
+ pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+ sc_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],100,10,skill_get_time2(SL_KAIZEL,sd->sc.data[SC_KAIZEL].val1));
+ status_change_end(&sd->bl,SC_KAIZEL,-1);
+ return 0;
+ }
+ if (sd->state.snovice_flag == 4)
+ {
+ clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,1,1);
+ status_percent_heal(&sd->bl, 100, 100);
clif_resurrection(&sd->bl, 1);
sd->state.snovice_flag = 0;
if(battle_config.pc_invincible_time)
pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
- if (resurrect_flag)
- sc_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],100,10,skill_get_time2(SL_KAIZEL, resurrect_flag));
- else
- sc_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],100,1,skill_get_time(MO_STEELBODY,1));
+ sc_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],100,1,skill_get_time(MO_STEELBODY,1));
return 0;
}
diff --git a/src/map/script.c b/src/map/script.c index f0ce4f200..41d84a92a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -5732,11 +5732,11 @@ int buildin_killmonster_sub(struct block_list *bl,va_list ap) if(!allflag){ if(strcmp(event,md->npc_event)==0) - unit_remove_map(bl,1); + status_kill(bl); return 0; }else{ if(!md->spawn) - unit_remove_map(bl,1); + status_kill(bl); return 0; } return 0; @@ -5760,7 +5760,7 @@ int buildin_killmonster(struct script_state *st) int buildin_killmonsterall_sub(struct block_list *bl,va_list ap) { - unit_remove_map(bl,1); + status_kill(bl); return 0; } int buildin_killmonsterall(struct script_state *st) diff --git a/src/map/status.c b/src/map/status.c index 7b95364b8..0ef6c3904 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -584,23 +584,69 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s { case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); - if (!status->hp) - mob_dead((TBL_MOB*)target, src, flag&4?3:0); break; case BL_PC: pc_damage((TBL_PC*)target,src,hp,sp); - if (!status->hp) - pc_dead((TBL_PC*)target,src); break; case BL_HOMUNCULUS: merc_damage((TBL_HOMUNCULUS*)target,src,hp,sp); - if (!status->hp) - merc_dead((TBL_HOMUNCULUS*)target,src); } - - if (walkdelay && status->hp) - unit_set_walkdelay(target, gettick(), walkdelay, 0); - + + if (status->hp) + { //Still lives! + if (walkdelay) + unit_set_walkdelay(target, gettick(), walkdelay, 0); + return hp+sp; + } + + status->hp = 1; //To let the dead function cast skills and all that. + //NOTE: These dead functions should return: [Skotlex] + //0: Death cancelled, auto-revived. + //Non-zero: Standard death. Clear status, cancel move/attack, etc + //&2: Also remove object from map. + //&4: Also delete object from memory. + switch (target->type) + { + case BL_MOB: + flag = mob_dead((TBL_MOB*)target, src, flag&4?3:0); + break; + case BL_PC: + flag = pc_dead((TBL_PC*)target,src); + break; + case BL_HOMUNCULUS: + flag = merc_dead((TBL_HOMUNCULUS*)target,src); + break; + default: //Unhandled case, do nothing to object. + flag = 0; + break; + } + + if(!flag) //Death cancelled. + return hp+sp; + + //Normal death + if (battle_config.clear_unit_ondeath && + battle_config.clear_unit_ondeath&target->type) + skill_clear_unitgroup(target); + status_change_clear(target,0); + + if(flag&2) //remove the unit from the map. + unit_remove_map(target,1); + else { //These are handled by unit_remove_map. + unit_stop_attack(target); + unit_stop_walking(target,0); + unit_skillcastcancel(target,0); + clif_clearchar_area(target,1); + skill_unit_move(target,gettick(),4); + skill_cleartimerskill(target); + } + + if(flag&4) { //Delete from memory. + map_delblock(target); + unit_free(target); + } + + return hp+sp; } diff --git a/src/map/unit.c b/src/map/unit.c index 02a95fd34..78e403aea 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1433,6 +1433,7 @@ int unit_changeviewsize(struct block_list *bl,short size) * Returns 1 on success. 0 if it couldn't be removed or the bl was free'd
* if clrtype is 1 (death), appropiate cleanup is performed.
* Otherwise it is assumed bl is being warped.
+ * On-Kill specific stuff is not performed here, look at status_damage for that.
*------------------------------------------
*/
int unit_remove_map(struct block_list *bl, int clrtype) {
@@ -1455,9 +1456,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) { ud->attackabletime = ud->canmove_tick = ud->canact_tick = gettick();
clif_clearchar_area(bl,clrtype);
- if (clrtype == 1) //Death. Remove all status changes.
- status_change_clear(bl,0);
- else if(sc && sc->count ) { //map-change/warp dispells.
+ if(sc && sc->count ) { //map-change/warp dispells.
if(sc->data[SC_BLADESTOP].timer!=-1)
status_change_end(bl,SC_BLADESTOP,-1);
if(sc->data[SC_BASILICA].timer!=-1)
@@ -1488,9 +1487,6 @@ int unit_remove_map(struct block_list *bl, int clrtype) { status_change_end(bl, SC_GOSPEL, -1);
}
- if (clrtype == 1 && battle_config.clear_unit_ondeath && //Clrtype 1 = died.
- battle_config.clear_unit_ondeath&bl->type)
- skill_clear_unitgroup(bl); // スキルユニットグループの削除
if (bl->type&BL_CHAR) {
skill_unit_move(bl,gettick(),4);
skill_cleartimerskill(bl); // タイマースキルクリア
@@ -1537,25 +1533,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) { struct mob_data *md = (struct mob_data*)bl;
md->target_id=0;
md->attacked_id=0;
- md->state.skillstate= clrtype==1?MSS_DEAD:MSS_IDLE;
- if (md->master_id) md->master_dist = 0;
- if (clrtype == 1) { //Death.
- md->last_deadtime=gettick();
- if(md->deletetimer!=-1)
- delete_timer(md->deletetimer,mob_timer_delete);
- md->deletetimer=-1;
- if(pcdb_checkid(md->vd->class_)) //Player mobs are not removed automatically by the client.
- clif_clearchar_delay(gettick()+3000,bl,0);
- mob_deleteslave(md);
-
- if(!md->spawn) {
- map_delblock(bl);
- unit_free(bl); //Mob does not respawn.
- map_freeblock_unlock();
- return 0;
- }
- mob_setdelayspawn(md); //Set respawning.
- }
+ md->state.skillstate= MSS_IDLE;
} else if (bl->type == BL_PET) {
struct pet_data *pd = (struct pet_data*)bl;
struct map_session_data *sd = pd->msd;
|