Rework Item Queue, Repeated connections should no longer give multiple copies of the same item
This commit is contained in:
@@ -30,6 +30,7 @@ ArchipelagoClient::ArchipelagoClient() {
|
|||||||
|
|
||||||
namespace apc = AP_Client_consts;
|
namespace apc = AP_Client_consts;
|
||||||
CVarSetInteger(CVAR_REMOTE_ARCHIPELAGO("Connected"), 0);
|
CVarSetInteger(CVAR_REMOTE_ARCHIPELAGO("Connected"), 0);
|
||||||
|
bool itemQueued = false;
|
||||||
|
|
||||||
// call poll every frame
|
// call poll every frame
|
||||||
COND_HOOK(GameInteractor::OnGameFrameUpdate, true, [](){ArchipelagoClient::GetInstance().Poll();});
|
COND_HOOK(GameInteractor::OnGameFrameUpdate, true, [](){ArchipelagoClient::GetInstance().Poll();});
|
||||||
@@ -73,7 +74,14 @@ 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, item.index);
|
ApItem apItem;
|
||||||
|
const std::string game = apClient->get_player_game(item.player);
|
||||||
|
apItem.itemName = apClient->get_item_name(item.item, game);
|
||||||
|
apItem.locationName = apClient->get_location_name(item.location, game);
|
||||||
|
apItem.playerName = apClient->get_player_alias(item.player);
|
||||||
|
apItem.flags = item.flags;
|
||||||
|
apItem.index = item.index;
|
||||||
|
OnItemReceived(apItem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,23 +195,37 @@ void ArchipelagoClient::CheckLocation(RandomizerCheck sohCheckId) {
|
|||||||
apClient->LocationChecks({ apItemId });
|
apClient->LocationChecks({ apItemId });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::OnItemReceived(int64_t apItemId, int64_t itemIndex) {
|
void ArchipelagoClient::OnItemReceived(const ApItem apItem) {
|
||||||
if(!GameInteractor::IsSaveLoaded(true)) {
|
if(!GameInteractor::IsSaveLoaded(true)) {
|
||||||
// Don't queue up any items when we aren't in game
|
// 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
|
// Any Items missed this way will get synched when we load the save
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(itemIndex < gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex) {
|
std::string logMessage = "[Log] Recieved " + apItem.itemName;
|
||||||
// Skip recieving any items we already have
|
ArchipelagoConsole_SendMessage(logMessage.c_str());
|
||||||
|
|
||||||
|
// add item to the queue
|
||||||
|
recieveQueue.push(apItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArchipelagoClient::QueueItem(const ApItem item) {
|
||||||
|
if(item.index < gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex) {
|
||||||
|
// Skip queueing any items we already have
|
||||||
|
std::string logMessage = "[Log] Skipping giving " + item.itemName + ". We recieved this previously.";
|
||||||
|
ArchipelagoConsole_SendMessage(logMessage.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string item_name = apClient->get_item_name(apItemId, AP_Client_consts::AP_GAME_NAME);
|
std::string logMessage = "[Log] Giving " + item.itemName;
|
||||||
std::string logMessage = "[Log] Recieved " + item_name;
|
|
||||||
ArchipelagoConsole_SendMessage(logMessage.c_str());
|
ArchipelagoConsole_SendMessage(logMessage.c_str());
|
||||||
const RandomizerGet item = Rando::StaticData::itemNameToEnum[item_name];
|
const RandomizerGet RG = Rando::StaticData::itemNameToEnum[item.itemName];
|
||||||
GameInteractor_ExecuteOnArchipelagoItemRecieved(static_cast<int32_t>(item));
|
if(RG == RG_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemQueued = true;
|
||||||
|
GameInteractor_ExecuteOnArchipelagoItemRecieved(static_cast<int32_t>(RG));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchipelagoClient::SendGameWon() {
|
void ArchipelagoClient::SendGameWon() {
|
||||||
@@ -218,6 +240,14 @@ void ArchipelagoClient::Poll() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queue another item to be recieved
|
||||||
|
if(!itemQueued && recieveQueue.size() > 0) {
|
||||||
|
|
||||||
|
const ApItem item = recieveQueue.front();
|
||||||
|
recieveQueue.pop();
|
||||||
|
QueueItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
apClient->poll();
|
apClient->poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,6 +399,7 @@ void RegisterArchipelago() {
|
|||||||
[](uint32_t rc) {
|
[](uint32_t rc) {
|
||||||
if (rc == RC_ARCHIPELAGO_RECIEVED_ITEM) {
|
if (rc == RC_ARCHIPELAGO_RECIEVED_ITEM) {
|
||||||
gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex++;
|
gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex++;
|
||||||
|
ArchipelagoClient::GetInstance().itemQueued = false;
|
||||||
} else {
|
} else {
|
||||||
ArchipelagoClient::GetInstance().CheckLocation((RandomizerCheck)rc);
|
ArchipelagoClient::GetInstance().CheckLocation((RandomizerCheck)rc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#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 <vector>
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
class APClient;
|
class APClient;
|
||||||
@@ -22,7 +23,7 @@ class ArchipelagoClient{
|
|||||||
std::string locationName;
|
std::string locationName;
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int index;
|
uint64_t index;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ArchipelagoClient& GetInstance();
|
static ArchipelagoClient& GetInstance();
|
||||||
@@ -46,14 +47,15 @@ class ArchipelagoClient{
|
|||||||
bool IsConnected();
|
bool IsConnected();
|
||||||
void CheckLocation(RandomizerCheck SoH_check_id);
|
void CheckLocation(RandomizerCheck SoH_check_id);
|
||||||
|
|
||||||
// todo move me back down when done testing
|
void OnItemReceived(const ApItem apItem);
|
||||||
void OnItemReceived(int64_t apItemId, int64_t itemIndex);
|
void QueueItem(const ApItem item);
|
||||||
|
|
||||||
void SendGameWon();
|
void SendGameWon();
|
||||||
|
|
||||||
void Poll();
|
void Poll();
|
||||||
|
|
||||||
std::unique_ptr<APClient> apClient;
|
std::unique_ptr<APClient> apClient;
|
||||||
|
bool itemQueued;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ArchipelagoClient();
|
ArchipelagoClient();
|
||||||
@@ -71,6 +73,7 @@ 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;
|
||||||
|
std::queue<ApItem> recieveQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoadArchipelagoData();
|
void LoadArchipelagoData();
|
||||||
|
|||||||
@@ -63,7 +63,13 @@ void ArchipelagoSettingsWindow::DrawElement() {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (UIWidgets::Button("Give Blue Rupee",
|
if (UIWidgets::Button("Give Blue Rupee",
|
||||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.0, 0.0)))) {
|
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.0, 0.0)))) {
|
||||||
ArchipelagoClient::GetInstance().OnItemReceived(16711816, true);
|
ArchipelagoClient::ApItem apItem;
|
||||||
|
apItem.itemName = "Blue Rupee";
|
||||||
|
apItem.locationName = "Nowhere";
|
||||||
|
apItem.playerName = "Nobody";
|
||||||
|
apItem.flags = 0b001;
|
||||||
|
apItem.index = 999999;
|
||||||
|
ArchipelagoClient::GetInstance().OnItemReceived(apItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user