aboutsummaryrefslogtreecommitdiff
path: root/internal/world/ground.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-19 18:20:26 -0400
committerhistoria <[not public]>2026-06-19 18:20:26 -0400
commit0ea4eec5dd2122c6704216971eb1249276297867 (patch)
tree430fbbef04e837820f1d031c190f52ecd6112e25 /internal/world/ground.go
parent3a58125d14bb307f861b38c6c5b0a63babde7e08 (diff)
downloadthehouseoficarus-0ea4eec5dd2122c6704216971eb1249276297867.tar.gz
shop fixes, 'toggle' completely removed, movement speed increased
Diffstat (limited to 'internal/world/ground.go')
-rw-r--r--internal/world/ground.go189
1 files changed, 189 insertions, 0 deletions
diff --git a/internal/world/ground.go b/internal/world/ground.go
new file mode 100644
index 0000000..6c3ecf3
--- /dev/null
+++ b/internal/world/ground.go
@@ -0,0 +1,189 @@
+package world
+
+import (
+ "strings"
+)
+
+const DropDespawnTicks = 1000
+const ReserveTicks = 100
+
+type GroundItemInfo struct {
+ ItemID string
+ Quantity int
+ ReservedFor string
+ ReserveTimer int
+ DespawnTimer int
+ IsSpawn bool
+}
+
+type groundEntry struct {
+ itemID string
+ quantity int
+ isSpawn bool
+ respawnTimer int // >0 = counting down to respawn
+ respawnQty int
+ respawnDelay int
+ despawnTimer int // >0 = counting down to despawn (dropped items)
+ reservedFor string
+ reserveTimer int // >0 = counting down reservation
+}
+
+func (w *World) GroundItemsDetailed(roomID int) []GroundItemInfo {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ var out []GroundItemInfo
+ for _, e := range w.groundItems[roomID] {
+ if e.quantity <= 0 {
+ continue
+ }
+ info := GroundItemInfo{
+ ItemID: e.itemID,
+ Quantity: e.quantity,
+ DespawnTimer: e.despawnTimer,
+ IsSpawn: e.isSpawn,
+ }
+ if e.reserveTimer > 0 && e.reservedFor != "" {
+ info.ReservedFor = e.reservedFor
+ info.ReserveTimer = e.reserveTimer
+ }
+ out = append(out, info)
+ }
+ return out
+}
+
+func (w *World) GroundItems(roomID int) map[string]int {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ out := make(map[string]int)
+ for _, e := range w.groundItems[roomID] {
+ if e.quantity > 0 {
+ out[e.itemID] += e.quantity
+ }
+ }
+ return out
+}
+
+func (w *World) AddReservedGroundItem(roomID int, itemID string, qty int, owner string) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ e := &groundEntry{
+ itemID: itemID,
+ quantity: qty,
+ despawnTimer: DropDespawnTicks,
+ reservedFor: owner,
+ reserveTimer: ReserveTicks,
+ }
+ w.groundItems[roomID] = append(w.groundItems[roomID], e)
+}
+
+func (w *World) AddGroundItem(roomID int, itemID string, qty int) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ e := &groundEntry{
+ itemID: itemID,
+ quantity: qty,
+ despawnTimer: DropDespawnTicks,
+ }
+ w.groundItems[roomID] = append(w.groundItems[roomID], e)
+}
+
+func (w *World) RemoveReservedGroundItem(roomID int, itemID string, qty int, owner string) (int, bool) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ removed := 0
+ remaining := qty
+ for _, e := range w.groundItems[roomID] {
+ if remaining <= 0 {
+ break
+ }
+ if !strings.EqualFold(e.itemID, itemID) {
+ continue
+ }
+ if e.quantity <= 0 {
+ continue
+ }
+ if e.reserveTimer > 0 && e.reservedFor != "" && e.reservedFor != owner {
+ return removed, false
+ }
+ take := e.quantity
+ if take > remaining {
+ take = remaining
+ }
+ e.quantity -= take
+ removed += take
+ remaining -= take
+ if e.isSpawn && e.quantity <= 0 && e.respawnDelay > 0 {
+ e.respawnTimer = e.respawnDelay
+ }
+ }
+ return removed, true
+}
+
+func (w *World) RemoveGroundItem(roomID int, itemID string, qty int) int {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ removed := 0
+ remaining := qty
+
+ for _, e := range w.groundItems[roomID] {
+ if remaining <= 0 {
+ break
+ }
+ if !strings.EqualFold(e.itemID, itemID) {
+ continue
+ }
+ if e.quantity <= 0 {
+ continue
+ }
+ take := e.quantity
+ if take > remaining {
+ take = remaining
+ }
+ e.quantity -= take
+ removed += take
+ remaining -= take
+
+ if e.isSpawn && e.quantity <= 0 && e.respawnDelay > 0 {
+ e.respawnTimer = e.respawnDelay
+ }
+ }
+ return removed
+}
+
+func (w *World) tickGroundItemsLocked() {
+ for _, entries := range w.groundItems {
+ for _, e := range entries {
+ if e.respawnTimer > 0 {
+ e.respawnTimer--
+ if e.respawnTimer <= 0 {
+ e.quantity = e.respawnQty
+ w.mergeNearbyItemsLocked(entries, e)
+ }
+ }
+ if e.despawnTimer > 0 {
+ e.despawnTimer--
+ if e.despawnTimer <= 0 {
+ e.quantity = 0
+ }
+ }
+ if e.reserveTimer > 0 {
+ e.reserveTimer--
+ if e.reserveTimer <= 0 {
+ e.reservedFor = ""
+ }
+ }
+ }
+ }
+}
+
+func (w *World) mergeNearbyItemsLocked(entries []*groundEntry, target *groundEntry) {
+ for _, other := range entries {
+ if other != target && other.quantity > 0 && strings.EqualFold(other.itemID, target.itemID) &&
+ (other.reserveTimer <= 0 || other.reservedFor == "") &&
+ other.despawnTimer <= 0 {
+ target.quantity += other.quantity
+ other.quantity = 0
+ }
+ }
+}