From f9b3ce3edbd6087987c1b79dae97568f33f973db Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 25 Jul 2020 23:13:05 +0100 Subject: [PATCH 1/2] Destroy the rover when it has 0 integrity --- pkg/rove/world.go | 44 +++++++++++++++++++++++++++++++++--------- pkg/rove/world_test.go | 20 +++++++++++++++++-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/pkg/rove/world.go b/pkg/rove/world.go index 7e22323..ea1fdd3 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -67,7 +67,11 @@ func NewWorld(chunkSize int) *World { func (w *World) SpawnRover(account string) (string, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() + return w.spawnRover(account) +} +// spawnRover adds an rover to the game (without lock) +func (w *World) spawnRover(account string) (string, error) { // Initialise the rover rover := DefaultRover() @@ -176,17 +180,28 @@ func (w *World) RoverBroadcast(rover string, message []byte) (err error) { return } -// DestroyRover Removes an rover from the game -func (w *World) DestroyRover(rover string) error { - w.worldMutex.Lock() - defer w.worldMutex.Unlock() - - _, ok := w.Rovers[rover] +// destroyRover Removes an rover from the game +func (w *World) destroyRover(rover string) error { + r, ok := w.Rovers[rover] if !ok { return fmt.Errorf("no rover matching id") } + // Remove this rover from tracked rovers delete(w.Rovers, rover) + + r.Owner = "" + r.AddLogEntryf("rover destroyed") + + // Marshal the rover data + data, err := json.Marshal(r) + if err != nil { + return err + } + + // Place the dormant rover down + w.Atlas.SetObject(r.Pos, Object{Type: roveapi.Object_RoverDormant, Data: data}) + return nil } @@ -276,9 +291,20 @@ func (w *World) TryMoveRover(rover string, b roveapi.Bearing) (maths.Vector, err i.AddLogEntryf("tried to move %s to %+v", b.String(), newPos) i.Integrity = i.Integrity - 1 i.AddLogEntryf("had a collision, new integrity %d", i.Integrity) - // TODO: The rover needs to be left dormant with the player - //if i.Integrity == 0 { - //} + + if i.Integrity == 0 { + // The rover has died destroy it + err := w.destroyRover(rover) + if err != nil { + return maths.Vector{}, err + } + + // Spawn a new one for this account + _, err = w.spawnRover(i.Owner) + if err != nil { + return maths.Vector{}, err + } + } } return i.Pos, nil diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 747a891..8363c0b 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -49,7 +49,7 @@ func TestWorld_DestroyRover(t *testing.T) { b, err := world.SpawnRover("") assert.NoError(t, err) - err = world.DestroyRover(a) + err = world.destroyRover(a) assert.NoError(t, err, "Error returned from rover destroy") // Basic duplicate check @@ -130,7 +130,9 @@ func TestWorld_RadarFromRover(t *testing.T) { func TestWorld_RoverDamage(t *testing.T) { world := NewWorld(2) - a, err := world.SpawnRover("") + acc, err := world.Accountant.RegisterAccount("tmp") + assert.NoError(t, err) + a, err := world.SpawnRover(acc.Name) assert.NoError(t, err) pos := maths.Vector{ @@ -155,6 +157,20 @@ func TestWorld_RoverDamage(t *testing.T) { assert.NoError(t, err, "couldn't get rover info") assert.Equal(t, info.Integrity-1, newinfo.Integrity, "rover should have lost integrity") assert.Contains(t, newinfo.Logs[len(newinfo.Logs)-1].Text, "collision", "Rover logs should contain the collision") + + // Keep moving to damage the rover + for i := 0; i < info.Integrity-1; i++ { + vec, err := world.TryMoveRover(a, roveapi.Bearing_North) + assert.NoError(t, err, "Failed to move rover") + assert.Equal(t, pos, vec, "Rover managed to move into large rock") + } + + // Rover should have been destroyed now + _, err = world.GetRover(a) + assert.Error(t, err) + + _, obj := world.Atlas.QueryPosition(info.Pos) + assert.Equal(t, roveapi.Object_RoverDormant, obj.Type) } func TestWorld_Daytime(t *testing.T) { From cd97220a11969c3219fa8f9ea965d6d4631d3295 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 25 Jul 2020 23:18:21 +0100 Subject: [PATCH 2/2] Perform rover destruction during the main server tick --- pkg/rove/world.go | 46 +++++++++++++++++++++++------------------- pkg/rove/world_test.go | 5 ++++- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/pkg/rove/world.go b/pkg/rove/world.go index ea1fdd3..dc163f3 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -63,15 +63,11 @@ func NewWorld(chunkSize int) *World { } } -// SpawnRover adds an rover to the game +// SpawnRover adds an rover to the game (without lock) func (w *World) SpawnRover(account string) (string, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() - return w.spawnRover(account) -} -// spawnRover adds an rover to the game (without lock) -func (w *World) spawnRover(account string) (string, error) { // Initialise the rover rover := DefaultRover() @@ -180,8 +176,11 @@ func (w *World) RoverBroadcast(rover string, message []byte) (err error) { return } -// destroyRover Removes an rover from the game -func (w *World) destroyRover(rover string) error { +// DestroyRover Removes an rover from the game +func (w *World) DestroyRover(rover string) error { + w.worldMutex.Lock() + defer w.worldMutex.Unlock() + r, ok := w.Rovers[rover] if !ok { return fmt.Errorf("no rover matching id") @@ -291,20 +290,6 @@ func (w *World) TryMoveRover(rover string, b roveapi.Bearing) (maths.Vector, err i.AddLogEntryf("tried to move %s to %+v", b.String(), newPos) i.Integrity = i.Integrity - 1 i.AddLogEntryf("had a collision, new integrity %d", i.Integrity) - - if i.Integrity == 0 { - // The rover has died destroy it - err := w.destroyRover(rover) - if err != nil { - return maths.Vector{}, err - } - - // Spawn a new one for this account - _, err = w.spawnRover(i.Owner) - if err != nil { - return maths.Vector{}, err - } - } } return i.Pos, nil @@ -695,6 +680,25 @@ func (w *World) Tick() { } } + // Check all rover integrities + for _, r := range w.Rovers { + if r.Integrity <= 0 { + // The rover has died destroy it + err := w.DestroyRover(r.Name) + if err != nil { + log.Println(err) + // TODO: Report this error somehow + } + + // Spawn a new one for this account + _, err = w.SpawnRover(r.Owner) + if err != nil { + log.Println(err) + // TODO: Report this error somehow + } + } + } + // Increment the current tick count w.CurrentTicks++ diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 8363c0b..afc8f53 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -49,7 +49,7 @@ func TestWorld_DestroyRover(t *testing.T) { b, err := world.SpawnRover("") assert.NoError(t, err) - err = world.destroyRover(a) + err = world.DestroyRover(a) assert.NoError(t, err, "Error returned from rover destroy") // Basic duplicate check @@ -165,6 +165,9 @@ func TestWorld_RoverDamage(t *testing.T) { assert.Equal(t, pos, vec, "Rover managed to move into large rock") } + // Tick the world to check for rover deaths + world.Tick() + // Rover should have been destroyed now _, err = world.GetRover(a) assert.Error(t, err)