diff --git a/plugins/proto/AdventureControl.proto b/plugins/proto/AdventureControl.proto index 4db1afdf7..3bef8d939 100644 --- a/plugins/proto/AdventureControl.proto +++ b/plugins/proto/AdventureControl.proto @@ -5,7 +5,71 @@ option optimize_for = LITE_RUNTIME; import "RemoteFortressReader.proto"; +enum AdvmodeMenu +{ + Default = 0; + Look = 1; + ConversationAddress = 2; + ConversationSelect = 3; + ConversationSpeak = 4; + Inventory = 5; + Drop = 6; + ThrowItem = 7; + Wear = 8; + Remove = 9; + Interact = 10; + Put = 11; + PutContainer = 12; + Eat = 13; + ThrowAim = 14; + Fire = 15; + Get = 16; + Unk17 = 17; + CombatPrefs = 18; + Companions = 19; + MovementPrefs = 20; + SpeedPrefs = 21; + InteractAction = 22; + MoveCarefully = 23; + Announcements = 24; + UseBuilding = 25; + Travel = 26; + Unk27 = 27; + Unk28 = 28; + SleepConfirm = 29; + SelectInteractionTarget = 30; + Unk31 = 31; + Unk32 = 32; + FallAction = 33; + ViewTracks = 34; + Jump = 35; + Unk36 = 36; + AttackConfirm = 37; + AttackType = 38; + AttackBodypart = 39; + AttackStrike = 40; + Unk41 = 41; + Unk42 = 42; + DodgeDirection = 43; + Unk44 = 44; + Unk45 = 45; + Build = 46; +} + message MoveCommandParams { optional RemoteFortressReader.Coord direction = 1; +} + +message MovementOption +{ + optional RemoteFortressReader.Coord dest = 1; + optional RemoteFortressReader.Coord source = 2; + optional RemoteFortressReader.Coord grab = 3; +} + +message MenuContents +{ + optional AdvmodeMenu current_menu = 1; + repeated MovementOption movements = 2; } \ No newline at end of file diff --git a/plugins/remotefortressreader/adventure_control.cpp b/plugins/remotefortressreader/adventure_control.cpp index 6e717ebd1..c3c2933ce 100644 --- a/plugins/remotefortressreader/adventure_control.cpp +++ b/plugins/remotefortressreader/adventure_control.cpp @@ -1,6 +1,13 @@ #include "adventure_control.h" #include "DataDefs.h" +#include "df/adventure_movement_attack_creaturest.h" +#include "df/adventure_movement_building_interactst.h" +#include "df/adventure_movement_climbst.h" +#include "df/adventure_movement_hold_itemst.h" +#include "df/adventure_movement_hold_tilest.h" +#include "df/adventure_movement_optionst.h" +#include "df/ui_advmode.h" #include "df/viewscreen.h" #include "modules/Gui.h" @@ -16,198 +23,242 @@ std::queue keyQueue; void KeyUpdate() { - if (!keyQueue.empty()) - { - getCurViewscreen()->feed_key(keyQueue.front()); - keyQueue.pop(); - } + if (!keyQueue.empty()) + { + getCurViewscreen()->feed_key(keyQueue.front()); + keyQueue.pop(); + } +} + +void SetCoord(df::coord in, RemoteFortressReader::Coord *out) +{ + out->set_x(in.x); + out->set_y(in.y); + out->set_z(in.z); } command_result MoveCommand(DFHack::color_ostream &stream, const MoveCommandParams *in) { - auto viewScreen = getCurViewscreen(); - if (!in->has_direction()) - return CR_WRONG_USAGE; - auto dir = in->direction(); - switch (dir.x()) - { - case -1: - switch (dir.y()) - { - case -1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_NW_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_NW); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_NW_UP); - break; - } - break; - case 0: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_W_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_W); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_W_UP); - break; - } - break; - case 1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_SW_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_SW); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_SW_UP); - break; - } - break; - } - break; - case 0: - switch (dir.y()) - { - case -1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_N_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_N); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_N_UP); - break; - } - break; - case 0: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_DOWN); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_UP); - break; - } - break; - case 1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_S_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_S); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_S_UP); - break; - } - break; - } - break; - case 1: - switch (dir.y()) - { - case -1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_NE_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_NE); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_NE_UP); - break; - } - break; - case 0: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_E_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_E); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_E_UP); - break; - } - break; - case 1: - switch (dir.z()) - { - case -1: - viewScreen->feed_key(interface_key::A_MOVE_SE_DOWN); - break; - case 0: - viewScreen->feed_key(interface_key::A_MOVE_SE); - break; - case 1: - viewScreen->feed_key(interface_key::A_MOVE_SE_UP); - break; - } - break; - } - break; - } - return CR_OK; + auto viewScreen = getCurViewscreen(); + if (!in->has_direction()) + return CR_WRONG_USAGE; + if (!df::global::ui_advmode->menu == ui_advmode_menu::Default) + return CR_OK; + auto dir = in->direction(); + switch (dir.x()) + { + case -1: + switch (dir.y()) + { + case -1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_NW_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_NW); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_NW_UP); + break; + } + break; + case 0: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_W_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_W); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_W_UP); + break; + } + break; + case 1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_SW_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_SW); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_SW_UP); + break; + } + break; + } + break; + case 0: + switch (dir.y()) + { + case -1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_N_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_N); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_N_UP); + break; + } + break; + case 0: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_DOWN); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_UP); + break; + } + break; + case 1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_S_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_S); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_S_UP); + break; + } + break; + } + break; + case 1: + switch (dir.y()) + { + case -1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_NE_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_NE); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_NE_UP); + break; + } + break; + case 0: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_E_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_E); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_E_UP); + break; + } + break; + case 1: + switch (dir.z()) + { + case -1: + viewScreen->feed_key(interface_key::A_MOVE_SE_DOWN); + break; + case 0: + viewScreen->feed_key(interface_key::A_MOVE_SE); + break; + case 1: + viewScreen->feed_key(interface_key::A_MOVE_SE_UP); + break; + } + break; + } + break; + } + return CR_OK; } command_result JumpCommand(DFHack::color_ostream &stream, const MoveCommandParams *in) { - if (!in->has_direction()) - return CR_WRONG_USAGE; - auto dir = in->direction(); - keyQueue.push(interface_key::A_JUMP); - int x = dir.x(); - int y = dir.y(); - if (x > 0) - { - for (int i = 0; i < x; i++) - { - keyQueue.push(interface_key::CURSOR_RIGHT); - } - } - if (x < 0) - { - for (int i = 0; i > x; i--) - { - keyQueue.push(interface_key::CURSOR_LEFT); - } - } - if (y > 0) - { - for (int i = 0; i < y; i++) - { - keyQueue.push(interface_key::CURSOR_DOWN); - } - } - if (y < 0) - { - for (int i = 0; i > y; i--) - { - keyQueue.push(interface_key::CURSOR_UP); - } - } - keyQueue.push(interface_key::SELECT); - return CR_OK; -} \ No newline at end of file + if (!in->has_direction()) + return CR_WRONG_USAGE; + if (!df::global::ui_advmode->menu == ui_advmode_menu::Default) + return CR_OK; + auto dir = in->direction(); + keyQueue.push(interface_key::A_JUMP); + int x = dir.x(); + int y = dir.y(); + if (x > 0) + { + for (int i = 0; i < x; i++) + { + keyQueue.push(interface_key::CURSOR_RIGHT); + } + } + if (x < 0) + { + for (int i = 0; i > x; i--) + { + keyQueue.push(interface_key::CURSOR_LEFT); + } + } + if (y > 0) + { + for (int i = 0; i < y; i++) + { + keyQueue.push(interface_key::CURSOR_DOWN); + } + } + if (y < 0) + { + for (int i = 0; i > y; i--) + { + keyQueue.push(interface_key::CURSOR_UP); + } + } + keyQueue.push(interface_key::SELECT); + return CR_OK; +} + +command_result MenuQuery(DFHack::color_ostream &stream, const EmptyMessage *in, MenuContents *out) +{ + auto advUi = df::global::ui_advmode; + + if (advUi == NULL) + return CR_FAILURE; + + out->set_current_menu((AdvmodeMenu)advUi->menu); + + switch (advUi->menu) + { + case ui_advmode_menu::MoveCarefully: + for (size_t i = 0; i < advUi->movements.size(); i++) + { + auto movement = advUi->movements[i]; + auto send_movement = out->add_movements(); + SetCoord(movement->source, send_movement->mutable_source()); + SetCoord(movement->dest, send_movement->mutable_dest()); + + STRICT_VIRTUAL_CAST_VAR(climbMovement, df::adventure_movement_climbst, movement); + if (climbMovement) + SetCoord(climbMovement->grab, send_movement->mutable_grab()); + STRICT_VIRTUAL_CAST_VAR(holdTileMovement, df::adventure_movement_hold_tilest, movement); + if (holdTileMovement) + SetCoord(holdTileMovement->grab, send_movement->mutable_grab()); + } + default: + break; + } + + return CR_OK; +} diff --git a/plugins/remotefortressreader/adventure_control.h b/plugins/remotefortressreader/adventure_control.h index c84fe9722..16d30aeee 100644 --- a/plugins/remotefortressreader/adventure_control.h +++ b/plugins/remotefortressreader/adventure_control.h @@ -6,6 +6,7 @@ DFHack::command_result MoveCommand(DFHack::color_ostream &stream, const AdventureControl::MoveCommandParams *in); DFHack::command_result JumpCommand(DFHack::color_ostream &stream, const AdventureControl::MoveCommandParams *in); +DFHack::command_result MenuQuery(DFHack::color_ostream &stream, const dfproto::EmptyMessage *in, AdventureControl::MenuContents *out); void KeyUpdate(); diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 8ebb75d79..ae392c7c1 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -130,6 +130,7 @@ REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(gamemode); +REQUIRE_GLOBAL(ui_advmode); #endif // Here go all the command declarations... @@ -291,8 +292,9 @@ DFhackCExport RPCService *plugin_rpcconnect(color_ostream &) svc->addFunction("GetVersionInfo", GetVersionInfo, SF_ALLOW_REMOTE); svc->addFunction("GetReports", GetReports, SF_ALLOW_REMOTE); svc->addFunction("MoveCommand", MoveCommand, SF_ALLOW_REMOTE); - svc->addFunction("JumpCommand", JumpCommand, SF_ALLOW_REMOTE); - return svc; + svc->addFunction("JumpCommand", JumpCommand, SF_ALLOW_REMOTE); + svc->addFunction("MenuQuery", MenuQuery, SF_ALLOW_REMOTE); + return svc; } // This is called right before the plugin library is removed from memory.