Hopefully last commit

This commit is contained in:
2025-06-11 23:01:05 +02:00
parent 78bccd6c6f
commit 8bbe17491b
74 changed files with 1306 additions and 516 deletions

34
tiles/ammoCrafter.c Normal file
View File

@@ -0,0 +1,34 @@
//
// Created by bruno on 11.6.2025.
//
#include "ammoCrafter.h"
const MachineRecipe AmmoCrafterRecipes[] = {
// INPUT1 INPUT2 OUTPUT TIME
{IRON_PLATE, IRON_INGOT, IRON_BULLET, 120},
{SILVER_PLATE, SILVER_INGOT, SILVER_BULLET, 140},
{GOLD_PLATE, GOLD_INGOT, GOLD_BULLET, 160},
{PLATINUM_PLATE, PLATINUM_INGOT, PLATINUM_BULLET, 180},
{IRON_ROD, IRON_INGOT, TYPE_BELT, 30},
{IRON_PLATE, IRON_INGOT, TYPE_SPLITTER, 60},
{GOLD_PLATE, SILVER_INGOT, TYPE_AMMOCRAFTER, 240},
{SILVER_PLATE, GOLD_INGOT, TYPE_WIRECRAFTER, 240},
{PLATINUM_PLATE, GOLD_INGOT, TYPE_TURRET, 240},
{SILVER_ROD, SILVER_INGOT, TYPE_FURNACE, 240},
{GOLD_ROD, IRON_INGOT, TYPE_BLOCK, 120},
};
void initAmmoCrafterTile() {
initMachineTile(TYPE_AMMOCRAFTER, AmmoCrafterRecipes, sizeof(AmmoCrafterRecipes) / sizeof(AmmoCrafterRecipes[0]),
1, /* start frame */
8 /* frame divisor */);
}
void updateAmmoCrafter(Tile *tile) {
updateMachine(tile, AmmoCrafterRecipes, sizeof(AmmoCrafterRecipes) / sizeof(AmmoCrafterRecipes[0]), WAVE_RAMP, 500, 1);
}

23
tiles/ammoCrafter.h Normal file
View File

@@ -0,0 +1,23 @@
//
// Created by bruno on 11.6.2025.
//
#ifndef FACTORYGAME_AMMOCRAFTER_H
#define FACTORYGAME_AMMOCRAFTER_H
#include "../items/item.h"
#include "stdint.h"
#include "../util/crafter.h"
#include "../util/audio.h"
extern const MachineRecipe AmmoCrafterRecipes[];
void updateAmmoCrafter(Tile *tile);
void initAmmoCrafterTile();
#define AMMO_CRAFTER_INPUT_SLOT 0
#define AMMO_CRAFTER_OUTPUT_SLOT 1
#endif //FACTORYGAME_AMMOCRAFTER_H

29
tiles/core.c Normal file
View File

@@ -0,0 +1,29 @@
//
// Created by bruno on 11.6.2025.
//
#include "core.h"
#include "../player/player.h"
void updateCore(Tile *tile) {
for (size_t slot = 0; slot < ItemSlotCount; slot++) {
ItemOnBelt *item = &tile->items[slot];
if (item->type == TYPE_AIR) {
continue;
} else if (item->type < ITEMREGISTRY_SIZE) {
mainPlayer.inventory.slotCounts[item->type]++;
item->type = TYPE_AIR;
}
}
}
void initCoreTile() {
// Force slot assignments for allowed items based on recipes
for (size_t i = 0; i < ITEMREGISTRY_SIZE; i++) {
for (size_t slot = 0; slot < ItemSlotCount; slot++) {
TileRegistry[TYPE_CORE].allowedInItems[slot][i] = true;
}
}
// Animation and behavior settings
TileRegistry[TYPE_CORE].needsTicks = true;
}

14
tiles/core.h Normal file
View File

@@ -0,0 +1,14 @@
//
// Created by bruno on 11.6.2025.
//
#ifndef FACTORYGAME_CORE_H
#define FACTORYGAME_CORE_H
#include "tile.h"
void updateCore(Tile *tile);
void initCoreTile();
#endif //FACTORYGAME_CORE_H

View File

@@ -11,7 +11,6 @@
// Suppose this is defined somewhere
extern const MachineRecipe FurnaceRecipes[];
extern const size_t FurnaceRecipeCount;
void updateFurnace(Tile *tile);
@@ -20,6 +19,4 @@ void initFurnaceTile();
#define FURNACE_INPUT_SLOT 0
#define FURNACE_OUTPUT_SLOT 1
void updateFurnace(Tile * tile);
#endif //FACTORYGAME_FURNACE_H

View File

@@ -10,6 +10,68 @@
#include "../util/font.h"
#include "miner.h"
#include "turret.h"
#include "../util/perlin.h"
#include "../util/button.h"
#include "../util/audio.h"
#include "ammoCrafter.h"
#include "wiredrawer.h"
#include "core.h"
MiniRect enemySpawn;
MiniRect playerCore;
SDL_Rect viewport;
uint16_t DISPLAY_MAP_WIDTH = 30;
uint16_t DISPLAY_MAP_HEIGHT = 16;
uint16_t DISPLAY_WIDTH = 30 * TILE_SIZE;
uint16_t DISPLAY_HEIGHT = 16 * TILE_SIZE;
void setTileView(uint16_t w, uint16_t h) {
DISPLAY_MAP_WIDTH = w;
DISPLAY_MAP_HEIGHT = h;
DISPLAY_WIDTH = DISPLAY_MAP_WIDTH * TILE_SIZE;
DISPLAY_HEIGHT = DISPLAY_MAP_HEIGHT * TILE_SIZE;
screenRect.x = 0;
screenRect.y = 0;
screenRect.w = DISPLAY_WIDTH;
screenRect.h = DISPLAY_HEIGHT;
SDL_RenderSetLogicalSize(mainRenderer, DISPLAY_WIDTH, DISPLAY_HEIGHT);
SDL_SetWindowSize(window, DISPLAY_WIDTH, DISPLAY_HEIGHT);
viewport = screenRect;
SDL_RenderSetViewport(mainRenderer, &viewport);
SDL_SetWindowPosition(window, 0, 0);
audioData.maxPanDistance = DISPLAY_WIDTH / 2;
SDL_DestroyTexture(hudTexture);
SDL_DestroyTexture(entityTexture);
SDL_DestroyTexture(itemsTexture);
SDL_DestroyTexture(tilesTexture);
SDL_DestroyTexture(backgroundTexture);
hudTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
screenRect.h);
entityTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
screenRect.h);
SDL_SetTextureBlendMode(entityTexture, SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(hudTexture, SDL_BLENDMODE_BLEND);
itemsTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
screenRect.h);
tilesTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
screenRect.h);
SDL_SetTextureBlendMode(tilesTexture, SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(itemsTexture, SDL_BLENDMODE_BLEND);
backgroundTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
screenRect.w,
screenRect.h);
PlayerRect.x = (DISPLAY_WIDTH / 2) - (PlayerRect.w / 2);
PlayerRect.y = (DISPLAY_HEIGHT / 2) - (PlayerRect.h / 2);
initButtons();
}
int scrollFrame = 0;
unsigned long beltFrames = 0;
@@ -117,7 +179,7 @@ void registerTile(char fname[20], SDL_Renderer *renderer) {
TileRegistry[indexTile].animation.atlasRects[o][frame] = allocate_32x32(textures[o], renderer);
}
printf("Bound %s to %d\n", fname, indexTile);
//printf("Bound %s to %d\n", fname, indexTile);
TileRegistry[indexTile].type = indexTile;
TileRegistry[indexTile].maxHealth = 200;
TileRegistry[indexTile].animation.frameCount = frame + 1;
@@ -262,8 +324,14 @@ void loadBackgroundTiles(SDL_Renderer *renderer) {
void preSetupTiles() {
TileRegistry[TYPE_MINER].animation.startFrame = 1;
TileRegistry[TYPE_FURNACE].animation.divisor = 8;
TileRegistry[TYPE_WIRECRAFTER].animation.divisor = 8;
TileRegistry[TYPE_SPLITTER].animation.divisor = 8;
TileRegistry[TYPE_AMMOCRAFTER].animation.divisor = 8;
TileRegistry[TYPE_CORE].animation.divisor = 8;
BackgroundTileRegistry[BGType_WATER_DEEP].animation.divisor = 16;
BackgroundTileRegistry[BGType_ENEMY_FLOOR].animation.divisor = 16;
BackgroundTileRegistry[BGType_WATER_SHALLOW].animation.divisor = 12;
BackgroundTileRegistry[BGType_GRASS_FLOWER0].animation.divisor = 16;
BackgroundTileRegistry[BGType_GRASS_FLOWER1].animation.divisor = 16;
@@ -309,6 +377,9 @@ void setupTiles() {
BackgroundTileRegistry[BGType_WATER_DEEP].walkable = false;
initFurnaceTile();
initWireDrawerTile();
initAmmoCrafterTile();
initCoreTile();
}
uint16_t getBreakTime(int type) {
@@ -481,4 +552,113 @@ bool isWalkable(MiniRect tileCoords) {
void updateTiles() {
}
}
// Main generator:
void genInitMap() {
const double terrainScale = 2;
const double humidityScale = 1;
const double oreScale = 2;
const int terrainOct = 4;
const int humidityOct = 4;
const int oreOct = 4;
int seedX = rand();
int seedY = rand();
int seedN = rand();
// Min/max trackers
double terrainMin = 1e9, terrainMax = -1e9;
double humidityMin = 1e9, humidityMax = -1e9;
double oreNrmMin = 1e9, oreNrmMax = -1e9;
for (uint16_t y = 0; y < MAP_HEIGHT; y++) {
for (uint16_t x = 0; x < MAP_WIDTH; x++) {
double terrain = pnoise2d(x + 1000 + seedX,
y + 1000 + seedY,
terrainScale, terrainOct, seedN);
double humidity = pnoise2d(x + seedX,
y + seedY,
humidityScale, humidityOct, seedN);
double oreNrm = pnoise2d(x + 9999 + seedX,
y + 1111 + seedY,
oreScale, oreOct, seedN);
// Track min/max
if (terrain < terrainMin) terrainMin = terrain;
if (terrain > terrainMax) terrainMax = terrain;
if (humidity < humidityMin) humidityMin = humidity;
if (humidity > humidityMax) humidityMax = humidity;
if (oreNrm < oreNrmMin) oreNrmMin = oreNrm;
if (oreNrm > oreNrmMax) oreNrmMax = oreNrm;
// [Same as your original terrain generation logic...]
BackgroundType baseType = BGType_COBBLE0;
if (terrain < 0.30) {
baseType = (humidity < 0.5) ? BGType_WATER_SHALLOW : BGType_WATER_DEEP;
} else if (terrain < 0.35) {
if (humidity < 0.3) baseType = BGType_SAND4;
else if (humidity < 0.6) baseType = BGType_SAND2;
else baseType = BGType_SAND7;
} else if (terrain < 0.7) {
double grassVal = (terrain - 0.35) / (0.70 - 0.35);
int idx = (int) (grassVal * 3.0);
if (idx >= 4) idx = 3;
if (humidity > 0.6 && ((rand() & 0xFF) < 10)) {
int flowerIdx = rand() % 4;
baseType = (BackgroundType) (BGType_GRASS_FLOWER0 + flowerIdx);
} else {
baseType = (BackgroundType) (BGType_GRASS0 + idx);
}
} else if (terrain < 0.85) {
int idx = rand() % 4;
baseType = (BackgroundType) (BGType_COBBLE0 + idx);
} else {
int idx = rand() % 4;
baseType = (BackgroundType) (BGType_TILES0 + idx);
}
BackgroundType finalType = baseType;
if (baseType != BGType_WATER_SHALLOW && baseType != BGType_WATER_DEEP) {
if (oreNrm > 0.86) {
double sub = (oreNrm - 0.86) / (1.0 - 0.86);
if (sub < 0.25) finalType = BGType_IRON_ORE;
else if (sub < 0.50) finalType = BGType_SILVER_ORE;
else if (sub < 0.80) finalType = BGType_GOLD_ORE;
else finalType = BGType_PLATINUM_ORE;
}
}
if (finalType > BGType_END) {
finalType = BGType_COBBLE0;
}
backgroundMap[y][x].type = finalType;
}
enemySpawn.x = MAP_WIDTH - 10;
enemySpawn.y = 10;
for (int enX = enemySpawn.x - 5; enX < enemySpawn.x + 6; enX++) {
for (int enY = enemySpawn.y - 5; enY < enemySpawn.y + 6; enY++) {
backgroundMap[enY][enX].type = BGType_ENEMY_FLOOR;
}
}
playerCore.x = 8;
playerCore.y = MAP_HEIGHT - 10;
for (int plX = playerCore.x - 5; plX < playerCore.x + 6; plX++) {
for (int plY = playerCore.y - 5; plY < playerCore.y + 6; plY++) {
backgroundMap[plY][plX].type = BGType_TILES0;
}
}
tileMap[playerCore.y][playerCore.x].type = TYPE_CORE;
tileMap[playerCore.y][playerCore.x].direction = ORIENT_LEFT;
tileMap[playerCore.y][playerCore.x].health = TileRegistry[TYPE_CORE].maxHealth;
tileMap[playerCore.y][playerCore.x].fixedFrame = 0;
tileMap[playerCore.y][playerCore.x].rect = playerCore;
}
// Debug printout
printf("Terrain Noise: min = %f, max = %f\n", terrainMin, terrainMax);
printf("Humidity Noise: min = %f, max = %f\n", humidityMin, humidityMax);
printf("Ore Normalized: min = %f, max = %f\n", oreNrmMin, oreNrmMax);
}

View File

@@ -9,17 +9,17 @@
#include "../items/item.h"
#include "tilecallbacks.h"
#define MAP_WIDTH 500
#define MAP_HEIGHT 500
#define MAP_WIDTH 200
#define MAP_HEIGHT 200
#define DISPLAY_MAP_WIDTH 60
#define DISPLAY_MAP_HEIGHT 31
extern uint16_t DISPLAY_MAP_WIDTH;
extern uint16_t DISPLAY_MAP_HEIGHT;
extern uint16_t DISPLAY_WIDTH;
extern uint16_t DISPLAY_HEIGHT;
#define TILE_SIZE 32
#define DISPLAY_WIDTH DISPLAY_MAP_WIDTH * TILE_SIZE
#define DISPLAY_HEIGHT DISPLAY_MAP_HEIGHT * TILE_SIZE
#define MAX_TILES MAP_WIDTH * MAP_HEIGHT
@@ -73,12 +73,16 @@ typedef enum BackgroundType {
BGType_SILVER_ORE,
BGType_GOLD_ORE,
BGType_PLATINUM_ORE,
BGType_ENEMY_FLOOR,
BGType_END
} BackgroundType;
#define MAX_BASE_NAMES 512
#define MAX_ANIMATION_FRAMES 32
extern MiniRect enemySpawn;
extern MiniRect playerCore;
typedef void (*UpdateTileCallback)(struct Tile *tile);
typedef struct TileTypeReg {
@@ -166,4 +170,9 @@ uint16_t getBreakTime(int type);
void initTiles();
void genInitMap();
void setTileView(uint16_t w, uint16_t h);
extern SDL_Rect viewport;
#endif //FACTORYGAME_TILE_H

View File

@@ -6,6 +6,9 @@
#include "furnace.h"
#include "miner.h"
#include "turret.h"
#include "ammoCrafter.h"
#include "wiredrawer.h"
#include "core.h"
const UpdateTileCallback ItemTileCallbacks[TILEREGISTRY_SIZE] = {
[TYPE_AIR] = NULL,
@@ -14,4 +17,8 @@ const UpdateTileCallback ItemTileCallbacks[TILEREGISTRY_SIZE] = {
[TYPE_FURNACE] = updateFurnace,
[TYPE_MINER] = updateMiner,
[TYPE_TURRET] = updateTurret,
[TYPE_SPLITTER] = NULL, //TODO MOVE implementation from updateItem
[TYPE_CORE] = updateCore,
[TYPE_WIRECRAFTER] = updateWireDrawer,
[TYPE_AMMOCRAFTER] = updateAmmoCrafter,
};

29
tiles/wiredrawer.c Normal file
View File

@@ -0,0 +1,29 @@
//
// Created by bruno on 11.6.2025.
//
#include "wiredrawer.h"
#include "tile.h"
#include "../util/audio.h"
const MachineRecipe WireDrawerRecipes[] = {
{IRON_INGOT, TYPE_AIR, IRON_PLATE, 120},
{SILVER_INGOT, TYPE_AIR, SILVER_PLATE, 140},
{GOLD_INGOT, TYPE_AIR, GOLD_PLATE, 160},
{PLATINUM_INGOT, TYPE_AIR, PLATINUM_PLATE, 180},
{IRON_PLATE, TYPE_AIR, IRON_ROD, 120},
{SILVER_PLATE, TYPE_AIR, SILVER_ROD, 140},
{GOLD_PLATE, TYPE_AIR, GOLD_ROD, 160},
{PLATINUM_PLATE, TYPE_AIR, PLATINUM_ROD, 180}
};
void initWireDrawerTile() {
initMachineTile(TYPE_WIRECRAFTER, WireDrawerRecipes, sizeof(WireDrawerRecipes) / sizeof(WireDrawerRecipes[0]),
1, /* start frame */
8 /* frame divisor */);
}
void updateWireDrawer(Tile *tile) {
updateMachine(tile, WireDrawerRecipes, sizeof(WireDrawerRecipes) / sizeof(WireDrawerRecipes[0]), WAVE_RAMP, 500, 1);
}

21
tiles/wiredrawer.h Normal file
View File

@@ -0,0 +1,21 @@
//
// Created by bruno on 11.6.2025.
//
#ifndef FACTORYGAME_WIREDRAWER_H
#define FACTORYGAME_WIREDRAWER_H
#include "../util/crafter.h"
// Suppose this is defined somewhere
extern const MachineRecipe WireDrawerRecipes[];
void updateWireDrawer(Tile *tile);
void initWireDrawerTile();
#define WIRE_DRAWER_INPUT_SLOT 0
#define WIRE_DRAWER_OUTPUT_SLOT 1
#endif //FACTORYGAME_WIREDRAWER_H