/*********************************** Write an array of tiles into a map set layer tile_array is a nullptr teminated tiles ID return RET_NOK if fails ***********************************/ ret_code_t map_set_tile_array(const char * map, int layer, const char** tile_array) { char ** previous_tile = nullptr; char ** current_tile = nullptr; char layer_name[SMALL_BUF]; if (map == nullptr) { return RET_NOK; } sprintf(layer_name, "%s%d", MAP_KEY_LAYER, layer); /* Manage concurrent access to map files */ SDL_LockMutex(map_mutex); /* read previous map set */ if (entry_read_list(MAP_TABLE, map, &previous_tile, layer_name, MAP_KEY_SET, nullptr) == RET_NOK) { SDL_UnlockMutex(map_mutex); return RET_NOK; } current_tile = previous_tile; while (*tile_array) { free(*current_tile); *current_tile = strdup(*tile_array); current_tile++; tile_array++; } if (entry_write_list(MAP_TABLE, map, previous_tile, layer_name, MAP_KEY_SET, nullptr) == RET_OK) { context_broadcast_map(map); } deep_free(previous_tile); SDL_UnlockMutex(map_mutex); return RET_OK; }
/********************************************* Send playable character templates *********************************************/ void character_send_list(context_t * context) { //TODO #if 0 char ** character_list; int i = 0; if(entry_read_list(USERS_TABLE, context->user_name,&character_list,USERS_CHARACTER_LIST,NULL) == RET_NOK) { return; } while( character_list[i] != NULL ) { network_send_command(context, CMD_SEND_CHARACTER, strlen(character_list[i])+1, character_list[i],false); i++; } deep_free(character_list); #endif }
void character_user_send_list(context_t * context) { char ** l_pCharacterList = nullptr; if (entry_read_list(USERS_TABLE, context->user_name, &l_pCharacterList, USERS_CHARACTER_LIST, nullptr) == RET_NOK) { return; } int l_Index = 0; while (l_pCharacterList[l_Index] != nullptr) { character_user_send(context, l_pCharacterList[l_Index]); l_Index++; } deep_free(l_pCharacterList); }
/********************************** Draw the "set" keyword of a layer **********************************/ static void compose_map_set(context_t * ctx, int layer_index) { int i = 0; int x = 0; int y = 0; anim_t * anim; item_t * item; char ** tile_set = NULL; char layer_name[SMALL_BUF]; layer_t * layer; sprintf(layer_name,"%s%d",MAP_KEY_LAYER,layer_index); if(entry_read_list(MAP_TABLE, ctx->map, &tile_set,layer_name,MAP_KEY_SET,NULL) == RET_NOK ) { return; } layer = map_layer_new(ctx->map,layer_index,default_layer); while(tile_set[i] != NULL ) { /* Skip empty tile */ if( tile_set[i][0] != 0 ) { item = item_list_add(&item_list); anim = imageDB_get_anim(ctx,tile_set[i]); item_set_pos(item,map_t2p_x(x,y,layer),map_t2p_y(x,y,layer)); item_set_anim(item,anim,0); } x++; if(x>=layer->map_w) { x=0; y++; } i++; } deep_free(tile_set); map_layer_delete(layer); }
/****************************************************** 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, ¶m, 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, ¶m, 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; }
/********************************************* 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); }
/*********************************** 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; }
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); }