summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt11
-rw-r--r--conf-tmpl/msg_athena.conf6
-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
9 files changed, 188 insertions, 143 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 4229e78a5..170e7eaec 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,17 @@ 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.
2007/03/19
+ * 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.
+ * 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.
+ * 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. [Skotlex]
* Fixed some wrong sql login logic
* Fixed some compiler warnings, cleaned up mapserver sql-related vars
* Removed the old 'mapserver charsave' mechanism [ultramage]
diff --git a/conf-tmpl/msg_athena.conf b/conf-tmpl/msg_athena.conf
index 04564fd69..a5bb16694 100644
--- a/conf-tmpl/msg_athena.conf
+++ b/conf-tmpl/msg_athena.conf
@@ -134,9 +134,9 @@
114: %d item(s) removed from the player.
115: %d item(s) removed. Player had only %d on %d items.
116: Character does not have the item.
-117: GM has send you in jails.
-118: Player warped in jails.
-119: This player is not in jails.
+117: GM has jailed you.
+118: Player jailed.
+119: This player is not jailed.
120: GM has discharge you.
121: Player unjailed.
122: Disguise applied.
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);