summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--doc/script_commands.txt4
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/pc.c8
-rw-r--r--src/map/script.c5
-rw-r--r--src/map/skill.c21
-rw-r--r--src/map/status.c19
-rw-r--r--src/map/status.h6
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);