summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-03-19 04:36:44 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-03-19 04:36:44 +0000
commit90e11bb615a4df66fcc3b538fffe6595bca05015 (patch)
tree291d75b907783d4d89b23a7bebef3baf142e9799 /src
parent6ce5dacb5b15f16ff4c672596c091a41a190d687 (diff)
downloadhercules-90e11bb615a4df66fcc3b538fffe6595bca05015.tar.gz
hercules-90e11bb615a4df66fcc3b538fffe6595bca05015.tar.bz2
hercules-90e11bb615a4df66fcc3b538fffe6595bca05015.tar.xz
hercules-90e11bb615a4df66fcc3b538fffe6595bca05015.zip
- Rewrote the jail logic to always use a status change. This means that the character's save point is not changed when jailed, and the char is always warped back to the point where it was before being jailed on unjail.
- Made pc_setpos fail if you are jailed, effectively blocking you from being moved out of the jail map for the duration of jail. - Modified @adjcmdlvl so you can't set a command to require higher level than yourself, and so you can't edit the level of a command which is higher than your own. - Corrected attack_attr_none setting disabling elemental resist cards. - Added missing cap check of 100% to drop rate configs for heal/use/adddrop (cards)/treasures. - Corrected Autoblitz yelling the skill name if the attack splashed. - Corrected Dispell removing Jailed status. - Corrected being able to revive with 0 hp. - Modified the "Restart" code so that it makes you stand on spot when pc_setpos fails to move you back to your originating location. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10028 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/map/atcommand.c133
-rw-r--r--src/map/battle.c32
-rw-r--r--src/map/chrif.c5
-rw-r--r--src/map/clif.c72
-rw-r--r--src/map/pc.c23
-rw-r--r--src/map/skill.c4
-rw-r--r--src/map/status.c45
7 files changed, 174 insertions, 140 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 25a6b4e19..d68bb16a1 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6217,8 +6217,8 @@ int atcommand_jail(const int fd, struct map_session_data* sd, const char* comman
return -1;
}
- if (pl_sd->mapindex == mapindex_name2id(MAP_JAIL))
- { //Already jailed
+ if (pl_sd->sc.data[SC_JAILED].timer != -1)
+ {
clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
return -1;
}
@@ -6235,12 +6235,9 @@ int atcommand_jail(const int fd, struct map_session_data* sd, const char* comman
y = 75;
break;
}
- if (pc_setpos(pl_sd, m_index, x, y, 3)) {
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
- pc_setsavepoint(pl_sd, m_index, x, y); // Save Char Respawn Point in the jail room [Lupus]
+ //Duration of INT_MAX to specify infinity.
+ sc_start4(&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
clif_displaymessage(pl_sd->fd, msg_txt(117)); // GM has send you in jails.
clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
return 0;
@@ -6254,8 +6251,6 @@ int atcommand_jail(const int fd, struct map_session_data* sd, const char* comman
int atcommand_unjail(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
struct map_session_data *pl_sd;
- unsigned short m_index;
- int x=0, y=0;
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -6275,30 +6270,16 @@ int atcommand_unjail(const int fd, struct map_session_data* sd, const char* comm
return -1;
}
- if (pl_sd->mapindex != mapindex_name2id(MAP_JAIL)) {
+ if (pl_sd->sc.data[SC_JAILED].timer == -1)
+ {
clif_displaymessage(fd, msg_txt(119)); // This player is not in jails.
return -1;
}
- if (pl_sd->sc.count && pl_sd->sc.data[SC_JAILED].timer != -1)
- { //Retrieve return map.
- m_index = pl_sd->sc.data[SC_JAILED].val3;
- x = pl_sd->sc.data[SC_JAILED].val4&0xFFFF;
- y = pl_sd->sc.data[SC_JAILED].val4>>16;
- status_change_end(&pl_sd->bl,SC_JAILED,-1);
- } else
- m_index = mapindex_name2id(MAP_PRONTERA);
-
- if (pc_setpos(pl_sd, m_index, x, y, 3) == 0 ||
- pc_setpos(pl_sd, mapindex_name2id(MAP_PRONTERA), 0, 0, 3) == 0
- ) { //Send to Prontera is saved SC map fails.
- pc_setsavepoint(pl_sd, m_index, x, y);
- clif_displaymessage(pl_sd->fd, msg_txt(120)); // GM has discharge you.
- clif_displaymessage(fd, msg_txt(121)); // Player unjailed.
- } else {
- clif_displaymessage(fd, msg_txt(1)); // Map not found.
- return -1;
- }
+ //Reset jail time to 1 sec.
+ sc_start(&pl_sd->bl,SC_JAILED,100,1,1000);
+ clif_displaymessage(pl_sd->fd, msg_txt(120)); // GM has discharge you.
+ clif_displaymessage(fd, msg_txt(121)); // Player unjailed.
return 0;
}
@@ -6373,7 +6354,8 @@ int atcommand_jailfor(const int fd, struct map_session_data* sd, const char* com
}
//Added by Coltaro
- if (pl_sd->sc.count && pl_sd->sc.data[SC_JAILED].timer != -1)
+ if (pl_sd->sc.count && pl_sd->sc.data[SC_JAILED].timer != -1 &&
+ pl_sd->sc.data[SC_JAILED].val1 != UINT_MAX)
{ //Update the player's jail time
jailtime += pl_sd->sc.data[SC_JAILED].val1;
if (jailtime <= 0) {
@@ -6417,12 +6399,17 @@ int atcommand_jailtime(const int fd, struct map_session_data* sd, const char* co
nullpo_retr(-1, sd);
- if (sd->bl.m != map_mapname2mapid(MAP_JAIL)) {
+ if (!sd->sc.count || sd->sc.data[SC_JAILED].timer == -1) {
clif_displaymessage(fd, "You are not in jail."); // You are not in jail.
return -1;
}
- if (!sd->sc.count || sd->sc.data[SC_JAILED].timer == -1 || sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
+ if (sd->sc.data[SC_JAILED].val1 == INT_MAX) {
+ clif_displaymessage(fd, "You have been jailed indefinitely.");
+ return 0;
+ }
+
+ if (sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
clif_displaymessage(fd, "You have been jailed for an unknown amount of time.");
return -1;
}
@@ -6449,29 +6436,31 @@ int atcommand_charjailtime(const int fd, struct map_session_data* sd, const char
return -1;
}
- if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
- if (pc_isGM(pl_sd) < pc_isGM(sd)) { // only lower or same level
- if (pl_sd->bl.m != map_mapname2mapid(MAP_JAIL)) {
- clif_displaymessage(fd, "This player is not in jail."); // You are not in jail.
- return -1;
- }
- if (!pl_sd->sc.count || pl_sd->sc.data[SC_JAILED].timer == -1 || pl_sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail?)
- clif_displaymessage(fd, "This player has been jailed for an unknown amount of time.");
- return -1;
- }
- //Get remaining jail time
- get_jail_time(pl_sd->sc.data[SC_JAILED].val1,&year,&month,&day,&hour,&minute);
- sprintf(atcmd_output,msg_txt(402),"This player will remain",year,month,day,hour,minute);
- clif_displaymessage(fd, atcmd_output);
- } else {
- clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorize you to do this action on this player.
- return -1;
- }
- } else {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
clif_displaymessage(fd, msg_txt(3)); // Character not found.
return -1;
}
+ if (pc_isGM(pl_sd) < pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorize you to do this action on this player.
+ return -1;
+ }
+ if (!pl_sd->sc.count || pl_sd->sc.data[SC_JAILED].timer == -1 ) {
+ clif_displaymessage(fd, "This player is not in jail."); // You are not in jail.
+ return -1;
+ }
+ if (pl_sd->sc.data[SC_JAILED].val2) {
+ clif_displaymessage(fd, "This player has been jailed indefinitely.");
+ return 0;
+ }
+ if (pl_sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail?)
+ clif_displaymessage(fd, "This player has been jailed for an unknown amount of time.");
+ return -1;
+ }
+ //Get remaining jail time
+ get_jail_time(pl_sd->sc.data[SC_JAILED].val1,&year,&month,&day,&hour,&minute);
+ sprintf(atcmd_output,msg_txt(402),"This player will remain",year,month,day,hour,minute);
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
@@ -8166,24 +8155,38 @@ int atcommand_summon(const int fd, struct map_session_data* sd, const char* comm
*/
int atcommand_adjcmdlvl(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
- int i, newlev;
- char cmd[100];
+ int i, newlev;
+ char cmd[100];
nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d %s", &newlev, cmd) != 2) {
- clif_displaymessage(fd, "Usage: @adjcmdlvl <lvl> <command>.");
- return -1;
- }
+ if (!message || !*message || sscanf(message, "%d %100s", &newlev, cmd) != 2)
+ {
+ clif_displaymessage(fd, "Usage: @adjcmdlvl <lvl> <command>.");
+ return -1;
+ }
- for (i = 0; (atcommand_info[i].command) && atcommand_info[i].type != AtCommand_None; i++)
- if (strcmpi(cmd, atcommand_info[i].command+1) == 0) {
- atcommand_info[i].level = newlev;
- clif_displaymessage(fd, "@command level changed.");
- return 0;
- }
+ if (newlev > pc_isGM(sd))
+ {
+ clif_displaymessage(fd, "You can't make a command require higher GM level than your own.");
+ return -1;
+ }
- clif_displaymessage(fd, "@command not found.");
- return -1;
+ for (i = 0; atcommand_info[i].command && atcommand_info[i].type != AtCommand_None; i++)
+ {
+ if (strcmpi(cmd, atcommand_info[i].command+1) != 0)
+ continue;
+ if (atcommand_info[i].level > pc_isGM(sd))
+ {
+ clif_displaymessage(fd, "You can't adjust the level of a command which's level is above your own.");
+ return -1;
+ }
+ atcommand_info[i].level = newlev;
+ clif_displaymessage(fd, "@command level changed.");
+ return 0;
+ }
+
+ clif_displaymessage(fd, "@command not found.");
+ return -1;
}
/*==========================================
diff --git a/src/map/battle.c b/src/map/battle.c
index c0b50b444..dd18d38bd 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -987,9 +987,6 @@ static struct Damage battle_calc_weapon_attack(
if (skill_num == GS_GROUNDDRIFT)
s_ele = s_ele_ = wflag; //element comes in flag.
- if (s_ele == ELE_NEUTRAL && (battle_config.attack_attr_none&src->type))
- nk|=NK_NO_ELEFIX;
-
if(!skill_num)
{ //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2)
if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0)
@@ -1813,7 +1810,8 @@ static struct Damage battle_calc_weapon_attack(
if(skill_num==TF_POISON)
ATK_ADD(15*skill_lv);
- if (!(nk&NK_NO_ELEFIX))
+ if (!(nk&NK_NO_ELEFIX) ||
+ (s_ele == ELE_NEUTRAL && (battle_config.attack_attr_none&src->type)))
{ //Elemental attribute fix
if (wd.damage > 0)
{
@@ -4242,14 +4240,26 @@ void battle_validate_conf() {
battle_config.item_drop_mvp_min = 1;
if(battle_config.item_drop_mvp_max > 10000)
battle_config.item_drop_mvp_max = 10000; // End Addition
-
-/* if (battle_config.night_at_start < 0) // added by [Yor]
- battle_config.night_at_start = 0;
- else if (battle_config.night_at_start > 1) // added by [Yor]
- battle_config.night_at_start = 1; */
- if (battle_config.day_duration != 0 && battle_config.day_duration < 60000) // added by [Yor]
+ if(battle_config.item_drop_heal_min < 1)
+ battle_config.item_drop_heal_min = 1;
+ if(battle_config.item_drop_heal_max > 10000)
+ battle_config.item_drop_heal_max = 10000;
+ if(battle_config.item_drop_use_min < 1)
+ battle_config.item_drop_use_min = 1;
+ if(battle_config.item_drop_use_max > 10000)
+ battle_config.item_drop_use_max = 10000;
+ if(battle_config.item_drop_adddrop_min < 1)
+ battle_config.item_drop_adddrop_min = 1;
+ if(battle_config.item_drop_adddrop_max > 10000)
+ battle_config.item_drop_adddrop_max = 10000;
+ if(battle_config.item_drop_treasure_min < 1)
+ battle_config.item_drop_treasure_min = 1;
+ if(battle_config.item_drop_treasure_max > 10000)
+ battle_config.item_drop_treasure_max = 10000;
+
+ if (battle_config.day_duration && battle_config.day_duration < 60000) // added by [Yor]
battle_config.day_duration = 60000;
- if (battle_config.night_duration != 0 && battle_config.night_duration < 60000) // added by [Yor]
+ if (battle_config.night_duration && battle_config.night_duration < 60000) // added by [Yor]
battle_config.night_duration = 60000;
if (battle_config.hack_info_GM_level > 100)
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 09565b608..e19f66126 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -184,8 +184,9 @@ int chrif_isconnect(void)
int chrif_save(struct map_session_data *sd, int flag)
{
nullpo_retr(-1, sd);
-
- pc_makesavestatus(sd);
+
+ if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out.
+ pc_makesavestatus(sd);
if(!chrif_isconnect())
{
if (flag) sd->state.finalsave = 1; //Will save character on reconnect.
diff --git a/src/map/clif.c b/src/map/clif.c
index e1c53077c..146095afb 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -8841,39 +8841,38 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
switch(RFIFOB(fd,2)) {
case 0x00:
- if (pc_isdead(sd)) {
- pc_setstand(sd);
- pc_setrestartvalue(sd, 3);
- if (sd->sc.count && battle_config.debuff_on_logout&2) {
- //For some reason food buffs are removed when you respawn.
- if(sd->sc.data[SC_STRFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_STRFOOD,-1);
- if(sd->sc.data[SC_AGIFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_AGIFOOD,-1);
- if(sd->sc.data[SC_VITFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_VITFOOD,-1);
- if(sd->sc.data[SC_INTFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_INTFOOD,-1);
- if(sd->sc.data[SC_DEXFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_DEXFOOD,-1);
- if(sd->sc.data[SC_LUKFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_LUKFOOD,-1);
- if(sd->sc.data[SC_HITFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_HITFOOD,-1);
- if(sd->sc.data[SC_FLEEFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_FLEEFOOD,-1);
- if(sd->sc.data[SC_BATKFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_BATKFOOD,-1);
- if(sd->sc.data[SC_WATKFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_WATKFOOD,-1);
- if(sd->sc.data[SC_MATKFOOD].timer!=-1)
- status_change_end(&sd->bl,SC_MATKFOOD,-1);
- }
- pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 2);
+ if (!pc_isdead(sd))
+ break;
+ pc_setstand(sd);
+ pc_setrestartvalue(sd, 3);
+ if (sd->sc.count && battle_config.debuff_on_logout&2) {
+ //For some reason food buffs are removed when you respawn.
+ if(sd->sc.data[SC_STRFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_STRFOOD,-1);
+ if(sd->sc.data[SC_AGIFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_AGIFOOD,-1);
+ if(sd->sc.data[SC_VITFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_VITFOOD,-1);
+ if(sd->sc.data[SC_INTFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_INTFOOD,-1);
+ if(sd->sc.data[SC_DEXFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_DEXFOOD,-1);
+ if(sd->sc.data[SC_LUKFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_LUKFOOD,-1);
+ if(sd->sc.data[SC_HITFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_HITFOOD,-1);
+ if(sd->sc.data[SC_FLEEFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_FLEEFOOD,-1);
+ if(sd->sc.data[SC_BATKFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_BATKFOOD,-1);
+ if(sd->sc.data[SC_WATKFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_WATKFOOD,-1);
+ if(sd->sc.data[SC_MATKFOOD].timer!=-1)
+ status_change_end(&sd->bl,SC_MATKFOOD,-1);
}
- // in case the player's status somehow wasn't updated yet [Celest]
- else if (sd->battle_status.hp <= 0)
- pc_setdead(sd);
+ //If warping fails, send a normal stand up packet.
+ if (pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 2))
+ clif_resurrection(&sd->bl, 1);
break;
case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */
@@ -11760,12 +11759,6 @@ int clif_parse(int fd) {
TBL_PC *sd;
RFIFOHEAD(fd);
- if (fd <= 0)
- { //Just in case, there are some checks for this later down below anyway which should be removed. [Skotlex]
- ShowError("clif_parse: Received invalid session %d\n", fd);
- return 0;
- }
-
sd = (TBL_PC *)session[fd]->session_data;
if (session[fd]->eof) {
if (sd) {
@@ -11945,8 +11938,7 @@ int clif_parse(int fd) {
if (dump) {
int i;
- if (fd)
- ShowDebug("\nclif_parse: session #%d, packet 0x%04x, length %d, version %d\n", fd, cmd, packet_len, packet_ver);
+ ShowDebug("\nclif_parse: session #%d, packet 0x%04x, length %d, version %d\n", fd, cmd, packet_len, packet_ver);
printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
for(i = 0; i < packet_len; i++) {
if ((i & 15) == 0)
diff --git a/src/map/pc.c b/src/map/pc.c
index e8515b553..059dc41fd 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -319,6 +319,19 @@ int pc_makesavestatus(struct map_session_data *sd)
sd->status.clothes_color=0;
sd->status.option = sd->sc.option; //Since the option saved is in
+
+ if (sd->sc.count && sd->sc.data[SC_JAILED].timer != -1)
+ { //When Jailed, do not move last point.
+ if(pc_isdead(sd))
+ pc_setrestartvalue(sd,0);
+ sd->status.hp = sd->battle_status.hp;
+ sd->status.sp = sd->battle_status.sp;
+ sd->status.last_point.map = sd->mapindex;
+ sd->status.last_point.x = sd->bl.x;
+ sd->status.last_point.y = sd->bl.y;
+ return 0;
+ }
+
if(pc_isdead(sd)){
pc_setrestartvalue(sd,0);
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
@@ -3335,12 +3348,10 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
if (sd->mapindex != mapindex)
{ //Misc map-changing settings
- party_send_dot_remove(sd); //minimap dot fix [Kevin]
- guild_send_dot_remove(sd);
- if (sd->regen.state.gc)
- sd->regen.state.gc = 0;
if (sd->sc.count)
{ //Cancel some map related stuff.
+ if (sd->sc.data[SC_JAILED].timer != -1)
+ return 1; //You may not get out!
if (sd->sc.data[SC_WARM].timer != -1)
status_change_end(&sd->bl,SC_WARM,-1);
if (sd->sc.data[SC_SUN_COMFORT].timer != -1)
@@ -3356,6 +3367,10 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
}
if (battle_config.clear_unit_onwarp&BL_PC)
skill_clear_unitgroup(&sd->bl);
+ party_send_dot_remove(sd); //minimap dot fix [Kevin]
+ guild_send_dot_remove(sd);
+ if (sd->regen.state.gc)
+ sd->regen.state.gc = 0;
}
if(m<0){
diff --git a/src/map/skill.c b/src/map/skill.c
index b3ad80d8d..20e30c79f 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2941,7 +2941,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
{ //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by.
if (skill_area_temp[1] != bl->id)
skill_attack(skill_get_type(skillid), src, src, bl,
- skillid, skilllv, tick, skill_area_temp[0]|SD_ANIMATION);
+ skillid, skilllv, tick, skill_area_temp[0]|SD_ANIMATION|(flag&SD_LEVEL));
break;
}
if ( skillid == NJ_BAKUENRYU )
@@ -4637,7 +4637,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SC_GUILDAURA: case SC_EDP: case SC_AUTOBERSERK:
case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
- case SC_ANKLE:
+ case SC_ANKLE: case SC_JAILED:
continue;
}
if(i==SC_BERSERK) tsc->data[i].val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
diff --git a/src/map/status.c b/src/map/status.c
index c15369d7e..5521bf517 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -896,9 +896,13 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
if(hp > status->max_hp - status->hp)
hp = status->max_hp - status->hp;
-
+ else if (per_hp && !hp)
+ hp = 1;
+
if(sp > status->max_sp - status->sp)
sp = status->max_sp - status->sp;
+ else if (per_sp && !sp)
+ sp = 1;
status->hp += hp;
status->sp += sp;
@@ -4891,7 +4895,6 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
case SC_ASPDPOTION3:
case SC_ATKPOTION:
case SC_MATKPOTION:
- case SC_JAILED:
case SC_ARMOR_ELEMENT:
break;
case SC_GOSPEL:
@@ -4916,6 +4919,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
sc->data[type].val4=-1;
}
break;
+ case SC_JAILED:
+ //When a player is already jailed, do not edit the jail data.
+ val2 = sc->data[type].val2;
+ val3 = sc->data[type].val3;
+ val4 = sc->data[type].val4;
+ break;
default:
if(sc->data[type].val1 > val1)
return 1; //Return true to not mess up skill animations. [Skotlex
@@ -5675,17 +5684,24 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
tick = 1000;
break;
case SC_JAILED:
+ //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
tick = val1>0?1000:250;
- if (sd && sd->mapindex != val2)
+ if (sd)
{
- int pos = (bl->x&0xFFFF)|(bl->y<<16), //Current Coordinates
- map = sd->mapindex; //Current Map
- //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
- if (pc_setpos(sd,(unsigned short)val2,val3,val4, 3) == 0)
- pc_setsavepoint(sd, (unsigned short)val2,val3,val4);
- //2. Set restore point (val3 -> return map, val4 return coords
- val3 = map;
- val4 = pos;
+ if (sd->mapindex != val2)
+ {
+ int pos = (bl->x&0xFFFF)|(bl->y<<16), //Current Coordinates
+ map = sd->mapindex; //Current Map
+ //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
+ pc_setpos(sd,(unsigned short)val2,val3,val4, 3);
+ //2. Set restore point (val3 -> return map, val4 return coords
+ val3 = map;
+ val4 = pos;
+ } else if (!val3 || val3 == sd->mapindex) { //Use save point.
+ val3 = sd->status.save_point.map;
+ val4 = (sd->status.save_point.x&0xFFFF)
+ |(sd->status.save_point.y<<16);
+ }
}
break;
case SC_UTSUSEMI:
@@ -6320,10 +6336,7 @@ int status_change_end( struct block_list* bl , int type,int tid )
break;
//natural expiration.
if(sd && sd->mapindex == sc->data[type].val2)
- {
- if (pc_setpos(sd,(unsigned short)sc->data[type].val3,sc->data[type].val4&0xFFFF, sc->data[type].val4>>16, 3) == 0)
- pc_setsavepoint(sd, sd->mapindex, bl->x, bl->y);
- }
+ pc_setpos(sd,(unsigned short)sc->data[type].val3,sc->data[type].val4&0xFFFF, sc->data[type].val4>>16, 3);
break; //guess hes not in jail :P
case SC_CHANGE:
if (tid == -1)
@@ -6868,7 +6881,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
break;
case SC_JAILED:
- if(--sc->data[type].val1 > 0)
+ if(sc->data[type].val1 == INT_MAX || --sc->data[type].val1 > 0)
{
sc->data[type].timer=add_timer(
60000+tick, status_change_timer, bl->id,data);