From a3fc5f67310d71e770a190e3c5d101315c983c42 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Mon, 24 Aug 2026 18:34:13 +0200 Subject: [PATCH] feat(core): declare mob AI state machine for wandering and targeting interface --- core/include/vf/Mob.h | 118 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 core/include/vf/Mob.h diff --git a/core/include/vf/Mob.h b/core/include/vf/Mob.h new file mode 100644 index 0000000..ae1964c --- /dev/null +++ b/core/include/vf/Mob.h @@ -0,0 +1,118 @@ +#pragma once + +#include +#include +#include "Entity.h" +#include "Item.h" +#include "Math.h" +#include "Pathfind.h" +#include "World.h" +#include "WorldGen.h" + +namespace vf { + +enum class Species : uint8_t { Sheep, Cow, Pig, Zombie, Skeleton, Creeper, Count }; + +bool isHostile(Species species); +inline bool isPassive(Species species) { return !isHostile(species); } + +struct SpeciesStats { + float maxHealth = 10.0f; + float width = 0.6f; + float height = 1.8f; + float walkSpeed = 2.0f; + float sprintMultiplier = 1.5f; // chase (hostile) or flee (passive) speed factor + float attackDamage = 0.0f; + float attackRange = 1.4f; + float attackCooldown = 1.0f; + float alertRadius = 12.0f; // hostile: aggro distance; passive: flee-trigger distance + float disengageRadius = 16.0f; // hysteresis give-up radius once engaged + int spawnLightMax = 7; // hostile: spawns only at or below this light + int spawnLightMin = 9; // passive: spawns only at or above this light +}; + +const SpeciesStats& speciesStats(Species species); + +enum class CreatureState : uint8_t { Idle, Wander, Flee, Chase, Attack }; + +// A gameplay mob: species identity, health and an AI state machine layered on +// top of the physics body from Entity.h. `body.wanderDir` is reused as the +// creature's persistent wander/flee heading between ticks. +struct Creature { + Mob body; + Species species = Species::Sheep; + CreatureState state = CreatureState::Idle; + float health = 10.0f; + float attackCooldownRemaining = 0.0f; + float stateTimer = 0.0f; + uint32_t rng = 0x9e3779b9u; + bool alive = true; +}; + +Creature spawnCreature(Species species, const Vec3& position, uint32_t seed); + +struct CreatureConfig { + MobConfig physics; +}; + +// One AI+physics tick. `hasThreat` false means no relevant target this tick +// (out of range, dead, or none nearby); the creature then wanders or idles. +// Hostile species chase and attack a present threat; passive species flee it. +void updateCreature(const World& world, Creature& creature, const Vec3& threatPos, bool hasThreat, + const CreatureConfig& config, float dt); + +bool damageCreature(Creature& creature, float amount); +bool creatureCanAttack(const Creature& creature, const Vec3& targetPos); +void creatureAttack(Creature& creature); + +struct DropEntry { + ItemId item = ItemId::None; + int minCount = 0; + int maxCount = 0; + float chance = 1.0f; +}; + +std::vector dropsFor(Species species); + +// Rolls the drop table for `species`, advancing `rng`. Deterministic given the +// same rng state. +std::vector rollDrops(Species species, uint32_t& rng); + +struct SpawnConfig { + int maxPerArea = 24; + float spawnAreaRadius = 64.0f; + float minPlayerDistance = 12.0f; + float maxPlayerDistance = 40.0f; +}; + +// Approximate ambient light at a cell for spawn checks: full skylight when the +// column above is unobstructed, combined with the strongest nearby block +// emitter attenuated per Manhattan step. +int mobSpawnLightLevel(const World& world, const Vec3i& cell, int searchRadius = 6); + +bool speciesAllowsBiome(Species species, Biome biome); + +bool canSpawnAt(const World& world, const Vec3i& cell, Species species, Biome biome, + const Vec3& playerPos, int currentPopulationInArea, const SpawnConfig& config = {}); + +struct SpawnAttempt { + bool spawned = false; + Species species = Species::Sheep; + Vec3 position; +}; + +// Tests every species against canSpawnAt and, if at least one qualifies, picks +// one deterministically from `rng`. +SpawnAttempt trySpawn(const World& world, const Vec3i& cell, Biome biome, const Vec3& playerPos, + int currentPopulationInArea, uint32_t& rng, const SpawnConfig& config = {}); + +struct SpawnCycle { + float interval = 1.0f; + float timer = 0.0f; +}; + +// Advances the cycle timer; returns true on ticks where a spawn attempt should +// run. Catches up at most once per call even after a large dt. +bool advanceSpawnCycle(SpawnCycle& cycle, float dt); + +} // namespace vf