aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_move.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/cmd_move.go
parent6a0f3d7a252de4b1741cfe5e1c561412c602becc (diff)
downloadthehouseoficarus-a226d72e51eecb768b13600303f73483118d9104.tar.gz
feat: implemented janky object interaction model
Diffstat (limited to 'internal/game/cmd_move.go')
-rw-r--r--internal/game/cmd_move.go122
1 files changed, 122 insertions, 0 deletions
diff --git a/internal/game/cmd_move.go b/internal/game/cmd_move.go
new file mode 100644
index 0000000..b95f5c5
--- /dev/null
+++ b/internal/game/cmd_move.go
@@ -0,0 +1,122 @@
+package game
+
+import (
+ "fmt"
+
+ "thirdcollapse/internal/combat"
+ "thirdcollapse/internal/net"
+ "thirdcollapse/internal/player"
+)
+
+func (g *Game) doMove(sess *net.Session, dir string) {
+ p := sess.Player.(*player.Player)
+ exitDir := g.World.ResolveExit(dir)
+ if exitDir == "" {
+ sess.WriteLine("Go where?")
+ return
+ }
+
+ room, err := g.World.LoadRoom(p.RoomID)
+ if err != nil {
+ sess.WriteLine("You can't move from here.")
+ return
+ }
+
+ exitDef, ok := room.Exits[exitDir]
+ if !ok {
+ sess.WriteLine("You can't go that way.")
+ return
+ }
+
+ if exitDef.Condition != nil && !g.CheckExitCondition(exitDef.Condition) {
+ msg := exitDef.BlockedMessage
+ if msg == "" {
+ msg = fmt.Sprintf("The way %s is blocked.", exitDir)
+ }
+ sess.WriteLine(msg)
+ return
+ }
+
+ targetID := exitDef.Room
+
+ _, err = g.World.LoadRoom(targetID)
+ if err != nil {
+ sess.WriteLine("That path seems blocked.")
+ return
+ }
+
+ if cs := combat.GetCombat(p.Name); cs != nil && cs.LockedTicks > 0 {
+ sess.WriteLine(fmt.Sprintf("You are locked in combat for another %d tick%s!", cs.LockedTicks, plural(cs.LockedTicks)))
+ return
+ }
+
+ g.stopCombat(p.Name)
+
+ if p.Action != nil {
+ g.CancelAction(p)
+ }
+
+ oldRoom := p.RoomID
+ p.RoomID = targetID
+ g.AccountStore.SaveCharacter(p)
+
+ g.World.SeedGroundItems(p.RoomID)
+ g.seedRoomMobs(p.RoomID)
+ g.ensureRoomObjects(p.RoomID)
+
+ if g.Hub != nil {
+ for _, other := range g.Hub.PlayersInRoom(oldRoom) {
+ if other != sess {
+ other.WriteLine(fmt.Sprintf("\n%s leaves to the %s.", p.Name, exitDir))
+ }
+ }
+ g.Hub.EnterRoom(sess, targetID)
+ for _, other := range g.Hub.PlayersInRoom(targetID) {
+ if other != sess {
+ other.WriteLine(fmt.Sprintf("\n%s arrives.", p.Name))
+ }
+ }
+ }
+
+ sess.WriteLine(fmt.Sprintf("\nYou walk %s.", exitDir))
+ if p.Toggles["description"] {
+ g.doLook(sess)
+ } else {
+ targetRoom, _ := g.World.LoadRoom(targetID)
+ if targetRoom != nil {
+ sess.WriteLine(targetRoom.Name)
+ }
+ }
+
+ g.RunEnterSteps(sess, targetID)
+}
+
+func (g *Game) seedRoomMobs(roomID int) {
+ room, err := g.World.LoadRoom(roomID)
+ if err != nil || len(room.Mobs) == 0 {
+ return
+ }
+ g.MobStore.SeedMobs(roomID, room.Mobs)
+}
+
+func (g *Game) ensureRoomObjects(roomID int) {
+ room, err := g.World.LoadRoom(roomID)
+ if err != nil {
+ return
+ }
+ var ids []string
+ for _, obj := range room.Objects {
+ ids = append(ids, obj.ID)
+ }
+ g.World.EnsureObjectStates(roomID, ids)
+ for _, obj := range room.Objects {
+ def, err := g.ObjectStore.Load(obj.ID)
+ if err != nil {
+ continue
+ }
+ g.World.SetObjName(roomID, obj.ID, def.Name)
+ if len(obj.WanderRooms) > 0 {
+ g.World.SetObjWander(roomID, obj.ID, obj.WanderRooms, obj.WanderInterval)
+ }
+ }
+}