Example #1
0
/*******************************
Update the memory context by reading the character's data file on disk
Return RET_NOK if there is an error
*******************************/
ret_code_t context_update_from_file(context_t * context)
{
	/* Don't call context_set_* functions here to avoid inter-blocking */

	char * result;
	ret_code_t ret  = RET_OK;

	context_lock_list();

	if( context->id == NULL ) {
		context_unlock_list();
		return RET_NOK;
	}

	if(entry_read_string(CHARACTER_TABLE,context->id,&result, CHARACTER_KEY_NAME,NULL) == RET_OK ) {
		free( context->character_name );
		context->character_name = result;
	} else {
		ret = RET_NOK;
	}


	if(entry_read_string(CHARACTER_TABLE,context->id,&result, CHARACTER_KEY_TYPE,NULL) == RET_OK ) {
		free( context->type );
		context->type = result;
	} else {
		ret = RET_NOK;
	}

	if(entry_read_string(CHARACTER_TABLE,context->id,&result, CHARACTER_KEY_MAP,NULL) == RET_OK ) {
		free( context->map );
		ret = _context_set_map(context, result);
		free(result);
	} else {
		ret = RET_NOK;
	}

	int pos_tx;
	if(entry_read_int(CHARACTER_TABLE,context->id,&pos_tx, CHARACTER_KEY_POS_X,NULL) == RET_NOK ) {
		ret = RET_NOK;
	}
	_context_set_pos_tx(context,pos_tx);

	int pos_ty;
	if(entry_read_int(CHARACTER_TABLE,context->id,&pos_ty, CHARACTER_KEY_POS_Y,NULL) == RET_NOK ) {
		ret = RET_NOK;
	}
	_context_set_pos_ty(context,pos_ty);

	context_unlock_list();
	return ret;
}
Example #2
0
/*****************************************************
 return template name of resource
 Returned string MUST BE FREED
 return NULL  if item is unique (i.e. not a resource)
 *****************************************************/
char * item_is_resource(const char * item_id)
{
	char * my_template = NULL;

	entry_read_string(ITEM_TABLE,item_id,&my_template,ITEM_TEMPLATE, NULL);

	return my_template;
}
Example #3
0
/*********************************************************
 Get character portrait.
must be freed
*********************************************************/
char * character_get_portrait(const char * id)
{
	char * portrait;

	if(entry_read_string(CHARACTER_TABLE,id,&portrait,CHARACTER_KEY_PORTRAIT,NULL) == RET_NOK ) {
		return NULL;
	}

	return portrait;
}
Example #4
0
/*****************************
 Return the name of an item
 return NULL on error
*****************************/
char * item_get_name(const char * item_id)
{
	char * my_template;
	char * name;

	if( (my_template=item_is_resource(item_id)) != NULL ) {
		if(entry_read_string(ITEM_TEMPLATE_TABLE,my_template,&name,ITEM_NAME,NULL) == RET_OK ) {
			free(my_template);
			return name;
		}
		free(my_template);
	} else {
		if(entry_read_string(ITEM_TABLE,item_id,&name,ITEM_NAME,NULL) == RET_OK ) {
			return name;
		}
	}

	return NULL;
}
Example #5
0
/****************************************
get the specified attribute tag's value
return NULL if fails
returned value MUST be freed
****************************************/
char * attribute_tag_get(const char * table, const char *id, const char * attribute)
{
	char * tag = NULL;

	SDL_LockMutex(attribute_mutex);

	entry_read_string(table,id,&tag,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_CURRENT, NULL);

	SDL_UnlockMutex(attribute_mutex);

	return tag;
}
Example #6
0
void character_user_send(context_t * p_pCtx, const char * p_pCharacterId)
{
	char * l_pType = nullptr;
	char * l_pName = nullptr;

	if (entry_read_string(CHARACTER_TABLE, p_pCharacterId, &l_pType,
	CHARACTER_KEY_TYPE, nullptr) == RET_NOK)
	{
		return;
	}

	if (entry_read_string(CHARACTER_TABLE, p_pCharacterId, &l_pName,
	CHARACTER_KEY_NAME, nullptr) == RET_NOK)
	{
		free(l_pType);
		return;
	}

	network_send_user_character(p_pCtx, p_pCharacterId, l_pType, l_pName);

	free(l_pType);
	free(l_pName);
}
Example #7
0
/**********************************
Draw the "list" keyword of a layer
**********************************/
static void compose_map_scenery(context_t * ctx, int layer_index)
{
	int i = 0;
	int x = 0;
	int y = 0;
	char * image_name = NULL;
	anim_t * anim;
	item_t * item;
	char ** scenery_list = NULL;
	char layer_name[SMALL_BUF];

	sprintf(layer_name,"%s%d",MAP_KEY_LAYER,layer_index);
	if(entry_get_group_list(MAP_TABLE, ctx->map, &scenery_list,layer_name,MAP_KEY_SCENERY,NULL) == RET_NOK ) {
		return;
	}

	while(scenery_list[i] != NULL ) {
		if(entry_read_int(MAP_TABLE, ctx->map, &x,layer_name,MAP_KEY_SCENERY,scenery_list[i],MAP_KEY_SCENERY_X,NULL) == RET_NOK ) {
			i++;
			continue;
		}
		if(entry_read_int(MAP_TABLE, ctx->map, &y,layer_name,MAP_KEY_SCENERY,scenery_list[i],MAP_KEY_SCENERY_Y,NULL) == RET_NOK ) {
			i++;
			continue;
		}
		if(entry_read_string(MAP_TABLE, ctx->map, &image_name,layer_name,MAP_KEY_SCENERY,scenery_list[i],MAP_KEY_SCENERY_IMAGE,NULL) == RET_NOK ) {
			i++;
			continue;
		}

		anim = imageDB_get_anim(ctx,image_name);

		item = item_list_add(&item_list);
		item_set_pos(item, x, y);
		item_set_anim(item,anim,0);
		//item_set_anim(item, x*ctx->tile_width, y*ctx->tile_height, anim,0);

		i++;
	}

	deep_free(scenery_list);
}
Example #8
0
/***********************************
 check if id is allowed to go on a tile
 return 1 if the context is allowed to go to the tile at coord x,y
 return 0 if the context is NOT allowed to go to the tile at coord x,y
 return RET_NOK on error or no data found
 *************************************/
ret_code_t map_check_tile(context_t * ctx, char * id, const char * map,
		int layer, int x, int y)
{
	char * script;
	char sx[64];
	char sy[64];
	char * param[5];
	int res;
	char * tile_type;
	char ** allowed_tile;
	int i = 0;
	int width = 0;
	int height = 0;

	if (entry_read_int(MAP_TABLE, map, &width, MAP_KEY_WIDTH,
			nullptr) == RET_NOK)
	{
		return RET_NOK;
	}
	if (entry_read_int(MAP_TABLE, map, &height, MAP_KEY_HEIGHT,
			nullptr) == RET_NOK)
	{
		return RET_NOK;
	}

	if (x < 0 || y < 0 || x >= width || y >= height)
	{
		return 0;
	}

	// If there is an allowed_tile_script, run it
	if (entry_read_string(CHARACTER_TABLE, id, &script,
			CHARACTER_KEY_ALLOWED_TILE_SCRIPT, nullptr) == RET_OK)
	{
		param[0] = id;
		param[1] = (char *) map;
		sprintf(sx, "%d", x);
		sprintf(sy, "%d", y);
		param[2] = sx;
		param[3] = sy;
		param[4] = nullptr;
		res = action_execute_script(ctx, script, (const char**) param);
		free(script);
		return res;
	}

	// Read tile at given index on this map
	entry_read_int(CHARACTER_TABLE, id, &layer, CHARACTER_LAYER, nullptr);
	tile_type = get_tile_type_through_layer(map, layer, x, y);

	// Allow tile if no type defined
	if (tile_type == nullptr)
	{
		return 1;
	}

	// Allow tile if its type is empty (i.e. "")
	if (tile_type[0] == 0)
	{
		free(tile_type);
		return 1;
	}

	// If there is allowed_tile list, check it
	if (entry_read_list(CHARACTER_TABLE, id, &allowed_tile,
			CHARACTER_KEY_ALLOWED_TILE, nullptr) == RET_OK)
	{
		i = 0;
		while (allowed_tile[i] != nullptr)
		{
			if (strcmp(allowed_tile[i], tile_type) == 0)
			{
				deep_free(allowed_tile);
				free(tile_type);
				return 1;
			}
			i++;
		}

		deep_free(allowed_tile);
		free(tile_type);
		return 0;
	}

	free(tile_type);
	// Allow all tiles by default
	return 1;
}
Example #9
0
/**********************************
Draw a single sprite
if image_file_name is not NULL, this file is used as an image rather than the normal sprite image
**********************************/
static void set_up_sprite(context_t * ctx, const char * image_file_name)
{
	anim_t ** sprite_list;
	anim_t ** sprite_move_list;
	item_t * item;
	int px;
	int py;
	int opx;
	int opy;
	Uint32 current_time;
	int angle;
	int flip;
	int force_flip;
	int move_status;
	char * zoom_str = NULL;
	double zoom = 1.0;
	int sprite_align = ALIGN_CENTER;
	int sprite_offset_y = 0;
	bool force_position = false;

	context_t * player_context = context_get_player();

	if( ctx->map == NULL ) {
		return;
	}
	if( ctx->in_game == false ) {
		return;
	}
	if( strcmp(ctx->map,player_context->map)) {
		return;
	}

	item = item_list_add(&item_list);

	current_time = sdl_get_global_time();

	// Force position when the player has changed map
	if( change_map == true ) {
		ctx->move_start_tick = current_time;
		ctx->animation_tick = current_time;
		force_position = true;
	}
	// Force position when this context has changed map
	if( ctx->change_map == true ) {
		ctx->move_start_tick = current_time;
		ctx->animation_tick = current_time;
		ctx->change_map = false;
		force_position = true;
	}

	if( ctx->animation_tick == 0 ) {
		ctx->animation_tick = current_time;
	}

	if( ctx->cur_pos_px == INT_MAX || ctx->cur_pos_py == INT_MAX ) {
		force_position = true;
	}

	// Detect sprite movement, initiate animation
	if( ctx->pos_changed && force_position == false ) {
		ctx->pos_changed = false;
		ctx->move_start_tick = current_time;
		ctx->start_pos_px = ctx->cur_pos_px;
		ctx->start_pos_py = ctx->cur_pos_py;

		/* flip need to remember previous direction to avoid resetting a
		   east -> west flip when a sprite goes to north for instance.
		   On the contrary rotation must not remember previous state, or
		   the rotation will be wrong.
		   Hence the distinction between orientation (no memory) and
		   direction (memory). */
		ctx->orientation = 0;
		// Compute direction
		if( ctx->pos_tx > ctx->prev_pos_tx ) {
			ctx->direction &= ~WEST;
			ctx->direction |= EAST;
			ctx->orientation |= EAST;
		}
		if( ctx->pos_tx < ctx->prev_pos_tx ) {
			ctx->direction &= ~EAST;
			ctx->direction |= WEST;
			ctx->orientation |= WEST;
		}
		if( ctx->pos_ty > ctx->prev_pos_ty ) {
			ctx->direction &= ~NORTH;
			ctx->direction |= SOUTH;
			ctx->orientation |= SOUTH;
		}
		if( ctx->pos_ty < ctx->prev_pos_ty ) {
			ctx->direction &= ~SOUTH;
			ctx->direction |= NORTH;
			ctx->orientation |= NORTH;
		}
	}

	// Select sprite to display
	sprite_list = select_sprite(ctx,image_file_name);
	if( sprite_list == NULL ) {
		return;
	}
	if( sprite_list[0] == NULL ) {
		free(sprite_list);
		return;
	}
	sprite_move_list = select_sprite_move(ctx,image_file_name);

	// Get position in pixel
	px = map_t2p_x(ctx->pos_tx,ctx->pos_ty,default_layer);
	py = map_t2p_y(ctx->pos_tx,ctx->pos_ty,default_layer);

	// Get per sprite zoom
	if(entry_read_string(CHARACTER_TABLE,ctx->id,&zoom_str,CHARACTER_KEY_ZOOM,NULL) == RET_OK ) {
		zoom = atof(zoom_str);
		free(zoom_str);
	}

	// Align sprite on tile
	entry_read_int(CHARACTER_TABLE,ctx->id,&sprite_align,CHARACTER_KEY_ALIGN,NULL);
	if( sprite_align == ALIGN_CENTER ) {
		px -= ((sprite_list[0]->w*default_layer->map_zoom*zoom)-default_layer->tile_width)/2;
		py -= ((sprite_list[0]->h*default_layer->map_zoom*zoom)-default_layer->tile_height)/2;
	}
	if( sprite_align == ALIGN_LOWER ) {
		px -= ((sprite_list[0]->w*default_layer->map_zoom*zoom)-default_layer->tile_width)/2;
		py -= (sprite_list[0]->h*default_layer->map_zoom*zoom)-default_layer->tile_height ;
	}

	// Add Y offset
	entry_read_int(CHARACTER_TABLE,ctx->id,&sprite_offset_y,CHARACTER_KEY_OFFSET_Y,NULL);
	py += sprite_offset_y;

	// Set sprite to item
	item_set_anim_start_tick(item,ctx->animation_tick);

	if( force_position == true ) {
		ctx->start_pos_px = px;
		ctx->cur_pos_px = px;
		ctx->start_pos_py = py;
		ctx->cur_pos_py = py;
	}

	opx = ctx->start_pos_px;
	opy = ctx->start_pos_py;

	item_set_move(item,opx,opy,px,py,ctx->move_start_tick,VIRTUAL_ANIM_DURATION);
	item_set_save_coordinate(item,&ctx->cur_pos_px,&ctx->cur_pos_py);
	item_set_anim_array(item,sprite_list);
	free(sprite_list);
	item_set_anim_move_array(item,sprite_move_list);
	free(sprite_move_list);

	// Get rotation configuration
	angle = 0;
	if( ctx->orientation & NORTH && ctx->orientation & EAST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_NE_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & SOUTH && ctx->orientation & EAST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_SE_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & SOUTH && ctx->orientation & WEST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_SW_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & NORTH && ctx->orientation & WEST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_NW_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & NORTH ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_N_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & SOUTH ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_S_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & WEST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_W_ROT,NULL);
		item_set_angle(item,(double)angle);
	} else if ( ctx->orientation & EAST ) {
		entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_E_ROT,NULL);
		item_set_angle(item,(double)angle);
	}

	// Get flip configuration
	force_flip = 0;
	entry_read_int(CHARACTER_TABLE,ctx->id,&force_flip,CHARACTER_KEY_FORCE_FLIP,NULL);
	move_status = ctx->direction;
	if( force_flip == true ) {
		move_status = ctx->orientation;
	}

	flip = 0;
	if( angle == 0 ) {
		if( move_status & NORTH ) {
			entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_N_FLIP,NULL);
		}
		if( move_status & SOUTH ) {
			entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_S_FLIP,NULL);
		}
		if( move_status & WEST ) {
			entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_W_FLIP,NULL);
		}
		if( move_status & EAST ) {
			entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_E_FLIP,NULL);
		}

		switch(flip) {
		case 1:
			item_set_flip(item,SDL_FLIP_HORIZONTAL);
			break;
		case 2:
			item_set_flip(item,SDL_FLIP_VERTICAL);
			break;
		case 3:
			item_set_flip(item,SDL_FLIP_HORIZONTAL|SDL_FLIP_VERTICAL);
			break;
		default:
			item_set_flip(item,SDL_FLIP_NONE);
		}
	}

	item_set_click_left(item,cb_select_sprite,ctx->id,NULL);
	item_set_click_right(item,cb_redo_sprite,item,NULL);

	item_set_zoom_x(item,zoom * default_layer->map_zoom );
	item_set_zoom_y(item,zoom * default_layer->map_zoom );
}
Example #10
0
/******************************************************
 return 0 if new position OK or if position has not changed.
 return -1 if the position was not set (because tile not allowed or out of bound)
 ******************************************************/
int character_set_pos(context_t * ctx, const char * map, int x, int y)
{
	char ** event_id;
	char * script;
	char ** param = nullptr;
	int i;
	bool change_map = false;
	int width = x + 1;
	int height = y + 1;
	int warpx = 0;
	int warpy = 0;
	int ctx_layer = 0;
	char layer_name[SMALL_BUF];
	char buf[SMALL_BUF];
	char * coord[3];
	int ret_value;
	int layer;

	if (ctx == nullptr)
	{
		return -1;
	}

	// Do nothing if no move
	if (!strcmp(ctx->map, map) && ctx->pos_tx == x && ctx->pos_ty == y)
	{
		return 0;
	}

	ctx_layer = 0;
	entry_read_int(CHARACTER_TABLE, ctx->id, &ctx_layer, CHARACTER_LAYER,
			nullptr);
	sprintf(layer_name, "%s%d", MAP_KEY_LAYER, ctx_layer);

	entry_read_int(MAP_TABLE, map, &width, MAP_KEY_WIDTH, nullptr);
	entry_read_int(MAP_TABLE, map, &height, MAP_KEY_HEIGHT, nullptr);
	entry_read_int(MAP_TABLE, map, &warpx, MAP_KEY_WARP_X, nullptr);
	entry_read_int(MAP_TABLE, map, &warpy, MAP_KEY_WARP_Y, nullptr);

	// Offscreen script
	entry_read_string(MAP_TABLE, map, &script, MAP_OFFSCREEN, nullptr);
	if (script != nullptr && (x < 0 || y < 0 || x >= width || y >= height))
	{
		snprintf(buf, SMALL_BUF, "%d", x);
		coord[0] = strdup(buf);
		snprintf(buf, SMALL_BUF, "%d", y);
		coord[1] = strdup(buf);
		coord[2] = nullptr;

		ret_value = action_execute_script(ctx, script, (const char **) coord);

		free(coord[0]);
		free(coord[1]);
		free(script);

		return ret_value;
	}
	if (script)
	{
		free(script);
	}

	// Coordinates warping
	if (x < 0)
	{
		if (warpy == 0)
		{
			return -1;
		}
		x = width - 1;
	}
	if (y < 0)
	{
		if (warpy == 0)
		{
			return -1;
		}
		y = height - 1;
	}
	if (x >= width)
	{
		if (warpx == 0)
		{
			return -1;
		}
		x = 0;
	}
	if (y >= height)
	{
		if (warpy == 0)
		{
			return -1;
		}
		y = 0;
	}

	// Check if this character is allowed to go to the target tile
	layer = ctx_layer;
	while (layer >= 0)
	{
		ret_value = map_check_tile(ctx, ctx->id, map, layer, x, y);
		/* not allowed */
		if (ret_value == 0)
		{
			return -1;
		}
		/* allowed */
		if (ret_value == 1)
		{
			break;
		}
		layer--;
	}

	if (layer < 0)
	{
		return -1;
	}

	if (strcmp(ctx->map, map))
	{
		change_map = true;
	}

	/* If this character is a platform, move all characters on it */
	platform_move(ctx, map, x, y, change_map);

	do_set_pos(ctx, map, x, y, change_map);

	event_id = map_get_event(map, ctx_layer, x, y);

	if (event_id)
	{
		i = 0;
		while (event_id[i])
		{
			script = nullptr;
			if (entry_read_string(MAP_TABLE, map, &script, layer_name,
			MAP_ENTRY_EVENT_LIST, event_id[i], MAP_EVENT_SCRIPT,
					nullptr) == RET_OK)
			{
				entry_read_list(MAP_TABLE, map, &param, layer_name,
				MAP_ENTRY_EVENT_LIST, event_id[i], MAP_EVENT_PARAM, nullptr);
			}
			else if (entry_read_string(MAP_TABLE, map, &script,
			MAP_ENTRY_EVENT_LIST, event_id[i], MAP_EVENT_SCRIPT,
					nullptr) == RET_OK)
			{
				entry_read_list(MAP_TABLE, map, &param, MAP_ENTRY_EVENT_LIST,
						event_id[i], MAP_EVENT_PARAM, nullptr);
			}

			if (script == nullptr)
			{
				i++;
				continue;
			}

			action_execute_script(ctx, script, (const char **) param);

			free(script);
			deep_free(param);
			param = nullptr;

			i++;
		}
		deep_free(event_id);
	}

	character_update_aggro(ctx);
	return 0;
}
Example #11
0
/*********************************************
 Send playable character templates
 *********************************************/
void character_playable_send_list(context_t * context)
{
	char * marquee;
	DIR * dir;
	char * dirname;
	struct dirent * ent;

	// Read all files in character template directory
	dirname = strconcat(base_directory, "/", CHARACTER_TEMPLATE_TABLE, nullptr);

	dir = opendir(dirname);
	if (dir == nullptr)
	{
		return;
	}
	free(dirname);

	std::vector<std::string> l_Array;

	while ((ent = readdir(dir)) != nullptr)
	{
		// skip hidden file
		if (ent->d_name[0] == '.')
		{
			continue;
		}

		if (entry_read_string(CHARACTER_TEMPLATE_TABLE, ent->d_name, &marquee,
		CHARACTER_KEY_MARQUEE, nullptr) == RET_OK)
		{
			if (marquee[0] == '\0')
			{
				free(marquee);
				continue;
			}
			free(marquee);
		}
		else
		{
			char ** marquee_list = nullptr;
			if (entry_read_list(CHARACTER_TEMPLATE_TABLE, ent->d_name,
					&marquee_list, CHARACTER_KEY_MARQUEE, nullptr) == RET_NOK)
			{
				wlog(LOGDESIGNER, "%s has no marquee", ent->d_name);
				continue;
			}
			if (marquee_list[0][0] == '\0')
			{
				deep_free(marquee_list);
				continue;
			}
			deep_free(marquee_list);
		}

		// add file name to network frame
		l_Array.push_back(std::string(ent->d_name));
	}

	closedir(dir);

	NetworkFrame l_Frame;
	l_Frame.push(l_Array);

	network_send_command(context, CMD_SEND_PLAYABLE_CHARACTER, l_Frame, false);
}
Example #12
0
/***********************************************************************
 Call aggro script for each context in every npc context aggro dist
 ***********************************************************************/
void character_update_aggro(context_t * agressor)
{
	context_t * target = nullptr;
	context_t * npc = nullptr;
	int aggro_dist;
	char * aggro_script;

	if (agressor == nullptr)
	{
		return;
	}

	if (agressor->map == nullptr)
	{
		return;
	}

	if (agressor->id == nullptr)
	{
		return;
	}

	/* If the current context is an NPC it might be an aggressor: compute its aggro */
	if (character_get_npc(agressor->id) && agressor->luaVM != nullptr)
	{
		if (entry_read_int(CHARACTER_TABLE, agressor->id, &aggro_dist,
		CHARACTER_KEY_AGGRO_DIST, nullptr) == RET_OK)
		{
			if (entry_read_string(CHARACTER_TABLE, agressor->id, &aggro_script,
			CHARACTER_KEY_AGGRO_SCRIPT, nullptr) == RET_OK)
			{
				target = context_get_first();

				while (target != nullptr)
				{
					/* Skip current context */
					if (agressor == target)
					{
						target = target->next;
						continue;
					}
					if (target->id == nullptr)
					{
						target = target->next;
						continue;
					}
					if (target->map == nullptr)
					{
						target = target->next;
						continue;
					}
					/* Skip if not on the same map */
					if (strcmp(agressor->map, target->map) != 0)
					{
						target = target->next;
						continue;
					}
					execute_aggro(agressor, target, aggro_script, aggro_dist);
					target = target->next;
				}
				free(aggro_script);
			}
		}
	}

	/* Compute aggro of all other NPC to the current context */
	target = agressor;
	npc = context_get_first();

	while (npc != nullptr)
	{
		/* Skip current context */
		if (target == npc)
		{
			npc = npc->next;
			continue;
		}
		if (npc->id == nullptr)
		{
			npc = npc->next;
			continue;
		}
		if (npc->map == nullptr)
		{
			npc = npc->next;
			continue;
		}
		if (npc->luaVM == nullptr)
		{
			npc = npc->next;
			continue;
		}
		/* Skip if not on the same map */
		if (strcmp(npc->map, target->map) != 0)
		{
			npc = npc->next;
			continue;
		}
		if (entry_read_int(CHARACTER_TABLE, npc->id, &aggro_dist,
		CHARACTER_KEY_AGGRO_DIST, nullptr) == RET_NOK)
		{
			npc = npc->next;
			continue;
		}
		if (entry_read_string(CHARACTER_TABLE, npc->id, &aggro_script,
		CHARACTER_KEY_AGGRO_SCRIPT, nullptr) == RET_NOK)
		{
			npc = npc->next;
			continue;
		}

		execute_aggro(npc, target, aggro_script, aggro_dist);

		free(aggro_script);

		npc = npc->next;
	}
}
Example #13
0
/**********************************
Compose item on map
**********************************/
static void compose_item(context_t * ctx,int layer_index)
{
	char * sprite_name = NULL;
	int sprite_align = ALIGN_CENTER;
	int sprite_offset_y = 0;
	anim_t * anim;
	item_t * item;
	int x;
	int y;
	int temp_x;
	int temp_y;
	char ** item_id;
	int i;
	static TTF_Font * font = NULL;
	char * mytemplate;
	int quantity;
	char buf[SMALL_BUF];
	char layer_name[SMALL_BUF];

	sprintf(layer_name,"%s%d",MAP_KEY_LAYER,layer_index);

	if(entry_get_group_list(MAP_TABLE,ctx->map,&item_id,layer_name,MAP_ENTRY_ITEM_LIST,NULL) == RET_NOK ) {
		return;
	}

	font = font_get(ctx,ITEM_FONT, ITEM_FONT_SIZE);

	i=0;
	while( item_id[i] != NULL ) {
		sprite_align = ALIGN_CENTER;

		if(entry_read_int(MAP_TABLE,ctx->map,&x,layer_name,MAP_ENTRY_ITEM_LIST,item_id[i],MAP_ITEM_POS_X,NULL) == RET_NOK ) {
			i++;
			continue;
		}

		if(entry_read_int(MAP_TABLE,ctx->map,&y,layer_name,MAP_ENTRY_ITEM_LIST,item_id[i],MAP_ITEM_POS_Y,NULL) == RET_NOK ) {
			i++;
			continue;
		}

		mytemplate = item_is_resource(item_id[i]);

		if ( mytemplate == NULL ) {
			if(entry_read_string(ITEM_TABLE,item_id[i],&sprite_name,ITEM_SPRITE,NULL) == RET_NOK ) {
				i++;
				continue;
			}
			entry_read_int(ITEM_TABLE,item_id[i],&sprite_align,ITEM_ALIGN,NULL);
			entry_read_int(ITEM_TABLE,item_id[i],&sprite_offset_y,ITEM_OFFSET_Y,NULL);
		} else {
			if(entry_read_string(ITEM_TEMPLATE_TABLE,mytemplate,&sprite_name,ITEM_SPRITE,NULL) == RET_NOK ) {
				free(mytemplate);
				i++;
				continue;
			}
			entry_read_int(ITEM_TEMPLATE_TABLE,mytemplate,&sprite_align,ITEM_ALIGN,NULL);
			entry_read_int(ITEM_TEMPLATE_TABLE,mytemplate,&sprite_offset_y,ITEM_OFFSET_Y,NULL);
			free(mytemplate);
		}

		item = item_list_add(&item_list);

		anim = imageDB_get_anim(ctx,sprite_name);
		free(sprite_name);

		temp_x = map_t2p_x(x,y,default_layer);
		temp_y = map_t2p_y(x,y,default_layer);
		x = temp_x;
		y = temp_y;
		/* Align on tile */
		if( sprite_align == ALIGN_CENTER ) {
			x -= ((anim->w*default_layer->map_zoom)-default_layer->tile_width)/2;
			y -= ((anim->h*default_layer->map_zoom)-default_layer->tile_height)/2;
		}
		if( sprite_align == ALIGN_LOWER ) {
			x -= ((anim->w*default_layer->map_zoom)-default_layer->tile_width)/2;
			y -= (anim->h*default_layer->map_zoom)-default_layer->tile_height;
		}

		y += sprite_offset_y;

		item_set_pos(item,x,y);
		item_set_anim(item,anim,0);
		item_set_zoom_x(item, default_layer->map_zoom );
		item_set_zoom_y(item, default_layer->map_zoom );
		if(font) {
			quantity = resource_get_quantity(item_id[i]);
			sprintf(buf,"%d",quantity);
			item_set_string(item,buf);
			item_set_font(item,font);
		}

		i++;
	}

	deep_free(item_id);
}
Example #14
0
/***************************************************************************
Add the specified value to the specified attribute
Check on max and min are done and call to on_* scripts are done if set
ctx is the context of the source of the attribute change request
id is the id of the target of the change
return -1 if fails
***************************************************************************/
int attribute_change(context_t * context, const char * table, const char * id, const char * attribute, int value)
{
	int current;
	int old;
	int min;
	int max;
	char buf[SMALL_BUF];
	bool do_min_action = false;
	bool do_down_action = false;
	bool do_max_action = false;
	bool do_up_action = false;
	char * action;
	char * min_action = NULL;
	char * down_action = NULL;
	char * max_action = NULL;
	char * up_action = NULL;

	SDL_LockMutex(attribute_mutex);

	if(entry_read_int(table,id,&current,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_CURRENT, NULL) == RET_NOK) {
		SDL_UnlockMutex(attribute_mutex);
		return -1;
	}

	if(entry_read_int(table,id,&min,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_MIN, NULL) == RET_NOK) {
		min = -1;
	}

	if(entry_read_int(table,id,&max,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_MAX, NULL) == RET_NOK) {
		max = -1;
	}

	old = current;
	current = current + value;
	if( min != -1 ) {
		if(current <= min) {
			do_min_action = true;
			current = min;
		}
	}

	if( max != -1 ) {
		if(current >= max) {
			do_max_action = true;
			current = max;
		}
	}

	if(entry_write_int(table,id,current,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_CURRENT, NULL) == RET_NOK ) {
		SDL_UnlockMutex(attribute_mutex);
		return -1;
	}
	if(entry_write_int(table,id,old,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_PREVIOUS, NULL) == RET_NOK ) {
		SDL_UnlockMutex(attribute_mutex);
		return -1;
	}

	// Check automatic actions
	if( value < 0 ) {
		if( do_min_action == true ) {
			if(entry_read_string(table,id,&action,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_ON_MIN, NULL) == RET_NOK ) {
				do_min_action = false;
			} else {
				min_action = action;
			}
		}

		if(entry_read_string(table,id,&action,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_ON_DOWN, NULL) == RET_OK ) {
			do_down_action = true;
			down_action = action;
		}
	}

	if( value > 0 ) {
		if( do_max_action == true ) {
			if(entry_read_string(table,id,&action,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_ON_MAX, NULL) == RET_NOK ) {
				do_max_action = false;
			} else {
				max_action = action;
			}
		}

		if(entry_read_string(table,id,&action,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_ON_UP, NULL) == RET_OK ) {
			do_up_action = true;
			up_action = action;
		}
	}

	SDL_UnlockMutex(attribute_mutex);

	// do automatic actions
	if( do_down_action == true && down_action != NULL ) {
		action_execute_script(context,down_action,NULL);
	}
	if( down_action ) {
		free(down_action);
	}

	if( do_min_action == true && min_action != NULL ) {
		action_execute_script(context,min_action,NULL);
	}
	if( min_action ) {
		free(min_action);
	}

	if( do_up_action == true && up_action != NULL ) {
		action_execute_script(context,up_action,NULL);
	}
	if( min_action ) {
		free(up_action);
	}

	if( do_max_action == true && max_action != NULL ) {
		action_execute_script(context,max_action,NULL);
		free(max_action);
	}
	if( max_action ) {
		free(max_action);
	}

	sprintf(buf,"%s.%s.%s",ATTRIBUTE_GROUP,attribute,ATTRIBUTE_CURRENT);
	network_broadcast_entry_int(table,id,buf,current,true);
	sprintf(buf,"%s.%s.%s",ATTRIBUTE_GROUP,attribute,ATTRIBUTE_PREVIOUS);
	network_broadcast_entry_int(table,id,buf,old,true);
	return 0;
}
Example #15
0
/**************************************
Return RET_NOK on error
**************************************/
ret_code_t parse_incoming_data(context_t * context, Uint32 command, Uint32 command_size, char * data)
{
	char * value = NULL;
	char * fullname;
	char * elements[512];
	char * cksum;
	int i;
	char * user_name;
	char * password;

	if( !context_get_connected(context) && ( command != CMD_REQ_LOGIN  && command != CMD_REQ_FILE) ) {
		werr(LOGUSER,"Request from not authenticated client, close connection");
		return RET_NOK;
	}

	switch(command) {
	case CMD_REQ_LOGIN:
		wlog(LOGDEBUG,"Received CMD_REQ_LOGIN");
		user_name = _strsep(&data,NETWORK_DELIMITER);
		password = _strsep(&data,NETWORK_DELIMITER);

		if(entry_read_string(PASSWD_TABLE, user_name, &value, PASSWD_KEY_PASSWORD,NULL) == RET_NOK) {
			return RET_NOK;
		}
		if( strcmp(value, password) != 0) {
			free(value);
			werr(LOGUSER,"Wrong login for %s",user_name);
			// send answer
			network_send_command(context, CMD_SEND_LOGIN_NOK, 0, NULL, false);
			// force client disconnection
			return RET_NOK;
		} else {
			free(value);

			if( context_set_username(context, user_name) == RET_NOK ) {
				return RET_NOK;
			}
			context_set_connected(context, true);

			// send answer
			network_send_command(context, CMD_SEND_LOGIN_OK, 0, NULL, false);
			wlog(LOGUSER,"Login successful for user %s",context->user_name);
		}
		break;
	case CMD_REQ_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_CHARACTER_LIST");
		character_send_list(context);
		wlog(LOGDEBUG,"character list sent");
		break;
	case CMD_REQ_FILE :
		i = 0;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}

		if(elements[0]==NULL || elements[1]==NULL) {
			werr(LOGDEV,"Received erroneous CMD_REQ_FILE");
			break;
		}
		wlog(LOGDEBUG,"Received CMD_REQ_FILE for %s",elements[0]);
		/* compare checksum */
		fullname = strconcat(base_directory,"/",elements[0],NULL);

		cksum = checksum_file(fullname);
		free(fullname);

		if( cksum == NULL) {
			werr(LOGUSER,"Required file %s doesn't exists",elements[0]);
			break;
		}

		if( strcmp(elements[1],cksum) == 0 ) {
			wlog(LOGDEBUG,"Client has already newest %s file",elements[0]);
			free(cksum);
			break;
		}
		free(cksum);

		network_send_file(context,elements[0]);
		wlog(LOGDEBUG,"File %s sent",elements[0]);
		break;
	case CMD_REQ_USER_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_USER_CHARACTER_LIST");
		character_user_send_list(context);
		wlog(LOGDEBUG,"user %s's character list sent",context->user_name);
		break;
	case CMD_REQ_START :
		if( context->in_game == false ) {
			context->id = strdup(data);
			context->in_game = true;
			context_update_from_file(context);
			context_spread(context);
			context_request_other_context(context);
		}
		wlog(LOGDEBUG,"Received CMD_REQ_START for %s /%s",context->user_name,context->id);
		break;
	case CMD_REQ_STOP :
		wlog(LOGDEBUG,"Received CMD_REQ_STOP for %s /%s",context->user_name,context->id);
		if( context->in_game == true ) {
			context->in_game = false;
			if( context->map ) {
				free(context->map);
			}
			context->map = NULL;
			if( context->prev_map ) {
				free(context->prev_map);
			}
			context->prev_map = NULL;
			if( context->id ) {
				free(context->id);
			}
			context->id = NULL;
			context_spread(context);
		}
		break;
	case CMD_REQ_ACTION :
		i = 0;
		elements[i] = NULL;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}
		elements[i+1] = NULL;

		wlog(LOGDEBUG,"Received CMD_REQ_ACTION %s from %s /%s",elements[0],context->user_name,context->character_name);

		action_execute(context,elements[0],&elements[1]);
		break;
	default:
		werr(LOGDEV,"Unknown request %d from client",command);
		return RET_NOK;
	}

	return RET_OK;
}
Example #16
0
void character_user_send_list(context_t * context)
{
	char * data = NULL;
	Uint32 data_size = 0;
	Uint32 string_size = 0;
	char ** character_list;
	char * type;
	char * name;
	int i;

	if(entry_read_list(USERS_TABLE, context->user_name,&character_list,USERS_CHARACTER_LIST,NULL) == RET_NOK ) {
		return;
	}

	i = 0;

	data = strdup("");
	while( character_list[i] != NULL ) {
		if(entry_read_string(CHARACTER_TABLE, character_list[i], &type, CHARACTER_KEY_TYPE,NULL) == RET_NOK ) {
			i++;
			continue;
		}

		if(entry_read_string(CHARACTER_TABLE, character_list[i], &name, CHARACTER_KEY_NAME,NULL) == RET_NOK ) {
			free(type);
			i++;
			continue;
		}

		// add the name of the character to the network frame
		string_size = strlen(character_list[i])+1;
		data = (char*)realloc(data, data_size + string_size);
		memcpy(data+data_size,character_list[i], string_size);
		data_size += string_size;

		// add the type of the character to the network frame
		string_size = strlen(type)+1;
		data = (char*)realloc(data, data_size + string_size);
		memcpy(data+data_size,type, string_size);
		data_size += string_size;

		// add the type of the character to the network frame
		string_size = strlen(name)+1;
		data = (char*)realloc(data, data_size + string_size);
		memcpy(data+data_size,name, string_size);
		data_size += string_size;

		free(type);
		free(name);

		i++;
	}

	deep_free(character_list);

	// Mark the end of the list
	data = (char*)realloc(data, data_size + 1);
	data[data_size] = 0;
	data_size ++;

	network_send_command(context, CMD_SEND_USER_CHARACTER, data_size, data,false);
	free(data);
}
Example #17
0
/**********************************
Compose the character select screen
**********************************/
item_t * scr_play_compose(context_t * ctx)
{
	int bg_red = 0;
	int bg_blue = 0;
	int bg_green = 0;
	char * map_filename;
	int layer_index = 0;
	char * old_sfx = NULL;

	option = option_get();

	if(item_list) {
		item_list_free(item_list);
		item_list = NULL;
	}

	if(ctx->map == NULL ) {
		if(context_update_from_file(ctx) == RET_NOK) {
			return NULL;
		}
	}

	if(init) {
		/* Register this character to receive server notifications */
		network_request_start(ctx,ctx->id);
		ui_play_init();
		init = false;
	}

	sdl_free_keycb();
	sdl_free_mousecb();
	sdl_add_mousecb(MOUSE_WHEEL_UP,cb_zoom);
	sdl_add_mousecb(MOUSE_WHEEL_DOWN,cb_unzoom);

	change_map = ctx->change_map;

	if( change_map == true ) {
		map_filename = strconcat( MAP_TABLE,"/",ctx->map,NULL);
		network_send_req_file(ctx,map_filename);
		free(map_filename);
		if(default_layer) {
			map_layer_delete(default_layer);
		}
		default_layer = map_layer_new(ctx->map,DEFAULT_LAYER,NULL);
	}

	if( default_layer && default_layer->active ) { // Make sure map data are available
		for(layer_index = 0; layer_index < MAX_LAYER; layer_index++) {
			compose_map_set(ctx,layer_index);
			compose_map_scenery(ctx,layer_index);
			compose_item(ctx,layer_index);
			compose_sprite(ctx,layer_index);
			compose_type(ctx,layer_index);
		}
		compose_map_button(ctx);
		compose_select(ctx);

		ui_play_compose(ctx,item_list);

		// force virtual coordinate on map change
		if( change_map == true ) {
			sdl_force_virtual_x(map_t2p_x(ctx->pos_tx,ctx->pos_ty,default_layer) + default_layer->col_width[ctx->pos_tx%default_layer->col_num]/2 + default_layer->row_width[ctx->pos_ty%default_layer->row_num]/2 );
			sdl_force_virtual_y(map_t2p_y(ctx->pos_tx,ctx->pos_ty,default_layer) + default_layer->col_height[ctx->pos_tx%default_layer->col_num]/2 + default_layer->row_height[ctx->pos_ty%default_layer->row_num]/2 );
		}
		// set virtual coordinate on the same map
		else {
			sdl_set_virtual_x(map_t2p_x(ctx->pos_tx,ctx->pos_ty,default_layer) + default_layer->col_width[ctx->pos_tx%default_layer->col_num]/2 + default_layer->row_width[ctx->pos_ty%default_layer->row_num]/2 );
			sdl_set_virtual_y(map_t2p_y(ctx->pos_tx,ctx->pos_ty,default_layer) + default_layer->col_height[ctx->pos_tx%default_layer->col_num]/2 + default_layer->row_height[ctx->pos_ty%default_layer->row_num]/2 );
		}
	}

	entry_read_int(MAP_TABLE,ctx->map,&bg_red,MAP_KEY_BG_RED,NULL);
	entry_read_int(MAP_TABLE,ctx->map,&bg_blue,MAP_KEY_BG_BLUE,NULL);
	entry_read_int(MAP_TABLE,ctx->map,&bg_green,MAP_KEY_BG_GREEN,NULL);
	SDL_SetRenderDrawColor(ctx->render, bg_red, bg_blue, bg_green, 255);

	old_sfx = sfx;
	sfx = NULL;

	entry_read_string(MAP_TABLE,ctx->map,&sfx,MAP_SFX,NULL);

	if(old_sfx)  {
		if( sfx ) {
			if( strcmp(old_sfx,sfx) ) {
				sfx_stop(ctx,old_sfx);
			}
		} else  { // sfx == NULL
			sfx_stop(ctx,old_sfx);
		}
		free(old_sfx);
	}

	if( sfx && sfx[0]!=0 ) {
		sfx_play(ctx,sfx,NO_RESTART);
	}

	return item_list;
}
Example #18
0
static void parse_client_conf()
{
	int version;

	if( already_parsed ) {
		return;
	}

	if (entry_read_int(NULL,CLIENT_CONF_FILE,&version,CLIENT_KEY_VERSION,NULL) == RET_NOK ) {
		return;
	}

	entry_read_string(NULL,CLIENT_CONF_FILE,&option.cursor_over_tile,CLIENT_KEY_CURSOR_OVER_TILE,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.cursor_sprite,CLIENT_KEY_CURSOR_SPRITE,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.cursor_tile,CLIENT_KEY_CURSOR_TILE,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.cursor_equipment,CLIENT_KEY_CURSOR_EQUIPMENT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.cursor_inventory,CLIENT_KEY_CURSOR_INVENTORY,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_up,CLIENT_KEY_ACTION_MOVE_UP,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_down,CLIENT_KEY_ACTION_MOVE_DOWN,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_left,CLIENT_KEY_ACTION_MOVE_LEFT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_right,CLIENT_KEY_ACTION_MOVE_RIGHT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_up_left,CLIENT_KEY_ACTION_MOVE_UP_LEFT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_up_right,CLIENT_KEY_ACTION_MOVE_UP_RIGHT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_down_left,CLIENT_KEY_ACTION_MOVE_DOWN_LEFT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_move_down_right,CLIENT_KEY_ACTION_MOVE_DOWN_RIGHT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_select_character,CLIENT_KEY_ACTION_SELECT_CHARACTER,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_select_tile,CLIENT_KEY_ACTION_SELECT_TILE,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_select_equipment,CLIENT_KEY_ACTION_SELECT_EQUIPMENT,NULL);
	entry_read_string(NULL,CLIENT_CONF_FILE,&option.action_select_inventory,CLIENT_KEY_ACTION_SELECT_INVENTORY,NULL);

	already_parsed = 1;
}
Example #19
0
/**********************************************
 Delete an event on map at given coordinate
 return RET_NOK if fails
 **********************************************/
ret_code_t map_delete_event(const char * map, int layer, const char * script,
		int x, int y)
{
	char ** eventlist;
	int i = 0;
	int mapx;
	int mapy;
	char * map_script = nullptr;
	const char * id = nullptr;
	char layer_name[SMALL_BUF];

	if (x < 0 || y < 0)
	{
		return RET_NOK;
	}

	sprintf(layer_name, "%s%d", MAP_KEY_LAYER, layer);

	/* Manage concurrent acces to map files */
	SDL_LockMutex(map_mutex);
	/* Search events on the specified tile */
	if (entry_get_group_list(MAP_TABLE, map, &eventlist, layer_name,
			MAP_ENTRY_EVENT_LIST, nullptr) == RET_NOK)
	{
		SDL_UnlockMutex(map_mutex);
		return RET_NOK;
	}

	while (eventlist[i] != nullptr)
	{
		if (entry_read_int(MAP_TABLE, map, &mapx, layer_name,
				MAP_ENTRY_EVENT_LIST, eventlist[i], MAP_EVENT_POS_X,
				nullptr) == RET_NOK)
		{
			i++;
			continue;
		}
		if (entry_read_int(MAP_TABLE, map, &mapy, layer_name,
				MAP_ENTRY_EVENT_LIST, eventlist[i], MAP_EVENT_POS_Y,
				nullptr) == RET_NOK)
		{
			i++;
			continue;
		}
		if (entry_read_string(MAP_TABLE, map, &map_script, layer_name,
				MAP_ENTRY_EVENT_LIST, eventlist[i], MAP_EVENT_SCRIPT,
				nullptr) == RET_NOK)
		{
			i++;
			continue;
		}
		if (x == mapx && y == mapy && !strcmp(map_script, script))
		{
			id = eventlist[i];
			free(map_script);
			break;
		}
		free(map_script);
		i++;
	}

	if (id == nullptr)
	{
		SDL_UnlockMutex(map_mutex);
		return RET_NOK;
	}

	/* remove the event from the events list of the map */
	if (entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_ENTRY_EVENT_LIST,
			nullptr) == RET_NOK)
	{
		SDL_UnlockMutex(map_mutex);
		return RET_NOK;
	}

	deep_free(eventlist);

	SDL_UnlockMutex(map_mutex);

	/* Send network notifications */
	context_broadcast_map(map);

	return RET_OK;
}