Implement tick-based game loop, combat overhaul, and attack-any-NPC
Replace immediate combat with a 3-second tick engine that resolves actions, NPC AI, status effects, respawns, and passive regeneration. Players queue combat actions (attack/defend/flee/use) that resolve on the next tick. Any NPC can now be attacked — non-hostile targets incur attitude penalties instead of being blocked. Status effects persist in the database and continue ticking while players are offline. Made-with: Cursor
This commit is contained in:
47
src/game.rs
47
src/game.rs
@@ -52,8 +52,18 @@ impl Player {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CombatAction {
|
||||
Attack,
|
||||
Defend,
|
||||
Flee,
|
||||
UseItem(usize),
|
||||
}
|
||||
|
||||
pub struct CombatState {
|
||||
pub npc_id: String,
|
||||
pub action: Option<CombatAction>,
|
||||
pub defending: bool,
|
||||
}
|
||||
|
||||
pub struct NpcInstance {
|
||||
@@ -69,11 +79,42 @@ pub struct PlayerConnection {
|
||||
pub combat: Option<CombatState>,
|
||||
}
|
||||
|
||||
pub struct XorShift64 {
|
||||
state: u64,
|
||||
}
|
||||
|
||||
impl XorShift64 {
|
||||
pub fn new(seed: u64) -> Self {
|
||||
XorShift64 {
|
||||
state: if seed == 0 { 0xdeadbeefcafe1234 } else { seed },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> u64 {
|
||||
let mut x = self.state;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 7;
|
||||
x ^= x << 17;
|
||||
self.state = x;
|
||||
x
|
||||
}
|
||||
|
||||
pub fn next_range(&mut self, min: i32, max: i32) -> i32 {
|
||||
if min >= max {
|
||||
return min;
|
||||
}
|
||||
let range = (max - min + 1) as u64;
|
||||
(self.next() % range) as i32 + min
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GameState {
|
||||
pub world: World,
|
||||
pub db: Arc<dyn GameDb>,
|
||||
pub players: HashMap<usize, PlayerConnection>,
|
||||
pub npc_instances: HashMap<String, NpcInstance>,
|
||||
pub rng: XorShift64,
|
||||
pub tick_count: u64,
|
||||
}
|
||||
|
||||
pub type SharedState = Arc<Mutex<GameState>>;
|
||||
@@ -93,11 +134,17 @@ impl GameState {
|
||||
);
|
||||
}
|
||||
}
|
||||
let seed = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_nanos() as u64;
|
||||
GameState {
|
||||
world,
|
||||
db,
|
||||
players: HashMap::new(),
|
||||
npc_instances,
|
||||
rng: XorShift64::new(seed),
|
||||
tick_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user