diff --git a/conf/battle/instance.conf b/conf/battle/instance.conf new file mode 100644 index 0000000000..14c7a9072a --- /dev/null +++ b/conf/battle/instance.conf @@ -0,0 +1,27 @@ +//-------------------------------------------------------------- +// rAthena Battle Configuration File +// Originally Translated by Peter Kieser +// Made in to plainer English by Ancyker +//-------------------------------------------------------------- +// Note 1: Value is a config switch (on/off, yes/no or 1/0) +// Note 2: Value is in percents (100 means 100%) +// Note 3: Value is a bit field. If no description is given, +// assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun) +//-------------------------------------------------------------- + +// Block leaving for parties, guilds or clans if they have an active instance? +// Default: yes (Official) +instance_block_leave: yes + +// Block leader changes for parties or guilds if they have an active instance? +// Default: yes (Official) +instance_block_leaderchange: yes + +// Block inviting for parties or guilds if they have an active instance? +// This also blocks joining parties, guilds or clans that have a running instance. +// Default: yes (Official) +instance_block_invite: yes + +// Block expulsion for parties or guilds if they have an active instance? +// Default: yes (Official) +instance_block_expulsion: yes diff --git a/conf/battle_athena.conf b/conf/battle_athena.conf index fe03deb7ee..d9c1aeff71 100644 --- a/conf/battle_athena.conf +++ b/conf/battle_athena.conf @@ -8,6 +8,9 @@ //General battle-related settings. import: conf/battle/battle.conf +//Battleground settings +import: conf/battle/battleground.conf + //Settings specific to the client. import: conf/battle/client.conf @@ -17,14 +20,20 @@ import: conf/battle/drops.conf //Experience rates, exp penalties, stats and max level settings. import: conf/battle/exp.conf +//Feature control (on/off) settings +import: conf/battle/feature.conf + //GM levels, atcommands and hack-related configs. import: conf/battle/gm.conf //Guild and WoE settings import: conf/battle/guild.conf -//Battleground settings -import: conf/battle/battleground.conf +//Homunc related configuration +import: conf/battle/homunc.conf + +//Instance settings +import: conf/battle/instance.conf //Item/card-specific and crafting related options. import: conf/battle/items.conf @@ -32,15 +41,16 @@ import: conf/battle/items.conf //Mob related configuration import: conf/battle/monster.conf +// Anything else that didn't fit anywhere else. +// Includes duel, day/night, mute/manner, log settings. +import: conf/battle/misc.conf + //Party related configuration import: conf/battle/party.conf //Pet related configuration import: conf/battle/pet.conf -//Homunc related configuration -import: conf/battle/homunc.conf - //Player specific settings import: conf/battle/player.conf @@ -50,12 +60,5 @@ import: conf/battle/skill.conf //Status change related settings import: conf/battle/status.conf -//Feature control (on/off) settings -import: conf/battle/feature.conf - -// Anything else that didn't fit anywhere else. -// Includes duel, day/night, mute/manner, log settings. -import: conf/battle/misc.conf - //Your custom config goes here. import: conf/import/battle_conf.txt diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 3171733a04..2682071ffc 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -11503,6 +11503,10 @@ static const struct _battle_data { { "pet_legacy_formula", &battle_config.pet_legacy_formula, 0, 0, 1, }, { "pet_distance_check", &battle_config.pet_distance_check, 5, 0, 50, }, { "pet_hide_check", &battle_config.pet_hide_check, 1, 0, 1, }, + { "instance_block_leave", &battle_config.instance_block_leave, 1, 0, 1, }, + { "instance_block_leaderchange", &battle_config.instance_block_leaderchange, 1, 0, 1, }, + { "instance_block_invite", &battle_config.instance_block_invite, 1, 0, 1, }, + { "instance_block_expulsion", &battle_config.instance_block_expulsion, 1, 0, 1, }, // 4th Job Stuff { "use_traitpoint_table", &battle_config.use_traitpoint_table, 1, 0, 1, }, diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 350320f89e..61d040fa5a 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -722,6 +722,10 @@ struct Battle_Config int pet_distance_check; int pet_hide_check; + int instance_block_leave; + int instance_block_leaderchange; + int instance_block_invite; + int instance_block_expulsion; // 4th Jobs Stuff int trait_points_job_change; int use_traitpoint_table; diff --git a/src/map/clan.cpp b/src/map/clan.cpp index bfdac03a53..65ae6bac1f 100644 --- a/src/map/clan.cpp +++ b/src/map/clan.cpp @@ -11,6 +11,7 @@ #include #include +#include "battle.hpp" #include "clif.hpp" #include "instance.hpp" #include "intif.hpp" @@ -165,6 +166,10 @@ bool clan_member_join( map_session_data& sd, int clan_id, uint32 account_id, uin return false; } + if( clan->instance_id > 0 && battle_config.instance_block_invite ){ + return false; + } + sd.status.clan_id = clan->id; clan_member_joined(sd); @@ -183,6 +188,10 @@ bool clan_member_leave( map_session_data& sd, int clan_id, uint32 account_id, ui return false; } + if( clan->instance_id > 0 && battle_config.instance_block_leave ){ + return false; + } + clan_member_left(sd); sd.clan = nullptr; diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 950988e6c8..f2d6c409ff 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -12358,8 +12358,8 @@ void clif_parse_ChatLeave(int fd, map_session_data* sd) chat_leavechat(sd,0); } - // Handles notifying asker and rejecter of what has just ocurred. +// Type is used to determine the correct msg_txt to use void clif_noask_sub( map_session_data& sd, map_session_data& tsd, int type ){ char output[CHAT_SIZE_MAX]; @@ -25042,6 +25042,16 @@ void clif_parse_partybooking_reply( int fd, map_session_data* sd ){ return; } + struct party_data* party = party_search( sd->status.party_id ); + + if( party == nullptr ){ + return; + } + + if( party->instance_id > 0 && battle_config.instance_block_invite ){ + return; + } + if( p->accept ){ party_join( *tsd, sd->status.party_id ); } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index d7d931d3ce..159792d6cb 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -163,6 +163,7 @@ enum e_party_invite_reply { PARTY_REPLY_OFFLINE, ///< result=7 : "The Character is not currently online or does not exist." -> MsgStringTable[71] (since 20070904) PARTY_REPLY_INVALID_MAPPROPERTY, ///< result=8 : !TODO "Unable to organize a party in this map" -> MsgStringTable[1388] (since 20080527) PARTY_REPLY_INVALID_MAPPROPERTY_ME, ///< return=9 : !TODO "Cannot join a party in this map" -> MsgStringTable[1871] (since 20110205) + PARTY_REPLY_MEMORIALDUNGEON, ///< return=10: "You cannot invite or withdraw while in memorial dungeon" -> MsgStringTable[3027] (since 20161130) }; /// Enum for Convex Mirror (SC_BOSSMAPINFO) diff --git a/src/map/guild.cpp b/src/map/guild.cpp index fb9126a8a2..08995914ff 100644 --- a/src/map/guild.cpp +++ b/src/map/guild.cpp @@ -930,6 +930,10 @@ bool guild_invite( map_session_data& sd, map_session_data* tsd ){ return false; } + if( g->instance_id && battle_config.instance_block_invite ){ + return false; + } + // Guild locked. if( map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. @@ -1028,6 +1032,12 @@ bool guild_reply_invite( map_session_data& sd, int guild_id, int flag ){ return false; } + if( g->instance_id && battle_config.instance_block_invite ){ + sd.guild_invite = 0; + sd.guild_invite_account = 0; + return false; + } + int i; ARR_FIND( 0, g->guild.max_member, i, g->guild.member[i].account_id == 0 ); @@ -1144,6 +1154,10 @@ bool guild_leave( map_session_data& sd, int guild_id, uint32 account_id, uint32 return false; } + if( g->instance_id > 0 && battle_config.instance_block_leave ){ + return false; + } + if( map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. return false; @@ -1181,6 +1195,10 @@ bool guild_expulsion( map_session_data& sd, int guild_id, uint32 account_id, uin return false; } + if( g->instance_id > 0 && battle_config.instance_block_expulsion ){ + return false; + } + // TODO: for leave this is different messages if( sd.bg_id || map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. @@ -2167,6 +2185,10 @@ bool guild_gm_change( int guild_id, uint32 char_id, bool showMessage ){ return false; } + if( g->instance_id > 0 && battle_config.instance_block_leaderchange ){ + return false; + } + int i; ARR_FIND( 0, MAX_GUILD, i, g->guild.member[i].char_id == char_id ); @@ -2291,6 +2313,10 @@ int guild_break( map_session_data& sd, char* name ){ } if( g->instance_id ){ + if( battle_config.instance_block_leave ){ + return 0; + } + instance_destroy(g->instance_id); } diff --git a/src/map/party.cpp b/src/map/party.cpp index e3ad127873..46b08e4a48 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -403,6 +403,11 @@ bool party_invite( map_session_data& sd, map_session_data *tsd ){ return false; } + if( p->instance_id > 0 && battle_config.instance_block_invite ){ + clif_party_invite_reply( sd, "", PARTY_REPLY_MEMORIALDUNGEON ); + return false; + } + if( tsd == NULL ){ clif_party_invite_reply( sd, "", PARTY_REPLY_OFFLINE ); return false; @@ -582,6 +587,13 @@ bool party_reply_invite( map_session_data& sd, int party_id, int flag ){ // accepted and allowed if( flag == 1 && !sd.party_creating && !sd.party_joining ) { struct party_data* party = party_search( party_id ); + + if( party && party->instance_id > 0 && battle_config.instance_block_invite ){ + sd.party_invite = 0; + sd.party_invite_account = 0; + return false; + } + struct party_member member = {}; sd.party_joining = true; @@ -696,6 +708,10 @@ bool party_removemember( map_session_data& sd, uint32 account_id, char* name ){ if( p == nullptr ) return false; + if( p->instance_id > 0 && battle_config.instance_block_expulsion ){ + return false; + } + int i; // check the requesting char's party membership @@ -757,6 +773,15 @@ bool party_leave( map_session_data& sd, bool showMessage ){ return false; } + if( p->instance_id > 0 && battle_config.instance_block_leave ){ + // If it was not triggered by the user itself, but from a script for example + if( showMessage ){ + clif_party_withdraw( sd, sd.status.account_id, sd.status.name, PARTY_MEMBER_WITHDRAW_CANT_LEAVE, SELF ); + } + + return false; + } + int i; ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd.status.account_id && p->party.member[i].char_id == sd.status.char_id ); @@ -933,6 +958,10 @@ int party_changeleader(map_session_data *sd, map_session_data *tsd, struct party if ((p = party_search(sd->status.party_id)) == nullptr ) return -1; + if( p->instance_id > 0 && battle_config.instance_block_leaderchange ){ + return 0; + } + ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); if (mi == MAX_PARTY) return 0; // Shouldn't happen