GUI fixed and order import completed

pull/678/head
lucaFiorini 2 months ago
parent 04721ba625
commit 3f678ade03

@ -229,6 +229,11 @@ static std::string FiosMakeFilename(const std::string *path, const char *name, c
* @param last Last element of buffer \a buf.
* @return The completed filename.
*/
std::string FiosMakeOrderListName(const char *name)
{
return FiosMakeFilename(_fios_path, name, ".json");
}
std::string FiosMakeSavegameName(const char *name)
{
const char *extension = (_game_mode == GM_EDITOR) ? ".scn" : ".sav";

@ -15,6 +15,7 @@
#include "newgrf_config.h"
#include "network/core/tcp_content_type.h"
#include <vector>
#include <order_type.h>
/** Special values for save-load window for the data parameter of #InvalidateWindowData. */
@ -51,7 +52,7 @@ DECLARE_ENUM_AS_BIT_SET(SortingBits)
/* Variables to display file lists */
extern SortingBits _savegame_sort_order;
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop);
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop,const Vehicle * veh = nullptr);
void FiosGetSavegameList(SaveLoadOperation fop, bool show_dirs, FileList &file_list);
void FiosGetScenarioList(SaveLoadOperation fop, bool show_dirs, FileList &file_list);
@ -65,6 +66,8 @@ std::optional<uint64_t> FiosGetDiskFreeSpace(const std::string &path);
bool FiosDelete(const char *name);
std::string FiosMakeHeightmapName(const char *name);
std::string FiosMakeSavegameName(const char *name);
std::string FiosMakeOrderListName(const char *name);
FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last);
FiosType FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last);

@ -29,6 +29,10 @@
#include "gamelog.h"
#include "stringfilter_type.h"
#include "gamelog.h"
#include "vehicle_base.h"
#include <string>
#include <fstream>
#include <streambuf>
#include "widgets/fios_widget.h"
@ -370,6 +374,7 @@ struct SaveLoadWindow : public Window {
private:
static const uint EDITBOX_MAX_SIZE = 50;
const Vehicle* veh;
QueryString filename_editbox; ///< Filename editbox.
AbstractFileType abstract_filetype; /// Type of file to select.
SaveLoadOperation fop; ///< File operation to perform.
@ -403,11 +408,13 @@ public:
this->filename_editbox.text.Assign(GenerateDefaultSaveName());
}
SaveLoadWindow(WindowDesc *desc, AbstractFileType abstract_filetype, SaveLoadOperation fop)
SaveLoadWindow(WindowDesc *desc, AbstractFileType abstract_filetype, SaveLoadOperation fop,const Vehicle * veh = nullptr)
: Window(desc), filename_editbox(64), abstract_filetype(abstract_filetype), fop(fop), filter_editbox(EDITBOX_MAX_SIZE)
{
assert(this->fop == SLO_SAVE || this->fop == SLO_LOAD);
this->veh = veh;
/* For saving, construct an initial file name. */
if (this->fop == SLO_SAVE) {
switch (this->abstract_filetype) {
@ -748,9 +755,14 @@ public:
ShowHeightmapLoad();
}else if (this->abstract_filetype == FT_ORDERLIST) {
std::ifstream t(this->selected->name);
std::stringstream buffer;
buffer << t.rdbuf();
veh->orders->FromJSONString(veh, buffer.str());
this->Close();
FILE *dataFile = fopen(this->selected->name, "r");
} else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
ClearErrorMessages();
@ -846,6 +858,18 @@ public:
case WID_SL_SAVE_GAME: // Save game
/* Note, this is also called via the OSK; and we need to lower the button. */
this->HandleButtonClick(WID_SL_SAVE_GAME);
if (this->abstract_filetype == FT_ORDERLIST) {
std::string fileName = FiosMakeOrderListName(this->filename_editbox.text.buf);
std::ofstream output;
output.open(fileName);
output << this->veh->orders->ToJSONString();
output.close();
this->Close();
}
break;
}
}
@ -1085,7 +1109,7 @@ static WindowDesc _save_orderlist_dialog_desc(__FILE__, __LINE__,
* @param abstract_filetype Kind of file to handle.
* @param fop File operation to perform (load or save).
*/
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop)
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop,const Vehicle * veh)
{
CloseWindowById(WC_SAVELOAD, 0);
@ -1105,5 +1129,5 @@ void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fo
sld = (abstract_filetype == FT_HEIGHTMAP) ? &_load_heightmap_dialog_desc : &_load_dialog_desc;
}
new SaveLoadWindow(sld, abstract_filetype, fop);
new SaveLoadWindow(sld, abstract_filetype, fop, veh);
}

@ -5856,3 +5856,8 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
#json messages
STR_ERROR_ORDERLIST_MALFORMED_JSON :{WHITE}Input JSON was malformed
STR_ERROR_JON :{WHITE}JSON error

@ -234,7 +234,7 @@ public:
void MakeLabel(OrderLabelSubType subtype);
std::string ToJSONString() const;
static void FromJSONString(const Vehicle * vehicle,std::string jsonSTR);
static Order FromJSONString(std::string jsonSTR);
/**
* Is this a 'goto' order with a real destination?

@ -26,6 +26,7 @@
#include "core/container_func.hpp"
#include "core/pool_func.hpp"
#include "core/random_func.hpp"
#include "core/serialisation.hpp"
#include "aircraft.h"
#include "roadveh.h"
#include "station_base.h"
@ -41,12 +42,14 @@
#include "train.h"
#include "date_func.h"
#include "3rdparty/nlohmann/json.hpp"
#include "command_aux.h"
#include "table/strings.h"
#include "3rdparty/robin_hood/robin_hood.h"
#include <3rdparty/nlohmann/json.hpp>
#include "safeguards.h"
#include <error.h>
/* DestinationID must be at least as large as every these below, because it can
* be any of them
@ -301,29 +304,67 @@ std::string Order::ToJSONString() const
return out;
}
void Order::FromJSONString(const Vehicle * v,std::string jsonSTR)
Order Order::FromJSONString(std::string jsonSTR)
{
/*
this->type = (OrderType)GB(packed, 0, 8); //done
this->flags = GB(packed, 8, 16); // done
this->dest = GB(packed, 24, 16); // done
this->extra = nullptr; //masive pain ??????
this->next = nullptr;
this->refit_cargo = CARGO_NO_REFIT;
this->occupancy = 0;
this->wait_time = 0;
this->travel_time = 0;
this->max_speed = UINT16_MAX;
*/
//hell
nlohmann::json json = nlohmann::json::parse(jsonSTR);
uint64_t order_pack = json.at("packed-data").get<uint64_t>();
uint64_t extra = json.at("packed-data").get<uint64_t>();
if (!json.contains("packed-data") && json["packed_data"].is_number_integer()) {
Order errOrder;
errOrder.MakeLabel(OLST_TEXT);
errOrder.SetColour(COLOUR_RED);
errOrder.SetLabelText("JSON_ERR: JSON does not contain mandatory 'packed-data' field for this order");
return errOrder;
}
DoCommandPEx(v->tile, v->index, 0, order_pack, CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), nullptr, nullptr, 0);
Order new_order = Order(json.at("packed-data").get<uint64_t>());
if (json.contains("destination-id") && json["destination-id"].is_number_integer())
json["destination-id"].get_to(new_order.dest);
if (json.contains("extra") && json["extra"].is_object()) {
auto &extraJson = json["extra"];
new_order.AllocExtraInfo();
if (extraJson.contains("cargo-type-flags") && extraJson["cargo-type-flags"].is_array())
for (int i = 0; i < 64; i++)
extraJson["cargo-type-flags"][i].get_to(new_order.extra->cargo_type_flags[i]);
if (extraJson.contains("colour"))
extraJson["colour"].get_to(new_order.extra->colour);
if (extraJson.contains("dispatch-index"))
extraJson["dispatch-index"].get_to(new_order.extra->dispatch_index);
if (extraJson.contains("xdata"))
extraJson["xdata"].get_to(new_order.extra->xdata);
if (extraJson.contains("xdata2"))
extraJson["xdata2"].get_to(new_order.extra->xdata2);
if (extraJson.contains("xflags"))
extraJson["xflags"].get_to(new_order.extra->xflags);
}
if (json.contains("refit-cargo"))
json["refit-cargo"].get_to(new_order.refit_cargo);
if (json.contains("wait-time"))
json["wait-time"].get_to(new_order.wait_time);
if (json.contains("travel-time"))
json["travel-time"].get_to(new_order.travel_time);
if (json.contains("max-speed"))
json["max-speed"].get_to(new_order.max_speed);
return new_order;
}
/**
@ -915,33 +956,39 @@ std::string OrderList::ToJSONString()
} while ((o = this->GetNext(o)) != this->GetFirstOrder());
}
std::cout << std::setw(4)<< json.dump() << "\n";
return json.dump();
}
void OrderList::FromJSONString(const Vehicle * v,std::string json_str)
{
nlohmann::json json = nlohmann::json::parse(json_str);
//plan... painful plan
CMD_DELETE_ORDER; //for all existing orders
CMD_INSERT_ORDER; //for each order new
Order errOrder;
errOrder.MakeLabel(OLST_TEXT);
errOrder.SetColour(COLOUR_RED);
nlohmann::json json;
try {
json = nlohmann::json::parse(json_str);
} catch(nlohmann::json::parse_error e){
ShowErrorMessage(STR_ERROR_JON, STR_ERROR_ORDERLIST_MALFORMED_JSON,WL_ERROR);
return;
}
CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE;
CMD_SCHEDULED_DISPATCH_ADD;
CMD_SCHEDULED_DISPATCH_RENAME_SCHEDULE;
//delete all orders before setting the new orders
DoCommandP(v->tile, v->index, v->GetNumOrders(), CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER));
if (json.contains("orders")) {
auto &ordersJson = json["orders"];
if (ordersJson.is_array()) {
for (nlohmann::json::iterator it = ordersJson.begin(); it != ordersJson.end(); ++it) {
auto &orderJson = it.value();
Order::FromJSONString(v,orderJson.dump());
Order new_order = Order::FromJSONString(orderJson.dump());
OrderID new_orderID = v->GetNumOrders();
DoCommandPEx(v->tile, v->index, new_orderID, 0, CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), nullptr, orderJson.dump().c_str(), nullptr, 0);
}
}
}
@ -1179,16 +1226,19 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int
* - p2 = (bit 0 - 15) - the selected order (if any). If the last order is given,
* the order will be inserted before that one
* @param p3 packed order to insert
* @param text unused
* @param orderJson is an optional field for an Order object encoded as JSON
* @return the cost of this operation or an error
*/
CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint32_t p2, uint64_t p3, const char *text, const CommandAuxiliaryBase *aux_data)
CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint32_t p2, uint64_t p3, const char *orderJson, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p2, 0, 16);
Order new_order(p3);
Order new_order = (orderJson != nullptr) ? Order::FromJSONString(orderJson) : Order(p3);
return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false);
VehicleOrderID sel_ord = GB(p2, 0, 16);
VehicleID veh = GB(p1, 0, 20);
CommandCost ret = CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false);
return ret;
}
/**

@ -1548,6 +1548,7 @@ private:
};
int selected_order;
VehicleID vehicle_id;
VehicleOrderID order_over; ///< Order over which another order is dragged, \c INVALID_VEH_ORDER_ID if none.
OrderPlaceObjectState goto_type;
Scrollbar *vscroll;
@ -3491,89 +3492,8 @@ public:
switch (index) {
case 0: this->OrderClick_ReverseOrderList(0); break;
case 1: this->OrderClick_ReverseOrderList(1); break;
case 2: this->vehicle->orders->ToJSONString(); break;
case 3: this->vehicle->orders->FromJSONString(this->vehicle, R"({
"head": {
"scheduled-dispatch": [
{
"duration": 106560,
"flags": 0,
"max-delay": 0,
"name": "alfredo",
"slots": [
{
"flags": 0,
"offset": 4514
},
{
"flags": 0,
"offset": 90280
}
],
"start-tick": 16729920
}
]
},
"orders": [
{
"destination-id": 2,
"destination-name": "Grateley Halt",
"max-speed": 65535,
"packed-data": 33554513,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
},
{
"destination-id": 3,
"destination-name": "Grateley Exchange",
"max-speed": 65535,
"packed-data": 50331729,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
},
{
"destination-id": 4,
"destination-name": "Grateley Annexe",
"max-speed": 65535,
"packed-data": 67108945,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
},
{
"destination-id": 3,
"destination-name": "Grateley Exchange",
"max-speed": 65535,
"packed-data": 50331729,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
},
{
"destination-id": 2,
"destination-name": "Grateley Halt",
"max-speed": 65535,
"packed-data": 33554513,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
},
{
"destination-id": 1,
"destination-name": "Grateley Transfer",
"max-speed": 65535,
"packed-data": 16777297,
"refit-cargo": 254,
"travel-time": 0,
"wait-time": 0
}
]
})"); break;
//case 2: ShowSaveLoadDialog(FT_ORDERLIST, SLO_SAVE); break;
//case 3: ShowSaveLoadDialog(FT_ORDERLIST, SLO_LOAD); break;
case 2: ShowSaveLoadDialog(FT_ORDERLIST, SLO_SAVE, this->GetVehicle()); break;
case 3: ShowSaveLoadDialog(FT_ORDERLIST, SLO_LOAD, this->GetVehicle()); break;
default: NOT_REACHED();
}
break;

@ -86,7 +86,7 @@
/* Define all types here, so we don't have to include the whole _type.h maze */
typedef uint BridgeType; ///< Internal name, not of any use for you.
typedef byte CargoID; ///< The ID of a cargo.
typedef uint8_t CargoID; ///< The ID of a cargo.
class CommandCost; ///< The cost of a command.
typedef uint16_t EngineID; ///< The ID of an engine.
typedef uint16_t GoalID; ///< The ID of a goal.

Loading…
Cancel
Save