Added Item Synch on game load
This commit is contained in:
@@ -6,10 +6,12 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "soh/Network/Archipelago/ArchipelagoConsoleWindow.h"
|
#include "soh/Network/Archipelago/ArchipelagoConsoleWindow.h"
|
||||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
#include "soh/Enhancements/randomizer/static_data.h"
|
#include "soh/Enhancements/randomizer/static_data.h"
|
||||||
|
#include "soh/Enhancements/randomizer/context.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
@@ -24,14 +26,15 @@ extern PlayState* gPlayState;
|
|||||||
ArchipelagoClient::ArchipelagoClient() {
|
ArchipelagoClient::ArchipelagoClient() {
|
||||||
std::string uuid = ap_get_uuid("uuid");
|
std::string uuid = ap_get_uuid("uuid");
|
||||||
|
|
||||||
ItemRecievedCallback = nullptr;
|
|
||||||
gameWon = false;
|
gameWon = false;
|
||||||
|
|
||||||
namespace apc = AP_Client_consts;
|
namespace apc = AP_Client_consts;
|
||||||
CVarSetInteger(CVAR_REMOTE_ARCHIPELAGO("Connected"), 0);
|
CVarSetInteger(CVAR_REMOTE_ARCHIPELAGO("Connected"), 0);
|
||||||
|
|
||||||
// call poll every frame
|
// call poll every frame
|
||||||
COND_HOOK(GameInteractor::OnGameFrameUpdate, true, [](){ArchipelagoClient::GetInstance().Poll();})
|
COND_HOOK(GameInteractor::OnGameFrameUpdate, true, [](){ArchipelagoClient::GetInstance().Poll();});
|
||||||
|
COND_HOOK(GameInteractor::OnLoadGame, true, [](int32_t file_id){ArchipelagoClient::GetInstance().GameLoaded();});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchipelagoClient& ArchipelagoClient::GetInstance() {
|
ArchipelagoClient& ArchipelagoClient::GetInstance() {
|
||||||
@@ -63,7 +66,7 @@ bool ArchipelagoClient::StartClient() {
|
|||||||
|
|
||||||
apClient->set_items_received_handler([&](const std::list<APClient::NetworkItem>& items) {
|
apClient->set_items_received_handler([&](const std::list<APClient::NetworkItem>& items) {
|
||||||
for(const APClient::NetworkItem& item : items) {
|
for(const APClient::NetworkItem& item : items) {
|
||||||
OnItemReceived(item.item, false); // todo get rid of notify, since it doesn't work for us right now anyway
|
OnItemReceived(item.item, item.index);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,6 +100,15 @@ bool ArchipelagoClient::StartClient() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArchipelagoClient::GameLoaded() {
|
||||||
|
if(!IS_ARCHIPELAGO) {
|
||||||
|
// apClient->reset();
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SynchItems();
|
||||||
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::StartLocationScouts() {
|
void ArchipelagoClient::StartLocationScouts() {
|
||||||
std::set<int64_t> missing_loc_set = apClient->get_missing_locations();
|
std::set<int64_t> missing_loc_set = apClient->get_missing_locations();
|
||||||
std::set<int64_t> found_loc_set = apClient->get_checked_locations();
|
std::set<int64_t> found_loc_set = apClient->get_checked_locations();
|
||||||
@@ -110,6 +122,32 @@ void ArchipelagoClient::StartLocationScouts() {
|
|||||||
apClient->LocationScouts(location_list);
|
apClient->LocationScouts(location_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArchipelagoClient::SynchItems() {
|
||||||
|
ArchipelagoConsole_SendMessage("[LOG] Synching Items and Locations.");
|
||||||
|
|
||||||
|
// send already checked locations
|
||||||
|
std::list<int64_t> checkedLocations;
|
||||||
|
for(const auto& loc : Rando::StaticData::GetLocationTable()) {
|
||||||
|
const RandomizerCheck rc = loc.GetRandomizerCheck();
|
||||||
|
if(Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained()) {
|
||||||
|
const int64_t apLocation = apClient->get_location_id(loc.GetName());
|
||||||
|
checkedLocations.emplace_back(apLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string locationLog = "[LOG] Synching " + std::to_string(checkedLocations.size())+ " checks already found in game";
|
||||||
|
ArchipelagoConsole_SendMessage(locationLog.c_str());
|
||||||
|
|
||||||
|
apClient->LocationChecks(checkedLocations);
|
||||||
|
// Open checks that have been found previously but went unsaved
|
||||||
|
for(const int64_t apLoc : apClient->get_checked_locations()) {
|
||||||
|
// TODO call location checked function to open any unopened checks.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a Synch request to get any items we may have missed
|
||||||
|
ArchipelagoConsole_SendMessage("[LOG] Sending synch request");
|
||||||
|
apClient->Sync();
|
||||||
|
}
|
||||||
|
|
||||||
bool ArchipelagoClient::IsConnected() {
|
bool ArchipelagoClient::IsConnected() {
|
||||||
return apClient->get_state() == APClient::State::SLOT_CONNECTED;
|
return apClient->get_state() == APClient::State::SLOT_CONNECTED;
|
||||||
}
|
}
|
||||||
@@ -130,16 +168,21 @@ void ArchipelagoClient::CheckLocation(RandomizerCheck sohCheckId) {
|
|||||||
apClient->LocationChecks({ apItemId });
|
apClient->LocationChecks({ apItemId });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::AddItemRecievedCallback(std::function<void(const std::string&)> callback) {
|
void ArchipelagoClient::OnItemReceived(int64_t apItemId, int64_t itemIndex) {
|
||||||
ItemRecievedCallback = callback;
|
if(!GameInteractor::IsSaveLoaded(true)) {
|
||||||
}
|
// Don't queue up any items when we aren't in game
|
||||||
|
// Any Items missed this way will get synched when we load the save
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::RemoveItemRecievedCallback(std::function<void(const std::string&)> old_callback) {
|
if(itemIndex < gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex) {
|
||||||
ItemRecievedCallback = nullptr;
|
// Skip recieving any items we already have
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::OnItemReceived(int64_t recieved_item_id, bool notify_player) {
|
const std::string item_name = apClient->get_item_name(apItemId, AP_Client_consts::AP_GAME_NAME);
|
||||||
const std::string item_name = apClient->get_item_name(recieved_item_id, AP_Client_consts::AP_GAME_NAME);
|
std::string logMessage = "[Log] Recieved " + item_name;
|
||||||
|
ArchipelagoConsole_SendMessage(logMessage.c_str());
|
||||||
const RandomizerGet item = Rando::StaticData::itemNameToEnum[item_name];
|
const RandomizerGet item = Rando::StaticData::itemNameToEnum[item_name];
|
||||||
GameInteractor_ExecuteOnArchipelagoItemRecieved(static_cast<int32_t>(item));
|
GameInteractor_ExecuteOnArchipelagoItemRecieved(static_cast<int32_t>(item));
|
||||||
}
|
}
|
||||||
@@ -159,7 +202,7 @@ void ArchipelagoClient::Poll() {
|
|||||||
apClient->poll();
|
apClient->poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& ArchipelagoClient::GetSlotName() const {
|
const std::string ArchipelagoClient::GetSlotName() const {
|
||||||
if(apClient == NULL) {
|
if(apClient == NULL) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -310,7 +353,7 @@ void RegisterArchipelago() {
|
|||||||
COND_HOOK(GameInteractor::OnRandomizerItemGivenHooks, IS_ARCHIPELAGO,
|
COND_HOOK(GameInteractor::OnRandomizerItemGivenHooks, IS_ARCHIPELAGO,
|
||||||
[](uint32_t rc) {
|
[](uint32_t rc) {
|
||||||
if (rc == RC_ARCHIPELAGO_RECIEVED_ITEM) {
|
if (rc == RC_ARCHIPELAGO_RECIEVED_ITEM) {
|
||||||
// Update lastReceivedIndex
|
gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex++;
|
||||||
} else {
|
} else {
|
||||||
ArchipelagoClient::GetInstance().CheckLocation((RandomizerCheck)rc);
|
ArchipelagoClient::GetInstance().CheckLocation((RandomizerCheck)rc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ class ArchipelagoClient{
|
|||||||
bool StartClient();
|
bool StartClient();
|
||||||
bool StopClient();
|
bool StopClient();
|
||||||
|
|
||||||
|
void GameLoaded();
|
||||||
void StartLocationScouts();
|
void StartLocationScouts();
|
||||||
|
void SynchItems();
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const std::string& GetSlotName() const;
|
const std::string GetSlotName() const;
|
||||||
|
|
||||||
const char* GetConnectionStatus();
|
const char* GetConnectionStatus();
|
||||||
const std::map<std::string, int>& GetSlotData();
|
const std::map<std::string, int>& GetSlotData();
|
||||||
@@ -42,12 +44,8 @@ class ArchipelagoClient{
|
|||||||
bool IsConnected();
|
bool IsConnected();
|
||||||
void CheckLocation(RandomizerCheck SoH_check_id);
|
void CheckLocation(RandomizerCheck SoH_check_id);
|
||||||
|
|
||||||
// callback slots
|
|
||||||
void AddItemRecievedCallback(std::function<void(const std::string&)> callback);
|
|
||||||
void RemoveItemRecievedCallback(std::function<void(const std::string&)> old_callback);
|
|
||||||
|
|
||||||
// todo move me back down when done testing
|
// todo move me back down when done testing
|
||||||
void OnItemReceived(int64_t recieved_item_id, bool notify_player);
|
void OnItemReceived(int64_t apItemId, int64_t itemIndex);
|
||||||
|
|
||||||
void SendGameWon();
|
void SendGameWon();
|
||||||
|
|
||||||
@@ -71,14 +69,6 @@ class ArchipelagoClient{
|
|||||||
std::map<std::string, int> slotData;
|
std::map<std::string, int> slotData;
|
||||||
std::set<int64_t> locations;
|
std::set<int64_t> locations;
|
||||||
std::vector<ApItem> scoutedItems;
|
std::vector<ApItem> scoutedItems;
|
||||||
|
|
||||||
// Callback Functions
|
|
||||||
void OnLocationChecked(int64_t location_id);
|
|
||||||
void OnDeathLinkReceived() { }; // TODO: implement me
|
|
||||||
|
|
||||||
// Callbacks
|
|
||||||
std::function<void(const std::string&)> ItemRecievedCallback;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoadArchipelagoData();
|
void LoadArchipelagoData();
|
||||||
|
|||||||
Reference in New Issue
Block a user