Expanded the instance system to support new modes
* New modes include: No player attached, single player, and guild. * Expanded script command instance_create to take in an owner ID and an optional mode. * Added a new script command instance_check_guild (works the same as instance_check_party). * Refactored all instance_id to unsigned short.
This commit is contained in:
parent
4c617bcd59
commit
c97be60bbf
@ -472,8 +472,8 @@ nothing - A permanent variable attached to the character, the default variable
|
||||
ends it. When a scope ends, its variables are converted to values
|
||||
('return .@var;' returns a value, not a reference).
|
||||
"'" - An instance variable.
|
||||
These are used with the instancing system, and are unique to each
|
||||
party's instance.
|
||||
These are used with the instancing system and are unique to each
|
||||
instance type.
|
||||
"#" - A permanent local account variable.
|
||||
They are stored by char-server in the `acc_reg_num` table and
|
||||
`acc_reg_str`.
|
||||
@ -503,6 +503,8 @@ $@name$ - temporary global string variable
|
||||
.name$ - NPC string variable
|
||||
.@name - scope integer variable
|
||||
.@name$ - scope string variable
|
||||
'name - instance integer variable
|
||||
'name$ - instance string variable
|
||||
#name - permanent local account integer variable
|
||||
#name$ - permanent local account string variable
|
||||
##name - permanent global account integer variable
|
||||
@ -8111,13 +8113,19 @@ This command will open a book item at the specified page.
|
||||
========================
|
||||
---------------------------------------
|
||||
|
||||
*instance_create("<instance name>");
|
||||
*instance_create("<instance name>",<owner_id>{,<mode>});
|
||||
|
||||
Creates an instance for the party of the attached player. The instance name,
|
||||
along with all other instance data, is read from 'db/(pre-)re/instance_db.txt'.
|
||||
Upon success, the command generates a unique instance ID, duplicates all listed
|
||||
maps and NPCs, sets the alive time, and triggers the "OnInstanceInit" label in
|
||||
all NPCs inside the instance.
|
||||
Creates an instance for the <owner_id> of <mode>. The instance name, along with
|
||||
all other instance data, is read from 'db/(pre-)re/instance_db.txt'. Upon success,
|
||||
the command generates a unique instance ID, duplicates all listed maps and NPCs,
|
||||
sets the alive time, and triggers the "OnInstanceInit" label in all NPCs inside
|
||||
the instance.
|
||||
|
||||
Instance Mode options:
|
||||
IM_NONE: Attached to no one.
|
||||
IM_CHAR: Attached to a single character.
|
||||
IM_PARTY: Attached to a party (default instance mode).
|
||||
IM_GUILD: Attached to a guild.
|
||||
|
||||
The command returns the instance ID upon success, and these values upon failure:
|
||||
-1: Invalid type.
|
||||
@ -8131,8 +8139,9 @@ 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
|
||||
the script is attached to is used. If the script is not attached to an instance,
|
||||
the instance of the currently attached player's party is used. If that fails,
|
||||
the script will come to a halt.
|
||||
the instance of the currently attached player is used (if it is a party or guild
|
||||
mode). If it is not owned by anyone, no player needs to be attached. If that
|
||||
fails, the script will come to a halt.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -8142,9 +8151,9 @@ Warps player to the specified instance after the script terminates. The map and
|
||||
coordinates are located in 'db/(pre-)re/instance_db.txt'.
|
||||
|
||||
The command returns 0 upon success, and these values upon failure:
|
||||
1: Party not found.
|
||||
2: Party does not have an instance.
|
||||
3: Other errors (invalid instance name, instance doesn't match with party).
|
||||
1: Party/Guild not found (for party/guild modes).
|
||||
2: Character/Party/Guild does not have an instance.
|
||||
3: Other errors (invalid instance name, instance doesn't match with character/party/guild).
|
||||
|
||||
Put -1 for x and y if want to warp player with default entrance coordinates.
|
||||
|
||||
@ -8163,16 +8172,18 @@ that fails, the script will come to a halt.
|
||||
|
||||
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
|
||||
an instance, the instance of the currently attached player's party is used. If
|
||||
that fails, the command returns an empty string instead.
|
||||
an instance, the instance of the currently attached player is used (if it is a
|
||||
party or guild mode). If it is not owned by anyone, no player needs to be
|
||||
attached. If that fails, the command returns an empty string instead.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*instance_id()
|
||||
|
||||
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's party is
|
||||
used. If that fails, the function will return 0.
|
||||
attached to an instance, the instance of the currently attached player is
|
||||
used (if it is a party or guild mode). If it is not owned by anyone, no
|
||||
player needs to be attached. If that fails, the function will return 0.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -8181,8 +8192,9 @@ used. If that fails, the function will return 0.
|
||||
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
|
||||
is used. If the script is not attached to an instance, the instance of the
|
||||
currently attached player's party is used. If that fails, the script will
|
||||
come to a halt.
|
||||
currently attached player is used (if it is a party or guild mode). If it
|
||||
is not owned by anyone, no player needs to be attached. If that
|
||||
fails, the script will come to a halt.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -8191,7 +8203,8 @@ come to a halt.
|
||||
Broadcasts a message to all players in the instance <instance id> currently
|
||||
residing on an instance map. If -1 is specified for <instance id>, 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's party is used.
|
||||
the instance of the currently attached player is used (if it is a party or guild
|
||||
mode). If it is not owned by anyone, no player needs to be attached.
|
||||
|
||||
For details on the other parameters, see 'announce'.
|
||||
|
||||
@ -8219,6 +8232,28 @@ if (instance_check_party(getcharid(1),2,2,149)) {
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*instance_check_guild(<guild id>{,<amount>{,<min>{,<max>}}})
|
||||
|
||||
This function checks if a guild meets certain requirements, returning 1 if all
|
||||
conditions are met and 0 otherwise. It will only check online characters.
|
||||
|
||||
amount - number of online guild members (default is 1).
|
||||
min - minimum level of all characters in the guild (default is 1).
|
||||
max - maximum level of all characters in the guild (default is max level in conf).
|
||||
|
||||
Example:
|
||||
|
||||
if (instance_check_guild(getcharid(2),2,2,149)) {
|
||||
mes "Your guild 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 guild does not meet requirements.";
|
||||
close;
|
||||
}
|
||||
|
||||
---------------------------------------
|
||||
|
||||
=========================
|
||||
|8.- Quest Log commands.|
|
||||
=========================
|
||||
|
@ -563,6 +563,7 @@ struct guild {
|
||||
struct guild_expulsion expulsion[MAX_GUILDEXPULSION];
|
||||
struct guild_skill skill[MAX_GUILDSKILL];
|
||||
struct Channel *channel;
|
||||
unsigned short instance_id;
|
||||
|
||||
/* Used by char-server to save events for guilds */
|
||||
unsigned short save_flag;
|
||||
|
@ -16572,80 +16572,99 @@ void clif_font(struct map_session_data *sd)
|
||||
}
|
||||
|
||||
|
||||
/*==========================================
|
||||
* Notifies party members of instance change
|
||||
*------------------------------------------*/
|
||||
void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag)
|
||||
/// Required to start the instancing information window on Client
|
||||
/// This window re-appears each "refresh" of client automatically until the keep_limit reaches 0.
|
||||
/// S 0x2cb <Instance name>.61B <Standby Position>.W
|
||||
void clif_instance_create(unsigned short instance_id, int num)
|
||||
{
|
||||
#if PACKETVER >= 20071128
|
||||
struct map_session_data *sd = NULL;
|
||||
enum send_target target = PARTY;
|
||||
unsigned char buf[65];
|
||||
|
||||
if(!sd) return;
|
||||
instance_getsd(instance_id, &sd, &target);
|
||||
|
||||
if (!sd)
|
||||
return;
|
||||
|
||||
WBUFW(buf,0) = 0x2cb;
|
||||
memcpy( WBUFP(buf,2), name, 62 );
|
||||
memcpy(WBUFP(buf,2), instance_data[instance_id].name, 62);
|
||||
WBUFW(buf,63) = num;
|
||||
if(flag) // A timer has changed or been added
|
||||
clif_send(buf,packet_len(0x2cb),&sd->bl,PARTY);
|
||||
else // No notification
|
||||
clif_send(buf,packet_len(0x2cb),&sd->bl,SELF);
|
||||
clif_send(buf,packet_len(0x2cb),&sd->bl,target);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void clif_instance_changewait(struct map_session_data *sd, int num, int flag)
|
||||
/// To announce Instancing queue creation if no maps available
|
||||
/// S 0x2cc <Standby Position>.W
|
||||
void clif_instance_changewait(unsigned short instance_id, int num)
|
||||
{
|
||||
#if PACKETVER >= 20071128
|
||||
struct map_session_data *sd = NULL;
|
||||
enum send_target target = PARTY;
|
||||
unsigned char buf[4];
|
||||
|
||||
if(!sd) return;
|
||||
instance_getsd(instance_id, &sd, &target);
|
||||
|
||||
if (!sd)
|
||||
return;
|
||||
|
||||
WBUFW(buf,0) = 0x2cc;
|
||||
WBUFW(buf,2) = num;
|
||||
if(flag) // A timer has changed or been added
|
||||
clif_send(buf,packet_len(0x2cc),&sd->bl,PARTY);
|
||||
else // No notification
|
||||
clif_send(buf,packet_len(0x2cc),&sd->bl,SELF);
|
||||
clif_send(buf,packet_len(0x2cc),&sd->bl,target);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag)
|
||||
/// Notify the current status to members
|
||||
/// S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
|
||||
void clif_instance_status(unsigned short instance_id, unsigned int limit1, unsigned int limit2)
|
||||
{
|
||||
#if PACKETVER >= 20071128
|
||||
struct map_session_data *sd = NULL;
|
||||
enum send_target target = PARTY;
|
||||
unsigned char buf[71];
|
||||
|
||||
if(!sd) return; //party_getavailablesd can return NULL
|
||||
instance_getsd(instance_id, &sd, &target);
|
||||
|
||||
if (!sd)
|
||||
return;
|
||||
|
||||
WBUFW(buf,0) = 0x2cd;
|
||||
memcpy( WBUFP(buf,2), name, 62 );
|
||||
memcpy(WBUFP(buf,2), instance_data[instance_id].name, 62);
|
||||
WBUFL(buf,63) = limit1;
|
||||
WBUFL(buf,67) = limit2;
|
||||
if(flag) // A timer has changed or been added
|
||||
clif_send(buf,packet_len(0x2cd),&sd->bl,PARTY);
|
||||
else // No notification
|
||||
clif_send(buf,packet_len(0x2cd),&sd->bl,SELF);
|
||||
clif_send(buf,packet_len(0x2cd),&sd->bl,target);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag)
|
||||
/// Notify a status change to members
|
||||
/// S 0x2ce <Message ID>.L
|
||||
/// 0 = Notification (EnterLimitDate update?)
|
||||
/// 1 = The Memorial Dungeon expired; it has been destroyed
|
||||
/// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
|
||||
/// 3 = The Memorial Dungeon has been removed.
|
||||
/// 4 = Create failure (removes the instance window)
|
||||
void clif_instance_changestatus(unsigned int instance_id, int type, unsigned int limit)
|
||||
{
|
||||
#if PACKETVER >= 20071128
|
||||
struct map_session_data *sd = NULL;
|
||||
enum send_target target = PARTY;
|
||||
unsigned char buf[10];
|
||||
|
||||
if(!sd) return;
|
||||
instance_getsd(instance_id, &sd, &target);
|
||||
|
||||
if (!sd)
|
||||
return;
|
||||
|
||||
WBUFW(buf,0) = 0x2ce;
|
||||
WBUFL(buf,2) = type;
|
||||
WBUFL(buf,6) = limit;
|
||||
if(flag) // A timer has changed or been added
|
||||
clif_send(buf,packet_len(0x2ce),&sd->bl,PARTY);
|
||||
else // No notification
|
||||
clif_send(buf,packet_len(0x2ce),&sd->bl,SELF);
|
||||
clif_send(buf,packet_len(0x2ce),&sd->bl,target);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
@ -745,10 +745,10 @@ void clif_sendbgemblem_area(struct map_session_data *sd);
|
||||
void clif_sendbgemblem_single(int fd, struct map_session_data *sd);
|
||||
|
||||
// Instancing
|
||||
void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag);
|
||||
void clif_instance_changewait(struct map_session_data *sd, int num, int flag);
|
||||
void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag);
|
||||
void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag);
|
||||
void clif_instance_create(unsigned short instance_id, int num);
|
||||
void clif_instance_changewait(unsigned short instance_id, int num);
|
||||
void clif_instance_status(unsigned short instance_id, unsigned int limit1, unsigned int limit2);
|
||||
void clif_instance_changestatus(unsigned int instance_id, int type, unsigned int limit);
|
||||
|
||||
// Custom Fonts
|
||||
void clif_font(struct map_session_data *sd);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "battle.h"
|
||||
#include "npc.h"
|
||||
#include "pc.h"
|
||||
#include "instance.h"
|
||||
#include "intif.h"
|
||||
#include "channel.h"
|
||||
#include "log.h"
|
||||
@ -551,6 +552,8 @@ int guild_recv_info(struct guild *sg) {
|
||||
clif_guild_notice(sd, g);
|
||||
sd->guild_emblem_id = g->emblem_id;
|
||||
}
|
||||
if (g->instance_id != 0)
|
||||
instance_reqinfo(sd, g->instance_id);
|
||||
}
|
||||
|
||||
//Occurrence of an event
|
||||
@ -694,6 +697,8 @@ void guild_member_joined(struct map_session_data *sd) {
|
||||
g->member[i].sd = sd;
|
||||
sd->guild = g;
|
||||
|
||||
if (g->instance_id != 0)
|
||||
instance_reqinfo(sd, g->instance_id);
|
||||
if( channel_config.ally_enable && channel_config.ally_autojoin ) {
|
||||
channel_gjoin(sd,3);
|
||||
}
|
||||
@ -744,6 +749,9 @@ int guild_member_added(int guild_id,uint32 account_id,uint32 char_id,int flag) {
|
||||
//Next line commented because it do nothing, look at guild_recv_info [LuzZza]
|
||||
//clif_charnameupdate(sd); //Update display name [Skotlex]
|
||||
|
||||
if (g->instance_id != 0)
|
||||
instance_reqinfo(sd, g->instance_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -860,6 +868,17 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f
|
||||
sd->guild = NULL;
|
||||
sd->guild_emblem_id = 0;
|
||||
|
||||
if (g->instance_id) {
|
||||
int16 m = sd->bl.m;
|
||||
|
||||
if (map[m].instance_id) { // User was on the instance map
|
||||
if (map[m].save.map)
|
||||
pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
|
||||
else
|
||||
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
|
||||
}
|
||||
}
|
||||
|
||||
clif_charnameupdate(sd); //Update display name [Skotlex]
|
||||
status_change_end(&sd->bl,SC_LEADERSHIP,INVALID_TIMER);
|
||||
status_change_end(&sd->bl,SC_GLORYWOUNDS,INVALID_TIMER);
|
||||
@ -1833,6 +1852,11 @@ int guild_break(struct map_session_data *sd,char *name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g->instance_id) {
|
||||
instance_data[g->instance_id].owner_id = 0;
|
||||
instance_destroy(g->instance_id);
|
||||
}
|
||||
|
||||
/* Regardless of char server allowing it, we clear the guild master's auras */
|
||||
if ((ud = unit_bl2ud(&sd->bl))) {
|
||||
int count = 0;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "../common/malloc.h"
|
||||
|
||||
#include "clif.h"
|
||||
#include "guild.h"
|
||||
#include "instance.h"
|
||||
#include "map.h"
|
||||
#include "npc.h"
|
||||
@ -30,7 +31,8 @@ struct instance_data instance_data[MAX_INSTANCE_DATA];
|
||||
struct instance_db {
|
||||
unsigned short id; ///< Instance ID
|
||||
StringBuf *name; ///< Instance name
|
||||
unsigned int limit; ///< Duration limit
|
||||
unsigned int limit, ///< Duration limit
|
||||
timeout; ///< Timeout limit
|
||||
struct {
|
||||
StringBuf *mapname; ///< Mapname, the limit should be MAP_NAME_LENGTH_EXT
|
||||
unsigned short x, y; ///< Map coordinates
|
||||
@ -59,6 +61,34 @@ static uint16 instance_name2id(const char *instance_name) {
|
||||
return (uint16)strdb_uiget(InstanceNameDB,instance_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a sd of an Instance
|
||||
* @param instance_id: Instance ID
|
||||
* @param sd: Player data to attach
|
||||
* @param target: Target display type
|
||||
*/
|
||||
void instance_getsd(unsigned short instance_id, struct map_session_data **sd, enum send_target *target) {
|
||||
switch(instance_data[instance_id].mode) {
|
||||
case IM_NONE:
|
||||
(*sd) = NULL;
|
||||
(*target) = SELF;
|
||||
break;
|
||||
case IM_GUILD:
|
||||
(*sd) = guild_getavailablesd(guild_search(instance_data[instance_id].owner_id));
|
||||
(*target) = GUILD;
|
||||
break;
|
||||
case IM_PARTY:
|
||||
(*sd) = party_getavailablesd(party_search(instance_data[instance_id].owner_id));
|
||||
(*target) = PARTY;
|
||||
break;
|
||||
case IM_CHAR:
|
||||
(*sd) = map_id2sd(instance_data[instance_id].owner_id);
|
||||
(*target) = SELF;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Searches for an instance name in the database
|
||||
*------------------------------------------*/
|
||||
@ -80,23 +110,42 @@ static int instance_delete_timer(int tid, unsigned int tick, int id, intptr_t da
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Create subscription timer for party
|
||||
* Create subscription timer
|
||||
*------------------------------------------*/
|
||||
static int instance_subscription_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
{
|
||||
int i, ret;
|
||||
int instance_id = instance_wait.id[0];
|
||||
struct party_data *p;
|
||||
unsigned short instance_id = instance_wait.id[0];
|
||||
struct map_session_data *sd = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
enum instance_mode mode;
|
||||
|
||||
if(instance_wait.count == 0 || instance_id <= 0)
|
||||
if(instance_wait.count == 0 || instance_id == 0)
|
||||
return 0;
|
||||
|
||||
// Check that maps have been added
|
||||
ret = instance_addmap(instance_id);
|
||||
mode = instance_data[instance_id].mode;
|
||||
|
||||
// If no maps are created, tell party to wait
|
||||
if(ret == 0 && ( p = party_search( instance_data[instance_id].party_id ) ) != NULL)
|
||||
clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
|
||||
switch(mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (ret == 0 && (sd = map_id2sd(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell player to wait
|
||||
clif_instance_changewait(instance_id, 0xffff);
|
||||
break;
|
||||
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
|
||||
clif_instance_changewait(instance_id, 0xffff);
|
||||
break;
|
||||
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
|
||||
clif_instance_changewait(instance_id, 0xffff);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
instance_wait.count--;
|
||||
memmove(&instance_wait.id[0],&instance_wait.id[1],sizeof(instance_wait.id[0])*instance_wait.count);
|
||||
@ -104,9 +153,9 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
|
||||
|
||||
for(i = 0; i < instance_wait.count; i++) {
|
||||
if( instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
|
||||
( p = party_search( instance_data[instance_wait.id[i]].party_id ) ) != NULL
|
||||
((mode == IM_CHAR && sd != NULL) || (mode == IM_GUILD && g != NULL) || (mode == IM_PARTY && p != NULL))
|
||||
){
|
||||
clif_instance_changewait( party_getavailablesd( p ), i + 1, 1 );
|
||||
clif_instance_changewait(instance_id, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,12 +168,11 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Adds timer back to party entering instance
|
||||
* Adds timer back to members entering instance
|
||||
*------------------------------------------*/
|
||||
static int instance_startkeeptimer(struct instance_data *im, short instance_id)
|
||||
static int instance_startkeeptimer(struct instance_data *im, unsigned short instance_id)
|
||||
{
|
||||
struct instance_db *db;
|
||||
struct party_data *p;
|
||||
|
||||
nullpo_retr(0, im);
|
||||
|
||||
@ -139,9 +187,24 @@ static int instance_startkeeptimer(struct instance_data *im, short instance_id)
|
||||
im->keep_limit = (unsigned int)time(NULL) + db->limit;
|
||||
im->keep_timer = add_timer(gettick()+db->limit*1000, instance_delete_timer, instance_id, 0);
|
||||
|
||||
// Notify party of the added instance timer
|
||||
if( ( p = party_search( im->party_id ) ) != NULL )
|
||||
clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1 );
|
||||
switch(im->mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (map_id2sd(im->owner_id) != NULL) // Notify player of the added instance timer
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (party_search(im->owner_id) != NULL) // Notify party of the added instance timer
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_GUILD:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -150,10 +213,9 @@ static int instance_startkeeptimer(struct instance_data *im, short instance_id)
|
||||
* Creates idle timer
|
||||
* Default before instance destroy is 5 minutes
|
||||
*------------------------------------------*/
|
||||
static int instance_startidletimer(struct instance_data *im, short instance_id)
|
||||
static int instance_startidletimer(struct instance_data *im, unsigned short instance_id)
|
||||
{
|
||||
struct instance_db *db;
|
||||
struct party_data *p;
|
||||
|
||||
nullpo_retr(1, im);
|
||||
|
||||
@ -161,16 +223,30 @@ static int instance_startidletimer(struct instance_data *im, short instance_id)
|
||||
if(im->idle_timer != INVALID_TIMER)
|
||||
return 1;
|
||||
|
||||
if ((db = instance_searchtype_db(im->type)) == NULL)
|
||||
return 1;
|
||||
|
||||
// Add the timer
|
||||
im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT/1000;
|
||||
im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
|
||||
|
||||
// Notify party of added instance timer
|
||||
if( ( p = party_search( im->party_id ) ) != NULL &&
|
||||
( db = instance_searchtype_db( im->type ) ) != NULL
|
||||
)
|
||||
{
|
||||
clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1 );
|
||||
switch(im->mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (map_id2sd(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify player of added instance timer
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (party_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify party of added instance timer
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_GUILD:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -179,10 +255,8 @@ static int instance_startidletimer(struct instance_data *im, short instance_id)
|
||||
/*==========================================
|
||||
* Delete the idle timer
|
||||
*------------------------------------------*/
|
||||
static int instance_stopidletimer(struct instance_data *im)
|
||||
static int instance_stopidletimer(struct instance_data *im, unsigned short instance_id)
|
||||
{
|
||||
struct party_data *p;
|
||||
|
||||
nullpo_retr(0, im);
|
||||
|
||||
// No timer
|
||||
@ -194,9 +268,24 @@ static int instance_stopidletimer(struct instance_data *im)
|
||||
delete_timer(im->idle_timer, instance_delete_timer);
|
||||
im->idle_timer = INVALID_TIMER;
|
||||
|
||||
// Notify the party
|
||||
if( ( p = party_search( im->party_id ) ) != NULL )
|
||||
clif_instance_changestatus( party_getavailablesd( p ), 0, im->idle_limit, 1 );
|
||||
switch(im->mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (map_id2sd(im->owner_id) != NULL) // Notify the player
|
||||
clif_instance_changestatus(instance_id, 0, im->idle_limit);
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (party_search(im->owner_id) != NULL) // Notify the party
|
||||
clif_instance_changestatus(instance_id, 0, im->idle_limit);
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if (guild_search(im->owner_id) != NULL) // Notify the guild
|
||||
clif_instance_changestatus(instance_id, 0, im->idle_limit);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -247,46 +336,84 @@ void instance_addnpc(struct instance_data *im)
|
||||
/*--------------------------------------
|
||||
* name : instance name
|
||||
* Return value could be
|
||||
* -4 = no free instances | -3 = already exists | -2 = party not found | -1 = invalid type
|
||||
* -4 = no free instances | -3 = already exists | -2 = character/party/guild not found | -1 = invalid type
|
||||
* On success return instance_id
|
||||
*--------------------------------------*/
|
||||
int instance_create(int party_id, const char *name)
|
||||
{
|
||||
short i;
|
||||
int instance_create(int owner_id, const char *name, enum instance_mode mode) {
|
||||
struct instance_db *db = instance_searchname_db(name);
|
||||
struct party_data *p = party_search(party_id);
|
||||
struct map_session_data *sd = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
unsigned short i;
|
||||
|
||||
if(db == NULL)
|
||||
return -1;
|
||||
nullpo_retr(-1, db);
|
||||
|
||||
if( p == NULL )
|
||||
return -2;
|
||||
|
||||
if( p->instance_id )
|
||||
return -3; // Party already instancing
|
||||
switch(mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if ((sd = map_id2sd(owner_id)) == NULL) {
|
||||
ShowError("instance_create: character %d not found for instance '%s'.\n", owner_id, name);
|
||||
return -2;
|
||||
}
|
||||
if (sd->instance_id)
|
||||
return -3; // Player already instancing
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if ((p = party_search(owner_id)) == NULL) {
|
||||
ShowError("instance_create: party %d not found for instance '%s'.\n", owner_id, name);
|
||||
return -2;
|
||||
}
|
||||
if (p->instance_id)
|
||||
return -3; // Party already instancing
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if ((g = guild_search(owner_id)) == NULL) {
|
||||
ShowError("instance_create: guild %d not found for instance '%s'.\n", owner_id, name);
|
||||
return -2;
|
||||
}
|
||||
if (g->instance_id)
|
||||
return -3; // Guild already instancing
|
||||
break;
|
||||
default:
|
||||
ShowError("instance_create: unknown mode %u for owner_id %d and name %s.\n", mode, owner_id, name);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Searching a Free Instance
|
||||
// 0 is ignored as this mean "no instance" on maps
|
||||
// 0 is ignored as this means "no instance" on maps
|
||||
ARR_FIND(1, MAX_INSTANCE_DATA, i, instance_data[i].state == INSTANCE_FREE);
|
||||
if( i >= MAX_INSTANCE_DATA )
|
||||
return -4;
|
||||
|
||||
instance_data[i].type = db->id;
|
||||
instance_data[i].state = INSTANCE_IDLE;
|
||||
instance_data[i].party_id = p->party.party_id;
|
||||
instance_data[i].owner_id = owner_id;
|
||||
instance_data[i].mode = mode;
|
||||
instance_data[i].keep_limit = 0;
|
||||
instance_data[i].keep_timer = INVALID_TIMER;
|
||||
instance_data[i].idle_limit = 0;
|
||||
instance_data[i].idle_timer = INVALID_TIMER;
|
||||
instance_data[i].regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
|
||||
instance_data[i].regs.arrays = NULL;
|
||||
safestrncpy(instance_data[i].name, name, sizeof(instance_data[i].name));
|
||||
memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
|
||||
|
||||
p->instance_id = i;
|
||||
switch(mode) {
|
||||
case IM_CHAR:
|
||||
sd->instance_id = i;
|
||||
break;
|
||||
case IM_PARTY:
|
||||
p->instance_id = i;
|
||||
break;
|
||||
case IM_GUILD:
|
||||
g->instance_id = i;
|
||||
break;
|
||||
}
|
||||
|
||||
instance_wait.id[instance_wait.count++] = p->instance_id;
|
||||
instance_wait.id[instance_wait.count++] = i;
|
||||
|
||||
clif_instance_create( party_getavailablesd( p ), name, instance_wait.count, 1);
|
||||
clif_instance_create(i, instance_wait.count);
|
||||
|
||||
instance_subscription_timer(0,0,0,0);
|
||||
|
||||
@ -298,24 +425,23 @@ int instance_create(int party_id, const char *name)
|
||||
/*--------------------------------------
|
||||
* Adds maps to the instance
|
||||
*--------------------------------------*/
|
||||
int instance_addmap(short instance_id)
|
||||
int instance_addmap(unsigned short instance_id)
|
||||
{
|
||||
int i, m;
|
||||
int cnt_map = 0;
|
||||
struct instance_data *im;
|
||||
struct instance_db *db;
|
||||
struct party_data *p;
|
||||
|
||||
if(instance_id <= 0)
|
||||
if (instance_id == 0)
|
||||
return 0;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
|
||||
// If the instance isn't idle, we can't do anything
|
||||
if(im->state != INSTANCE_IDLE)
|
||||
if (im->state != INSTANCE_IDLE)
|
||||
return 0;
|
||||
|
||||
if((db = instance_searchtype_db(im->type)) == NULL)
|
||||
if ((db = instance_searchtype_db(im->type)) == NULL)
|
||||
return 0;
|
||||
|
||||
// Set to busy, update timers
|
||||
@ -343,9 +469,24 @@ int instance_addmap(short instance_id)
|
||||
// Create NPCs on all maps
|
||||
instance_addnpc(im);
|
||||
|
||||
// Inform party members of the created instance
|
||||
if( (p = party_search( im->party_id ) ) != NULL )
|
||||
clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1);
|
||||
switch(im->mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (map_id2sd(im->owner_id) != NULL) // Inform player of the created instance
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (party_search(im->owner_id) != NULL) // Inform party members of the created instance
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
break;
|
||||
case IM_GUILD:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cnt_map;
|
||||
}
|
||||
@ -357,7 +498,7 @@ int instance_addmap(short instance_id)
|
||||
* instance_id : where to search
|
||||
* result : mapid of map "name" in this instance
|
||||
*------------------------------------------*/
|
||||
int instance_mapname2mapid(const char *name, short instance_id)
|
||||
int instance_mapname2mapid(const char *name, unsigned short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
int m = map_mapname2mapid(name);
|
||||
@ -371,7 +512,7 @@ int instance_mapname2mapid(const char *name, short instance_id)
|
||||
|
||||
strcpy(iname,name);
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return m;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
@ -395,14 +536,17 @@ int instance_mapname2mapid(const char *name, short instance_id)
|
||||
/*==========================================
|
||||
* Removes a instance, all its maps and npcs.
|
||||
*------------------------------------------*/
|
||||
int instance_destroy(short instance_id)
|
||||
int instance_destroy(unsigned short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
struct party_data *p;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
int i, type = 0;
|
||||
unsigned int now = (unsigned int)time(NULL);
|
||||
enum instance_mode mode;
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return 1;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
@ -410,6 +554,33 @@ int instance_destroy(short instance_id)
|
||||
if(im->state == INSTANCE_FREE)
|
||||
return 1;
|
||||
|
||||
mode = im->mode;
|
||||
switch(mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if ((sd = map_id2sd(im->owner_id)) == NULL) {
|
||||
ShowError("instance_destroy: character %d not found for instance '%s'.\n", im->owner_id, im->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if ((p = party_search(im->owner_id)) == NULL) {
|
||||
ShowError("instance_destroy: party %d not found for instance '%s'.\n", im->owner_id, im->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if ((g = guild_search(im->owner_id)) == NULL) {
|
||||
ShowError("instance_destroy: guild %d not found for instance '%s'.\n", im->owner_id, im->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ShowError("instance_destroy: unknown owner type %u for owner_id %d and name %s.\n", mode, im->owner_id, im->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(im->state == INSTANCE_IDLE) {
|
||||
for(i = 0; i < instance_wait.count; i++) {
|
||||
if(instance_wait.id[i] == instance_id) {
|
||||
@ -419,8 +590,8 @@ int instance_destroy(short instance_id)
|
||||
|
||||
for(i = 0; i < instance_wait.count; i++)
|
||||
if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
|
||||
if((p = party_search(instance_data[instance_wait.id[i]].party_id)) != NULL)
|
||||
clif_instance_changewait( party_getavailablesd( p ), i+1, 1);
|
||||
if ((mode == IM_CHAR && sd != NULL) || (mode == IM_PARTY && p != NULL) || (mode == IM_GUILD && g != NULL))
|
||||
clif_instance_changewait(instance_id, i + 1);
|
||||
|
||||
if(instance_wait.count)
|
||||
instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
|
||||
@ -451,13 +622,18 @@ int instance_destroy(short instance_id)
|
||||
im->idle_timer = INVALID_TIMER;
|
||||
}
|
||||
|
||||
if((p = party_search(im->party_id))) {
|
||||
if (mode == IM_CHAR)
|
||||
sd->instance_id = 0;
|
||||
else if (mode == IM_PARTY)
|
||||
p->instance_id = 0;
|
||||
else if (mode == IM_GUILD)
|
||||
g->instance_id = 0;
|
||||
|
||||
if (mode != IM_NONE) {
|
||||
if(type)
|
||||
clif_instance_changestatus( party_getavailablesd( p ), type, 0, 1 );
|
||||
clif_instance_changestatus(instance_id, type, 0);
|
||||
else
|
||||
clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
|
||||
clif_instance_changewait(instance_id, 0xffff);
|
||||
}
|
||||
|
||||
if( im->regs.vars ) {
|
||||
@ -478,61 +654,78 @@ int instance_destroy(short instance_id)
|
||||
/*==========================================
|
||||
* Allows a user to enter an instance
|
||||
*------------------------------------------*/
|
||||
int instance_enter(struct map_session_data *sd, const char *name)
|
||||
int instance_enter(struct map_session_data *sd, unsigned short instance_id, const char *name)
|
||||
{
|
||||
struct instance_db *db = instance_searchname_db(name);
|
||||
|
||||
if(db == NULL)
|
||||
return 3;
|
||||
nullpo_retr(-1, sd);
|
||||
nullpo_retr(3, db);
|
||||
|
||||
return instance_enter_position(sd, name, db->enter.x, db->enter.y);
|
||||
return instance_enter_position(sd, instance_id, name, db->enter.x, db->enter.y);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Warp a user into instance
|
||||
*------------------------------------------*/
|
||||
int instance_enter_position(struct map_session_data *sd, const char *name, short x, short y)
|
||||
int instance_enter_position(struct map_session_data *sd, unsigned short instance_id, const char *name, short x, short y)
|
||||
{
|
||||
struct instance_data *im;
|
||||
struct instance_data *im = &instance_data[instance_id];
|
||||
struct instance_db *db = instance_searchname_db(name);
|
||||
struct party_data *p;
|
||||
int m;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
int16 m;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
nullpo_retr(3, db);
|
||||
|
||||
// Character must be in instance party
|
||||
if(sd->status.party_id == 0)
|
||||
return 1;
|
||||
if((p = party_search(sd->status.party_id)) == NULL)
|
||||
return 1;
|
||||
switch(instance_data[instance_id].mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (sd->instance_id == 0) // Player must have an instance
|
||||
return 2;
|
||||
if (im->owner_id != sd->status.account_id)
|
||||
return 3;
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (sd->status.party_id == 0) // Character must be in instance party
|
||||
return 1;
|
||||
if ((p = party_search(sd->status.party_id)) == NULL)
|
||||
return 1;
|
||||
if (p->instance_id == 0) // Party must have an instance
|
||||
return 2;
|
||||
if (im->owner_id != p->party.party_id)
|
||||
return 3;
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if (sd->status.guild_id == 0) // Character must be in instance guild
|
||||
return 1;
|
||||
if ((g = guild_search(sd->status.guild_id)) == NULL)
|
||||
return 1;
|
||||
if (g->instance_id == 0) // Guild must have an instance
|
||||
return 2;
|
||||
if (im->owner_id != g->guild_id)
|
||||
return 3;
|
||||
break;
|
||||
}
|
||||
|
||||
// Party must have an instance
|
||||
if(p->instance_id == 0)
|
||||
return 2;
|
||||
|
||||
if(db == NULL)
|
||||
if (im->state != INSTANCE_BUSY)
|
||||
return 3;
|
||||
|
||||
im = &instance_data[p->instance_id];
|
||||
if(im->party_id != p->party.party_id)
|
||||
return 3;
|
||||
if(im->state != INSTANCE_BUSY)
|
||||
return 3;
|
||||
if(im->type != db->id)
|
||||
if (im->type != db->id)
|
||||
return 3;
|
||||
|
||||
// Does the instance match?
|
||||
if((m = instance_mapname2mapid(StringBuf_Value(db->enter.mapname), p->instance_id)) < 0)
|
||||
if ((m = instance_mapname2mapid(StringBuf_Value(db->enter.mapname), instance_id)) < 0)
|
||||
return 3;
|
||||
|
||||
if(pc_setpos(sd, map_id2index(m), x, y, CLR_OUTSIGHT))
|
||||
if (pc_setpos(sd, map_id2index(m), x, y, CLR_OUTSIGHT))
|
||||
return 3;
|
||||
|
||||
// If there was an idle timer, let's stop it
|
||||
instance_stopidletimer(im);
|
||||
instance_stopidletimer(im, instance_id);
|
||||
|
||||
// Now we start the instance timer
|
||||
instance_startkeeptimer(im, p->instance_id);
|
||||
instance_startkeeptimer(im, instance_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -540,14 +733,14 @@ int instance_enter_position(struct map_session_data *sd, const char *name, short
|
||||
/*==========================================
|
||||
* Request some info about the instance
|
||||
*------------------------------------------*/
|
||||
int instance_reqinfo(struct map_session_data *sd, short instance_id)
|
||||
int instance_reqinfo(struct map_session_data *sd, unsigned short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
struct instance_db *db;
|
||||
|
||||
nullpo_retr(1, sd);
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return 1;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
@ -561,12 +754,12 @@ int instance_reqinfo(struct map_session_data *sd, short instance_id)
|
||||
|
||||
for(i = 0; i < instance_wait.count; i++) {
|
||||
if(instance_wait.id[i] == instance_id) {
|
||||
clif_instance_create(sd, StringBuf_Value(db->name), i+1, 0);
|
||||
clif_instance_create(instance_id, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
|
||||
clif_instance_status(sd, StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 0);
|
||||
clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -574,11 +767,11 @@ int instance_reqinfo(struct map_session_data *sd, short instance_id)
|
||||
/*==========================================
|
||||
* Add players to the instance (for timers)
|
||||
*------------------------------------------*/
|
||||
int instance_addusers(short instance_id)
|
||||
int instance_addusers(unsigned short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return 1;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
@ -586,7 +779,7 @@ int instance_addusers(short instance_id)
|
||||
return 1;
|
||||
|
||||
// Stop the idle timer if we had one
|
||||
instance_stopidletimer(im);
|
||||
instance_stopidletimer(im, instance_id);
|
||||
|
||||
// Start the instance keep timer
|
||||
instance_startkeeptimer(im, instance_id);
|
||||
@ -597,12 +790,12 @@ int instance_addusers(short instance_id)
|
||||
/*==========================================
|
||||
* Delete players from the instance (for timers)
|
||||
*------------------------------------------*/
|
||||
int instance_delusers(short instance_id)
|
||||
int instance_delusers(unsigned short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
int i, idle = 0;
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return 1;
|
||||
|
||||
im = &instance_data[instance_id];
|
||||
@ -637,8 +830,8 @@ static bool instance_readdb_sub(char* str[], int columns, int current)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapindex_name2id(str[3]) == 0) {
|
||||
ShowError("instance_readdb_sub: Invalid map '%s' as entrance map.\n", str[3]);
|
||||
if (mapindex_name2id(str[4]) == 0) {
|
||||
ShowError("instance_readdb_sub: Invalid map '%s' as entrance map.\n", str[4]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -662,12 +855,13 @@ static bool instance_readdb_sub(char* str[], int columns, int current)
|
||||
|
||||
StringBuf_AppendStr(db->name, str[1]);
|
||||
db->limit = atoi(str[2]);
|
||||
StringBuf_AppendStr(db->enter.mapname, str[3]);
|
||||
db->enter.x = atoi(str[4]);
|
||||
db->enter.y = atoi(str[5]);
|
||||
db->timeout = atoi(str[3]);
|
||||
StringBuf_AppendStr(db->enter.mapname, str[4]);
|
||||
db->enter.x = atoi(str[5]);
|
||||
db->enter.y = atoi(str[6]);
|
||||
|
||||
//Instance maps
|
||||
for (i = 6; i < columns; i++) {
|
||||
for (i = 7; i < columns; i++) {
|
||||
if (strlen(str[i])) {
|
||||
if (mapindex_name2id(str[i]) == 0) {
|
||||
ShowWarning("instance_readdb_sub: Invalid map '%s' in maplist, skipping...\n", str[i]);
|
||||
@ -675,7 +869,7 @@ static bool instance_readdb_sub(char* str[], int columns, int current)
|
||||
}
|
||||
RECREATE(db->maplist, StringBuf *, db->maplist_count+1);
|
||||
db->maplist[db->maplist_count] = StringBuf_Malloc();
|
||||
if (strcmpi(str[i], str[3]) == 0)
|
||||
if (strcmpi(str[i], str[4]) == 0)
|
||||
defined = true;
|
||||
StringBuf_AppendStr(db->maplist[db->maplist_count], str[i]);
|
||||
db->maplist_count++;
|
||||
@ -732,7 +926,7 @@ void instance_readdb(void) {
|
||||
int f;
|
||||
|
||||
for (f = 0; f<ARRAYLENGTH(filename); f++) {
|
||||
sv_readdb(db_path, filename[f], ',', 7, 7+MAX_MAP_PER_INSTANCE, -1, &instance_readdb_sub, f);
|
||||
sv_readdb(db_path, filename[f], ',', 8, 8+MAX_MAP_PER_INSTANCE, -1, &instance_readdb_sub, f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -754,7 +948,7 @@ void do_reload_instance(void)
|
||||
struct instance_db *db;
|
||||
struct s_mapiterator* iter;
|
||||
struct map_session_data *sd;
|
||||
int i;
|
||||
unsigned short i;
|
||||
|
||||
for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
|
||||
im = &instance_data[i];
|
||||
@ -775,10 +969,14 @@ void do_reload_instance(void)
|
||||
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
|
||||
if(sd && map[sd->bl.m].instance_id) {
|
||||
struct party_data *p;
|
||||
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
|
||||
struct guild *g;
|
||||
|
||||
if (instance_data[map[sd->bl.m].instance_id].mode == IM_PARTY && (!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
|
||||
continue;
|
||||
if (instance_data[map[sd->bl.m].instance_id].mode == IM_GUILD && (!(g = guild_search(sd->status.guild_id)) || g->instance_id != map[sd->bl.m].instance_id)) // Someone not in guild is on instance map
|
||||
continue;
|
||||
im = &instance_data[p->instance_id];
|
||||
if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,StringBuf_Value(db->name))) { // All good
|
||||
if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd, i, StringBuf_Value(db->name))) { // All good
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
|
||||
instance_reqinfo(sd,p->instance_id);
|
||||
} else // Something went wrong
|
||||
|
@ -14,13 +14,27 @@ struct block_list;
|
||||
|
||||
#define INSTANCE_NAME_LENGTH (60+1)
|
||||
|
||||
typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
|
||||
typedef enum instance_state {
|
||||
INSTANCE_FREE,
|
||||
INSTANCE_IDLE,
|
||||
INSTANCE_BUSY
|
||||
} instance_state;
|
||||
|
||||
enum instance_mode {
|
||||
IM_NONE,
|
||||
IM_CHAR,
|
||||
IM_PARTY,
|
||||
IM_GUILD,
|
||||
IM_MAX,
|
||||
};
|
||||
|
||||
struct instance_data {
|
||||
unsigned short type, ///< Instance DB ID
|
||||
cnt_map;
|
||||
int state;
|
||||
int party_id;
|
||||
char name[INSTANCE_NAME_LENGTH];
|
||||
enum instance_state state;
|
||||
enum instance_mode mode;
|
||||
int owner_id;
|
||||
unsigned int keep_limit;
|
||||
int keep_timer;
|
||||
unsigned int idle_limit;
|
||||
@ -37,15 +51,17 @@ struct instance_data {
|
||||
extern int instance_start;
|
||||
extern struct instance_data instance_data[MAX_INSTANCE_DATA];
|
||||
|
||||
int instance_create(int party_id, const char *name);
|
||||
int instance_destroy(short instance_id);
|
||||
int instance_enter(struct map_session_data *sd, const char *name);
|
||||
int instance_enter_position(struct map_session_data *sd, const char *name, short x, short y);
|
||||
int instance_reqinfo(struct map_session_data *sd, short instance_id);
|
||||
int instance_addusers(short instance_id);
|
||||
int instance_delusers(short instance_id);
|
||||
int instance_mapname2mapid(const char *name, short instance_id);
|
||||
int instance_addmap(short instance_id);
|
||||
void instance_getsd(unsigned short instance_id, struct map_session_data **sd, enum send_target *target);
|
||||
|
||||
int instance_create(int owner_id, const char *name, enum instance_mode mode);
|
||||
int instance_destroy(unsigned short instance_id);
|
||||
int instance_enter(struct map_session_data *sd, unsigned short instance_id, const char *name);
|
||||
int instance_enter_position(struct map_session_data *sd, unsigned short instance_id, const char *name, short x, short y);
|
||||
int instance_reqinfo(struct map_session_data *sd, unsigned short instance_id);
|
||||
int instance_addusers(unsigned short instance_id);
|
||||
int instance_delusers(unsigned short instance_id);
|
||||
int instance_mapname2mapid(const char *name, unsigned short instance_id);
|
||||
int instance_addmap(unsigned short instance_id);
|
||||
|
||||
void instance_addnpc(struct instance_data *im);
|
||||
void instance_readdb(void);
|
||||
|
@ -2554,7 +2554,7 @@ bool map_addnpc(int16 m,struct npc_data *nd)
|
||||
/*==========================================
|
||||
* Add an instance map
|
||||
*------------------------------------------*/
|
||||
int map_addinstancemap(const char *name, int id)
|
||||
int map_addinstancemap(const char *name, unsigned short instance_id)
|
||||
{
|
||||
int src_m = map_mapname2mapid(name);
|
||||
int dst_m = -1, i;
|
||||
@ -2594,9 +2594,9 @@ int map_addinstancemap(const char *name, int id)
|
||||
// This also allows us to maintain complete independence with main map functions
|
||||
if((strchr(iname,'@') == NULL) && strlen(iname) > 8) {
|
||||
memmove(iname, iname+(strlen(iname)-9), strlen(iname));
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%d#%s", id, iname);
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%hu#%s", instance_id, iname);
|
||||
} else
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%.3d%s", id, iname);
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%.3hu%s", instance_id, iname);
|
||||
map[dst_m].name[MAP_NAME_LENGTH-1] = '\0';
|
||||
|
||||
// Mimic questinfo
|
||||
@ -2607,7 +2607,7 @@ int map_addinstancemap(const char *name, int id)
|
||||
}
|
||||
|
||||
map[dst_m].m = dst_m;
|
||||
map[dst_m].instance_id = id;
|
||||
map[dst_m].instance_id = instance_id;
|
||||
map[dst_m].instance_src_map = src_m;
|
||||
map[dst_m].users = 0;
|
||||
|
||||
|
@ -689,7 +689,7 @@ struct map_data {
|
||||
} skill_damage;
|
||||
#endif
|
||||
// Instance Variables
|
||||
int instance_id;
|
||||
unsigned short instance_id;
|
||||
int instance_src_map;
|
||||
|
||||
/* rAthena Local Chat */
|
||||
@ -800,8 +800,8 @@ void map_clearflooritem(struct block_list* bl);
|
||||
int map_addflooritem(struct item *item, int amount, int16 m, int16 x, int16 y, int first_charid, int second_charid, int third_charid, int flags, unsigned short mob_id);
|
||||
|
||||
// instances
|
||||
int map_addinstancemap(const char*,int);
|
||||
int map_delinstancemap(int);
|
||||
int map_addinstancemap(const char *name, unsigned short instance_id);
|
||||
int map_delinstancemap(int m);
|
||||
|
||||
// player to map session
|
||||
void map_addnickdb(int charid, const char* nick);
|
||||
|
@ -660,7 +660,7 @@ int party_broken(int party_id)
|
||||
return 0;
|
||||
|
||||
if( p->instance_id ) {
|
||||
instance_data[p->instance_id].party_id = 0;
|
||||
instance_data[p->instance_id].owner_id = 0;
|
||||
instance_destroy( p->instance_id );
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ struct party_data {
|
||||
struct party party;
|
||||
struct party_member_data data[MAX_PARTY];
|
||||
uint8 itemc; //For item distribution, position of last picker in party
|
||||
unsigned int instance_id;
|
||||
unsigned short instance_id;
|
||||
struct {
|
||||
unsigned monk : 1; //There's at least one monk in party?
|
||||
unsigned sg : 1; //There's at least one Star Gladiator in party?
|
||||
|
17
src/map/pc.c
17
src/map/pc.c
@ -5285,10 +5285,21 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
sd->state.changemap = (sd->mapindex != mapindex);
|
||||
sd->state.warping = 1;
|
||||
|
||||
if(sd->status.party_id && map[sd->bl.m].instance_id && sd->state.changemap && !map[m].instance_id) {
|
||||
struct party_data *p;
|
||||
if((p = party_search(sd->status.party_id)) != NULL && p->instance_id )
|
||||
if(map[sd->bl.m].instance_id && sd->state.changemap && !map[m].instance_id) {
|
||||
bool instance_found = false;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
|
||||
if (sd->instance_id) {
|
||||
instance_delusers(sd->instance_id);
|
||||
instance_found = true;
|
||||
}
|
||||
if (!instance_found && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id) {
|
||||
instance_delusers(p->instance_id);
|
||||
instance_found = true;
|
||||
}
|
||||
if (!instance_found && sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL && g->instance_id)
|
||||
instance_delusers(g->instance_id);
|
||||
}
|
||||
if( sd->state.changemap ) { // Misc map-changing settings
|
||||
int i;
|
||||
|
@ -679,6 +679,8 @@ struct map_session_data {
|
||||
short prizeStage;
|
||||
bool claimPrize;
|
||||
} roulette;
|
||||
|
||||
unsigned short instance_id;
|
||||
};
|
||||
|
||||
struct eri *pc_sc_display_ers; /// Player's SC display table
|
||||
|
209
src/map/script.c
209
src/map/script.c
@ -295,7 +295,7 @@ struct {
|
||||
*------------------------------------------*/
|
||||
const char* parse_subexpr(const char* p,int limit);
|
||||
int run_func(struct script_state *st);
|
||||
int script_instancegetid(struct script_state *st);
|
||||
unsigned short script_instancegetid(struct script_state *st);
|
||||
|
||||
enum {
|
||||
MF_NOMEMO, //0
|
||||
@ -2593,7 +2593,7 @@ void get_val_(struct script_state* st, struct script_data* data, struct map_sess
|
||||
break;
|
||||
case '\'':
|
||||
{
|
||||
int instance_id = script_instancegetid(st);
|
||||
unsigned short instance_id = script_instancegetid(st);
|
||||
if( instance_id )
|
||||
data->u.str = (char*)i64db_get(instance_data[instance_id].regs.vars,reference_getuid(data));
|
||||
else {
|
||||
@ -2651,7 +2651,7 @@ void get_val_(struct script_state* st, struct script_data* data, struct map_sess
|
||||
break;
|
||||
case '\'':
|
||||
{
|
||||
int instance_id = script_instancegetid(st);
|
||||
unsigned short instance_id = script_instancegetid(st);
|
||||
if( instance_id )
|
||||
data->u.num = (int)i64db_iget(instance_data[instance_id].regs.vars,reference_getuid(data));
|
||||
else {
|
||||
@ -2867,7 +2867,7 @@ struct reg_db *script_array_src(struct script_state *st, struct map_session_data
|
||||
break;
|
||||
case '\'': // instance
|
||||
{
|
||||
int instance_id = script_instancegetid(st);
|
||||
unsigned short instance_id = script_instancegetid(st);
|
||||
|
||||
if( instance_id ) {
|
||||
src = &instance_data[instance_id].regs;
|
||||
@ -2981,7 +2981,7 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
|
||||
return 1;
|
||||
case '\'':
|
||||
{
|
||||
int instance_id = script_instancegetid(st);
|
||||
unsigned short instance_id = script_instancegetid(st);
|
||||
if( instance_id ) {
|
||||
if( str[0] ) {
|
||||
i64db_put(instance_data[instance_id].regs.vars, num, aStrdup(str));
|
||||
@ -3044,7 +3044,7 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
|
||||
return 1;
|
||||
case '\'':
|
||||
{
|
||||
int instance_id = script_instancegetid(st);
|
||||
unsigned short instance_id = script_instancegetid(st);
|
||||
if( instance_id ) {
|
||||
if( val != 0 ) {
|
||||
i64db_iput(instance_data[instance_id].regs.vars, num, val);
|
||||
@ -18827,19 +18827,27 @@ BUILDIN_FUNC(bg_get_data)
|
||||
* Instancing System
|
||||
*------------------------------------------*/
|
||||
//Returns an Instance ID
|
||||
//Checks NPC first, then if player is attached we check party
|
||||
int script_instancegetid(struct script_state* st)
|
||||
//Checks NPC first, then if player is attached we check
|
||||
unsigned short script_instancegetid(struct script_state* st)
|
||||
{
|
||||
short instance_id = 0;
|
||||
|
||||
unsigned short instance_id = 0;
|
||||
struct npc_data *nd;
|
||||
|
||||
if( (nd = map_id2nd(st->oid)) && nd->instance_id > 0 )
|
||||
instance_id = nd->instance_id;
|
||||
else {
|
||||
struct map_session_data *sd;
|
||||
struct party_data *p;
|
||||
if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
|
||||
instance_id = p->instance_id;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
|
||||
if ((sd = script_rid2sd(st)) != NULL) {
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
return instance_id;
|
||||
@ -18851,12 +18859,20 @@ int script_instancegetid(struct script_state* st)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_create)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
enum instance_mode mode = IM_PARTY;
|
||||
int owner_id;
|
||||
|
||||
if((sd = script_rid2sd(st)) == NULL)
|
||||
return -1;
|
||||
owner_id = script_getnum(st, 3);
|
||||
if (script_hasdata(st, 4)) {
|
||||
mode = script_getnum(st, 4);
|
||||
|
||||
script_pushint(st,instance_create(sd->status.party_id, script_getstr(st, 2)));
|
||||
if (mode < IM_NONE || mode >= IM_MAX) {
|
||||
ShowError("buildin_instance_create: Unknown instance owner type %d for '%s'\n", mode, script_getstr(st, 2));
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
script_pushint(st, instance_create(owner_id, script_getstr(st, 2), mode));
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -18868,7 +18884,7 @@ BUILDIN_FUNC(instance_create)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_destroy)
|
||||
{
|
||||
short instance_id;
|
||||
unsigned short instance_id;
|
||||
|
||||
if( script_hasdata(st,2) )
|
||||
instance_id = script_getnum(st,2);
|
||||
@ -18876,7 +18892,7 @@ BUILDIN_FUNC(instance_destroy)
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
if( instance_id <= 0 || instance_id >= MAX_MAP_PER_SERVER ) {
|
||||
ShowError("script:instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
|
||||
ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -18888,9 +18904,9 @@ BUILDIN_FUNC(instance_destroy)
|
||||
* Warps player to instance
|
||||
* Results:
|
||||
* 0: Success
|
||||
* 1: Character not in party
|
||||
* 2: Party doesn't have instance
|
||||
* 3: Other errors (instance not in DB, instance doesn't match with party, etc.)
|
||||
* 1: Character not in party/guild (for party/guild type instances)
|
||||
* 2: Character/Party/Guild doesn't have instance
|
||||
* 3: Other errors (instance not in DB, instance doesn't match with character/party/guild, etc.)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_enter)
|
||||
{
|
||||
@ -18902,9 +18918,9 @@ BUILDIN_FUNC(instance_enter)
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
if (x != -1 && y != -1)
|
||||
script_pushint(st,instance_enter_position(sd,script_getstr(st, 2),x,y));
|
||||
script_pushint(st, instance_enter_position(sd, script_instancegetid(st), script_getstr(st, 2), x, y));
|
||||
else
|
||||
script_pushint(st,instance_enter(sd,script_getstr(st, 2)));
|
||||
script_pushint(st, instance_enter(sd, script_instancegetid(st), script_getstr(st, 2)));
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -18918,8 +18934,7 @@ BUILDIN_FUNC(instance_enter)
|
||||
BUILDIN_FUNC(instance_npcname)
|
||||
{
|
||||
const char *str;
|
||||
short instance_id = 0;
|
||||
|
||||
unsigned short instance_id = 0;
|
||||
struct npc_data *nd;
|
||||
|
||||
str = script_getstr(st,2);
|
||||
@ -18933,7 +18948,7 @@ BUILDIN_FUNC(instance_npcname)
|
||||
snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id);
|
||||
script_pushconststr(st,npcname);
|
||||
} else {
|
||||
ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
|
||||
ShowError("buildin_instance_npcname: Invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
@ -18950,7 +18965,7 @@ BUILDIN_FUNC(instance_mapname)
|
||||
{
|
||||
const char *str;
|
||||
int16 m;
|
||||
short instance_id = 0;
|
||||
unsigned short instance_id = 0;
|
||||
|
||||
str = script_getstr(st,2);
|
||||
|
||||
@ -18973,12 +18988,12 @@ BUILDIN_FUNC(instance_mapname)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_id)
|
||||
{
|
||||
short instance_id;
|
||||
unsigned short instance_id;
|
||||
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
if(!instance_id) {
|
||||
//ShowError("script:instance_id: No instance attached to NPC or player");
|
||||
//ShowError("buildin_instance_id: No instance attached to NPC or player");
|
||||
script_pushint(st, 0);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -18991,11 +19006,29 @@ BUILDIN_FUNC(instance_id)
|
||||
*
|
||||
* instance_warpall <map_name>,<x>,<y>{,<instance_id>};
|
||||
*------------------------------------------*/
|
||||
static int buildin_instance_warpall_sub(struct block_list *bl, va_list ap)
|
||||
{
|
||||
unsigned int m = va_arg(ap,unsigned int);
|
||||
int x = va_arg(ap,int);
|
||||
int y = va_arg(ap,int);
|
||||
|
||||
nullpo_retr(0, bl);
|
||||
|
||||
if (bl->type != BL_PC)
|
||||
return 0;
|
||||
|
||||
pc_setpos((TBL_PC *)bl, m, x, y, CLR_TELEPORT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BUILDIN_FUNC(instance_warpall)
|
||||
{
|
||||
struct party_data *p;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
int16 m, i;
|
||||
short instance_id;
|
||||
unsigned short instance_id;
|
||||
const char *mapn;
|
||||
int x, y;
|
||||
|
||||
@ -19008,16 +19041,30 @@ BUILDIN_FUNC(instance_warpall)
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
if( !instance_id || (m = map_mapname2mapid(mapn)) < 0 || (m = instance_mapname2mapid(map[m].name,instance_id)) < 0)
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
if( !(p = party_search(instance_data[instance_id].party_id)) )
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
for( i = 0; i < MAX_PARTY; i++ ) {
|
||||
struct map_session_data *pl_sd;
|
||||
if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == instance_id ) pc_setpos(pl_sd,map_id2index(m),x,y,CLR_TELEPORT);
|
||||
switch(instance_data[instance_id].mode) {
|
||||
case IM_NONE:
|
||||
break;
|
||||
case IM_CHAR:
|
||||
if (!(sd = map_id2sd(instance_data[instance_id].owner_id)))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if (!(p = party_search(instance_data[instance_id].owner_id)))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if (!(g = guild_search(instance_data[instance_id].owner_id)))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
default:
|
||||
ShowError("buildin_instance_warpall: Invalid instance owner type (instance_id: %d)\n", instance_id);
|
||||
break;
|
||||
}
|
||||
|
||||
for(i = 0; i < instance_data[instance_id].cnt_map; i++)
|
||||
map_foreachinmap(buildin_instance_warpall_sub, instance_data[instance_id].map[i].m, BL_PC, map_id2index(m), x, y);
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -19028,15 +19075,14 @@ BUILDIN_FUNC(instance_warpall)
|
||||
* Using -1 for <instance id> will auto-detect the id.
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_announce) {
|
||||
int instance_id = script_getnum(st,2);
|
||||
const char *mes = script_getstr(st,3);
|
||||
int flag = script_getnum(st,4);
|
||||
const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
|
||||
int fontType = script_hasdata(st,6) ? script_getnum(st,6) : FW_NORMAL; // default fontType
|
||||
int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
|
||||
int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
|
||||
int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
|
||||
|
||||
unsigned short instance_id = script_getnum(st,2);
|
||||
const char *mes = script_getstr(st,3);
|
||||
int flag = script_getnum(st,4);
|
||||
const char *fontColor = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
|
||||
int fontType = script_hasdata(st,6) ? script_getnum(st,6) : FW_NORMAL; // default fontType
|
||||
int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize
|
||||
int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign
|
||||
int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY
|
||||
int i;
|
||||
|
||||
if( instance_id == -1 ) {
|
||||
@ -19114,6 +19160,68 @@ BUILDIN_FUNC(instance_check_party)
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* instance_check_guild
|
||||
* Values:
|
||||
* guild_id : Guild ID of the invoking character. [Required Parameter]
|
||||
* amount : Amount of needed Guild 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_guild (getcharid(2){,amount}{,min}{,max});
|
||||
* Example 2: instance_check_guild (getcharid(2),1,1,99);
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(instance_check_guild)
|
||||
{
|
||||
int amount, min, max, i, guild_id, c = 0;
|
||||
struct guild *g = NULL;
|
||||
|
||||
amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Guild 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_guild: Invalid min level, %d\n", min);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
} else if (max < 1 || max > MAX_LEVEL) {
|
||||
ShowError("buildin_instance_check_guild: Invalid max level, %d\n", max);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
if (script_hasdata(st,2))
|
||||
guild_id = script_getnum(st,2);
|
||||
else
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
if (!(g = guild_search(guild_id))) {
|
||||
script_pushint(st, 0); // Returns false if guild does not exist.
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
for(i = 0; i < MAX_GUILD; i++) {
|
||||
struct map_session_data *pl_sd;
|
||||
|
||||
if ((pl_sd = g->member[i].sd)) {
|
||||
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 Guild to join Instance.
|
||||
else
|
||||
script_pushint(st, 1);
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Custom Fonts
|
||||
*------------------------------------------*/
|
||||
@ -21783,7 +21891,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(bg_updatescore,"sii"),
|
||||
|
||||
// Instancing
|
||||
BUILDIN_DEF(instance_create,"s"),
|
||||
BUILDIN_DEF(instance_create,"si?"),
|
||||
BUILDIN_DEF(instance_destroy,"?"),
|
||||
BUILDIN_DEF(instance_id,""),
|
||||
BUILDIN_DEF(instance_enter,"s???"),
|
||||
@ -21792,6 +21900,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(instance_warpall,"sii?"),
|
||||
BUILDIN_DEF(instance_announce,"isi?????"),
|
||||
BUILDIN_DEF(instance_check_party,"i???"),
|
||||
BUILDIN_DEF(instance_check_guild,"i???"),
|
||||
/**
|
||||
* 3rd-related
|
||||
**/
|
||||
|
@ -3062,6 +3062,12 @@
|
||||
export_constant(DIR_EAST);
|
||||
export_constant(DIR_NORTHEAST);
|
||||
|
||||
/* instance modes */
|
||||
export_constant(IM_NONE);
|
||||
export_constant(IM_CHAR);
|
||||
export_constant(IM_PARTY);
|
||||
export_constant(IM_GUILD);
|
||||
|
||||
#undef export_constant
|
||||
|
||||
#endif /* _SCRIPT_CONSTANTS_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user