Added returning to instances (#7622)

Fixes #5226

Thanks to @Forte22, @attackjom and @OptimusM

Co-authored-by: Aleos <aleos89@users.noreply.github.com>
This commit is contained in:
Lemongrass3110 2023-03-23 15:49:39 +01:00 committed by GitHub
parent 8abf9960a0
commit 49ba072f3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 194 additions and 283 deletions

View File

@ -168,3 +168,10 @@ feature.mesitemlink_dbname: no
// Stylist UI (Note 1)
// Requires: 2015-11-04 or later
feature.stylist: on
// Are players allowed to reconnect into instances? (Note 1)
// This is enabled by default in Renewal mode and
// disabled by default in Pre-Renewal mode.
// If this is allowed the "nosave" mapflag is still being respected
// and may prevent players from warping back into the instance.
//feature.instance_allow_reconnect: yes

View File

@ -7,6 +7,7 @@
//= 1.7 Updated. [Lupus]
//= 1.8 Updated. [L0ne_W0lf]
//= 1.9 Renewal split. [Euphy]
//= 2.0 Moved instances to pre-renewal. [Lemongrass]
//============================================================
//============================================================
@ -268,23 +269,6 @@ que_qaru03 mapflag nosave SavePoint
que_qaru04 mapflag nosave SavePoint
que_qaru05 mapflag nosave SavePoint
//============================================================
// Sealed Shrine
//============================================================
1@cata mapflag nosave SavePoint
2@cata mapflag nosave SavePoint
//============================================================
// Endless Tower
//============================================================
e_tower mapflag nosave SavePoint
1@tower mapflag nosave SavePoint
2@tower mapflag nosave SavePoint
3@tower mapflag nosave SavePoint
4@tower mapflag nosave SavePoint
5@tower mapflag nosave SavePoint
6@tower mapflag nosave SavePoint
//============================================================
// Battlegrounds
//============================================================
@ -307,18 +291,6 @@ schg_dun01 mapflag nosave SavePoint
arug_que01 mapflag nosave SavePoint
arug_dun01 mapflag nosave SavePoint
//============================================================
// Orc's Memory
//============================================================
1@orcs mapflag nosave SavePoint
2@orcs mapflag nosave SavePoint
//============================================================
// Nidhoggr's Instance
//============================================================
1@nyd mapflag nosave SavePoint
2@nyd mapflag nosave SavePoint
//============================================================
// RWC
//============================================================

View File

@ -0,0 +1,37 @@
//===== rAthena Script =======================================
//= Mapflag: Disable auto-save.
//===== Description: =========================================
//= Characters logging out on the specified map will be warped
//= to the map specified in the last field, or "SavePoint".
//===== Additional Comments: =================================
//= 1.0 Renewal Split. [Lemongrass]
//============================================================
//============================================================
// Endless Tower
//============================================================
e_tower mapflag nosave SavePoint
1@tower mapflag nosave SavePoint
2@tower mapflag nosave SavePoint
3@tower mapflag nosave SavePoint
4@tower mapflag nosave SavePoint
5@tower mapflag nosave SavePoint
6@tower mapflag nosave SavePoint
//============================================================
// Sealed Shrine
//============================================================
1@cata mapflag nosave SavePoint
2@cata mapflag nosave SavePoint
//============================================================
// Orc's Memory
//============================================================
1@orcs mapflag nosave SavePoint
2@orcs mapflag nosave SavePoint
//============================================================
// Nidhoggr's Instance
//============================================================
1@nyd mapflag nosave SavePoint
2@nyd mapflag nosave SavePoint

View File

@ -6,6 +6,7 @@
//===== Changelogs: ==========================================
//= 1.0 Renewal split. [Euphy]
//= 1.1 Added GVG TE Guild Dungeons. [Capuche]
//= 1.2 Removed instances. [Lemongrass]
//============================================================
//============================================================
@ -60,27 +61,10 @@ te_aldecas3 mapflag nosave SavePoint
te_aldecas4 mapflag nosave SavePoint
te_aldecas5 mapflag nosave SavePoint
//============================================================
// Misty Forest Labyrinth
//============================================================
1@mist mapflag nosave SavePoint
//============================================================
// Octopus Cave
//============================================================
1@cash mapflag nosave SavePoint
//============================================================
// Drain
//============================================================
1@pump mapflag nosave SavePoint
2@pump mapflag nosave SavePoint
//============================================================
// Somatology Laboratory
//============================================================
que_lhz mapflag nosave SavePoint
1@lhz mapflag nosave SavePoint
//============================================================
// Port Malaya
@ -95,246 +79,22 @@ ma_zif07 mapflag nosave SavePoint
ma_zif08 mapflag nosave SavePoint
ma_zif09 mapflag nosave SavePoint
//============================================================
// Bangungot Hospital F2
//============================================================
1@ma_h mapflag nosave SavePoint
//============================================================
// Buwaya Cave
//============================================================
1@ma_c mapflag nosave SavePoint
//============================================================
// Bakonawa Hideout
//============================================================
1@ma_b mapflag nosave SavePoint
//============================================================
// Inside Eclage
//============================================================
que_avan01 mapflag nosave SavePoint
1@ecl mapflag nosave SavePoint
//============================================================
// Glastheim Memorial Dungeon
//============================================================
1@gl_k mapflag nosave SavePoint
2@gl_k mapflag nosave SavePoint
//============================================================
// Wave Mode Memorial Dungeon
//============================================================
1@def01 mapflag nosave SavePoint
1@def02 mapflag nosave SavePoint
1@def03 mapflag nosave SavePoint
//============================================================
// Heroes' Trail - Part 1
//============================================================
1@face mapflag nosave SavePoint
1@sara mapflag nosave SavePoint
//============================================================
// Heroes' Trail - Part 2
//============================================================
1@ge_st mapflag nosave SavePoint
1@gef mapflag nosave SavePoint
1@gef_in mapflag nosave SavePoint
1@spa mapflag nosave SavePoint
1@tnm1 mapflag nosave SavePoint
1@tnm2 mapflag nosave SavePoint
1@tnm3 mapflag nosave SavePoint
//============================================================
// Horror Toy Factory Memorial Dungeon
//============================================================
1@xm_d mapflag nosave SavePoint
//============================================================
// Heroes' Trail - Part 3
//============================================================
1@glast mapflag nosave SavePoint
1@air1 mapflag nosave SavePoint
1@air2 mapflag nosave SavePoint
//============================================================
// Decisive Battle - Part 1
//============================================================
1@dth1 mapflag nosave SavePoint
1@dth2 mapflag nosave SavePoint
1@dth3 mapflag nosave SavePoint
1@rev mapflag nosave SavePoint
//============================================================
// Decisive Battle - Part 2
//============================================================
1@eom mapflag nosave SavePoint
1@jtb mapflag nosave SavePoint
//============================================================
// Episode 15 - Phantasmagorica
//============================================================
1@lab mapflag nosave SavePoint
1@uns mapflag nosave SavePoint
un_myst mapflag nosave SavePoint
1@mcd mapflag nosave SavePoint
//============================================================
// Infinite Space
//============================================================
1@infi mapflag nosave
//============================================================
// Episode 16.1 - Banquet of Heroes
//============================================================
que_swat mapflag nosave SavePoint
1@mir mapflag nosave SavePoint
2@mir mapflag nosave SavePoint
1@sthb mapflag nosave SavePoint
1@sthc mapflag nosave SavePoint
1@sthd mapflag nosave SavePoint
1@slw mapflag nosave SavePoint
1@swat mapflag nosave SavePoint
//============================================================
// Rockridge
//============================================================
rockmi2 mapflag nosave SavePoint
//============================================================
// Memorial day
//============================================================
1@md_gef mapflag nosave SavePoint
1@md_pay mapflag nosave SavePoint
//============================================================
// Chicken Mode - Nightmare Glastheim
//============================================================
1@gl_k2 mapflag nosave SavePoint
2@gl_k2 mapflag nosave SavePoint
//============================================================
// Chicken Mode - Horror Toy Factory
//============================================================
1@xm_d2 mapflag nosave SavePoint
//============================================================
// Suspicious Shipwreck
//============================================================
1@tre mapflag nosave SavePoint
//============================================================
// Poring Village
//============================================================
1@begi mapflag nosave SavePoint
//============================================================
// Volcanic Island Korodo
//============================================================
1@crd mapflag nosave SavePoint
//============================================================
// Noodles Festival July
//============================================================
1@drdo mapflag nosave SavePoint
//============================================================
// Soul Reaper Job Change
//============================================================
1@soul mapflag nosave SavePoint
//============================================================
// Episode 17.1
//============================================================
1@cor mapflag nosave SavePoint
1@os_a mapflag nosave SavePoint
1@os_b mapflag nosave SavePoint
1@rgsr mapflag nosave SavePoint
//============================================================
// Episode 17.2
//============================================================
1@bamn mapflag nosave SavePoint
1@bamq mapflag nosave SavePoint
1@ghg mapflag nosave SavePoint
1@herbs mapflag nosave SavePoint
1@lost mapflag nosave SavePoint
1@odin mapflag nosave SavePoint
//============================================================
// 4th Jobs Change
//============================================================
1@4win mapflag nosave SavePoint
1@4mag mapflag nosave SavePoint
1@4mst mapflag nosave SavePoint
1@4sac mapflag nosave SavePoint
1@4tro mapflag nosave SavePoint
1@4inq mapflag nosave SavePoint
1@4cdn mapflag nosave SavePoint
1@4igd mapflag nosave SavePoint
1@4drk mapflag nosave SavePoint
//============================================================
// Geffen Night Arena
//============================================================
1@ge_sn mapflag nosave SavePoint
//============================================================
// Traces of Heroes
//============================================================
1@mjo1 mapflag nosave SavePoint
1@mjo2 mapflag nosave SavePoint
1@spa2 mapflag nosave SavePoint
//============================================================
// Thanatos Tower Memorial Dungeon
//============================================================
1@thts mapflag nosave SavePoint
2@thts mapflag nosave SavePoint
3@thts mapflag nosave SavePoint
4@thts mapflag nosave SavePoint
5@thts mapflag nosave SavePoint
6@thts mapflag nosave SavePoint
7@thts mapflag nosave SavePoint
8@thts mapflag nosave SavePoint
//============================================================
// Glastheim Challenge Mode
//============================================================
1@gl_he mapflag nosave SavePoint
1@gl_he2 mapflag nosave SavePoint
//============================================================
// EDDA
//============================================================
1@gl_prq mapflag nosave SavePoint
1@gol1 mapflag nosave SavePoint
1@gol2 mapflag nosave SavePoint
//============================================================
// 2018 Halloween
//============================================================
1@halo mapflag nosave SavePoint
//============================================================
// Constellation Tower
//============================================================
1@ch_t mapflag nosave SavePoint
2@ch_t mapflag nosave SavePoint
3@ch_t mapflag nosave SavePoint
//============================================================
// Episode 18 - Direction of Prayer
//============================================================
1@adv mapflag nosave SavePoint
1@advs mapflag nosave SavePoint
1@nyr mapflag nosave SavePoint
1@oz mapflag nosave SavePoint
1@tcamp mapflag nosave SavePoint
2@nyr mapflag nosave SavePoint
//============================================================
// Sunken Tower
//============================================================
1@ch_u mapflag nosave SavePoint

View File

@ -259,6 +259,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`last_map` varchar(11) NOT NULL default '',
`last_x` smallint(4) unsigned NOT NULL default '53',
`last_y` smallint(4) unsigned NOT NULL default '111',
`last_instanceid` int(11) unsigned NOT NULL default '0',
`save_map` varchar(11) NOT NULL default '',
`save_x` smallint(4) unsigned NOT NULL default '53',
`save_y` smallint(4) unsigned NOT NULL default '111',

View File

@ -0,0 +1,3 @@
ALTER TABLE `char`
ADD COLUMN `last_instanceid` int(11) unsigned NOT NULL default '0' AFTER `last_y`
;

View File

@ -279,7 +279,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
(p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) ||
(p->zeny != cp->zeny) ||
( strncmp( p->last_point.map, cp->last_point.map, sizeof( p->last_point.map ) ) != 0 ) ||
(p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) ||
(p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) || (p->last_point_instanceid != cp->last_point_instanceid) ||
( strncmp( p->save_point.map, cp->save_point.map, sizeof( p->save_point.map ) ) != 0 ) ||
( p->save_point.x != cp->save_point.x ) || ( p->save_point.y != cp->save_point.y ) ||
(p->max_hp != cp->max_hp) || (p->hp != cp->hp) ||
@ -307,7 +307,8 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
"`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`last_instanceid`='%d',"
"`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
"`delete_date`='%lu',`robe`='%d',`moves`='%d',`font`='%u',`uniqueitem_counter`='%u',"
"`hotkey_rowshift`='%d', `clan_id`='%d', `title_id`='%lu', `show_equip`='%d', `hotkey_rowshift2`='%d',"
"`max_ap`='%u',`ap`='%u',`trait_point`='%d',"
@ -319,7 +320,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id,
p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
p->last_point.map, p->last_point.x, p->last_point.y,
p->last_point.map, p->last_point.x, p->last_point.y, p->last_point_instanceid,
p->save_point.map, p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size
p->robe, p->character_moves, p->font, p->uniqueitem_counter,
@ -1060,7 +1061,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`,"
"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`,`hotkey_rowshift2`,"
"`max_ap`,`ap`,`trait_point`,`pow`,`sta`,`wis`,`spl`,`con`,`crt`,"
"`inventory_slots`,`body_direction`,`disable_call`"
"`inventory_slots`,`body_direction`,`disable_call`,`last_instanceid`"
" FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db)
|| SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|| SQL_ERROR == SqlStmt_Execute(stmt)
@ -1138,7 +1139,8 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 71, SQLDT_SHORT, &p->crt, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 72, SQLDT_UINT16, &p->inventory_slots, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 73, SQLDT_UINT8, &p->body_direction, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 74, SQLDT_UINT16, &p->disable_call, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 74, SQLDT_UINT8, &p->disable_call, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 75, SQLDT_INT, &p->last_point_instanceid, 0, NULL, NULL)
)
{
SqlStmt_ShowDebug(stmt);
@ -1516,8 +1518,8 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int
//Insert the new char entry to the database
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `class`, `zeny`, `status_point`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`, `sex`) VALUES ("
"'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c')",
"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`, `sex`, `last_instanceid`) VALUES ("
"'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c', '0')",
schema_config.char_db, sd->account_id , slot, esc_name, start_job, charserv_config.start_zeny, status_points, str, agi, vit, int_, dex, luk,
(40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, sex ) )
@ -2330,7 +2332,7 @@ bool char_checkdb(void){
"`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`,"
"`hotkey_rowshift2`,"
"`max_ap`,`ap`,`trait_point`,`pow`,`sta`,`wis`,`spl`,`con`,`crt`,"
"`inventory_slots`,`body_direction`,`disable_call`"
"`inventory_slots`,`body_direction`,`disable_call`,`last_instanceid`"
" FROM `%s` LIMIT 1;", schema_config.char_db) ){
Sql_ShowDebug(sql_handle);
return false;

View File

@ -595,6 +595,7 @@ struct mmo_charstatus {
uint16 mapport;
struct s_point_str last_point;
int32 last_point_instanceid;
struct s_point_str save_point;
struct s_point_str memo_point[MAX_MEMOPOINTS];
struct s_skill skill[MAX_SKILL];

View File

@ -10458,6 +10458,11 @@ static const struct _battle_data {
{ "feature.stylist", &battle_config.feature_stylist, 1, 0, 1, },
{ "feature.banking_state_enforce", &battle_config.feature_banking_state_enforce, 0, 0, 1, },
#ifdef RENEWAL
{ "feature.instance_allow_reconnect", &battle_config.instance_allow_reconnect, 1, 0, 1, },
#else
{ "feature.instance_allow_reconnect", &battle_config.instance_allow_reconnect, 0, 0, 1, },
#endif
#include <custom/battle_config_init.inc>
};

View File

@ -730,6 +730,7 @@ struct Battle_Config
int feature_stylist;
int feature_banking_state_enforce;
int instance_allow_reconnect;
#include <custom/battle_config_struct.inc>
};

View File

@ -1307,6 +1307,10 @@ void pc_makesavestatus(map_session_data *sd) {
#else
sd->status.option = sd->sc.option&(OPTION_INVISIBLE|OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR);
#endif
// Mark last point as not instance related by default
sd->status.last_point_instanceid = 0;
if (sd->sc.getSCE(SC_JAILED)) { //When Jailed, do not move last point.
if(pc_isdead(sd)){
pc_setrestartvalue(sd, 0);
@ -1348,12 +1352,22 @@ void pc_makesavestatus(map_session_data *sd) {
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}
// If the user is on a instance map, we return him to his save point
// If the user is on a instance map, special handling is needed
}else if( mapdata->instance_id ){
// Return the user to his save point
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
if( battle_config.instance_allow_reconnect ){
// Store the original mapname
struct map_data* mapdata_source = map_getmapdata( mapdata->instance_src_map );
mapindex_getmapname( mapindex_id2name( mapdata_source->index ), sd->status.last_point.map );
sd->status.last_point.x = sd->bl.x;
sd->status.last_point.y = sd->bl.y;
sd->status.last_point_instanceid = mapdata->instance_id;
}else{
// Return the user to his save point
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}
}else{
// Save normally
mapindex_getmapname( mapindex_id2name( sd->mapindex ), sd->status.last_point.map );
@ -1890,6 +1904,106 @@ uint8 pc_isequip(map_session_data *sd,int n)
return ITEM_EQUIP_ACK_OK;
}
/**
* Performs some special modifications to a player's last point location,
* if the map has a nosave mapflag or if the map was an instance.
* @param sd: Player data
* @return True if the player should be returned to his savepoint or false if not
*/
bool pc_lastpoint_special( map_session_data& sd ){
int16 mapid = map_mapname2mapid( sd.status.last_point.map );
// Should not happen because otherwise the char-server would have sent the player to another map-server
if( mapid < 0 ){
// Return the player to his savepoint
return true;
}
struct map_data* mapdata = map_getmapdata( mapid );
if( mapdata == nullptr ){
// Return the player to his savepoint
return true;
}
// Maybe since the player's logout the nosave mapflag was added to the map
if( mapdata->flag[MF_NOSAVE] ){
// The map has a specific return point
if( mapdata->save.map ){
safestrncpy( sd.status.last_point.map, mapindex_id2name( mapdata->save.map ), sizeof( sd.status.last_point.map ) );
sd.status.last_point.x = mapdata->save.x;
sd.status.last_point.y = mapdata->save.y;
return false;
}else{
// Return the user to his save point
return true;
}
}
// Check if the last point was an instance
if( sd.status.last_point_instanceid == 0 ){
// Nothing to do
return false;
}
// Check if returning to the instance is allowed in general
if( !battle_config.instance_allow_reconnect ){
// Return the player to his savepoint
return true;
}
std::shared_ptr<s_instance_data> instance_data = util::umap_find( instances, sd.status.last_point_instanceid );
if( instance_data == nullptr ){
// Instance does not exist anymore, return the player to his savepoint
return true;
}
switch( instance_data->mode ){
case IM_NONE:
// Cannot validate
break;
case IM_CHAR:
if( sd.status.char_id != instance_data->owner_id ){
// It is a character bound instance and the player is not the owner, return the player to his savepoint
return true;
}
break;
case IM_PARTY:
if( sd.status.party_id != instance_data->owner_id ){
// It is a party bound instance and the player is not in the party, return the player to his savepoint
return true;
}
break;
case IM_GUILD:
if( sd.status.guild_id != instance_data->owner_id ){
// It is a guild bound instance and the player is not in the guild, return the player to his savepoint
return true;
}
break;
case IM_CLAN:
if( sd.status.clan_id != instance_data->owner_id ){
// It is a clan bound instance and the player is not in the clan, return the player to his savepoint
return true;
}
break;
}
int16 imapid = instance_mapid( mapid, sd.status.last_point_instanceid );
if( imapid < 0 ){
// Instance does not contain this map anymore, return the player to his savepoint
return true;
}
// Overwrite the stored "source mapname" with the real mapname
instance_generate_mapname( mapid, sd.status.last_point_instanceid, sd.status.last_point.map );
// X/Y coordinates are already correct and do not need to be modified
// Dont warp the player back to his savepoint
return false;
}
/*==========================================
* No problem with the session id
* set the status that has been sent from char server
@ -2030,6 +2144,14 @@ bool pc_authok(map_session_data *sd, uint32 login_id2, time_t expiration_time, i
sd->vars_ok = false;
sd->vars_received = 0x0;
// Check if the player's last point requires special handling and if conditions apply to return the player to his savepoint
if( pc_lastpoint_special( *sd ) ){
// The player should be warped back to his savepoint
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}
//warp player
enum e_setpos setpos_result = pc_setpos( sd, mapindex_name2id( sd->status.last_point.map ), sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT );
if( setpos_result != SETPOS_OK ){