From 234ababd8c1a9df4391c6c54f9167f625e432dc2 Mon Sep 17 00:00:00 2001 From: skotlex Date: Thu, 10 Jan 2008 22:02:33 +0000 Subject: - Fixed getmonsterinfo to return "null" when returning the name of a non-existing mob instead of -1. - Extended the status_percent_damage define to include a bolean to specify whether or not the target can be killed from it. - Corrected CR_CULTIVATION to fail when the target cell has some BL_CHAR on it already. - Changed the meaning of 'flag' in status_percent_change, to enable differentiation between damage that can kill the object and damage that cannot. - Script command percentheal will no longer kill the player if the specified amount is negative (and not -100). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12051 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 6 ++++++ doc/script_commands.txt | 4 ++-- src/map/battle.c | 2 +- src/map/clif.c | 2 +- src/map/pc.c | 8 ++++---- src/map/script.c | 5 ++++- src/map/skill.c | 21 ++++++++++++--------- src/map/status.c | 19 ++++++++++++------- src/map/status.h | 6 +++--- 9 files changed, 45 insertions(+), 28 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 068eaea60..a25feedce 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2008/01/10 + * Fixed getmonsterinfo to return "null" when returning the name of a + non-existing mob instead of -1. + * Corrected CR_CULTIVATION to fail when the target cell has some BL_CHAR on + it already. + * Script command percentheal will no longer kill the player if the + specified amount is negative (and not -100). * Fixed Abracadabra unable to cast non-targeted skills (bugreport:186) * Another round of login server cleaning [ultramage] - fixed passwordencrypt on SQL not behaving correctly (since r10753) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 2c52024d2..1a9987587 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -2839,8 +2839,8 @@ set @i, petstat(PET_CLASS); This function will look up the monster with the specified ID number in the mob database and return the info set by TYPE argument. -It will return -1 if there is no such item. Due to specific of MOB DB routines, -it's better to check monster name. It'd return "Dummy" for a non-existing mob. +It will return -1 if there is no such monster (or the type value is invalid), +or "null" if you requested the monster's name. Valid types are listed in const.txt: MOB_NAME 0 MOB_LV 1 diff --git a/src/map/battle.c b/src/map/battle.c index 45abe63b9..122688a1a 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2724,7 +2724,7 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage, } if (sd->sp_vanish_rate && rand()%1000 < sd->sp_vanish_rate) - status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->sp_vanish_per); + status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->sp_vanish_per, false); if (!thp && !tsp) return; status_heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain?3:1); diff --git a/src/map/clif.c b/src/map/clif.c index b74f4f582..002210485 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10238,7 +10238,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) break; } case BL_MOB: - status_percent_damage(&sd->bl, target, 100, 0); + status_percent_damage(&sd->bl, target, 100, 0, true); if(log_config.gm && lv >= log_config.gm) { char message[NAME_LENGTH+16]; sprintf(message, "/kick %s (%d)", status_get_name(target), status_get_class(target)); diff --git a/src/map/pc.c b/src/map/pc.c index d524a5766..d3281985a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5494,22 +5494,22 @@ int pc_percentheal(struct map_session_data *sd,int hp,int sp) if(hp >= 0 && sp >= 0) //Heal return status_percent_heal(&sd->bl, hp, sp); - if(hp <= 0 && sp <= 0) //Damage (negative rates indicate % of max rather than current) - return status_percent_damage(NULL, &sd->bl, hp, sp); + if(hp <= 0 && sp <= 0) //Damage (negative rates indicate % of max rather than current), and only kill target IF the specified amount is 100% + return status_percent_damage(NULL, &sd->bl, hp, sp, hp==-100); //Crossed signs if(hp) { if(hp > 0) status_percent_heal(&sd->bl, hp, 0); else - status_percent_damage(NULL, &sd->bl, hp, 0); + status_percent_damage(NULL, &sd->bl, hp, 0, hp==-100); } if(sp) { if(sp > 0) status_percent_heal(&sd->bl, 0, sp); else - status_percent_damage(NULL, &sd->bl, 0, sp); + status_percent_damage(NULL, &sd->bl, 0, sp, false); } return 0; } diff --git a/src/map/script.c b/src/map/script.c index a56135dd8..f63be3fb5 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12104,7 +12104,10 @@ BUILDIN_FUNC(getmonsterinfo) mob_id = script_getnum(st,2); if (!mobdb_checkid(mob_id)) { ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i", mob_id); - script_pushint(st,-1); + if ( !script_getnum(st,3) ) //requested a string + script_pushconststr(st,"null"); + else + script_pushint(st,-1); return -1; } mob = mob_db(mob_id); diff --git a/src/map/skill.c b/src/map/skill.c index 2fba7b6ca..1015f2092 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -561,7 +561,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case HT_SHOCKWAVE: - status_percent_damage(src, bl, 0, 15*skilllv+5); + status_percent_damage(src, bl, 0, 15*skilllv+5, false); break; case HT_SANDMAN: @@ -603,7 +603,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case PA_PRESSURE: - status_percent_damage(src, bl, 0, 15+5*skilllv); + status_percent_damage(src, bl, 0, 15+5*skilllv, false); break; case RG_RAID: @@ -2710,12 +2710,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int clif_skill_nodamage(src,bl,skillid,skilllv,1); if (skilllv == 5) skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - status_percent_damage(src, bl, 0, 100); + status_percent_damage(src, bl, 0, 100, false); } else { clif_skill_nodamage(src,src,skillid,skilllv,1); if (skilllv == 5) skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,flag); - status_percent_damage(src, src, 0, 100); + status_percent_damage(src, src, 0, 100, false); } if (sd) skill_blockpc_start (sd, skillid, (skilllv < 5 ? 10000: 15000)); break; @@ -4261,7 +4261,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if(sp < 1) sp = 1; status_heal(bl,0,sp,2); clif_skill_nodamage(bl,bl,SA_MAGICROD,tsc->data[SC_MAGICROD]->val1,1); - status_percent_damage(bl, src, 0, -20); //20% max SP damage. + status_percent_damage(bl, src, 0, -20, false); //20% max SP damage. } else { struct unit_data *ud = unit_bl2ud(bl); int bl_skillid=0,bl_skilllv=0,hp = 0; @@ -4787,7 +4787,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in switch (eff) { case 0: // heals SP to 0 - status_percent_damage(src, bl, 0, 100); + status_percent_damage(src, bl, 0, 100, false); break; case 1: // matk halved sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv)); @@ -5815,14 +5815,17 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk int i = skilllv - 1; int j = pc_search_inventory(sd,skill_db[skillid].itemid[i]); if(j < 0 || skill_db[skillid].itemid[i] <= 0 || sd->inventory_data[j] == NULL || - sd->status.inventory[j].amount < skill_db[skillid].amount[i]) { + sd->status.inventory[j].amount < skill_db[skillid].amount[i] || + map_count_oncell(src->m,x,y,BL_CHAR) > 0 + ) { clif_skill_fail(sd,skillid,0,0); return 1; } + pc_delitem(sd,j,skill_db[skillid].amount[i],0); clif_skill_poseffect(src,skillid,skilllv,x,y,tick); if (rand()%100 < 50) - mob_once_spawn(sd, sd->bl.m, x, y, "--ja--",(skilllv < 2 ? 1084+rand()%2 : 1078+rand()%6), 1, ""); + mob_once_spawn(sd, src->m, x, y, "--ja--",(skilllv < 2 ? 1084+rand()%2 : 1078+rand()%6), 1, ""); else clif_skill_fail(sd,skillid,0,0); } @@ -10263,7 +10266,7 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in } else { switch (skill_id) { case ASC_CDP: //25% Damage yourself, and display same effect as failed potion. - status_percent_damage(NULL, &sd->bl, -25, 0); + status_percent_damage(NULL, &sd->bl, -25, 0, true); case AM_PHARMACY: case AM_TWILIGHT1: case AM_TWILIGHT2: diff --git a/src/map/status.c b/src/map/status.c index 0c06e32b6..768d9fc1d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -851,7 +851,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag) //no exp/drops will be awarded if there is no src (or src is target) //If rates are > 0, percent is of current HP/SP //If rates are < 0, percent is of max HP/SP -//If flag, this is heal, otherwise it is damage. +//If !flag, this is heal, otherwise it is damage. +//Furthermore, if flag==2, then the target must not die from the substraction. int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag) { struct status_data *status; @@ -878,6 +879,9 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe if (hp_rate && !hp) hp = 1; + if (flag == 2 && hp >= status->hp) + hp = status->hp-1; //Must not kill target. + //Should be safe to not do overflow protection here, noone should have //millions upon millions of SP if (sp_rate > 99) @@ -896,19 +900,20 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe if (hp > INT_MAX) { hp -= INT_MAX; if (flag) - status_heal(target, INT_MAX, 0, 0); - else status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1)); + else + status_heal(target, INT_MAX, 0, 0); } if (sp > INT_MAX) { sp -= INT_MAX; if (flag) - status_heal(target, 0, INT_MAX, 0); - else status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1)); + else + status_heal(target, 0, INT_MAX, 0); } - if (flag) return status_heal(target, hp, sp, 0); - return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1)); + if (flag) + return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1)); + return status_heal(target, hp, sp, 0); } int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp) diff --git a/src/map/status.h b/src/map/status.h index d204c3f39..97aea9d2b 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -588,10 +588,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp,int sp int status_charge(struct block_list* bl, int hp, int sp); int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag); //Easier handling of status_percent_change -#define status_percent_heal(bl, hp_rate, sp_rate) status_percent_change(NULL, bl, -(hp_rate), -(sp_rate), 1) -#define status_percent_damage(src, target, hp_rate, sp_rate) status_percent_change(src, target, hp_rate, sp_rate, 0) +#define status_percent_heal(bl, hp_rate, sp_rate) status_percent_change(NULL, bl, -(hp_rate), -(sp_rate), 0) +#define status_percent_damage(src, target, hp_rate, sp_rate, kill) status_percent_change(src, target, hp_rate, sp_rate, (kill)?1:2) //Instant kill with no drops/exp/etc -#define status_kill(bl) status_percent_damage(NULL, bl, 100, 0) +#define status_kill(bl) status_percent_damage(NULL, bl, 100, 0, true) //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); -- cgit v1.2.3-70-g09d2