first
Some checks failed
Linux / Build Linux (push) Has been cancelled
Linux / Build Linux-1 (push) Has been cancelled
macOS / Build macOS (push) Has been cancelled
macOS / Build macOS-1 (push) Has been cancelled
Windows (MinGW) / Build MinGW (push) Has been cancelled
Windows (MinGW) / Build MinGW-1 (push) Has been cancelled
Windows (MSVC) / Build Windows (push) Has been cancelled
Windows (MSVC) / Build Windows-1 (push) Has been cancelled
Some checks failed
Linux / Build Linux (push) Has been cancelled
Linux / Build Linux-1 (push) Has been cancelled
macOS / Build macOS (push) Has been cancelled
macOS / Build macOS-1 (push) Has been cancelled
Windows (MinGW) / Build MinGW (push) Has been cancelled
Windows (MinGW) / Build MinGW-1 (push) Has been cancelled
Windows (MSVC) / Build Windows (push) Has been cancelled
Windows (MSVC) / Build Windows-1 (push) Has been cancelled
This commit is contained in:
commit
8269b17aa7
652 changed files with 273930 additions and 0 deletions
276
Quake/sh_game.h
Normal file
276
Quake/sh_game.h
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* sh_game.h -- Space Hulk turn-based game system for Quakespasm
|
||||
*
|
||||
* Copyright (C) 2026 fish fvch studios
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef SH_GAME_H
|
||||
#define SH_GAME_H
|
||||
|
||||
/* ============================================================
|
||||
* CONSTANTS
|
||||
* ============================================================ */
|
||||
|
||||
#define SH_GRID_SIZE 128 /* quake units per grid cell */
|
||||
#define SH_MAX_MARINES 5
|
||||
#define SH_MAX_GENESTEALERS 32
|
||||
#define SH_MAX_DOORS 16
|
||||
#define SH_MAX_BLIP_ENTRIES 8
|
||||
#define SH_MAX_LOG_MESSAGES 32
|
||||
#define SH_LOG_MSG_LEN 80
|
||||
|
||||
#define SH_DEFAULT_AP 4
|
||||
#define SH_MAX_COMMAND_POINTS 6 /* 1d6 bonus AP per round */
|
||||
|
||||
#define SH_GENESTEALER_MP 6 /* movement points per alien phase */
|
||||
|
||||
/* AP costs */
|
||||
#define SH_AP_MOVE_FORWARD 1
|
||||
#define SH_AP_TURN 0 /* free turns for snappy gameplay */
|
||||
#define SH_AP_SHOOT 1
|
||||
#define SH_AP_OVERWATCH 2
|
||||
#define SH_AP_MELEE 1
|
||||
#define SH_AP_DOOR 1
|
||||
|
||||
/* animation durations (seconds) */
|
||||
#define SH_ANIM_MOVE_DURATION 0.2
|
||||
#define SH_ANIM_TURN_DURATION 0.15
|
||||
#define SH_ANIM_SHOOT_DURATION 0.3
|
||||
|
||||
#define SH_MAX_ANIMS 8
|
||||
|
||||
/* standing eye height above grid floor */
|
||||
#define SH_EYE_HEIGHT 32
|
||||
|
||||
/* ============================================================
|
||||
* ENUMERATIONS
|
||||
* ============================================================ */
|
||||
|
||||
typedef enum {
|
||||
SH_PHASE_INACTIVE, /* game not started */
|
||||
SH_PHASE_BRIEFING, /* pre-mission screen */
|
||||
SH_PHASE_PLAYER, /* player marine phase */
|
||||
SH_PHASE_ALIEN, /* AI genestealer phase */
|
||||
SH_PHASE_OVERWATCH_REACT, /* interrupt: marine reaction fire */
|
||||
SH_PHASE_ROUND_END, /* cleanup, check win/lose */
|
||||
SH_PHASE_VICTORY,
|
||||
SH_PHASE_DEFEAT
|
||||
} sh_phase_t;
|
||||
|
||||
typedef enum {
|
||||
SH_ACTION_NONE,
|
||||
SH_ACTION_MOVE_FORWARD,
|
||||
SH_ACTION_TURN_LEFT,
|
||||
SH_ACTION_TURN_RIGHT,
|
||||
SH_ACTION_TURN_180,
|
||||
SH_ACTION_SHOOT,
|
||||
SH_ACTION_OVERWATCH,
|
||||
SH_ACTION_MELEE,
|
||||
SH_ACTION_DOOR,
|
||||
SH_ACTION_END_TURN
|
||||
} sh_action_t;
|
||||
|
||||
typedef enum {
|
||||
SH_FACING_NORTH, /* +Y: yaw 90 */
|
||||
SH_FACING_EAST, /* +X: yaw 0 */
|
||||
SH_FACING_SOUTH, /* -Y: yaw 270 */
|
||||
SH_FACING_WEST /* -X: yaw 180 */
|
||||
} sh_facing_t;
|
||||
|
||||
typedef enum {
|
||||
SH_WEAPON_STORM_BOLTER,
|
||||
SH_WEAPON_ASSAULT_CANNON,
|
||||
SH_WEAPON_POWER_FIST,
|
||||
SH_WEAPON_FLAMER
|
||||
} sh_weapon_t;
|
||||
|
||||
typedef enum {
|
||||
SH_LOG_INFO,
|
||||
SH_LOG_COMBAT,
|
||||
SH_LOG_ALERT,
|
||||
SH_LOG_KILL
|
||||
} sh_log_type_t;
|
||||
|
||||
typedef enum {
|
||||
SH_AI_IDLE,
|
||||
SH_AI_ADVANCE,
|
||||
SH_AI_ATTACK,
|
||||
SH_AI_FLANK
|
||||
} sh_ai_state_t;
|
||||
|
||||
/* ============================================================
|
||||
* DATA STRUCTURES
|
||||
* ============================================================ */
|
||||
|
||||
/* Sidecar data for a marine entity */
|
||||
typedef struct {
|
||||
qboolean active;
|
||||
edict_t *ent; /* quake edict for rendering/collision */
|
||||
int squad_index;
|
||||
int grid_x, grid_y;
|
||||
sh_facing_t facing;
|
||||
int ap; /* action points remaining this turn */
|
||||
int ap_max; /* base AP (default 4) */
|
||||
sh_weapon_t weapon;
|
||||
int health; /* 1 = alive in Space Hulk */
|
||||
qboolean on_overwatch;
|
||||
int overwatch_ap;
|
||||
qboolean has_acted; /* activated this phase */
|
||||
qboolean alive;
|
||||
char name[32];
|
||||
} sh_marine_t;
|
||||
|
||||
/* Sidecar data for a genestealer entity */
|
||||
typedef struct {
|
||||
qboolean active;
|
||||
edict_t *ent;
|
||||
int grid_x, grid_y;
|
||||
sh_facing_t facing;
|
||||
int mp; /* movement points remaining this phase */
|
||||
sh_ai_state_t ai_state;
|
||||
int target_marine; /* index into marines[], or -1 */
|
||||
qboolean alive;
|
||||
qboolean is_blip;
|
||||
int blip_count; /* 1-3 genestealers per blip */
|
||||
} sh_genestealer_t;
|
||||
|
||||
/* Door entity */
|
||||
typedef struct {
|
||||
qboolean active;
|
||||
edict_t *ent;
|
||||
int grid_x, grid_y;
|
||||
qboolean is_open;
|
||||
} sh_door_t;
|
||||
|
||||
/* Blip spawn entry point */
|
||||
typedef struct {
|
||||
int grid_x, grid_y;
|
||||
sh_facing_t entry_facing;
|
||||
qboolean active;
|
||||
} sh_blip_entry_t;
|
||||
|
||||
/* Message log (adapted from ideas/turn_manager.c) */
|
||||
typedef struct {
|
||||
char text[SH_LOG_MSG_LEN];
|
||||
sh_log_type_t type;
|
||||
int round;
|
||||
int stack_count;
|
||||
} sh_log_msg_t;
|
||||
|
||||
typedef struct {
|
||||
sh_log_msg_t messages[SH_MAX_LOG_MESSAGES];
|
||||
int write_index;
|
||||
int count;
|
||||
qboolean updated;
|
||||
} sh_message_log_t;
|
||||
|
||||
/* Animation lerp for smooth grid movement in 3D */
|
||||
typedef struct {
|
||||
qboolean active;
|
||||
edict_t *ent;
|
||||
vec3_t start_pos;
|
||||
vec3_t end_pos;
|
||||
float start_yaw;
|
||||
float end_yaw;
|
||||
double start_time;
|
||||
double duration;
|
||||
} sh_anim_t;
|
||||
|
||||
/* ============================================================
|
||||
* MASTER GAME STATE
|
||||
* ============================================================ */
|
||||
|
||||
typedef struct {
|
||||
/* phase management */
|
||||
sh_phase_t phase;
|
||||
sh_phase_t phase_before_interrupt;
|
||||
int round_number;
|
||||
int command_points;
|
||||
int command_points_used;
|
||||
|
||||
/* marines */
|
||||
sh_marine_t marines[SH_MAX_MARINES];
|
||||
int num_marines;
|
||||
int selected_marine;
|
||||
|
||||
/* genestealers */
|
||||
sh_genestealer_t genestealers[SH_MAX_GENESTEALERS];
|
||||
int num_genestealers;
|
||||
int current_alien;
|
||||
|
||||
/* doors */
|
||||
sh_door_t doors[SH_MAX_DOORS];
|
||||
int num_doors;
|
||||
|
||||
/* spawn points */
|
||||
sh_blip_entry_t blip_entries[SH_MAX_BLIP_ENTRIES];
|
||||
int num_blip_entries;
|
||||
|
||||
/* animation queue */
|
||||
sh_anim_t anims[SH_MAX_ANIMS];
|
||||
int num_anims;
|
||||
|
||||
/* message log */
|
||||
sh_message_log_t log;
|
||||
|
||||
/* camera (follows selected marine for now) */
|
||||
int camera_marine;
|
||||
} sh_gamestate_t;
|
||||
|
||||
extern sh_gamestate_t sh_game;
|
||||
|
||||
/* ============================================================
|
||||
* PUBLIC API -- sh_game.c
|
||||
* ============================================================ */
|
||||
|
||||
void SH_Init (void);
|
||||
void SH_Shutdown (void);
|
||||
void SH_NewGame (void);
|
||||
void SH_Frame (void);
|
||||
qboolean SH_Active (void);
|
||||
|
||||
/* coordinate conversion */
|
||||
void SH_GridToWorld (int gx, int gy, vec3_t out);
|
||||
void SH_WorldToGrid (vec3_t pos, int *gx, int *gy);
|
||||
|
||||
/* facing helpers */
|
||||
float SH_FacingToYaw (sh_facing_t facing);
|
||||
sh_facing_t SH_YawToFacing (float yaw);
|
||||
void SH_FacingToDir (sh_facing_t facing, int *dx, int *dy);
|
||||
|
||||
/* grid collision */
|
||||
qboolean SH_GridBlocked (int gx, int gy, edict_t *ignore);
|
||||
|
||||
/* animation */
|
||||
void SH_AnimPush (edict_t *ent, vec3_t start, vec3_t end,
|
||||
float start_yaw, float end_yaw, double duration);
|
||||
qboolean SH_AnimBusy (void);
|
||||
|
||||
/* logging */
|
||||
void SH_Log (sh_log_type_t type, const char *fmt, ...) FUNC_PRINTF(2,3);
|
||||
|
||||
/* ============================================================
|
||||
* PUBLIC API -- sh_marine.c
|
||||
* ============================================================ */
|
||||
|
||||
void SH_Marine_Spawn (int index, int gx, int gy,
|
||||
sh_facing_t facing, sh_weapon_t weapon, const char *name);
|
||||
qboolean SH_Marine_TryAction (int marine_index, sh_action_t action);
|
||||
void SH_Marine_BeginPlayerPhase (void);
|
||||
qboolean SH_Marine_AllDone (void);
|
||||
void SH_Marine_SelectNext (void);
|
||||
void SH_Marine_SelectPrev (void);
|
||||
|
||||
/* ============================================================
|
||||
* PUBLIC API -- sh_input.c
|
||||
* ============================================================ */
|
||||
|
||||
void SH_Input_Init (void);
|
||||
qboolean SH_Input_KeyEvent (int key, qboolean down);
|
||||
|
||||
#endif /* SH_GAME_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue