mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-30 20:22:04 +00:00 
			
		
		
		
	Merge pull request #1675 from DarkflameUniverse/invisible-items
the client code for this is a mess and should load everything at once or use non race condition code
This commit is contained in:
		| @@ -1141,6 +1141,25 @@ void InventoryComponent::AddItemSkills(const LOT lot) { | ||||
| 	SetSkill(slot, skill); | ||||
| } | ||||
|  | ||||
| void InventoryComponent::FixInvisibleItems() { | ||||
| 	const auto numberItemsLoadedPerFrame = 12.0f; | ||||
| 	const auto callbackTime = 0.125f; | ||||
| 	const auto arbitaryInventorySize = 300.0f; // max in live + dlu is less than 300, seems like a good number. | ||||
| 	auto* const items = GetInventory(eInventoryType::ITEMS); | ||||
| 	if (!items) return; | ||||
|  | ||||
| 	// Add an extra update to make sure the client can see all the items. | ||||
| 	const auto something = static_cast<int32_t>(std::ceil(items->GetItems().size() / arbitaryInventorySize)) + 1; | ||||
| 	LOG_DEBUG("Fixing invisible items with %i updates", something); | ||||
|  | ||||
| 	for (int32_t i = 1; i < something + 1; i++) { | ||||
| 		// client loads 12 items every 1/8 seconds, we're adding a small hack to fix invisible inventory items due to closing the news screen too fast. | ||||
| 		m_Parent->AddCallbackTimer((arbitaryInventorySize / numberItemsLoadedPerFrame) * callbackTime * i, [this]() { | ||||
| 			GameMessages::SendUpdateInventoryUi(m_Parent->GetObjectID(), m_Parent->GetSystemAddress()); | ||||
| 			}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void InventoryComponent::RemoveItemSkills(const LOT lot) { | ||||
| 	const auto info = Inventory::FindItemComponent(lot); | ||||
|  | ||||
|   | ||||
| @@ -404,6 +404,8 @@ public: | ||||
| 	void UpdateGroup(const GroupUpdate& groupUpdate); | ||||
| 	void RemoveGroup(const std::string& groupId); | ||||
|  | ||||
| 	void FixInvisibleItems(); | ||||
|  | ||||
| 	~InventoryComponent() override; | ||||
|  | ||||
| private: | ||||
|   | ||||
| @@ -104,6 +104,18 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	// Currently not actually used for our implementation, however its used right now to get around invisible inventory items in the client. | ||||
| 	case MessageType::Game::SELECT_SKILL: { | ||||
| 		auto var = entity->GetVar<bool>(u"dlu_first_time_load"); | ||||
| 		if (var) { | ||||
| 			entity->SetVar<bool>(u"dlu_first_time_load", false); | ||||
| 			InventoryComponent* inventoryComponent = entity->GetComponent<InventoryComponent>(); | ||||
| 			 | ||||
| 			if (inventoryComponent) inventoryComponent->FixInvisibleItems(); | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case MessageType::Game::PLAYER_LOADED: { | ||||
| 		GameMessages::SendRestoreToPostLoadStats(entity, sysAddr); | ||||
| 		entity->SetPlayerReadyForUpdates(); | ||||
|   | ||||
| @@ -982,7 +982,7 @@ void GameMessages::SendResurrect(Entity* entity) { | ||||
| 				destroyableComponent->SetImagination(imaginationToRestore); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| 		}); | ||||
|  | ||||
| 	CBITSTREAM; | ||||
| 	CMSGHEADER; | ||||
| @@ -5080,6 +5080,12 @@ void GameMessages::HandleSetFlag(RakNet::BitStream& inStream, Entity* entity) { | ||||
|  | ||||
| 	auto character = entity->GetCharacter(); | ||||
| 	if (character) character->SetPlayerFlag(iFlagID, bFlag); | ||||
|  | ||||
| 	// This is always set the first time a player loads into a world from character select | ||||
| 	// and is used to know when to refresh the players inventory items so they show up. | ||||
| 	if (iFlagID == ePlayerFlag::IS_NEWS_SCREEN_VISIBLE && bFlag) { | ||||
| 		entity->SetVar<bool>(u"dlu_first_time_load", true); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void GameMessages::HandleRespondToMission(RakNet::BitStream& inStream, Entity* entity) { | ||||
| @@ -5147,12 +5153,12 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream& inStream, Entity* en | ||||
| 	} | ||||
|  | ||||
| 	if (Game::config->GetValue("allow_players_to_skip_cinematics") != "1" | ||||
| 	|| !player->GetCharacter() | ||||
| 	|| !player->GetCharacter()->GetPlayerFlag(ePlayerFlag::DLU_SKIP_CINEMATICS)) return; | ||||
| 		|| !player->GetCharacter() | ||||
| 		|| !player->GetCharacter()->GetPlayerFlag(ePlayerFlag::DLU_SKIP_CINEMATICS)) return; | ||||
| 	player->AddCallbackTimer(0.5f, [player]() { | ||||
| 		if (!player) return; | ||||
| 		GameMessages::SendEndCinematic(player->GetObjectID(), u"", player->GetSystemAddress()); | ||||
| 	}); | ||||
| 		}); | ||||
| } | ||||
|  | ||||
| void GameMessages::HandleRequestLinkedMission(RakNet::BitStream& inStream, Entity* entity) { | ||||
| @@ -6324,3 +6330,14 @@ void GameMessages::SendForceCameraTargetCycle(Entity* entity, bool bForceCycling | ||||
| 	auto sysAddr = entity->GetSystemAddress(); | ||||
| 	SEND_PACKET; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GameMessages::SendUpdateInventoryUi(LWOOBJID objectId, const SystemAddress& sysAddr) { | ||||
| 	CBITSTREAM; | ||||
| 	CMSGHEADER; | ||||
|  | ||||
| 	bitStream.Write(objectId); | ||||
| 	bitStream.Write(MessageType::Game::UPDATE_INVENTORY_UI); | ||||
| 	 | ||||
| 	SEND_PACKET; | ||||
| } | ||||
|   | ||||
| @@ -677,6 +677,9 @@ namespace GameMessages { | ||||
| 	void HandleUpdateInventoryGroup(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr); | ||||
| 	void HandleUpdateInventoryGroupContents(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr); | ||||
| 	void SendForceCameraTargetCycle(Entity* entity, bool bForceCycling, eCameraTargetCyclingMode cyclingMode, LWOOBJID optionalTargetID); | ||||
|  | ||||
| 	// This is a client gm however its default values are exactly what we need to get around the invisible inventory item issues. | ||||
| 	void SendUpdateInventoryUi(LWOOBJID objectId, const SystemAddress& sysAddr); | ||||
| }; | ||||
|  | ||||
| #endif // GAMEMESSAGES_H | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Aaron Kimbrell
					Aaron Kimbrell