From fb34f770dd98850c14760cf96ddfb573420de5c1 Mon Sep 17 00:00:00 2001 From: Konst Date: Tue, 23 Jul 2024 17:25:05 +0300 Subject: [PATCH] Added Raft returning back to the island after looting; Added shipwreck resources spawner once in a hour; --- cardinal/component/building.go | 1 + cardinal/component/effect.go | 2 + cardinal/component/shipwreck_resources.go | 3 +- cardinal/constants/buildings.go | 7 +- cardinal/constants/shipwreck.go | 12 ++-- cardinal/main.go | 1 + cardinal/query/global_map.go | 6 +- cardinal/system/farming.go | 10 +-- cardinal/system/player_spawner.go | 3 +- cardinal/system/sail_ship.go | 64 ++++++++++++++++++- .../system/shipwreck_resources_spawner.go | 37 +++++++++++ 11 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 cardinal/system/shipwreck_resources_spawner.go diff --git a/cardinal/component/building.go b/cardinal/component/building.go index 64fe052..72d6aab 100644 --- a/cardinal/component/building.go +++ b/cardinal/component/building.go @@ -104,6 +104,7 @@ var BuildingConfigs = map[BuildingType]BuildingConstants{ {Type: Fish, Amount: constants.ShipyardEffectRaftResourceFish}, }, BuildingTimeSeconds: constants.ShipyardEffectRaftBuildSeconds, + Speed: constants.RaftTravelSpeedPerMinute, }, TileType: CoastlineTile, }, diff --git a/cardinal/component/effect.go b/cardinal/component/effect.go index 1948121..3c12496 100644 --- a/cardinal/component/effect.go +++ b/cardinal/component/effect.go @@ -30,6 +30,8 @@ type Effect struct { Amount int `json:"amount"` Capacity int `json:"capacity"` Resources []Resource `json:"resources,omitempty"` + LootResources *[]Resource `json:"lootResources,omitempty"` + Speed float64 `json:"speed"` Position [2]float64 `json:"position,omitempty"` TargetPosition *[2]float64 `json:"targetPosition,omitempty"` BuildingTimeSeconds int `json:"buildingTimeSeconds,omitempty"` diff --git a/cardinal/component/shipwreck_resources.go b/cardinal/component/shipwreck_resources.go index 3f413dd..aa2e6e6 100644 --- a/cardinal/component/shipwreck_resources.go +++ b/cardinal/component/shipwreck_resources.go @@ -7,7 +7,8 @@ import ( ) type ShipwreckResources struct { - Resources []Resource `json:"resources"` + Resources *[]Resource `json:"resources"` + LastSpawnTime uint64 `json:"lastSpawnTime"` } func GetShipwreckResourceTypes() []ResourceType { diff --git a/cardinal/constants/buildings.go b/cardinal/constants/buildings.go index ec6e15c..3baf7b2 100644 --- a/cardinal/constants/buildings.go +++ b/cardinal/constants/buildings.go @@ -1,5 +1,7 @@ package constants +import "time" + const ( MainTileID = 22 MainUnitLimit = 5 @@ -51,4 +53,7 @@ const ( UnitLimitHouseUnitLimit = 15 ) -const ShipwreckDistanceFromIsland = 0.4 +const ( + ShipwreckDistanceFromIsland = 0.4 + ShipwreckResourcesRespawnInterval = time.Hour +) diff --git a/cardinal/constants/shipwreck.go b/cardinal/constants/shipwreck.go index 90bd2a0..08c14bd 100644 --- a/cardinal/constants/shipwreck.go +++ b/cardinal/constants/shipwreck.go @@ -1,16 +1,16 @@ package constants const ( - ShipwreckMinWoodAmount = 5 - ShipwreckMaxWoodAmount = 10 + ShipwreckMinWoodAmount = 50 + ShipwreckMaxWoodAmount = 100 ) const ( - ShipwreckMinStoneAmount = 5 - ShipwreckMaxStoneAmount = 10 + ShipwreckMinStoneAmount = 50 + ShipwreckMaxStoneAmount = 100 ) const ( - ShipwreckMinFishAmount = 5 - ShipwreckMaxFishAmount = 10 + ShipwreckMinFishAmount = 50 + ShipwreckMaxFishAmount = 100 ) diff --git a/cardinal/main.go b/cardinal/main.go index 2e21b18..52fbfed 100644 --- a/cardinal/main.go +++ b/cardinal/main.go @@ -95,6 +95,7 @@ func MustInitWorld(w *cardinal.World) { system.RelocateBuildingSystem, system.StartSailShipwreckSystem, system.SailShip, + system.ShipwreckResourcesSpawner, )) } diff --git a/cardinal/query/global_map.go b/cardinal/query/global_map.go index 4179ad4..d53f28e 100644 --- a/cardinal/query/global_map.go +++ b/cardinal/query/global_map.go @@ -18,8 +18,8 @@ type GlobalMapResponse struct { } type ResourcePoint struct { - Position [2]float64 `json:"position"` - Resources []comp.Resource `json:"resources"` + Position [2]float64 `json:"position"` + Resources *[]comp.Resource `json:"resources"` } func GlobalMap(world cardinal.WorldContext, _ *GlobalMapRequest) (*[]GlobalMapResponse, error) { @@ -41,7 +41,7 @@ func GlobalMap(world cardinal.WorldContext, _ *GlobalMapRequest) (*[]GlobalMapRe Player: players[i].Nickname, Island: ResourcePoint{ Position: position.Island, - Resources: playerResources.Resources, + Resources: &playerResources.Resources, }, Shipwreck: ResourcePoint{ Position: position.Shipwreck, diff --git a/cardinal/system/farming.go b/cardinal/system/farming.go index dafca9a..67a3d8e 100644 --- a/cardinal/system/farming.go +++ b/cardinal/system/farming.go @@ -45,10 +45,12 @@ func FarmingSystem(world cardinal.WorldContext) error { for i := range playerResources.Resources { if playerResources.Resources[i].Type == farmingComponent.Type { tickFarmedAmount := farmingComponent.Speed * constants.TickRate.Seconds() / time.Minute.Seconds() - playerResources.Resources[i].Amount = math.Min( - playerResources.Resources[i].Amount+tickFarmedAmount, - float64(totalCapacity), - ) + if playerResources.Resources[i].Amount <= float64(totalCapacity) { + playerResources.Resources[i].Amount = math.Min( + playerResources.Resources[i].Amount+tickFarmedAmount, + float64(totalCapacity), + ) + } if err := cardinal.SetComponent[comp.PlayerResources](world, playerEntityID, playerResources); err != nil { return true } diff --git a/cardinal/system/player_spawner.go b/cardinal/system/player_spawner.go index fc64c26..e665c62 100644 --- a/cardinal/system/player_spawner.go +++ b/cardinal/system/player_spawner.go @@ -108,7 +108,8 @@ func createPlayerData(world cardinal.WorldContext, nickname string) error { Effects: effects, }, comp.ShipwreckResources{ - Resources: shipWreckResources, + Resources: &shipWreckResources, + LastSpawnTime: world.Timestamp(), }, comp.Position{ Island: islandCoordinates, diff --git a/cardinal/system/sail_ship.go b/cardinal/system/sail_ship.go index 3d5f2c7..413584a 100644 --- a/cardinal/system/sail_ship.go +++ b/cardinal/system/sail_ship.go @@ -18,7 +18,6 @@ func SailShip(world cardinal.WorldContext) error { filter.Contains(filter.Component[comp.Building](), filter.Component[comp.Effect]())). Each(world, func(id types.EntityID) bool { effectComponent, _ := cardinal.GetComponent[comp.Effect](world, id) - if effectComponent.Amount == 0 || effectComponent.TargetPosition == nil { return true } @@ -33,6 +32,22 @@ func SailShip(world cardinal.WorldContext) error { raftTravelDistancePerTick, ) + _, playerPosition, _ := QueryPlayerComponent[comp.Position]( + world, + buildingComponent.Effect.Player, + filter.Component[comp.Player](), + filter.Component[comp.TileMap](), + filter.Component[comp.Position](), + ) + + if buildingComponent.Effect.Position == playerPosition.Island { + buildingComponent.Effect.TargetPosition = nil + _ = unloadShip(world, buildingComponent.Effect) + } else if buildingComponent.Effect.Position == *buildingComponent.Effect.TargetPosition { + buildingComponent.Effect.TargetPosition = &playerPosition.Island + _ = lootShipwreck(world, buildingComponent.Effect) + } + err := updateEffect(world, id, buildingComponent.Effect) if err != nil { return true @@ -62,3 +77,50 @@ func findPointAtDistance(start, end [2]float64, distance float64) [2]float64 { return [2]float64{newX, newY} } + +func lootShipwreck(world cardinal.WorldContext, effect *comp.Effect) error { + playerPositionsIDs, playerPositions, _ := QueryAllComponents[comp.Position]( + world, + filter.Component[comp.Player](), + filter.Component[comp.TileMap](), + filter.Component[comp.Position](), + ) + + var shipwreckResources *comp.ShipwreckResources + var playerMapEntityID types.EntityID + for i, position := range playerPositions { + if position.Shipwreck == effect.Position { + playerMapEntityID = playerPositionsIDs[i] + shipwreckResources, _ = cardinal.GetComponent[comp.ShipwreckResources](world, playerMapEntityID) + break + } + } + + effect.LootResources = shipwreckResources.Resources + shipwreckResources.Resources = nil + if err := cardinal.SetComponent(world, playerMapEntityID, shipwreckResources); err != nil { + return err + } + + return nil +} + +func unloadShip(world cardinal.WorldContext, effect *comp.Effect) error { + playerResourcesID, playerResources, _ := QueryPlayerComponent[comp.PlayerResources]( + world, + effect.Player, + filter.Component[comp.Player](), + filter.Component[comp.TileMap](), + filter.Component[comp.PlayerResources](), + ) + + var err error + for _, lootResource := range *effect.LootResources { + playerResource, _ := GetResourceByType(playerResources, lootResource.Type) + playerResource.Amount += lootResource.Amount + SetResourceByType(playerResources, *playerResource) + err = cardinal.SetComponent(world, playerResourcesID, playerResources) + } + effect.LootResources = nil + return err +} diff --git a/cardinal/system/shipwreck_resources_spawner.go b/cardinal/system/shipwreck_resources_spawner.go new file mode 100644 index 0000000..ddc4c62 --- /dev/null +++ b/cardinal/system/shipwreck_resources_spawner.go @@ -0,0 +1,37 @@ +package system + +import ( + "pkg.world.dev/world-engine/cardinal" + "pkg.world.dev/world-engine/cardinal/search/filter" + "pkg.world.dev/world-engine/cardinal/types" + + comp "oceanus-shard/component" + "oceanus-shard/constants" +) + +// ShipwreckResourcesSpawner - +func ShipwreckResourcesSpawner(world cardinal.WorldContext) error { + return cardinal.NewSearch().Entity( + filter.Contains(filter.Component[comp.Player](), filter.Component[comp.ShipwreckResources]())). + Each(world, func(id types.EntityID) bool { + shipwreckResources, _ := cardinal.GetComponent[comp.ShipwreckResources](world, id) + if (shipwreckResources.LastSpawnTime + + uint64(constants.ShipwreckResourcesRespawnInterval.Milliseconds())) < world.Timestamp() { + return true + } + if shipwreckResources.Resources != nil { + return true + } + + shipWreckResources := make([]comp.Resource, len(comp.GetShipwreckResourceTypes())) + for i, resourceType := range comp.GetShipwreckResourceTypes() { + shipWreckResources[i] = comp.Resource{ + Type: resourceType, + Amount: comp.GetShipwreckDefaultResourceAmount(resourceType), + } + } + shipwreckResources.Resources = &shipWreckResources + _ = cardinal.SetComponent(world, id, shipwreckResources) + return true + }) +}