aboutsummaryrefslogtreecommitdiff
path: root/internal/game/utils.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-10 01:48:28 -0400
committerhistoria <[not public]>2026-06-10 01:48:28 -0400
commita226d72e51eecb768b13600303f73483118d9104 (patch)
tree458d15ef049732c15dacc591a830d3beddbedfde /internal/game/utils.go
parent6a0f3d7a252de4b1741cfe5e1c561412c602becc (diff)
downloadthehouseoficarus-a226d72e51eecb768b13600303f73483118d9104.tar.gz
feat: implemented janky object interaction model
Diffstat (limited to 'internal/game/utils.go')
-rw-r--r--internal/game/utils.go114
1 files changed, 114 insertions, 0 deletions
diff --git a/internal/game/utils.go b/internal/game/utils.go
new file mode 100644
index 0000000..0559f4f
--- /dev/null
+++ b/internal/game/utils.go
@@ -0,0 +1,114 @@
+package game
+
+import (
+ "fmt"
+ "math/rand"
+
+ "thirdcollapse/internal/net"
+ "thirdcollapse/internal/object"
+ "thirdcollapse/internal/player"
+ "thirdcollapse/internal/world"
+)
+
+var EquipSlots = []object.EquipSlot{
+ object.SlotHead, object.SlotNeck, object.SlotTorso, object.SlotLegs,
+ object.SlotHands, object.SlotFeet, object.SlotBack, object.SlotAmmo,
+ object.SlotMainHand, object.SlotOffHand, object.SlotRing,
+}
+
+type itemMatch struct {
+ ID string
+ Name string
+ Slot int
+}
+
+type xpGain struct {
+ Skill string
+ XP int
+}
+
+type deathDrop struct {
+ itemID string
+ quantity int
+ totalVal int
+ isEquip bool
+ equipSlot object.EquipSlot
+ invSlot int
+}
+
+func plural(n int) string {
+ if n == 1 {
+ return ""
+ }
+ return "s"
+}
+
+func parseIndex(s string) (int, error) {
+ var idx int
+ _, err := fmt.Sscanf(s, "%d", &idx)
+ return idx, err
+}
+
+func mobDisplayName(m *world.MobInstance, definite bool) string {
+ if m.Unique {
+ return m.Name
+ }
+ if definite {
+ return "the " + m.Name
+ }
+ return "a " + m.Name
+}
+
+func mobCombatLevel(m *world.MobInstance) int {
+ return int(0.25*float64(m.Attack+m.Strength+m.Defense+m.MaxHP) + 0.5)
+}
+
+func uniqueItemNames(matches []itemMatch) []string {
+ seen := make(map[string]bool)
+ var out []string
+ for _, m := range matches {
+ if !seen[m.Name] {
+ seen[m.Name] = true
+ out = append(out, m.Name)
+ }
+ }
+ return out
+}
+
+func randInt(max int) int {
+ if max <= 0 {
+ return 0
+ }
+ return rand.Intn(max)
+}
+
+func innerPickupReport(sess *net.Session, picked []string) {
+ for i, name := range picked {
+ if i == len(picked)-1 {
+ sess.WriteLine(name)
+ } else if i == len(picked)-2 {
+ sess.Write(name + " and ")
+ } else {
+ sess.Write(name + ", ")
+ }
+ }
+}
+
+func actionDesc(p *player.Player) string {
+ if p.Action == nil {
+ return ""
+ }
+ target := p.Action.TargetName
+ if idx, ok := p.Action.Data["instance_idx"]; ok {
+ target += fmt.Sprintf(" [%d]", idx)
+ }
+ switch p.Action.Type {
+ case "gather":
+ return "mining a " + target
+ case "talk":
+ return "talking to " + target
+ case "use":
+ return "using a " + target
+ }
+ return ""
+}