From bfb4c510052f56c0af3f7fbca417ce23d0fd2203 Mon Sep 17 00:00:00 2001 From: skotlex Date: Sun, 28 May 2006 17:58:56 +0000 Subject: - Added functions status_revive, pc_revive and mob_revive to handle revival (it doesn't handles player respawning, though) - Corrected alive, raisemap, raiseall to use these functions. - Updated resurrection/mob-kaizel to use status_revive - Added SC_BLADESTOP to the skill enum at the beginning of status.c (fixes Bladestop causing an unknown status change message) - Fixed MSS_DEAD state skills not triggering. - Corrected some compilation warnings on the merc.* files. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6807 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 59 +++++++++++++++++------------------------------------ src/map/mercenary.c | 8 ++++---- src/map/mercenary.h | 6 +++--- src/map/mob.c | 47 +++++++++++++++++++++++------------------- src/map/mob.h | 1 + src/map/pc.c | 10 ++++++++- src/map/pc.h | 1 + src/map/pet.c | 2 +- src/map/skill.c | 51 +++++++++++++++++++++++---------------------- src/map/status.c | 37 ++++++++++++++++++++++++++++++--- src/map/status.h | 1 + 11 files changed, 124 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 5274c4225..40c957ae6 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2428,20 +2428,11 @@ int atcommand_alive( const char* command, const char* message) { nullpo_retr(-1, sd); - if (pc_isdead(sd)) { - sd->status.hp = sd->status.max_hp; - sd->status.sp = sd->status.max_sp; + if (!status_revive(&sd->bl, 100, 100)) + return -1; clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - pc_setstand(sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_updatestatus(sd, SP_HP); - clif_updatestatus(sd, SP_SP); - clif_resurrection(&sd->bl, 1); clif_displaymessage(fd, msg_table[16]); // You've been revived! It's a miracle! return 0; - } - return -1; } /*========================================== @@ -4583,26 +4574,19 @@ int atcommand_revive( clif_displaymessage(fd, "Please, enter a player name (usage: @revive )."); return -1; } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isdead(pl_sd)) { - pl_sd->status.hp = pl_sd->status.max_hp; - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - pc_setstand(pl_sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(pl_sd, battle_config.pc_invincible_time); - clif_updatestatus(pl_sd, SP_HP); - clif_updatestatus(pl_sd, SP_SP); - clif_resurrection(&pl_sd->bl, 1); - clif_displaymessage(fd, msg_table[51]); // Character revived. - return 0; - } - return -1; - } else { + + pl_sd = map_nick2sd(atcmd_player_name); + + if (!pl_sd) { clif_displaymessage(fd, msg_table[3]); // Character not found. return -1; } - + + if (!status_revive(&sd->bl, 100, 0)) + return -1; + + clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); + clif_displaymessage(fd, msg_table[51]); // Character revived. return 0; } @@ -4890,18 +4874,13 @@ int atcommand_doommap( */ static void atcommand_raise_sub(struct map_session_data* sd) { - if (sd && sd->state.auth && pc_isdead(sd)) { - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - sd->status.hp = sd->status.max_hp; - sd->status.sp = sd->status.max_sp; - pc_setstand(sd); - clif_updatestatus(sd, SP_HP); - clif_updatestatus(sd, SP_SP); - clif_resurrection(&sd->bl, 1); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_displaymessage(sd->fd, msg_table[63]); // Mercy has been shown. - } + if (!sd->state.auth || !status_isdead(&sd->bl)) + return; + + if(!status_revive(&sd->bl, 100, 100)) + return; + clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); + clif_displaymessage(sd->fd, msg_table[63]); // Mercy has been shown. } /*========================================== diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 8ef7162db..e84acecf6 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -61,7 +61,7 @@ char32 merc_skillname[20] = {"NULL","HLIF_HEAL","HLIF_AVOID","HLIF_BRAIN","HLIF_ "HFLI_MOON","HFLI_FLEET","HFLI_SPEED","HFLI_SBR44", "HVAN_CAPRICE","HVAN_CHAOTIC","HVAN_INSTRUCT","HVAN_EXPLOSION"}; -void merc_load_exptables(); +void merc_load_exptables(void); void merc_save(struct map_session_data *sd); int mercskill_castend_id( int tid, unsigned int tick, int id,int data ); @@ -78,7 +78,7 @@ static int diry[8]={1,1,0,-1,-1,-1,0,1}; static unsigned long hexptbl[126]; -void merc_load_exptables() +void merc_load_exptables(void) { FILE *fl; int i; @@ -95,7 +95,7 @@ void merc_load_exptables() fclose(fl); } -char *merc_skill_get_name(id) +char *merc_skill_get_name(int id) { return merc_skillname[id-8000]; } @@ -498,4 +498,4 @@ int merc_create_homunculus(struct map_session_data *sd,int id,int m,int x,int y) clif_homuninfo(sd);*/ // send this x2. dunno why, but kRO does that [blackhole89] } -int do_final_merc (void); \ No newline at end of file +int do_final_merc (void); diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 24ef6bbb6..e4db4e54a 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -1,8 +1,8 @@ // Homunculus and future Mercenary system code go here [Celest] int do_init_merc (void); -void merc_load_exptables(); -char *merc_skill_get_name(id); +void merc_load_exptables(void); +char *merc_skill_get_name(int id); void merc_die(struct map_session_data *sd); int merc_damage(struct block_list *src,struct homun_data *hd,int damage,int type); void merc_calc_status(struct homun_data *hd); @@ -13,4 +13,4 @@ int merc_heal(struct homun_data *hd,int hp,int sp); void merc_save(struct map_session_data *sd); void merc_res(struct map_session_data *sd,int skilllv); void merc_load(struct map_session_data *sd); -int merc_create_homunculus(struct map_session_data *sd,int id,int m,int x,int y); \ No newline at end of file +int merc_create_homunculus(struct map_session_data *sd,int id,int m,int x,int y); diff --git a/src/map/mob.c b/src/map/mob.c index 3c04a5ead..f564878ea 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -1558,22 +1558,10 @@ int mob_deleteslave(struct mob_data *md) // Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex] int mob_respawn(int tid, unsigned int tick, int id,int data ) { - struct mob_data *md = (struct mob_data*)map_id2bl(id); - if (!md || md->bl.type != BL_MOB) - return 0; - //Mob must be dead and not in a map to respawn! - if (md->bl.prev != NULL || md->status.hp) - return 0; + struct block_list *bl = map_id2bl(id); - md->state.skillstate = MSS_IDLE; - md->last_thinktime = tick; - md->next_walktime = tick+rand()%50+5000; - md->last_linktime = tick; - map_addblock(&md->bl); - status_percent_heal(&md->bl, data, 0); - clif_spawn(&md->bl); - skill_unit_move(&md->bl,tick,1); - mobskill_use(md, tick, MSC_SPAWN); + if(!bl) return 0; + status_revive(bl, data, 0); return 1; } @@ -1699,9 +1687,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) status = &md->status; - if(status->hp) //Requested instant death? - status->hp = 0; - if(md->guardian_data && md->guardian_data->number < MAX_GUARDIANS) { // guardian hp update [Valaris] (updated by [Skotlex]) guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); @@ -1709,7 +1694,9 @@ 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. @@ -2149,6 +2136,22 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) return 1; } +void mob_revive(struct mob_data *md, unsigned int hp) +{ + unsigned int tick = gettick(); + md->state.skillstate = MSS_IDLE; + md->last_thinktime = tick; + md->next_walktime = tick+rand()%50+5000; + md->last_linktime = tick; + if (!md->bl.prev) + map_addblock(&md->bl); + clif_spawn(&md->bl); + skill_unit_move(&md->bl,tick,1); + mobskill_use(md, tick, MSC_SPAWN); + if (battle_config.show_mob_hp) + clif_charnameack (0, &md->bl); +} + int mob_guardian_guildchange(struct block_list *bl,va_list ap) { struct mob_data *md; @@ -2573,9 +2576,11 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) c2 = ms[i].cond2; - if (ms[i].state != md->state.skillstate && md->state.skillstate != MSS_DEAD) { - if (ms[i].state == MSS_ANY || (ms[i].state == MSS_ANYTARGET && md->target_id)) - ; //ANYTARGET works with any state as long as there's a target. [Skotlex] + if (ms[i].state != md->state.skillstate) { + if (md->state.skillstate != MSS_DEAD && ( + ms[i].state == MSS_ANY || (ms[i].state == MSS_ANYTARGET && md->target_id) + )) //ANYTARGET works with any state as long as there's a target. [Skotlex] + ; else continue; } diff --git a/src/map/mob.h b/src/map/mob.h index f608ad4aa..64f234285 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -150,6 +150,7 @@ int mob_setdelayspawn(struct mob_data *md); int mob_parse_dataset(struct spawn_data *data); void mob_damage(struct mob_data *md, struct block_list *src, int damage); int mob_dead(struct mob_data *md, struct block_list *src, int type); +void mob_revive(struct mob_data *md, unsigned int hp); void mob_heal(struct mob_data *md,unsigned int heal); #define mob_stop_walking(md, type) { if (md->ud.walktimer != -1) unit_stop_walking(&md->bl, type); } diff --git a/src/map/pc.c b/src/map/pc.c index 64ee6b6e8..24c607130 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4735,7 +4735,15 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) return 1; } -// +void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp) +{ + if(hp) clif_updatestatus(sd,SP_HP); + if(sp) clif_updatestatus(sd,SP_SP); + + pc_setstand(sd); + if(battle_config.pc_invincible_time > 0) + pc_setinvincibletimer(sd, battle_config.pc_invincible_time); +} // script? ˜A // /*========================================== diff --git a/src/map/pc.h b/src/map/pc.h index ae7a78f80..9959bb4ec 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -154,6 +154,7 @@ int pc_useitem(struct map_session_data*,int); void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int hp, unsigned int sp); int pc_dead(struct map_session_data *sd,struct block_list *src); +void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp); void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int type); int pc_itemheal(struct map_session_data *sd,int hp,int sp); int pc_percentheal(struct map_session_data *sd,int,int); diff --git a/src/map/pet.c b/src/map/pet.c index 54ae71631..39e16ea70 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -893,7 +893,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns return 0; } - if (!check_distance_bl(&sd->bl, &pd->bl, pd->db->range2)) { + if (!check_distance_bl(&sd->bl, &pd->bl, pd->db->range2) && DIFF_TICK(tick, pd->ud.canmove_tick) > 0) { //Master too far, chase. if(pd->target_id) pet_unlocktarget(pd); diff --git a/src/map/skill.c b/src/map/skill.c index 7a53cf63c..af0fef4b5 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3254,7 +3254,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } status_zap(src, sstatus->hp-1, sstatus->sp-1); break; - } else if (dstsd && pc_isdead(dstsd) && flag&1) { //Revive + } else if (status_isdead(bl) && flag&1) { //Revive skill_area_temp[0]++; //Count it in, then fall-through to the Resurrection code. skilllv = 3; //Resurrection level 3 is used } else //Invalid target, skip resurrection. @@ -3266,40 +3266,39 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_fail(sd,skillid,0,0); break; } - if(dstsd && pc_isdead(dstsd)) { - int per = 0; - if (map[bl->m].flag.pvp && dstsd->pvp_point < 0) + if (!status_isdead(bl)) + break; + { + int per = 0, sper = 0; + if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0) break; - clif_skill_nodamage(src,bl,ALL_RESURRECTION,skilllv,1); //Both Redemption and Res show this skill-animation. switch(skilllv){ case 1: per=10; break; case 2: per=30; break; case 3: per=50; break; case 4: per=80; break; } - tstatus->hp = 1; - if (dstsd->special_state.restart_full_recover) - status_percent_heal(bl, 100, 100); - else - status_percent_heal(bl, per, 0); - pc_setstand(dstsd); - if(battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(dstsd, battle_config.pc_invincible_time); - clif_resurrection(bl, 1); - if(sd && battle_config.resurrection_exp > 0) { - int exp = 0,jexp = 0; - int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level; - if(lv > 0) { - exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); - if (exp < 1) exp = 1; - } - if(jlv > 0) { - jexp = (int)((double)dstsd->status.job_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); - if (jexp < 1) jexp = 1; + if(dstsd && dstsd->special_state.restart_full_recover) + per = sper = 100; + if (status_revive(bl, per, sper)) + { + clif_skill_nodamage(src,bl,ALL_RESURRECTION,skilllv,1); //Both Redemption and Res show this skill-animation. + if(sd && dstsd && battle_config.resurrection_exp > 0) + { + int exp = 0,jexp = 0; + int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level; + if(lv > 0) { + exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); + if (exp < 1) exp = 1; + } + if(jlv > 0) { + jexp = (int)((double)dstsd->status.job_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); + if (jexp < 1) jexp = 1; + } + if(exp > 0 || jexp > 0) + pc_gainexp (sd, exp, jexp); } - if(exp > 0 || jexp > 0) - pc_gainexp (sd, exp, jexp); } } break; diff --git a/src/map/status.c b/src/map/status.c index 2c408b47b..24821895a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -216,6 +216,7 @@ void initChangeTables(void) { set_sc(CR_SPEARQUICKEN, SC_SPEARQUICKEN, SI_SPEARQUICKEN, SCB_ASPD); set_sc(MO_STEELBODY, SC_STEELBODY, SI_STEELBODY, SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED); add_sc(MO_BLADESTOP, SC_BLADESTOP_WAIT); + add_sc(MO_BLADESTOP, SC_BLADESTOP); set_sc(MO_EXPLOSIONSPIRITS, SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI); add_sc(MO_EXTREMITYFIST, SC_EXTREMITYFIST); add_sc(SA_MAGICROD, SC_MAGICROD); @@ -595,9 +596,6 @@ int status_heal(struct block_list *bl,unsigned int hp,unsigned int sp, int flag) } if(sp) { - if (bl->type != BL_PC) - sp = 0; //Only players get SP changes - if(sp > status->max_sp - status->sp) sp = status->max_sp - status->sp; } @@ -656,6 +654,39 @@ int status_percent_change(struct block_list *src,struct block_list *target,char return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1)); } +int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp) +{ + struct status_data *status; + unsigned int hp, sp; + if (!status_isdead(bl)) return 0; + + status = status_get_status_data(bl); + if (status == &dummy_status) + return 0; //Invalid target. + + hp = status->max_hp * per_hp/100; + sp = status->max_sp * per_hp/100; + + if(hp > status->max_hp - status->hp) + hp = status->max_hp - status->hp; + + if(sp > status->max_sp - status->sp) + sp = status->max_sp - status->sp; + + status->hp += hp; + status->sp += sp; + + clif_resurrection(bl, 1); + switch (bl->type) { + case BL_MOB: + mob_revive((TBL_MOB*)bl, hp); + break; + case BL_PC: + pc_revive((TBL_PC*)bl, hp, sp); + break; + } + return 1; +} /*========================================== * Checks whether the src can use the skill on the target, * taking into account status/option of both source/target. [Skotlex] diff --git a/src/map/status.h b/src/map/status.h index 03126ba0c..21688df56 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -516,6 +516,7 @@ int status_percent_change(struct block_list *src,struct block_list *target,char // #define status_kill(bl) status_percent_damage(NULL, bl, 100, 0) int status_heal(struct block_list *bl,unsigned int hp,unsigned int sp, int flag); +int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp); //Define for copying a status_data structure from b to a, without overwriting current Hp and Sp, nor messing the lhw pointer. #define status_cpy(a, b) { memcpy(&((a)->max_hp), &((b)->max_hp), sizeof(struct status_data)-(sizeof((a)->hp)+sizeof((a)->sp)+sizeof((a)->lhw))); \ -- cgit v1.2.3-70-g09d2