예제 #1
0
/*--------------------------------------
 * Checks if there are users in the instance or not to start idle timer
 *--------------------------------------*/
void instance_check_idle(int instance_id)
{
	bool idle = true;
	time_t now = time(NULL);

	if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
		return;

	if( instance[instance_id].users )
		idle = false;

	if( instance[instance_id].idle_timer != INVALID_TIMER && !idle )
	{
		delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
		instance[instance_id].idle_timer = INVALID_TIMER;
		instance[instance_id].idle_timeout = 0;
		clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
	}
	else if( instance[instance_id].idle_timer == INVALID_TIMER && idle )
	{
		instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
		instance[instance_id].idle_timer = add_timer( gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
		clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
	}
}
예제 #2
0
/*--------------------------------------
 * Init all map on the instance. Npcs are created here
 *--------------------------------------*/
void instance_init(int instance_id)
{
	int i;

	if( !instance_is_valid(instance_id) )
		return; // nothing to do

	for( i = 0; i < instance[instance_id].num_map; i++ )
		map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);

	instance[instance_id].state = INSTANCE_BUSY;
	ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
}
예제 #3
0
/*--------------------------------------
 * m : source map of this instance
 * party_id : source party of this instance
 * type : result (0 = map id | 1 = instance id)
 *--------------------------------------*/
int instance_map2imap(int16 m, int instance_id)
{
	int i;

	if(!instance_is_valid(instance_id)) {
		return -1;
	}

	for(i = 0; i < instance[instance_id].num_map; i++) {
		if(instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m)
			return instance[instance_id].map[i];
	}
	return -1;
}
예제 #4
0
/*--------------------------------------
 * Removes a instance, all its maps and npcs.
 *--------------------------------------*/
void instance_destroy(int instance_id)
{
	int last = 0, type;
	struct party_data *p;
	time_t now = time(NULL);

	if( !instance_is_valid(instance_id) )
		return; // nothing to do

	if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
		type = 1;
	else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now )
		type = 2;
	else
		type = 3;

	clif_instance(instance_id, 5, type); // Report users this instance has been destroyed

	while( instance[instance_id].num_map && last != instance[instance_id].map[0] )
	{ // Remove all maps from instance
		last = instance[instance_id].map[0];
		instance_del_map( instance[instance_id].map[0] );
	}

	if( instance[instance_id].ivar )
		linkdb_final( &instance[instance_id].ivar ); // Remove numeric vars

	if( instance[instance_id].svar )
	{ // Remove string vars
		linkdb_foreach( &instance[instance_id].svar, instance_destroy_freesvar );
		linkdb_final( &instance[instance_id].svar );
	}

	if( instance[instance_id].progress_timer != INVALID_TIMER )
		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
	if( instance[instance_id].idle_timer != INVALID_TIMER )
		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);

	instance[instance_id].ivar = NULL;
	instance[instance_id].svar = NULL;

	if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL )
		p->instance_id = 0; // Update Party information

	ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
	memset( &instance[instance_id], 0x00, sizeof(instance[0]) );

	instance[instance_id].state = INSTANCE_FREE;
}
예제 #5
0
/*--------------------------------------
 * m : source map
 * instance_id : where to search
 * result : mapid of map "m" in this instance
 *--------------------------------------*/
int instance_mapid2imapid(int m, int instance_id)
{
	if( map[m].flag.src4instance == 0 )
		return m; // not instances found for this map
	else if( map[m].instance_id )
	{ // This map is a instance, not a src map instance
		ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
		return -1;
	}

	if( !instance_is_valid(instance_id) )
		return -1;

	return instance_map2imap(m, instance_id);
}
예제 #6
0
/*--------------------------------------
 * Set instance Timers
 *--------------------------------------*/
void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout)
{
	time_t now = time(0);

	if( !instance_is_valid(instance_id) )
		return;

	if( instance[instance_id].progress_timer != INVALID_TIMER )
		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
	if( instance[instance_id].idle_timer != INVALID_TIMER )
		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);

	if( progress_timeout )
	{
		instance[instance_id].progress_timeout = now + progress_timeout;
		instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
	}
	else
	{
		instance[instance_id].progress_timeout = 0;
		instance[instance_id].progress_timer = INVALID_TIMER;
	}

	if( idle_timeout )
	{
		instance[instance_id].idle_timeoutval = idle_timeout;
		instance[instance_id].idle_timer = INVALID_TIMER;
		instance_check_idle(instance_id);
	}
	else
	{
		instance[instance_id].idle_timeoutval = 0;
		instance[instance_id].idle_timeout = 0;
		instance[instance_id].idle_timer = INVALID_TIMER;
	}

	if( instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER )
		clif_instance(instance_id, 3, 0);
}
예제 #7
0
/*--------------------------------------
 * Add a map to the instance using src map "name"
 *--------------------------------------*/
int instance_add_map(const char *name, int instance_id, bool usebasename)
{
	int m = map_mapname2mapid(name), i, im = -1;
	size_t num_cell, size;

	if( m < 0 )
		return -1; // source map not found

	if( !instance_is_valid(instance_id) )
	{
		ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
		return -1;
	}
	if( instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE )
	{
		ShowError("instance_add_map: trying to add '%s' map to instance %d (%s) failed. Please increase MAX_MAP_PER_INSTANCE.\n", name, instance_id, instance[instance_id].name);
		return -2;
	}
	if( map[m].instance_id != 0 )
	{ // Source map already belong to a Instance.
		ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
		return -4;
	}

	ARR_FIND( instance_start, map_num, i, !map[i].name[0] ); // Searching for a Free Map
	if( i < map_num ) im = i; // Unused map found (old instance)
	else if( map_num - 1 >= MAX_MAP_PER_SERVER )
	{ // No more free maps
		ShowError("instance_add_map: no more free space to create maps on this server.\n");
		return -5;
	}
	else im = map_num++; // Using next map index

	memcpy( &map[im], &map[m], sizeof(struct map_data) ); // Copy source map
	snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
	map[im].index = mapindex_addmap(-1, map[im].name); // Add map index

	if( !map[im].index )
	{
		map[im].name[0] = '\0';
		ShowError("instance_add_map: no more free map indexes.\n");
		return -3; // No free map index
	}

	// Reallocate cells
	num_cell = map[im].xs * map[im].ys;
	CREATE( map[im].cell, struct mapcell, num_cell );
	memcpy( map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell) );

	size = map[im].bxs * map[im].bys * sizeof(struct block_list*);
	map[im].block = (struct block_list**)aCalloc(size, 1);
	map[im].block_mob = (struct block_list**)aCalloc(size, 1);

	memset(map[im].npc, 0x00, sizeof(map[i].npc));
	map[im].npc_num = 0;

	memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
	map[im].mob_delete_timer = INVALID_TIMER;

	map[im].m = im;
	map[im].instance_id = instance_id;
	map[im].instance_src_map = m;
	map[m].flag.src4instance = 1; // Flag this map as a src map for instances

	instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
	map_addmap2db(&map[im]);

	return im;
}