/****************************************************** 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; }
/****************************************************** 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; }
/****************************************************** 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; }