dreva in kamni top

This commit is contained in:
2025-12-07 22:32:45 +01:00
parent 974141c08c
commit 6b8f9aee66
13 changed files with 384 additions and 90 deletions

View File

@@ -9,6 +9,18 @@ const CITY_SIZE = 15;
const CITY_START_X = 65; // Desni del mape (npr. med 65 in 80)
const CITY_START_Y = 65;
// ========================================================
// NOVE KONSTANTE ZA RUDNIK IN RUDE
// ========================================================
const TILE_STONE_ORE = 82; // ID za navadni kamen (Ore Tile)
const TILE_IRON_ORE = 83; // ID za železovo rudo
const TILE_PAVEMENT = 16; // ID za prehodno ploščico (tla rudnika)
const TILE_MINE_WALL = 81; // ID za zid rudnika (Solid/Kolizija)
// ID-ji Virov
const ITEM_STONE = 20; // ID za kamen, ki ga igralec dobi
const ITEM_IRON = 21; // ID za železo
// Terrain Generator System
class TerrainSystem {
constructor(scene, width = 100, height = 100) {
@@ -23,6 +35,7 @@ class TerrainSystem {
this.decorations = [];
this.decorationsMap = new Map();
this.cropsMap = new Map();
this.tileHealthMap = new Map(); // Global register zdravja ploščic
this.visibleTiles = new Map();
this.visibleDecorations = new Map();
@@ -92,7 +105,12 @@ class TerrainSystem {
PAVEMENT: { name: 'pavement', height: 0.6, color: 0x777777 },
RUINS: { name: 'ruins', height: 0.6, color: 0x555555 },
PATH: { name: 'path', height: -1, color: 0xc2b280 },
FARMLAND: { name: 'farmland', height: -1, color: 0x5c4033 }
FARMLAND: { name: 'farmland', height: -1, color: 0x5c4033 },
// MINE TYPES
MINE_FLOOR: { name: 'mine_floor', height: 0, color: 0x333333, id: TILE_PAVEMENT },
MINE_WALL: { name: 'mine_wall', height: 1, color: 0x1a1a1a, id: TILE_MINE_WALL },
ORE_STONE: { name: 'ore_stone', height: 0.5, color: 0x555555, id: TILE_STONE_ORE },
ORE_IRON: { name: 'ore_iron', height: 0.5, color: 0x884444, id: TILE_IRON_ORE }
};
this.offsetX = 0;
@@ -218,6 +236,12 @@ class TerrainSystem {
hasDecoration: false,
hasCrop: false
};
// Place Trees dynamically during generation
this.placeTree(x, y, terrainType.name);
// Place Rocks dynamically
this.placeRock(x, y, terrainType.name);
}
}
@@ -240,61 +264,12 @@ class TerrainSystem {
}
}
for (let i = validPositions.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[validPositions[i], validPositions[j]] = [validPositions[j], validPositions[i]];
}
// DECORATIONS REMOVED BY REQUEST
// Drevesa, kamni, rože in ruševine so odstranjeni.
for (let i = 0; i < Math.min(25, validPositions.length); i++) {
const pos = validPositions[i];
let treeType = 'tree_green_new';
const rand = Math.random();
if (rand < 0.15) treeType = 'tree_blue_new';
else if (rand < 0.25) treeType = 'tree_dead_new';
// Ostalo je samo generiranje ploščic (tiles) in fixnih con (farm, city floor).
this.addDecoration(pos.x, pos.y, treeType);
treeCount++;
}
for (let i = 25; i < Math.min(50, validPositions.length); i++) {
const pos = validPositions[i];
// Uporabi uporabnikove kamne
const rockType = Math.random() > 0.5 ? 'rock_1' : 'rock_2';
this.addDecoration(pos.x, pos.y, rockType);
rockCount++;
}
const flowerNoise = new PerlinNoise(Date.now() + 3000);
for (let y = 5; y < this.height - 5; y++) {
for (let x = 5; x < this.width - 5; x++) {
if (isFarm(x, y) || isCity(x, y)) continue;
const tile = this.tiles[y][x];
const val = flowerNoise.noise(x * 0.12, y * 0.12);
if (val > 0.85 && tile.type.includes('grass')) {
this.addDecoration(x, y, 'flowers_new');
flowerCount++;
}
}
}
const roomSize = 5;
const roomsAcross = Math.floor(CITY_SIZE / roomSize);
for (let ry = 0; ry < roomsAcross; ry++) {
for (let rx = 0; rx < roomsAcross; rx++) {
if (Math.random() < 0.75) {
const gx = CITY_START_X + rx * roomSize;
const gy = CITY_START_Y + ry * roomSize;
this.placeStructure(gx, gy, 'ruin_room');
} else {
const gx = CITY_START_X + rx * roomSize + 2;
const gy = CITY_START_Y + ry * roomSize + 2;
const rockType = Math.random() > 0.5 ? 'rock_1' : 'rock_2';
this.addDecoration(gx, gy, rockType);
}
}
}
console.log(`✅ Teren generiran (CLEAN): ${treeCount} dreves, ${rockCount} kamnov.`);
console.log(`✅ Teren generiran: ${treeCount} dreves, ${rockCount} kamnov.`);
}
@@ -356,6 +331,80 @@ class TerrainSystem {
}
}
placeTree(x, y, tileType) {
// 1. Safety Checks
if (!tileType || !tileType.includes('grass')) return;
const isFarm = Math.abs(x - FARM_CENTER_X) <= FARM_SIZE / 2 + 2;
const isCity = x >= CITY_START_X - 2 && x < CITY_START_X + CITY_SIZE + 2 && y >= CITY_START_Y - 2 && y < CITY_START_Y + CITY_SIZE + 2;
if (isFarm || isCity) return;
// 2. Noise for clustering (Forests)
// Offset inputs to decouple from terrain height noise
const noiseVal = this.noise.noise(x * 0.1 + 123.45, y * 0.1 + 678.90);
// 3. Selection Logic (Scattered & Saplings focus)
let shouldPlace = false;
let type = window.SPRITE_TREE_HEALTHY || 'tree_green_final';
// Bolj enakomerna porazdelitev (Scattered)
// Noise uporabimo le za rahlo variacijo, ne za stroge gruče
let chance = 0.015; // 1.5% base chance (zelo redko)
if (noiseVal > 0.30) chance = 0.03; // Malo večja gostota v "gozdu"
if (Math.random() < chance) {
shouldPlace = true;
// Variants Logic
const r = Math.random();
// 50% možnosti, da je drevo komaj začelo rasti (Sapling)
if (r < 0.50) type = window.SPRITE_TREE_SAPLING || 'tree_sapling';
else if (r < 0.60) type = window.SPRITE_TREE_DEAD || 'tree_dead_final';
else if (r < 0.65) type = window.SPRITE_TREE_BLUE || 'tree_blue_final';
// Ostalo (35%) je odraslo drevo
}
// 4. Placement
if (shouldPlace) {
this.addDecoration(x, y, type);
}
}
placeRock(x, y, tileType) {
if (!tileType || !tileType.includes('grass') && !tileType.includes('dirt')) return;
const isFarm = Math.abs(x - FARM_CENTER_X) <= FARM_SIZE / 2 + 2;
const isCity = x >= CITY_START_X - 2 && x < CITY_START_X + CITY_SIZE + 2 && y >= CITY_START_Y - 2 && y < CITY_START_Y + CITY_SIZE + 2;
if (isFarm || isCity) return;
// Če je že dekoracija (drevo), ne dajaj kamna
if (this.tiles[y][x].hasDecoration) return;
// Noise for Rock Clusters
const noiseVal = this.noise.noise(x * 0.15 + 99.99, y * 0.15 + 88.88);
let shouldPlace = false;
let type = 'rock_1'; // Default
let chance = 0.01; // 1% Scattered chance
if (noiseVal > 0.45) { // Rock Cluster Area
chance = 0.30; // High density in cluster
}
if (Math.random() < chance) {
shouldPlace = true;
// Variants - "Lepi kamni" (rock_asset)
// Odstranili smo nedokončane velike kamne
type = 'rock_asset';
}
if (shouldPlace) {
this.addDecoration(x, y, type);
}
}
placeStructure(gridX, gridY, type) {
if (type === 'ruin') {
for (let y = 0; y < 6; y++) {
@@ -422,6 +471,7 @@ class TerrainSystem {
else if (type === 'fence') scale = 0.025;
else if (type === 'gravestone') scale = 0.03;
else if (type === 'hill_sprite') scale = 0.025;
else if (type.includes('_final')) scale = 1.0; // New Final Trees
else {
// Old Assets (Low Res)
if (type.includes('tree')) scale = 1.2 + Math.random() * 0.4;
@@ -429,6 +479,15 @@ class TerrainSystem {
else scale = 1.0;
}
// Calculate Plant Day for Saplings (Growth System)
let plantDay = -1;
if (type.includes('sapling')) {
const w = this.scene.weatherSystem;
plantDay = w ? w.getDayCount() : 1;
// Random init offset for initial generation
if (!w) plantDay = 1 - Math.floor(Math.random() * 2);
}
const decorData = {
gridX: gridX,
gridY: gridY,
@@ -436,7 +495,8 @@ class TerrainSystem {
id: key,
maxHp: 10,
hp: 10,
scale: scale
scale: scale,
plantDay: plantDay // Added for Growth System
};
this.decorations.push(decorData);
this.decorationsMap.set(key, decorData);
@@ -535,7 +595,7 @@ class TerrainSystem {
sprite.setTexture(tile.type);
const screenPos = this.iso.toScreen(x, y);
sprite.setPosition(screenPos.x + this.offsetX, screenPos.y + this.offsetY);
sprite.setDepth(this.iso.getDepth(x, y));
sprite.setDepth(this.iso.getDepth(x, y, this.iso.LAYER_FLOOR)); // Tiles = Floor
this.visibleTiles.set(key, sprite);
}
}
@@ -552,6 +612,7 @@ class TerrainSystem {
if (decor.type.includes('house') || decor.type.includes('market') || decor.type.includes('structure')) {
sprite.setOrigin(0.5, 0.8);
} else {
// DREVESA: Origin na dno, da Y-sort deluje
sprite.setOrigin(0.5, 1.0);
}
@@ -562,7 +623,8 @@ class TerrainSystem {
sprite.setAlpha(decor.alpha);
}
sprite.setDepth(this.iso.getDepth(x, y) + 1);
// Layer Objects
sprite.setDepth(this.iso.getDepth(x, y, this.iso.LAYER_OBJECTS));
this.visibleDecorations.set(key, sprite);
}
}
@@ -576,7 +638,8 @@ class TerrainSystem {
sprite.setPosition(screenPos.x + this.offsetX, screenPos.y + this.offsetY - voxelOffset);
sprite.setTexture(`crop_stage_${crop.stage}`);
sprite.setOrigin(0.5, 1);
sprite.setDepth(this.iso.getDepth(x, y) + 0.5);
// Layer Objects (da igralec hodi okoli njih)
sprite.setDepth(this.iso.getDepth(x, y, this.iso.LAYER_OBJECTS));
this.visibleCrops.set(key, sprite);
}
}
@@ -605,4 +668,48 @@ class TerrainSystem {
}
}
}
getTile(x, y) {
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
return this.tiles[y][x];
}
return null;
}
update(delta) {
this.growthTimer = (this.growthTimer || 0) + delta;
if (this.growthTimer < 5000) return;
this.growthTimer = 0;
const weather = this.scene.weatherSystem;
if (!weather) return;
const currentDay = weather.getDayCount();
const healthyType = window.SPRITE_TREE_HEALTHY || 'tree_green_final';
for (const decor of this.decorationsMap.values()) {
if (decor.type.includes('sapling')) {
if (decor.plantDay !== undefined && decor.plantDay > -100 && (currentDay - decor.plantDay >= 3)) {
decor.type = healthyType;
decor.scale = 1.0;
decor.hp = 10;
decor.plantDay = -1;
const key = decor.id;
if (this.visibleDecorations.has(key)) {
const sprite = this.visibleDecorations.get(key);
sprite.setTexture(decor.type);
sprite.setScale(decor.scale);
this.scene.tweens.add({
targets: sprite,
scaleY: { from: 0.1, to: decor.scale },
duration: 800,
ease: 'Bounce.out'
});
console.log(`🌳 Tree grew on Day ${currentDay}`);
}
}
}
}
}
}