/****************************************** Add a scenery on map at given coordinate return nullptr if fails return the scenery id is success the return scenery id must be freed by caller ***********************************************/ char * map_add_scenery(const char * map, int layer, int x, int y, const char * image_name) { char layer_name[SMALL_BUF]; char * id; if (x < 0 || y < 0) { return nullptr; } sprintf(layer_name, "%s%d", MAP_KEY_LAYER, layer); /* Make sure the MAP_KEY_SCENERY group exists */ entry_group_create(MAP_TABLE, map, layer_name, MAP_KEY_SCENERY, nullptr); id = entry_get_unused_group(MAP_TABLE, map, layer_name, MAP_KEY_SCENERY, nullptr); if (id == nullptr) { return nullptr; } SDL_LockMutex(map_mutex); if (entry_write_int(MAP_TABLE, map, x, layer_name, MAP_KEY_SCENERY, id, MAP_KEY_SCENERY_X, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_KEY_SCENERY, nullptr); SDL_UnlockMutex(map_mutex); free(id); return nullptr; } if (entry_write_int(MAP_TABLE, map, y, layer_name, MAP_KEY_SCENERY, id, MAP_KEY_SCENERY_Y, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_KEY_SCENERY, nullptr); SDL_UnlockMutex(map_mutex); free(id); return nullptr; } if (entry_write_string(MAP_TABLE, map, image_name, layer_name, MAP_KEY_SCENERY, id, MAP_KEY_SCENERY_IMAGE, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_KEY_SCENERY, nullptr); SDL_UnlockMutex(map_mutex); free(id); return nullptr; } SDL_UnlockMutex(map_mutex); // Send network notifications context_broadcast_map(map); return id; }
/********************************************************* Set AI script name return -1 on error *********************************************************/ int character_set_ai_script(const char * id, const char * script_name) { if(entry_write_string(CHARACTER_TABLE,id,script_name,CHARACTER_KEY_AI,NULL) == RET_NOK ) { return -1; } return 0; }
/******************************* Write a context to server's disk return RET_NOK on error *******************************/ ret_code_t context_write_to_file(context_t * context) { context_lock_list(); if( context->id == NULL ) { context_unlock_list(); return RET_NOK; } entry_write_string(CHARACTER_TABLE, context->id,context->type,CHARACTER_KEY_TYPE,NULL); entry_write_string(CHARACTER_TABLE, context->id,context->map,CHARACTER_KEY_MAP, NULL); entry_write_int(CHARACTER_TABLE, context->id,context->pos_tx,CHARACTER_KEY_POS_X, NULL); entry_write_int(CHARACTER_TABLE, context->id,context->pos_ty,CHARACTER_KEY_POS_Y, NULL); context_unlock_list(); return RET_OK; }
/****************************************************** Create a new character based on the specified template return the id of the newly created character the returned string MUST BE FREED by caller return nullptr if fails *******************************************************/ char * character_create_from_template(context_t * ctx, const char * my_template, const char * map, int layer, int x, int y) { char * new_id; new_id = file_new(CHARACTER_TABLE, nullptr); if (file_copy(CHARACTER_TEMPLATE_TABLE, my_template, CHARACTER_TABLE, new_id) == false) { file_delete(CHARACTER_TABLE, new_id); return nullptr; } // Check if new character is allowed to be created here if (map_check_tile(ctx, new_id, map, layer, x, y) == 0) { entry_destroy(CHARACTER_TABLE, new_id); file_delete(CHARACTER_TABLE, new_id); free(new_id); return nullptr; } // Write position if (entry_write_string(CHARACTER_TABLE, new_id, map, CHARACTER_KEY_MAP, nullptr) == RET_NOK) { entry_destroy(CHARACTER_TABLE, new_id); file_delete(CHARACTER_TABLE, new_id); free(new_id); return nullptr; } if (entry_write_int(CHARACTER_TABLE, new_id, x, CHARACTER_KEY_POS_X, nullptr) == RET_NOK) { entry_destroy(CHARACTER_TABLE, new_id); file_delete(CHARACTER_TABLE, new_id); free(new_id); return nullptr; } if (entry_write_int(CHARACTER_TABLE, new_id, y, CHARACTER_KEY_POS_Y, nullptr) == RET_NOK) { entry_destroy(CHARACTER_TABLE, new_id); file_delete(CHARACTER_TABLE, new_id); free(new_id); return nullptr; } return new_id; }
/********************************************************* return -1 if error *********************************************************/ int character_set_portrait(const char * id,const char * portrait) { context_t * ctx; if(entry_write_string(CHARACTER_TABLE,id,portrait,CHARACTER_KEY_PORTRAIT,NULL) == RET_NOK ) { return -1; } ctx = context_find(id); network_send_character_file(ctx); return RET_OK; }
/********************************************************************* set the specified attribute tag's value return -1 if fails *********************************************************************/ int attribute_tag_set(const char * table, const char * id, const char * attribute, const char * value) { SDL_LockMutex(attribute_mutex); if(entry_write_string(table,id,value,ATTRIBUTE_GROUP,attribute, ATTRIBUTE_CURRENT, NULL) == RET_NOK ) { SDL_UnlockMutex(attribute_mutex); return -1; } SDL_UnlockMutex(attribute_mutex); return 0; }
static void do_set_pos(context_t * ctx,const char * map, int x, int y, bool change_map) { context_set_map(ctx,map); context_set_pos_tx(ctx,x); context_set_pos_ty(ctx,y); entry_write_string(CHARACTER_TABLE,ctx->id,map,CHARACTER_KEY_MAP,NULL); entry_write_int(CHARACTER_TABLE,ctx->id,x,CHARACTER_KEY_POS_X,NULL); entry_write_int(CHARACTER_TABLE,ctx->id,y,CHARACTER_KEY_POS_Y,NULL); context_spread(ctx); if( change_map == true ) { context_request_other_context(ctx); } }
/****************************************************** Create a new character based on the specified template return the id of the newly created character the returned string MUST BE FREED by caller return NULL if fails *******************************************************/ char * character_create_from_template(context_t * ctx,const char * my_template,const char * map, int layer, int x, int y) { char * new_id; char * templatename; char * fullname; new_id = file_new(CHARACTER_TABLE,NULL); templatename = strconcat(base_directory,"/",CHARACTER_TEMPLATE_TABLE,"/",my_template,NULL); fullname = strconcat(base_directory,"/",CHARACTER_TABLE,"/",new_id,NULL); file_copy(templatename,fullname); free(templatename); free(fullname); /* Check if new character is allowed to be created here */ if(map_check_tile(ctx,new_id,map,layer,x,y) == 0) { entry_destroy(CHARACTER_TABLE,new_id); file_delete(CHARACTER_TABLE,new_id); free(new_id); return NULL; } /* Write position */ if(entry_write_string(CHARACTER_TABLE,new_id,map,CHARACTER_KEY_MAP,NULL) == RET_NOK ) { entry_destroy(CHARACTER_TABLE,new_id); file_delete(CHARACTER_TABLE,new_id); free(new_id); return NULL; } if(entry_write_int(CHARACTER_TABLE,new_id,x,CHARACTER_KEY_POS_X,NULL) == RET_NOK ) { entry_destroy(CHARACTER_TABLE,new_id); file_delete(CHARACTER_TABLE,new_id); free(new_id); return NULL; } if(entry_write_int(CHARACTER_TABLE,new_id,y,CHARACTER_KEY_POS_Y,NULL) == RET_NOK ) { entry_destroy(CHARACTER_TABLE,new_id); file_delete(CHARACTER_TABLE,new_id); free(new_id); return NULL; } return new_id; }
/*********************************** Set offscreen script of a map return RET_NOK if fails ***********************************/ ret_code_t map_set_offscreen(const char * map, const char * script) { ret_code_t res; if (map == nullptr || script == nullptr) { return RET_NOK; } /* Manage concurrent access to map files */ SDL_LockMutex(map_mutex); res = entry_write_string(MAP_TABLE, map, script, MAP_OFFSCREEN, nullptr); SDL_UnlockMutex(map_mutex); return res; }
/*********************************************************** Create a new resource with the specified quantity return the id of the newly created resource the returned string must be freed by caller return NULL if fails ***********************************************************/ char * resource_new(const char * my_template, int quantity) { char * new_id; new_id = item_create_empty(); if( new_id == NULL ) { return NULL; } if(entry_write_string(ITEM_TABLE,new_id,my_template,ITEM_TEMPLATE, NULL) == RET_NOK ) { entry_destroy(ITEM_TABLE,new_id); return NULL; } if(entry_write_int(ITEM_TABLE,new_id,quantity,ITEM_QUANTITY, NULL) == RET_NOK ) { entry_destroy(ITEM_TABLE,new_id); return NULL; } return new_id; }
/****************************************** Add an event on map at given coordinate return nullptr if fails return the event id is success the return event id must be freed by caller ***********************************************/ char * map_add_event(const char * map, int layer, const char * script, int x, int y) { char * id; char layer_name[SMALL_BUF]; if (x < 0 || y < 0) { return nullptr; } sprintf(layer_name, "%s%d", MAP_KEY_LAYER, layer); // Make sure the MAP_ENTRY_EVENT_LIST group exists entry_group_create(MAP_TABLE, map, layer_name, MAP_ENTRY_EVENT_LIST, nullptr); id = entry_get_unused_group(MAP_TABLE, map, layer_name, MAP_ENTRY_EVENT_LIST, nullptr); if (id == nullptr) { return nullptr; } SDL_LockMutex(map_mutex); if (entry_write_int(MAP_TABLE, map, x, layer_name, MAP_ENTRY_EVENT_LIST, id, MAP_EVENT_POS_X, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_ENTRY_EVENT_LIST, nullptr); free(id); SDL_UnlockMutex(map_mutex); return nullptr; } if (entry_write_int(MAP_TABLE, map, y, layer_name, MAP_ENTRY_EVENT_LIST, id, MAP_EVENT_POS_Y, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_ENTRY_EVENT_LIST, nullptr); free(id); SDL_UnlockMutex(map_mutex); return nullptr; } if (entry_write_string(MAP_TABLE, map, script, layer_name, MAP_ENTRY_EVENT_LIST, id, MAP_EVENT_SCRIPT, nullptr) == RET_NOK) { entry_remove_group(MAP_TABLE, map, id, layer_name, MAP_ENTRY_EVENT_LIST, nullptr); free(id); SDL_UnlockMutex(map_mutex); return nullptr; } SDL_UnlockMutex(map_mutex); // Send network notifications context_broadcast_map(map); return id; }