Zappy GUI
C++ graphic client: renderer, camera, network
Loading...
Searching...
No Matches
TileSlotMap.cpp
Go to the documentation of this file.
1#include "TileSlotMap.hpp"
2
3#include <cstdlib>
4
5static constexpr std::pair<float, float> SLOT_OFFSETS[8] = {
6 {-0.35f, -0.35f}, // 0: corner
7 {0.35f, -0.35f}, // 1: corner
8 {-0.35f, 0.35f}, // 2: corner
9 {0.35f, 0.35f}, // 3: corner
10 {0.00f, -0.35f}, // 4: edge
11 {0.00f, 0.35f}, // 5: edge
12 {-0.35f, 0.00f}, // 6: edge
13 {0.35f, 0.00f}, // 7: edge
14};
15
16std::pair<float, float> TileSlotMap::slotOffset(int slotIndex) { return SLOT_OFFSETS[slotIndex]; }
17
19{
20 // Build shuffled list of free slots for random assignment
21 int free[8], count = 0;
22 for (int i = 0; i < 8; i++)
23 if (!occupied[i]) free[count++] = i;
24
25 if (count == 0) return rand() % 8; // all taken: overlap fallback
26
27 int chosen = free[rand() % count];
28 occupied[chosen] = true;
29 return chosen;
30}
31
32void TileSlotMap::TileOccupancy::release(int slotIndex) { occupied[slotIndex] = false; }
33
34uint64_t TileSlotMap::tileKey(int x, int y)
35{
36 return (static_cast<uint64_t>(static_cast<uint32_t>(x)) << 32) | static_cast<uint32_t>(y);
37}
38
39uint64_t TileSlotMap::resourceKey(int x, int y, int resourceType)
40{
41 // pack x (20 bits), y (20 bits), type (4 bits) into 44 bits — safe for realistic map sizes
42 return (static_cast<uint64_t>(x) << 24) | (static_cast<uint64_t>(y) << 4) |
43 static_cast<uint64_t>(resourceType);
44}
45
46std::array<int, 7> TileSlotMap::updateResourceSlots(int tileX, int tileY,
47 const Resources& resources)
48{
49 std::array<int, 7> result;
50 result.fill(-1);
51
52 for (int i = 0; i < 7; i++) {
53 uint64_t rkey = resourceKey(tileX, tileY, i);
54 bool hasSlot = _resourceSlots.count(rkey) > 0;
55 bool hasCount = resources[i] > 0;
56
57 if (hasCount && !hasSlot) {
58 int slot = _tileOccupancy[tileKey(tileX, tileY)].acquire();
59 _resourceSlots[rkey] = slot;
60 _resourceRotations[rkey] = static_cast<float>(rand() % 360);
61 result[i] = slot;
62 } else if (!hasCount && hasSlot) {
63 _tileOccupancy[tileKey(tileX, tileY)].release(_resourceSlots[rkey]);
64 _resourceSlots.erase(rkey);
65 _resourceRotations.erase(rkey);
66 } else if (hasCount && hasSlot) {
67 result[i] = _resourceSlots[rkey];
68 }
69 }
70
71 return result;
72}
73
74void TileSlotMap::syncEggs(const std::unordered_map<int, Egg>& eggs)
75{
76 // Release slots for eggs that disappeared
77 for (auto it = _knownEggs.begin(); it != _knownEggs.end();) {
78 int id = *it;
79 if (eggs.find(id) == eggs.end()) {
80 auto tileIt = _eggTile.find(id);
81 if (tileIt != _eggTile.end()) {
82 auto [ex, ey] = tileIt->second;
83 _tileOccupancy[tileKey(ex, ey)].release(_eggSlots[id]);
84 _eggTile.erase(tileIt);
85 }
86 _eggSlots.erase(id);
87 it = _knownEggs.erase(it);
88 } else {
89 ++it;
90 }
91 }
92
93 // Assign slots for new eggs
94 for (const auto& [id, egg] : eggs) {
95 if (_knownEggs.find(id) == _knownEggs.end()) {
96 int slot = _tileOccupancy[tileKey(egg.x, egg.y)].acquire();
97 _eggSlots[id] = slot;
98 _eggTile[id] = {egg.x, egg.y};
99 _knownEggs.insert(id);
100 }
101 }
102}
103
104int TileSlotMap::eggSlot(int eggId) const
105{
106 auto it = _eggSlots.find(eggId);
107 return it != _eggSlots.end() ? it->second : -1;
108}
109
110float TileSlotMap::resourceRotation(int tileX, int tileY, int resourceType) const
111{
112 auto it = _resourceRotations.find(resourceKey(tileX, tileY, resourceType));
113 return it != _resourceRotations.end() ? it->second : 0.0f;
114}
115
117{
118 _tileOccupancy.clear();
119 _resourceSlots.clear();
120 _resourceRotations.clear();
121 _eggSlots.clear();
122 _eggTile.clear();
123 _knownEggs.clear();
124}
static constexpr std::pair< float, float > SLOT_OFFSETS[8]
std::unordered_set< int > _knownEggs
static std::pair< float, float > slotOffset(int slotIndex)
Returns the XZ offset pair {dx, dz} for a slot index (0-7).
std::unordered_map< uint64_t, int > _resourceSlots
float resourceRotation(int tileX, int tileY, int resourceType) const
Returns the stable random Y rotation for a resource slot, or 0 if absent.
static uint64_t tileKey(int x, int y)
void syncEggs(const std::unordered_map< int, Egg > &eggs)
Syncs egg slot assignments against the current egg map. Assigns slots to new eggs,...
std::unordered_map< int, std::pair< int, int > > _eggTile
std::array< int, 7 > updateResourceSlots(int tileX, int tileY, const Resources &resources)
Updates slot assignments for all resource types on a tile. Assigns a slot when count goes 0→nonzero,...
void clear()
Resets all state. Call on reconnect.
std::unordered_map< int, int > _eggSlots
static uint64_t resourceKey(int x, int y, int resourceType)
std::unordered_map< uint64_t, float > _resourceRotations
int eggSlot(int eggId) const
Returns the slot index for an egg id, or -1 if unknown.
std::unordered_map< uint64_t, TileOccupancy > _tileOccupancy
void release(int slotIndex)
std::array< bool, 8 > occupied