kitchen: README + MISSIONS/engine-c keep-drop notes

This commit is contained in:
Hernâni Marques 2026-09-17 21:48:48 +02:00
parent 1d351918da
commit 575d7d29b8
No known key found for this signature in database
130 changed files with 9817 additions and 1 deletions

273
engine-c/src/config.c Normal file
View file

@ -0,0 +1,273 @@
#include "kknd.h"
/* =========================================================================
* config.c - Unit & building statistics, themed on KKND 1 (recreated).
*
* Two factions are modelled after the original game:
* FACTION_SURVIVOR - underground military remnants, high-tech war machines
* FACTION_EVOLVED - surface mutant tribes, warped animals & beasts
* The resource is "Scrap" (salvaged post-war materiel), harvested from
* scrap fields by harvesters and processed at refineries.
* ========================================================================= */
static const UnitDef UNIT_DEFS[] = {
/* ---- Survivor war machines ---- */
{ "Rifleman", UT_INFANTRY, FACTION_SURVIVOR, 50, 400, 40, 5, 62, 96, 220, 0, 2, AB_NONE,
"Booted foot soldier with a rapid rifle." },
{ "Scout Car", UT_BUGGY, FACTION_SURVIVOR, 200, 600, 55, 10, 132, 112, 260, 0, 6, AB_NONE,
"Fast lightly-armoured recon buggy with twin MG." },
{ "Battle Tank",UT_TANK, FACTION_SURVIVOR, 500, 1400,130, 40, 82, 132, 280, 0, 12, AB_SIEGE,
"Heavily armoured main battle tank. [Siege] boosts range." },
{ "Hammer", UT_ARTILLERY, FACTION_SURVIVOR, 450, 700,160, 15, 60, 264, 330, 0, 14, AB_SIEGE,
"Long-range self-propelled artillery. [Siege] extends reach." },
{ "Scavenger", UT_HARVESTER, FACTION_SURVIVOR, 300, 900, 0, 10, 72, 0, 200, 1000, 8, AB_NONE,
"Armoured truck that hauls scrap to the refinery." },
{ "Medic", UT_MEDIC, FACTION_SURVIVOR, 250, 600, 0, 10, 90, 120, 220, 0, 7, AB_HEAL,
"Field medic that pulses repairs to nearby allies." },
{ "Pathfinder", UT_JEEP, FACTION_SURVIVOR, 150, 500, 45, 8, 150, 100, 240, 0, 5, AB_NONE,
"Fast scout jeep with a roof-mounted machine gun." },
{ "Mammoth", UT_RAVAGER, FACTION_SURVIVOR, 800, 2600,200, 70, 70, 140, 300, 0, 18, AB_NONE,
"Super-heavy siege tank that levels anything." },
{ "Flamer", UT_FLAME, FACTION_SURVIVOR, 250, 700, 90, 12, 70, 52, 200, 0, 7, AB_NONE,
"Flame trooper that clears clustered enemies." },
{ "Rocketeer", UT_MISSILE, FACTION_SURVIVOR, 350, 650,120, 10, 64, 220, 300, 0, 10, AB_NONE,
"Mobile rocket launcher with punishing range." },
/* ---- Evolved mutant warbeasts ---- */
{ "Berserker", UT_INFANTRY, FACTION_EVOLVED, 40, 320, 40, 4, 62, 96, 220, 0, 2, AB_NONE,
"Barefoot mutant warrior loosing mutated arrows." },
{ "Razorbeast", UT_BUGGY, FACTION_EVOLVED, 200, 650, 60, 12, 142, 104, 260, 0, 6, AB_NONE,
"Mutated quadruped that charges and tears." },
{ "Ravager", UT_TANK, FACTION_EVOLVED, 500, 1500,140, 45, 76, 126, 280, 0, 12, AB_SIEGE,
"Hulking armored brute of the mutant horde. [Siege] boosts range." },
{ "Spitter", UT_ARTILLERY, FACTION_EVOLVED, 450, 720,150, 14, 56, 258, 330, 0, 14, AB_SIEGE,
"Acid-spitting mutant with lobbing attack. [Siege] extends reach." },
{ "Gnawer", UT_HARVESTER, FACTION_EVOLVED, 300, 900, 0, 10, 72, 0, 200, 1000, 8, AB_NONE,
"Swarm-beast that drags scrap back to the hive." },
{ "Mendbeast", UT_MEDIC, FACTION_EVOLVED, 250, 600, 0, 10, 88, 118, 220, 0, 7, AB_HEAL,
"Regenerating mutant that heals the brood around it." },
{ "Cackler", UT_MUTANT, FACTION_EVOLVED, 60, 360, 38, 5, 70, 92, 220, 0, 3, AB_NONE,
"Skittering mutant with a crude slug-thrower." },
{ "Loper", UT_BEAST, FACTION_EVOLVED, 180, 620, 58, 10, 150, 100, 240, 0, 5, AB_NONE,
"Loping pack-hunter beast that strikes fast." },
{ "Warlord", UT_RAVAGER, FACTION_EVOLVED, 800, 2700,210, 75, 68, 134, 300, 0, 18, AB_NONE,
"Mountain-sized mutant warlord of the horde." },
{ "Pyro", UT_FLAME, FACTION_EVOLVED, 250, 700, 90, 12, 70, 52, 200, 0, 7, AB_NONE,
"Mutant with a gout of war-fire for close work." },
{ "Spore", UT_MISSILE, FACTION_EVOLVED, 350, 650,120, 10, 64, 220, 300, 0, 10, AB_NONE,
"Fungal spore-launcher with punishing range." },
/* ---- Series 9: rogue war machines (third faction) ---- */
{ "S9 Drone", UT_INFANTRY, FACTION_SERIES9, 50, 380, 42, 6, 64, 98, 220, 0, 2, AB_NONE,
"Autonomous combat drone with a pulse repeater." },
{ "S9 Crawler", UT_BUGGY, FACTION_SERIES9, 200, 620, 58, 12, 140, 108, 260, 0, 6, AB_NONE,
"Treaded recon crawler with twin autocannons." },
{ "S9 Crusher", UT_TANK, FACTION_SERIES9, 500, 1500,135, 45, 80, 130, 280, 0, 12, AB_SIEGE,
"Heavy war-robot crush-tank. [Siege] boosts range." },
{ "S9 Mortar", UT_ARTILLERY, FACTION_SERIES9, 450, 720,155, 16, 58, 262, 330, 0, 14, AB_SIEGE,
"Self-levelling robotic mortar platform. [Siege] extends reach." },
{ "S9 Hauler", UT_HARVESTER, FACTION_SERIES9, 300, 900, 0, 10, 72, 0, 200, 1000, 8, AB_NONE,
"Salvage automaton that hauls scrap to the foundry." },
{ "S9 Mender", UT_MEDIC, FACTION_SERIES9, 250, 600, 0, 10, 90, 120, 220, 0, 7, AB_HEAL,
"Repair automaton that welds wounded machines." },
{ "S9 Scorch", UT_FLAME, FACTION_SERIES9, 250, 700, 95, 12, 70, 52, 200, 0, 7, AB_NONE,
"Incendiary war-bot that melts infantry." },
{ "S9 Rocket", UT_MISSILE, FACTION_SERIES9, 350, 650,125, 10, 64, 220, 300, 0, 10, AB_NONE,
"Shoulder-mounted rocket drone with long reach." },
{ NULL, UT_NONE, FACTION_NONE, 0,0,0,0,0,0,0,0, 0, AB_NONE, NULL }
};
static const BldDef BLD_DEFS[] = {
{ "Command Centre", BT_BASE, 0, 0, 5000, 2, 2, 0, 12, {0},0, 0, 0, 0, 0,
"Faction headquarters. Trains infantry, provides pop." },
{ "War Factory", BT_WARFACTORY, 400, 12, 2500, 2, 2, 0, 8,
{ UT_BUGGY, UT_TANK, UT_ARTILLERY, UT_JEEP, UT_RAVAGER, UT_FLAME, UT_MISSILE, UT_MEDIC }, 8, 0, 0, 0, 0,
"Builds ground war machines." },
{ "Refinery", BT_REFINERY, 300, 10, 2000, 2, 2, 0, 6,
{ UT_HARVESTER }, 1, 0, 0, 0, 0,
"Processes scrap delivered by harvesters." },
{ "Power Plant", BT_POWER, 200, 8, 1500, 1, 1, 100, 4, {0},0, 0, 0, 0, 0,
"Generates power for the war effort." },
{ "Research Lab", BT_RESEARCH, 400, 12, 1500, 2, 2, 0, 0, {0},0, 0, 0, 0, 1,
"Researches damage, armour, speed, reload and build upgrades." },
{ "Repair Depot", BT_REPAIR, 300, 10, 1500, 2, 2, 0, 4, {0},0, 0, 0, 0, 0,
"Slowly repairs damaged units in range." },
{ "Turret", BT_TURRET, 250, 6, 1800, 1, 1, 0, 3, {0},0, 1, 60, 200, 0,
"Automated defensive gun emplacement." },
{ "Wall", BT_WALL, 25, 2, 800, 1, 1, 0, 0, {0},0, 0, 0, 0, 0,
"Cheap blast wall to channel the enemy." },
{ NULL, BT_NONE, 0,0,0,0,0,0,0,{0},0,0,0,0,0, NULL }
};
static UnitRegistry *g_unit_cards = NULL;
static UnitRegistry *g_bld_cards = NULL;
const UnitDef *unit_def(UnitType t, Faction f) {
for (int i = 0; UNIT_DEFS[i].name; i++) {
if (UNIT_DEFS[i].type == t && UNIT_DEFS[i].faction == f)
return &UNIT_DEFS[i];
}
/* fall back to survivor stats for unknown pairings */
for (int i = 0; UNIT_DEFS[i].name; i++)
if (UNIT_DEFS[i].type == t && UNIT_DEFS[i].faction == FACTION_SURVIVOR)
return &UNIT_DEFS[i];
return &UNIT_DEFS[0];
}
const BldDef *bld_def(BuildingType t) {
for (int i = 0; BLD_DEFS[i].name; i++)
if (BLD_DEFS[i].type == t) return &BLD_DEFS[i];
return &BLD_DEFS[0];
}
void config_init(void) {
if (g_unit_cards) return;
g_unit_cards = create_registry();
g_bld_cards = create_registry();
/* Build the unit-card registry from the same tables so the merged
* unit_card system stays the authoritative stats source. */
for (int i = 0; UNIT_DEFS[i].name; i++) {
const UnitDef *d = &UNIT_DEFS[i];
uint8_t ut = (d->type == UT_INFANTRY) ? UNIT_INFANTRY
: (d->type == UT_HARVESTER) ? UNIT_SPECIAL
: UNIT_VEHICLE;
UnitCard *c = create_unit_card(
d->name, faction_name(d->faction), (uint32_t)d->cost,
(uint32_t)d->hp, (uint32_t)d->attack, (uint32_t)d->defense,
(uint32_t)d->speed, (uint32_t)d->range, d->desc,
"assets/units/proc", ut);
if (c) add_unit(g_unit_cards, c);
}
for (int i = 0; BLD_DEFS[i].name; i++) {
const BldDef *d = &BLD_DEFS[i];
UnitCard *c = create_unit_card(
d->name, "Building", (uint32_t)d->cost, (uint32_t)d->hp,
(uint32_t)(d->is_turret ? d->atk : 0), 0,
(uint32_t)d->build_time, 0, d->desc,
"assets/buildings/proc", UNIT_SPECIAL);
if (c) add_unit(g_bld_cards, c);
}
}
UnitRegistry *unit_card_registry(void) { return g_unit_cards; }
UnitRegistry *bld_card_registry(void) { return g_bld_cards; }
Faction enemy_of(Faction f) {
if (f == FACTION_SURVIVOR) return FACTION_EVOLVED;
if (f == FACTION_EVOLVED) return FACTION_SURVIVOR;
return FACTION_NONE;
}
const char *faction_name(Faction f) {
switch (f) {
case FACTION_SURVIVOR: return "Survivors";
case FACTION_EVOLVED: return "Evolved";
case FACTION_SERIES9: return "Series 9";
default: return "Neutral";
}
}
const char *unit_name(UnitType t, Faction f) {
return unit_def(t, f)->name;
}
SDL_Color faction_color(Faction f) {
switch (f) {
case FACTION_SURVIVOR: return (SDL_Color){ 90, 160, 70, 255 }; /* olive green */
case FACTION_EVOLVED: return (SDL_Color){170, 70, 180, 255 }; /* mutant purple */
case FACTION_SERIES9: return (SDL_Color){200, 200, 60, 255 };
default: return (SDL_Color){140, 140, 140, 255 };
}
}
/* ----------------------------------------------------------------------- */
/* Campaign / missions */
/* ----------------------------------------------------------------------- */
static const Mission MISSIONS[] = {
{ 0, "First Strike",
"The mutant Evolved have crawled from the irradiated wasteland. "
"Crush their hive and secure the scrap fields before they dig in.",
OBJ_DESTROY_ALL, FACTION_EVOLVED, DIFF_NORMAL, 0, 0, 0, 1337u },
{ 1, "Hold the Line",
"Survive the relentless Evolved assault for eight minutes while your "
"own war machine gears up in the rear.",
OBJ_SURVIVE, FACTION_EVOLVED, DIFF_NORMAL, 0, 480.0f, 1, 24601u },
{ 2, "Scrap Rush",
"Out-produce the Evolved: stockpile 6000 scrap before their warbands "
"overrun your refinery line.",
OBJ_GATHER, FACTION_EVOLVED, DIFF_NORMAL, 6000, 0, 2, 9001u },
{ 3, "Hardened Nest",
"A fortified Evolved brood holds the far wastes behind walls of rubble. "
"Tear the nest down on Hard difficulty.",
OBJ_DESTROY_ALL, FACTION_EVOLVED, DIFF_HARD, 0, 0, 3, 31337u },
{ 4, "Rogue Machines",
"The Series 9 war machines have awakened and turned on everyone. "
"Crush the rogue robots before they scrape the wastes bare.",
OBJ_DESTROY_ALL, FACTION_SERIES9, DIFF_NORMAL, 0, 0, 2, 667u },
{ 5, "Crossfire",
"The Evolved and Series 9 are at each other's throats. Pick your moment, "
"then smash the survivor of their war.",
OBJ_DESTROY_ALL, FACTION_EVOLVED, DIFF_HARD, 0, 0, 1, 555u },
{ 6, "Scorched Earth",
"A scorched plateau offers no cover. Gather 9000 scrap in the open "
"while two enemy factions hunt you.",
OBJ_GATHER, FACTION_SERIES9, DIFF_HARD, 9000, 0, 0, 808u },
{ 7, "Last Stand",
"Your perimeter is the only thing left. Hold for twelve minutes against "
"a three-way onslaught.",
OBJ_SURVIVE, FACTION_EVOLVED, DIFF_HARD, 0, 720.0f, 3, 404u },
{ 8, "Deep Recon",
"Push into the mutant swamps and destroy the Evolved command links. "
"The terrain hides ambushes at every turn.",
OBJ_DESTROY_ALL, FACTION_EVOLVED, DIFF_NORMAL, 0, 0, 1, 2718u },
{ 9, "Machine Purge",
"Series 9 has massed a legion of scrap-hungry tanks. Wipe the assembly "
"grounds from the map.",
OBJ_DESTROY_ALL, FACTION_SERIES9, DIFF_HARD, 0, 0, 2, 90210u },
{ 10, "Broken Alliance",
"The Evolved courted the machines and lost. Now both want you dead. "
"End the pact by force.",
OBJ_DESTROY_ALL, FACTION_SERIES9, DIFF_HARD, 0, 0, 3, 1337u },
{ 11, "Final Approach",
"The enemy heartland lies ahead, bristling with turrets and walls. "
"Break through and destroy their core.",
OBJ_DESTROY_ALL, FACTION_EVOLVED, DIFF_HARD, 0, 0, 3, 4242u },
{ 12, "Krush, Kill 'n' Destroy",
"All-out war. Every faction fields its finest. Be the last army "
"standing on the poisoned earth.",
OBJ_DESTROY_ALL, FACTION_SERIES9, DIFF_HARD, 0, 0, 0, 1u },
{ -1, NULL, NULL, 0, FACTION_NONE, 0, 0, 0, 0, 0u }
};
int mission_count(void) {
int n = 0;
for (int i = 0; MISSIONS[i].name; i++) n++;
return n;
}
const Mission *mission_get(int id) {
for (int i = 0; MISSIONS[i].name; i++)
if (MISSIONS[i].id == id) return &MISSIONS[i];
return &MISSIONS[0];
}
/* ----------------------------------------------------------------------- */
/* Research */
/* ----------------------------------------------------------------------- */
const char *research_name(int up) {
switch (up) {
case UP_DAMAGE: return "Munitions";
case UP_ARMOR: return "Plating";
case UP_SPEED: return "Drivetrain";
case UP_RELOAD: return "Autoloaders";
case UP_BUILD: return "Logistics";
default: return "?";
}
}
int research_cost(int up, int level) {
(void)up;
return 250 * (level + 1);
}