Exemple #1
0
/*==========================================
 * Create subscription timer for party
 *------------------------------------------*/
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;

	if(instance_wait.count == 0 || instance_id <= 0)
		return 0;

	// Check that maps have been added
	ret = instance_addmap(instance_id);

	// 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);

	instance_wait.count--;
	memmove(&instance_wait.id[0], &instance_wait.id[1], sizeof(instance_wait.id[0]) * instance_wait.count);
	memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));

	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)
			clif_instance_changewait(party_getavailablesd(p), i + 1, 1);
	}

	if(instance_wait.count)
		instance_wait.timer = add_timer(gettick() + INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
	else
		instance_wait.timer = INVALID_TIMER;

	return 0;
}
Exemple #2
0
/*--------------------------------------
 * Adds maps to the instance
 *--------------------------------------*/
int instance_addmap(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)
		return 0;

	im = &instance_data[instance_id];

	// If the instance isn't idle, we can't do anything
	if(im->state != INSTANCE_IDLE)
		return 0;

	if((db = instance_searchtype_db(im->type)) == NULL)
		return 0;

	// Set to busy, update timers
	im->state = INSTANCE_BUSY;
	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT / 1000;
	im->idle_timer = add_timer(gettick() + INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);

	// Add the maps
	for(i = 0; i < db->maplist_count; i++) {
		if(strlen(StringBuf_Value(db->maplist[i])) < 1)
			continue;
		else if((m = map_addinstancemap(StringBuf_Value(db->maplist[i]), instance_id)) < 0) {
			// An error occured adding a map
			ShowError("instance_addmap: No maps added to instance %d.\n",instance_id);
			return 0;
		} else {
			im->map[cnt_map].m = m;
			im->map[cnt_map].src_m = map_mapname2mapid(StringBuf_Value(db->maplist[i]));
			cnt_map++;
		}
	}

	im->cnt_map = cnt_map;

	// 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);

	return cnt_map;
}
Exemple #3
0
/// Invoked (from char-server) when a party member leaves the party.
int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type)
{
	struct map_session_data* sd = map_charid2sd(char_id);
	struct party_data* p = party_search(party_id);

	if( p ) {
		int i;
		clif_party_withdraw(party_getavailablesd(p), account_id, name, type, PARTY);
		ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
		if( i < MAX_PARTY ) {
			memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
			memset(&p->data[i], 0, sizeof(p->data[0]));
			p->party.count--;
			party_check_state(p);
		}
	}

	if( sd && sd->status.party_id == party_id ) {
#ifdef BOUND_ITEMS
		int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion
		int j,i;

		party_trade_bound_cancel(sd);
		j = pc_bound_chk(sd,BOUND_PARTY,idxlist);

		for(i = 0; i < j; i++)
			pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL);
#endif

		sd->status.party_id = 0;
		clif_name_area(&sd->bl); //Update name display [Skotlex]
		//TODO: hp bars should be cleared too

		if( p->instance_id ) {
			struct map_data *mapdata = map_getmapdata(sd->bl.m);

			if( mapdata->instance_id ) { // User was on the instance map
				if( mapdata->save.map )
					pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->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);
			}
		}
	}

	return 0;
}
Exemple #4
0
/*--------------------------------------
 * name : instance name
 * Return value could be
 * -4 = no free instances | -3 = already exists | -2 = party not found | -1 = invalid type
 * On success return instance_id
 *--------------------------------------*/
int instance_create(int party_id, const char *name)
{
	short i;
	struct instance_db *db = instance_searchname_db(name);
	struct party_data *p = party_search(party_id);

	if(db == NULL)
		return -1;

	if(p == NULL)
		return -2;

	if(p->instance_id)
		return -3; // Party already instancing

	// Searching a Free Instance
	// 0 is ignored as this mean "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].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].vars = idb_alloc(DB_OPT_RELEASE_DATA);
	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));

	p->instance_id = i;

	instance_wait.id[instance_wait.count++] = p->instance_id;

	clif_instance_create(party_getavailablesd(p), name, instance_wait.count, 1);

	instance_subscription_timer(0, 0, 0, 0);

	ShowInfo("[Instance] Created: %s.\n", name);

	return i;
}
Exemple #5
0
/*==========================================
 * Delete the idle timer
 *------------------------------------------*/
static int instance_stopidletimer(struct instance_data *im)
{
	struct party_data *p;

	nullpo_retr(0, im);
	
	// No timer
	if(im->idle_timer == INVALID_TIMER)
		return 1;

	// Delete the timer - Party has returned or instance is destroyed
	im->idle_limit = 0;
	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);

	return 0;
}
Exemple #6
0
/*==========================================
 * Creates idle timer
 * Default before instance destroy is 5 minutes
 *------------------------------------------*/
static int instance_startidletimer(struct instance_data *im, short instance_id)
{
	struct instance_db *db;
	struct party_data *p;

	nullpo_retr(1, im);

	// No current timer
	if(im->idle_timer != INVALID_TIMER)
		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);

	return 0;
}
Exemple #7
0
/*==========================================
 * Adds timer back to party entering instance
 *------------------------------------------*/
static int instance_startkeeptimer(struct instance_data *im, short instance_id)
{
	struct instance_db *db;
	struct party_data *p;

	nullpo_retr(0, im);

	// No timer
	if(im->keep_timer != -1)
		return 1;

	if((db = instance_searchtype_db(im->type)) == NULL)
		return 1;

	// Add timer
	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 ), db->name, im->keep_limit, im->idle_limit, 1 );

	return 0;
}
Exemple #8
0
/*==========================================
 * Removes a instance, all its maps and npcs.
 *------------------------------------------*/
int instance_destroy(short instance_id)
{
	struct instance_data *im;
	struct party_data *p;
	int i, type = 0;
	unsigned int now = (unsigned int)time(NULL);

	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
		return 1;

	im = &instance_data[instance_id];

	if(im->state == INSTANCE_FREE)
		return 1;

	if(im->state == INSTANCE_IDLE) {
		for(i = 0; i < instance_wait.count; i++) {
			if(instance_wait.id[i] == instance_id) {
				instance_wait.count--;
				memmove(&instance_wait.id[i], &instance_wait.id[i + 1], sizeof(instance_wait.id[0]) * (instance_wait.count - i));
				memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));

				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)
						clif_instance_changewait(party_getavailablesd(p), i + 1, 1);
				}

				if(instance_wait.count)
					instance_wait.timer = add_timer(gettick() + INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
				else
					instance_wait.timer = INVALID_TIMER;
				type = 0;
				break;
			}
		}
	} else {
		if(im->keep_limit && im->keep_limit <= now)
			type = 1;
		else if(im->idle_limit && im->idle_limit <= now)
			type = 2;
		else
			type = 3;

		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
			map_delinstancemap(im->map[i].m);
	}

	if(im->keep_timer != INVALID_TIMER) {
		delete_timer(im->keep_timer, instance_delete_timer);
		im->keep_timer = INVALID_TIMER;
	}

	if(im->idle_timer != INVALID_TIMER) {
		delete_timer(im->idle_timer, instance_delete_timer);
		im->idle_timer = INVALID_TIMER;
	}

	if((p = party_search(im->party_id))) {
		p->instance_id = 0;

		if(type)
			clif_instance_changestatus(party_getavailablesd(p), type, 0, 1);
		else
			clif_instance_changewait(party_getavailablesd(p), 0xffff, 1);
	}

	if(im->vars) {
		db_destroy(im->vars);
		im->vars = NULL;
	}

	ShowInfo("[Instance] Destroyed %d.\n", instance_id);

	memset(&instance_data[instance_id], 0, sizeof(instance_data[instance_id]));

	return 0;
}