فهرست منبع

Implemented Clan Instance support (#2178)

* Allows instances to be created specifically for clans.
* Added script command instance_check_clan.
Thanks to @Lemongrass3110 for the idea and testing!
Aleos 8 سال پیش
والد
کامیت
f450538f4c
6فایلهای تغییر یافته به همراه211 افزوده شده و 53 حذف شده
  1. 34 11
      doc/script_commands.txt
  2. 1 0
      src/common/mmo.h
  3. 95 36
      src/map/instance.c
  4. 1 0
      src/map/instance.h
  5. 79 6
      src/map/script.c
  6. 1 0
      src/map/script_constants.h

+ 34 - 11
doc/script_commands.txt

@@ -8402,10 +8402,11 @@ Instance Mode options:
  IM_CHAR: Attached to a single character.
  IM_CHAR: Attached to a single character.
  IM_PARTY: Attached to a party (default instance mode).
  IM_PARTY: Attached to a party (default instance mode).
  IM_GUILD: Attached to a guild.
  IM_GUILD: Attached to a guild.
+ IM_CLAN: Attached to a clan.
 
 
 The command returns the instance ID upon success, and these values upon failure:
 The command returns the instance ID upon success, and these values upon failure:
  -1: Invalid type.
  -1: Invalid type.
- -2: Character/Party/Guild not found.
+ -2: Character/Party/Guild/Clan not found.
  -3: Instance already exists.
  -3: Instance already exists.
  -4: No free instances (MAX_INSTANCE exceeded).
  -4: No free instances (MAX_INSTANCE exceeded).
 
 
@@ -8416,7 +8417,7 @@ The command returns the instance ID upon success, and these values upon failure:
 Destroys instance with the ID <instance id>. If no ID is specified, the instance
 Destroys instance with the ID <instance id>. If no ID is specified, the instance
 the script is attached to is used. If the script is not attached to an instance,
 the script is attached to is used. If the script is not attached to an instance,
 the instance of the currently attached player is used (if it is a character, party,
 the instance of the currently attached player is used (if it is a character, party,
-or guild mode). If it is not owned by anyone, no player needs to be attached. If
+guild or clan mode). If it is not owned by anyone, no player needs to be attached. If
 that fails, the script will come to a halt. This will also trigger the "OnInstanceDestroy"
 that fails, the script will come to a halt. This will also trigger the "OnInstanceDestroy"
 label in all NPCs inside the instance.
 label in all NPCs inside the instance.
 
 
@@ -8428,9 +8429,9 @@ Warps player to the specified instance after the script terminates. The map and
 coordinates are located in 'db/(pre-)re/instance_db.txt'.
 coordinates are located in 'db/(pre-)re/instance_db.txt'.
 
 
 The command returns IE_OK upon success, and these values upon failure:
 The command returns IE_OK upon success, and these values upon failure:
- IE_NOMEMBER:	Party/Guild not found (for party/guild modes).
- IE_NOINSTANCE:	Character/Party/Guild does not have an instance.
- IE_OTHER:		Other errors (invalid instance name, instance doesn't match with character/party/guild).
+ IE_NOMEMBER:	Party/Guild/Clan not found (for party/guild/clan modes).
+ IE_NOINSTANCE:	Character/Party/Guild/Clan does not have an instance.
+ IE_OTHER:		Other errors (invalid instance name, instance doesn't match with character/party/guild/clan).
 
 
 Put -1 for x and y if want to warp player with default entrance coordinates.
 Put -1 for x and y if want to warp player with default entrance coordinates.
 
 
@@ -8440,8 +8441,8 @@ Put -1 for x and y if want to warp player with default entrance coordinates.
 
 
 Returns the unique name of the instanced script. If no ID is specified,
 Returns the unique name of the instanced script. If no ID is specified,
 the instance the script is attached to is used. If the script is not attached to
 the instance the script is attached to is used. If the script is not attached to
-an instance, the instance of the currently attached NPC, player, party, or guild
-is used. If that fails, the script will come to a halt.
+an instance, the instance of the currently attached NPC, player, party, guild
+or clan is used. If that fails, the script will come to a halt.
 
 
 ---------------------------------------
 ---------------------------------------
 
 
@@ -8450,7 +8451,7 @@ is used. If that fails, the script will come to a halt.
 Returns the unique name of the instanced map. If no instance ID is specified,
 Returns the unique name of the instanced map. If no instance ID is specified,
 the instance the script is attached to is used. If the script is not attached to
 the instance the script is attached to is used. If the script is not attached to
 an instance, the instance of the currently attached player is used (if it is a
 an instance, the instance of the currently attached player is used (if it is a
-character, party, or guild mode). If it is not owned by anyone, no player needs
+character, party, guild or clan mode). If it is not owned by anyone, no player needs
 to be attached. If that fails, the command returns an empty string instead.
 to be attached. If that fails, the command returns an empty string instead.
 
 
 ---------------------------------------
 ---------------------------------------
@@ -8459,7 +8460,7 @@ to be attached. If that fails, the command returns an empty string instead.
 
 
 Returns the unique instance id of the attached script. If the script is not
 Returns the unique instance id of the attached script. If the script is not
 attached to an instance, the instance of the currently attached player is
 attached to an instance, the instance of the currently attached player is
-used (if it is a character, party, or guild mode). If it is not owned by anyone, no
+used (if it is a character, party, guild or clan mode). If it is not owned by anyone, no
 player needs to be attached. If that fails, the function will return 0.
 player needs to be attached. If that fails, the function will return 0.
 
 
 ---------------------------------------
 ---------------------------------------
@@ -8469,7 +8470,7 @@ player needs to be attached. If that fails, the function will return 0.
 Warps all players in the instance <instance id> to <map name> at given
 Warps all players in the instance <instance id> to <map name> at given
 coordinates. If no ID is specified, the instance the script is attached to
 coordinates. If no ID is specified, the instance the script is attached to
 is used. If the script is not attached to an instance, the instance of the
 is used. If the script is not attached to an instance, the instance of the
-currently attached player is used (if it is a character, party, or guild
+currently attached player is used (if it is a character, party, guild or clan
 mode). If it is not owned by anyone, no player needs to be attached. If that
 mode). If it is not owned by anyone, no player needs to be attached. If that
 fails, the script will come to a halt.
 fails, the script will come to a halt.
 
 
@@ -8481,7 +8482,7 @@ Broadcasts a message to all players in the instance <instance id> currently
 residing on an instance map. If 0 is specified for <instance id>, the instance
 residing on an instance map. If 0 is specified for <instance id>, the instance
 the script is attached to is used. If the script is not attached to an instance,
 the script is attached to is used. If the script is not attached to an instance,
 the instance of the currently attached player is used (if it is a character,
 the instance of the currently attached player is used (if it is a character,
-party, or guild mode). If it is not owned by anyone, no player needs to be attached.
+party, guild or clan mode). If it is not owned by anyone, no player needs to be attached.
 
 
 For details on the other parameters, see 'announce'.
 For details on the other parameters, see 'announce'.
 
 
@@ -8531,6 +8532,28 @@ if (instance_check_guild(getcharid(2),2,2,149)) {
 
 
 ---------------------------------------
 ---------------------------------------
 
 
+*instance_check_clan(<clan id>{,<amount>{,<min>{,<max>}}})
+
+This function checks if a clan meets certain requirements, returning 1 if all
+conditions are met and 0 otherwise. It will only check online characters.
+
+amount - number of online clan members (default is 1).
+min    - minimum level of all characters in the clan (default is 1).
+max    - maximum level of all characters in the clan (default is max level in conf).
+
+Example:
+
+if (instance_check_clan(getcharid(5),2,2,149)) {
+	mes "Your clan meets the Memorial Dungeon requirements.",
+	mes "All online members are between levels 1-150 and at least two are online.";
+	close;
+} else {
+	mes "Sorry, your clan does not meet requirements.";
+	close;
+}
+
+---------------------------------------
+
 *instance_info("<instance name>",<info type>{,<instance_db map index>});
 *instance_info("<instance name>",<info type>{,<instance_db map index>});
 
 
 Returns the specified <info type> of the given <instance name> from the instance database.
 Returns the specified <info type> of the given <instance name> from the instance database.

+ 1 - 0
src/common/mmo.h

@@ -917,6 +917,7 @@ struct clan{
 	short max_member, connect_member;
 	short max_member, connect_member;
 	struct map_session_data *members[MAX_CLAN];
 	struct map_session_data *members[MAX_CLAN];
 	struct clan_alliance alliance[MAX_CLANALLIANCE];
 	struct clan_alliance alliance[MAX_CLANALLIANCE];
+	unsigned short instance_id;
 };
 };
 
 
 // Sanity checks...
 // Sanity checks...

+ 95 - 36
src/map/instance.c

@@ -81,6 +81,9 @@ void instance_getsd(unsigned short instance_id, struct map_session_data **sd, en
 			(*sd) = map_charid2sd(instance_data[instance_id].owner_id);
 			(*sd) = map_charid2sd(instance_data[instance_id].owner_id);
 			(*target) = SELF;
 			(*target) = SELF;
 			break;
 			break;
+		case IM_CLAN:
+			(*sd) = clan_getavailablesd(clan_search(instance_data[instance_id].owner_id));
+			(*target) = CLAN;
 	}
 	}
 	return;
 	return;
 }
 }
@@ -103,8 +106,9 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
 	int i, ret;
 	int i, ret;
 	unsigned short instance_id = instance_wait.id[0];
 	unsigned short instance_id = instance_wait.id[0];
 	struct map_session_data *sd = NULL;
 	struct map_session_data *sd = NULL;
-	struct party_data *p = NULL;
-	struct guild *g = NULL;
+	struct party_data *pd = NULL;
+	struct guild *gd = NULL;
+	struct clan *cd = NULL;
 	enum instance_mode mode;
 	enum instance_mode mode;
 
 
 	if(instance_wait.count == 0 || instance_id == 0)
 	if(instance_wait.count == 0 || instance_id == 0)
@@ -122,11 +126,15 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
 				clif_instance_changewait(instance_id, 0xffff);
 				clif_instance_changewait(instance_id, 0xffff);
 			break;
 			break;
 		case IM_PARTY:
 		case IM_PARTY:
-			if (ret == 0 && (p = party_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell party to wait
+			if (ret == 0 && (pd = party_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell party to wait
 				clif_instance_changewait(instance_id, 0xffff);
 				clif_instance_changewait(instance_id, 0xffff);
 			break;
 			break;
 		case IM_GUILD:
 		case IM_GUILD:
-			if (ret == 0 && (g = guild_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell guild to wait
+			if (ret == 0 && (gd = guild_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell guild to wait
+				clif_instance_changewait(instance_id, 0xffff);
+			break;
+		case IM_CLAN:
+			if (ret == 0 && (cd = clan_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell clan to wait
 				clif_instance_changewait(instance_id, 0xffff);
 				clif_instance_changewait(instance_id, 0xffff);
 			break;
 			break;
 		default:
 		default:
@@ -139,7 +147,7 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
 
 
 	for(i = 0; i < instance_wait.count; i++) {
 	for(i = 0; i < instance_wait.count; i++) {
 		if(	instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
 		if(	instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
-			((mode == IM_CHAR && sd != NULL) || (mode == IM_GUILD && g != NULL) || (mode == IM_PARTY && p != NULL))
+			((mode == IM_CHAR && sd != NULL) || (mode == IM_GUILD && gd != NULL) || (mode == IM_PARTY && pd != NULL) || (mode == IM_CLAN && cd != NULL))
 		){
 		){
 			clif_instance_changewait(instance_id, i + 1);
 			clif_instance_changewait(instance_id, i + 1);
 		}
 		}
@@ -188,6 +196,10 @@ static int instance_startkeeptimer(struct instance_data *im, unsigned short inst
 			if (guild_search(im->owner_id) != NULL) // Notify guild of the added instance timer
 			if (guild_search(im->owner_id) != NULL) // Notify guild of the added instance timer
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 			break;
 			break;
+		case IM_CLAN:
+			if (clan_search(im->owner_id) != NULL) // Notify clan of the added instance timer
+				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
+			break;
 		default:
 		default:
 			return 1;
 			return 1;
 	}
 	}
@@ -231,6 +243,10 @@ static int instance_startidletimer(struct instance_data *im, unsigned short inst
 			if (guild_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify guild of added instance timer
 			if (guild_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify guild of added instance timer
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 			break;
 			break;
+		case IM_CLAN:
+			if (clan_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify clan of added instance timer
+				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
+			break;
 		default:
 		default:
 			return 1;
 			return 1;
 	}
 	}
@@ -269,6 +285,10 @@ static int instance_stopidletimer(struct instance_data *im, unsigned short insta
 			if (guild_search(im->owner_id) != NULL) // Notify the guild
 			if (guild_search(im->owner_id) != NULL) // Notify the guild
 				clif_instance_changestatus(instance_id, 0, im->idle_limit);
 				clif_instance_changestatus(instance_id, 0, im->idle_limit);
 			break;
 			break;
+		case IM_CLAN:
+			if (clan_search(im->owner_id) != NULL) // Notify the clan
+				clif_instance_changestatus(instance_id, 0, im->idle_limit);
+			break;
 		default:
 		default:
 			return 1;
 			return 1;
 	}
 	}
@@ -342,8 +362,9 @@ void instance_addnpc(struct instance_data *im)
 int instance_create(int owner_id, const char *name, enum instance_mode mode) {
 int instance_create(int owner_id, const char *name, enum instance_mode mode) {
 	struct instance_db *db = instance_searchname_db(name);
 	struct instance_db *db = instance_searchname_db(name);
 	struct map_session_data *sd = NULL;
 	struct map_session_data *sd = NULL;
-	struct party_data *p = NULL;
-	struct guild *g = NULL;
+	struct party_data *pd = NULL;
+	struct guild *gd = NULL;
+	struct clan* cd = NULL;
 	unsigned short i;
 	unsigned short i;
 
 
 	nullpo_retr(-1, db);
 	nullpo_retr(-1, db);
@@ -360,21 +381,29 @@ int instance_create(int owner_id, const char *name, enum instance_mode mode) {
 				return -3; // Player already instancing
 				return -3; // Player already instancing
 			break;
 			break;
 		case IM_PARTY:
 		case IM_PARTY:
-			if ((p = party_search(owner_id)) == NULL) {
+			if ((pd = party_search(owner_id)) == NULL) {
 				ShowError("instance_create: party %d not found for instance '%s'.\n", owner_id, name);
 				ShowError("instance_create: party %d not found for instance '%s'.\n", owner_id, name);
 				return -2;
 				return -2;
 			}
 			}
-			if (p->instance_id)
+			if (pd->instance_id)
 				return -3; // Party already instancing
 				return -3; // Party already instancing
 			break;
 			break;
 		case IM_GUILD:
 		case IM_GUILD:
-			if ((g = guild_search(owner_id)) == NULL) {
+			if ((gd = guild_search(owner_id)) == NULL) {
 				ShowError("instance_create: guild %d not found for instance '%s'.\n", owner_id, name);
 				ShowError("instance_create: guild %d not found for instance '%s'.\n", owner_id, name);
 				return -2;
 				return -2;
 			}
 			}
-			if (g->instance_id)
+			if (gd->instance_id)
 				return -3; // Guild already instancing
 				return -3; // Guild already instancing
 			break;
 			break;
+		case IM_CLAN:
+			if ((cd = clan_search(owner_id)) == NULL) {
+				ShowError("instance_create: clan %d not found for instance '%s'.\n", owner_id, name);
+				return -2;
+			}
+			if (cd->instance_id)
+				return -3; // Clan already instancing
+			break;
 		default:
 		default:
 			ShowError("instance_create: unknown mode %u for owner_id %d and name %s.\n", mode, owner_id, name);
 			ShowError("instance_create: unknown mode %u for owner_id %d and name %s.\n", mode, owner_id, name);
 			return -2;
 			return -2;
@@ -403,10 +432,13 @@ int instance_create(int owner_id, const char *name, enum instance_mode mode) {
 			sd->instance_id = i;
 			sd->instance_id = i;
 			break;
 			break;
 		case IM_PARTY:
 		case IM_PARTY:
-			p->instance_id = i;
+			pd->instance_id = i;
 			break;
 			break;
 		case IM_GUILD:
 		case IM_GUILD:
-			g->instance_id = i;
+			gd->instance_id = i;
+			break;
+		case IM_CLAN:
+			cd->instance_id = i;
 			break;
 			break;
 	}
 	}
 
 
@@ -499,6 +531,10 @@ int instance_addmap(unsigned short instance_id) {
 			if (guild_search(im->owner_id) != NULL) // Inform guild members of the created instance
 			if (guild_search(im->owner_id) != NULL) // Inform guild members of the created instance
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
 			break;
 			break;
+		case IM_CLAN:
+			if (clan_search(im->owner_id) != NULL) // Inform clan members of the created instance
+				clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
+			break;
 		default:
 		default:
 			return 0;
 			return 0;
 	}
 	}
@@ -555,8 +591,9 @@ int instance_destroy(unsigned short instance_id)
 {
 {
 	struct instance_data *im;
 	struct instance_data *im;
 	struct map_session_data *sd = NULL;
 	struct map_session_data *sd = NULL;
-	struct party_data *p = NULL;
-	struct guild *g = NULL;
+	struct party_data *pd = NULL;
+	struct guild *gd = NULL;
+	struct clan *cd = NULL;
 	int i, type = 0;
 	int i, type = 0;
 	unsigned int now = (unsigned int)time(NULL);
 	unsigned int now = (unsigned int)time(NULL);
 	enum instance_mode mode;
 	enum instance_mode mode;
@@ -577,10 +614,13 @@ int instance_destroy(unsigned short instance_id)
 			sd = map_charid2sd(im->owner_id);
 			sd = map_charid2sd(im->owner_id);
 			break;
 			break;
 		case IM_PARTY:
 		case IM_PARTY:
-			p = party_search(im->owner_id);
+			pd = party_search(im->owner_id);
 			break;
 			break;
 		case IM_GUILD:
 		case IM_GUILD:
-			g = guild_search(im->owner_id);
+			gd = guild_search(im->owner_id);
+			break;
+		case IM_CLAN:
+			cd = clan_search(im->owner_id);
 			break;
 			break;
 	}
 	}
 
 
@@ -593,7 +633,7 @@ int instance_destroy(unsigned short instance_id)
 
 
 				for(i = 0; i < instance_wait.count; i++)
 				for(i = 0; i < instance_wait.count; i++)
 					if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
 					if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
-						if ((mode == IM_CHAR && sd) || (mode == IM_PARTY && p) || (mode == IM_GUILD && g))
+						if ((mode == IM_CHAR && sd) || (mode == IM_PARTY && pd) || (mode == IM_GUILD && gd) || (mode == IM_CLAN && cd))
 							clif_instance_changewait(instance_id, i + 1);
 							clif_instance_changewait(instance_id, i + 1);
 
 
 				if(instance_wait.count)
 				if(instance_wait.count)
@@ -637,10 +677,12 @@ int instance_destroy(unsigned short instance_id)
 
 
 	if (mode == IM_CHAR && sd)
 	if (mode == IM_CHAR && sd)
 		sd->instance_id = 0;
 		sd->instance_id = 0;
-	else if (mode == IM_PARTY && p)
-		p->instance_id = 0;
-	else if (mode == IM_GUILD && g)
-		g->instance_id = 0;
+	else if (mode == IM_PARTY && pd)
+		pd->instance_id = 0;
+	else if (mode == IM_GUILD && gd)
+		gd->instance_id = 0;
+	else if (mode == IM_CLAN && cd)
+		cd->instance_id = 0;
 
 
 	if (mode != IM_NONE) {
 	if (mode != IM_NONE) {
 		if(type)
 		if(type)
@@ -671,8 +713,9 @@ enum e_instance_enter instance_enter(struct map_session_data *sd, unsigned short
 {
 {
 	struct instance_data *im = NULL;
 	struct instance_data *im = NULL;
 	struct instance_db *db = NULL;
 	struct instance_db *db = NULL;
-	struct party_data *p = NULL;
-	struct guild *g = NULL;
+	struct party_data *pd = NULL;
+	struct guild *gd = NULL;
+	struct clan *cd = NULL;
 	enum instance_mode mode;
 	enum instance_mode mode;
 	int16 m;
 	int16 m;
 
 
@@ -710,21 +753,31 @@ enum e_instance_enter instance_enter(struct map_session_data *sd, unsigned short
 		case IM_PARTY:
 		case IM_PARTY:
 			if (sd->status.party_id == 0) // Character must be in instance party
 			if (sd->status.party_id == 0) // Character must be in instance party
 				return IE_NOMEMBER;
 				return IE_NOMEMBER;
-			if ((p = party_search(sd->status.party_id)) == NULL)
+			if ((pd = party_search(sd->status.party_id)) == NULL)
 				return IE_NOMEMBER;
 				return IE_NOMEMBER;
-			if (p->instance_id == 0 || im == NULL) // Party must have an instance
+			if (pd->instance_id == 0 || im == NULL) // Party must have an instance
 				return IE_NOINSTANCE;
 				return IE_NOINSTANCE;
-			if (im->owner_id != p->party.party_id)
+			if (im->owner_id != pd->party.party_id)
 				return IE_OTHER;
 				return IE_OTHER;
 			break;
 			break;
 		case IM_GUILD:
 		case IM_GUILD:
 			if (sd->status.guild_id == 0) // Character must be in instance guild
 			if (sd->status.guild_id == 0) // Character must be in instance guild
 				return IE_NOMEMBER;
 				return IE_NOMEMBER;
-			if ((g = guild_search(sd->status.guild_id)) == NULL)
+			if ((gd = guild_search(sd->status.guild_id)) == NULL)
 				return IE_NOMEMBER;
 				return IE_NOMEMBER;
-			if (g->instance_id == 0) // Guild must have an instance
+			if (gd->instance_id == 0) // Guild must have an instance
 				return IE_NOINSTANCE;
 				return IE_NOINSTANCE;
-			if (im->owner_id != g->guild_id)
+			if (im->owner_id != gd->guild_id)
+				return IE_OTHER;
+			break;
+		case IM_CLAN:
+			if (sd->status.clan_id == 0) // Character must be in instance clan
+				return IE_NOMEMBER;
+			if ((cd = clan_search(sd->status.clan_id)) == NULL)
+				return IE_NOMEMBER;
+			if (cd->instance_id == 0) // Clan must have an instance
+				return IE_NOINSTANCE;
+			if (im->owner_id != cd->id)
 				return IE_OTHER;
 				return IE_OTHER;
 			break;
 			break;
 	}
 	}
@@ -1027,8 +1080,9 @@ void do_reload_instance(void)
 	iter = mapit_getallusers();
 	iter = mapit_getallusers();
 	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
 	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
 		if(sd && map[sd->bl.m].instance_id) {
 		if(sd && map[sd->bl.m].instance_id) {
-			struct party_data *p = NULL;
-			struct guild *g = NULL;
+			struct party_data *pd = NULL;
+			struct guild *gd = NULL;
+			struct clan *cd = NULL;
 			unsigned short instance_id;
 			unsigned short instance_id;
 
 
 			im = &instance_data[map[sd->bl.m].instance_id];
 			im = &instance_data[map[sd->bl.m].instance_id];
@@ -1041,14 +1095,19 @@ void do_reload_instance(void)
 					instance_id = sd->instance_id;
 					instance_id = sd->instance_id;
 					break;
 					break;
 				case IM_PARTY:
 				case IM_PARTY:
-					if ((!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
+					if ((!(pd = party_search(sd->status.party_id)) || pd->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
 						continue;
 						continue;
-					instance_id = p->instance_id;
+					instance_id = pd->instance_id;
 					break;
 					break;
 				case IM_GUILD:
 				case IM_GUILD:
-					if (!(g = guild_search(sd->status.guild_id)) || g->instance_id != map[sd->bl.m].instance_id) // Someone not in guild is on instance map
+					if (!(gd = guild_search(sd->status.guild_id)) || gd->instance_id != map[sd->bl.m].instance_id) // Someone not in guild is on instance map
+						continue;
+					instance_id = gd->instance_id;
+					break;
+				case IM_CLAN:
+					if (!(cd = clan_search(sd->status.clan_id)) || cd->instance_id != map[sd->bl.m].instance_id) // Someone not in clan is on instance map
 						continue;
 						continue;
-					instance_id = g->instance_id;
+					instance_id = cd->instance_id;
 					break;
 					break;
 				default:
 				default:
 					ShowError("do_reload_instance: Unexpected instance mode for instance %s (id=%u, mode=%u).\n", (db) ? StringBuf_Value(db->name) : "Unknown", map[sd->bl.m].instance_id, (unsigned short)im->mode);
 					ShowError("do_reload_instance: Unexpected instance mode for instance %s (id=%u, mode=%u).\n", (db) ? StringBuf_Value(db->name) : "Unknown", map[sd->bl.m].instance_id, (unsigned short)im->mode);

+ 1 - 0
src/map/instance.h

@@ -25,6 +25,7 @@ enum instance_mode {
 	IM_CHAR,
 	IM_CHAR,
 	IM_PARTY,
 	IM_PARTY,
 	IM_GUILD,
 	IM_GUILD,
+	IM_CLAN,
 	IM_MAX,
 	IM_MAX,
 };
 };
 
 

+ 79 - 6
src/map/script.c

@@ -19523,16 +19523,19 @@ unsigned short script_instancegetid(struct script_state* st)
 		instance_id = nd->instance_id;
 		instance_id = nd->instance_id;
 	else {
 	else {
 		struct map_session_data *sd = NULL;
 		struct map_session_data *sd = NULL;
-		struct party_data *p = NULL;
-		struct guild *g = NULL;
+		struct party_data *pd = NULL;
+		struct guild *gd = NULL;
+		struct clan *cd = NULL;
 
 
 		if (script_rid2sd(sd)) {
 		if (script_rid2sd(sd)) {
 			if (sd->instance_id)
 			if (sd->instance_id)
 				instance_id = sd->instance_id;
 				instance_id = sd->instance_id;
-			if (instance_id == 0 && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id)
-				instance_id = p->instance_id;
-			if (instance_id == 0 && sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL && g->instance_id)
-				instance_id = g->instance_id;
+			if (instance_id == 0 && sd->status.party_id && (pd = party_search(sd->status.party_id)) != NULL && pd->instance_id)
+				instance_id = pd->instance_id;
+			if (instance_id == 0 && sd->status.guild_id && (gd = guild_search(sd->status.guild_id)) != NULL && gd->instance_id)
+				instance_id = gd->instance_id;
+			if (instance_id == 0 && sd->status.clan_id && (cd = clan_search(sd->status.clan_id)) != NULL && cd->instance_id)
+				instance_id = cd->instance_id;
 		}
 		}
 	}
 	}
 
 
@@ -19578,6 +19581,10 @@ BUILDIN_FUNC(instance_create)
 				if (script_rid2sd(sd))
 				if (script_rid2sd(sd))
 					owner_id = sd->status.guild_id;
 					owner_id = sd->status.guild_id;
 				break;
 				break;
+			case IM_CLAN:
+				if (script_rid2sd(sd))
+					owner_id = sd->status.clan_id;
+				break;
 			default:
 			default:
 				ShowError("buildin_instance_create: Invalid instance mode (instance name: %s)\n", script_getstr(st, 2));
 				ShowError("buildin_instance_create: Invalid instance mode (instance name: %s)\n", script_getstr(st, 2));
 				return SCRIPT_CMD_FAILURE;
 				return SCRIPT_CMD_FAILURE;
@@ -19742,6 +19749,9 @@ static int buildin_instance_warpall_sub(struct block_list *bl, va_list ap)
 		case IM_GUILD:
 		case IM_GUILD:
 			if (sd->status.guild_id != owner_id)
 			if (sd->status.guild_id != owner_id)
 				return 0;
 				return 0;
+		case IM_CLAN:
+			if (sd->status.clan_id != owner_id)
+				return 0;
 	}
 	}
 
 
 	pc_setpos(sd, m, x, y, CLR_TELEPORT);
 	pc_setpos(sd, m, x, y, CLR_TELEPORT);
@@ -19927,6 +19937,68 @@ BUILDIN_FUNC(instance_check_guild)
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
+/*==========================================
+ * instance_check_clan
+ * Values:
+ * clan_id : Clan ID of the invoking character. [Required Parameter]
+ * amount : Amount of needed Clan members for the Instance. [Optional Parameter]
+ * min : Minimum Level needed to join the Instance. [Optional Parameter]
+ * max : Maxium Level allowed to join the Instance. [Optional Parameter]
+ * Example: instance_check_clan (getcharid(5){,amount}{,min}{,max});
+ * Example 2: instance_check_clan (getcharid(5),1,1,99);
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_check_clan)
+{
+	int amount, min, max, i, clan_id = 0, c = 0;
+	struct clan *cd = NULL;
+
+	amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Clan members for the Instance.
+	min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
+	max  = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance.
+
+	if (min < 1 || min > MAX_LEVEL) {
+		ShowError("buildin_instance_check_clan: Invalid min level, %d\n", min);
+		return SCRIPT_CMD_FAILURE;
+	} else if (max < 1 || max > MAX_LEVEL) {
+		ShowError("buildin_instance_check_clan: Invalid max level, %d\n", max);
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	if (script_hasdata(st,2))
+		clan_id = script_getnum(st,2);
+	else
+		return SCRIPT_CMD_FAILURE;
+
+	if (!(cd = clan_search(clan_id))) {
+		script_pushint(st, 0); // Returns false if clan does not exist.
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	for(i = 0; i < MAX_CLAN; i++) {
+		struct map_session_data *pl_sd;
+
+		if ((pl_sd = cd->members[i])) {
+			if (map_id2bl(pl_sd->bl.id)) {
+				if (pl_sd->status.base_level < min) {
+					script_pushint(st, 0);
+					return SCRIPT_CMD_SUCCESS;
+				} else if (pl_sd->status.base_level > max) {
+					script_pushint(st, 0);
+					return SCRIPT_CMD_SUCCESS;
+				}
+				c++;
+			}
+		}
+	}
+
+	if (c < amount)
+		script_pushint(st, 0); // Not enough Members in the Clan to join Instance.
+	else
+		script_pushint(st, 1);
+
+	return SCRIPT_CMD_SUCCESS;
+}
+
 /*==========================================
 /*==========================================
 * instance_info
 * instance_info
 * Values:
 * Values:
@@ -23520,6 +23592,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(instance_announce,"isi?????"),
 	BUILDIN_DEF(instance_announce,"isi?????"),
 	BUILDIN_DEF(instance_check_party,"i???"),
 	BUILDIN_DEF(instance_check_party,"i???"),
 	BUILDIN_DEF(instance_check_guild,"i???"),
 	BUILDIN_DEF(instance_check_guild,"i???"),
+	BUILDIN_DEF(instance_check_clan,"i???"),
 	BUILDIN_DEF(instance_info,"si?"),
 	BUILDIN_DEF(instance_info,"si?"),
 	/**
 	/**
 	 * 3rd-related
 	 * 3rd-related

+ 1 - 0
src/map/script_constants.h

@@ -3214,6 +3214,7 @@
 	export_constant(IM_CHAR);
 	export_constant(IM_CHAR);
 	export_constant(IM_PARTY);
 	export_constant(IM_PARTY);
 	export_constant(IM_GUILD);
 	export_constant(IM_GUILD);
+	export_constant(IM_CLAN);
 
 
 	/* mob random groups */
 	/* mob random groups */
 	export_constant(MOBG_Branch_Of_Dead_Tree);
 	export_constant(MOBG_Branch_Of_Dead_Tree);