the whole game

This commit is contained in:
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

229
src/world/level/biome/Biome.cpp Executable file
View File

@@ -0,0 +1,229 @@
#include "BiomeInclude.h"
#include "../levelgen/feature/TreeFeature.h"
#include "../levelgen/feature/TallgrassFeature.h"
#include "../../entity/EntityTypes.h"
#include "../../entity/MobCategory.h"
#include "../../level/tile/TallGrass.h"
Biome* Biome::rainForest = NULL;
Biome* Biome::swampland = NULL;
Biome* Biome::seasonalForest = NULL;
Biome* Biome::forest = NULL;
Biome* Biome::savanna = NULL;
Biome* Biome::shrubland = NULL;
Biome* Biome::taiga = NULL;
Biome* Biome::desert = NULL;
Biome* Biome::plains = NULL;
Biome* Biome::iceDesert = NULL;
Biome* Biome::tundra = NULL;
/*static*/
Biome::MobList Biome::_emptyMobList;
int Biome::defaultTotalEnemyWeight = 0;
int Biome::defaultTotalFriendlyWeight = 0;
/*static*/
Biome* Biome::map[64*64];
Biome::Biome()
: topMaterial(((Tile*)Tile::grass)->id),
material(((Tile*)Tile::dirt)->id),
leafColor(0x4EE031)
{
_friendlies.insert(_friendlies.end(), MobSpawnerData(MobTypes::Sheep, 12, 2, 3));
_friendlies.insert(_friendlies.end(), MobSpawnerData(MobTypes::Pig, 10, 1, 3));
_friendlies.insert(_friendlies.end(), MobSpawnerData(MobTypes::Chicken, 10, 2, 4));
_friendlies.insert(_friendlies.end(), MobSpawnerData(MobTypes::Cow, 8, 2, 3));
_enemies.insert(_enemies.end(), MobSpawnerData(MobTypes::Spider, 8, 2, 3));
_enemies.insert(_enemies.end(), MobSpawnerData(MobTypes::Zombie, 12, 2, 4));
_enemies.insert(_enemies.end(), MobSpawnerData(MobTypes::Skeleton, 6, 1, 3));
_enemies.insert(_enemies.end(), MobSpawnerData(MobTypes::Creeper, 4, 1, 1));
//_enemies.insert(_enemies.end(), MobSpawnerData(Slime.class, 10, 4, 4));
//_enemies.insert(_enemies.end(), MobSpawnerData(EnderMan.class, 1, 1, 4));
// wolves are added to forests and taigas
// _friendlies.insert(_friendlies.end(), new MobSpawnerData(Wolf.class, 2));
//_waterFriendlies.insert(_waterFriendlies.end(), (new MobSpawnerData(Squid.class, 10, 4, 4));
//
// Sum up the weights
//
defaultTotalEnemyWeight = 0;
for (MobList::const_iterator cit = _enemies.begin(); cit != _enemies.end(); ++cit)
defaultTotalEnemyWeight += cit->randomWeight;
defaultTotalFriendlyWeight = 0;
for (MobList::const_iterator cit = _friendlies.begin(); cit != _friendlies.end(); ++cit)
defaultTotalFriendlyWeight += cit->randomWeight;
}
Biome* Biome::setName( const std::string& name )
{
this->name = name;
return this;
}
Biome* Biome::setLeafColor( int leafColor )
{
this->leafColor = leafColor;
return this;
}
Biome* Biome::setColor( int color )
{
this->color = color;
return this;
}
Biome* Biome::setSnowCovered()
{
return this;
}
Biome* Biome::clearMobs( bool friendlies /*= true*/, bool waterFriendlies /*= true*/, bool enemies /*= true*/ )
{
if (friendlies) _friendlies.clear();
if (waterFriendlies) _waterFriendlies.clear();
if (enemies) _enemies.clear();
return this;
}
/*static*/
void Biome::recalc()
{
for (int a = 0; a < 64; a++) {
for (int b = 0; b < 64; b++) {
map[a + b * 64] = _getBiome(a / 63.0f, b / 63.0f);
}
}
Biome::desert->topMaterial = Biome::desert->material = (char) Tile::sand->id;
Biome::iceDesert->topMaterial = Biome::iceDesert->material = (char) Tile::sand->id;
}
/*static*/
void Biome::initBiomes() {
rainForest = (new RainforestBiome())->setColor(0x08FA36)->setName("Rainforest")->setLeafColor(0x1FF458);
swampland = (new SwampBiome())->setColor(0x07F9B2)->setName("Swampland")->setLeafColor(0x8BAF48);
seasonalForest = (new Biome())->setColor(0x9BE023)->setName("Seasonal Forest");
forest = (new ForestBiome())->setColor(0x056621)->setName("Forest")->setLeafColor(0x4EBA31);
savanna = (new FlatBiome())->setColor(0xD9E023)->setName("Savanna");
shrubland = (new Biome())->setColor(0xA1AD20)->setName("Shrubland");
taiga = (new TaigaBiome())->setColor(0x2EB153)->setName("Taiga")->setSnowCovered()->setLeafColor(0x7BB731);
desert = (new FlatBiome())->setColor(0xFA9418)->clearMobs(true, true, false)->setName("Desert");
plains = (new FlatBiome())->setColor(0xFFD910)->setName("Plains");
iceDesert = (new FlatBiome())->setColor(0xFFED93)->clearMobs(true, false, false)->setName("Ice Desert")->setSnowCovered()->setLeafColor(0xC4D339);
tundra = (new Biome())->setColor(0x57EBF9)->setName("Tundra")->setSnowCovered()->setLeafColor(0xC4D339);
recalc();
}
/*static*/
void Biome::teardownBiomes() {
delete rainForest; rainForest= NULL;
delete swampland; swampland = NULL;
delete seasonalForest; seasonalForest = NULL;
delete forest; forest = NULL;
delete savanna; savanna = NULL;
delete shrubland; shrubland = NULL;
delete taiga; taiga = NULL;
delete desert; desert = NULL;
delete plains; plains = NULL;
delete iceDesert; iceDesert = NULL;
delete tundra; tundra = NULL;
}
Feature* Biome::getTreeFeature( Random* random )
{
if (random->nextInt(10) == 0) {
//return /*new*/ BasicTree();
}
return new TreeFeature(false);
}
Feature* Biome::getGrassFeature( Random* random ) {
return new TallgrassFeature(Tile::tallgrass->id, TallGrass::TALL_GRASS);
}
Biome* Biome::getBiome( float temperature, float downfall )
{
int a = (int) (temperature * 63);
int b = (int) (downfall * 63);
//printf("Getting biome: %s\n", map[a + b * 64]->name.c_str());
return map[a + b * 64];
}
Biome* Biome::_getBiome( float temperature, float downfall )
{
downfall *= (temperature);
if (temperature < 0.10f) {
return Biome::tundra;
} else if (downfall < 0.20f) {
if (temperature < 0.50f) {
return Biome::tundra;
} else if (temperature < 0.95f) {
return Biome::savanna;
} else {
return Biome::desert;
}
} else if (downfall > 0.5f && temperature < 0.7f) {
return Biome::swampland;
} else if (temperature < 0.50f) {
return Biome::taiga;
} else if (temperature < 0.97f) {
if (downfall < 0.35f) {
return Biome::shrubland;
} else {
return Biome::forest;
}
} else {
if (downfall < 0.45f) {
return Biome::plains;
} else if (downfall < 0.90f) {
return Biome::seasonalForest;
} else {
return Biome::rainForest;
}
}
}
float Biome::adjustScale( float scale )
{
return scale;
}
float Biome::adjustDepth( float depth )
{
return depth;
}
int Biome::getSkyColor( float temp )
{
// temp /= 3.f;
// if (temp < -1) temp = -1;
// if (temp > 1) temp = 1;
return 0x80808080;
//return Color.getHSBColor(224 / 360.0f - temp * 0.05f, 0.50f + temp * 0.1f, 1.0f).getRGB();
}
Biome::MobList& Biome::getMobs(const MobCategory& category)
{
if (&category == &MobCategory::monster)
return _enemies;
if (&category == &MobCategory::creature)
return _friendlies;
if (&category == &MobCategory::waterCreature)
return _waterFriendlies;
LOGE("Unknown MobCategory!");
return _emptyMobList;
}
float Biome::getCreatureProbability() {
return 0.08f;
}

95
src/world/level/biome/Biome.h Executable file
View File

@@ -0,0 +1,95 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__Biome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__Biome_H__
//package net.minecraft.world.level.biome;
#include <string>
#include <vector>
#include "../../../util/WeighedRandom.h"
class Feature;
class MobCategory;
class Biome
{
public:
static Biome* rainForest;
static Biome* swampland;
static Biome* seasonalForest;
static Biome* forest;
static Biome* savanna;
static Biome* shrubland;
static Biome* taiga;
static Biome* desert;
static Biome* plains;
static Biome* iceDesert;
static Biome* tundra;
class MobSpawnerData: public WeighedRandom::WeighedRandomItem
{
typedef WeighedRandom::WeighedRandomItem super;
public:
int mobClassId;
int minCount;
int maxCount;
MobSpawnerData()
{}
MobSpawnerData(int mobClassId, int probabilityWeight, int minCount, int maxCount)
: super(probabilityWeight),
mobClassId(mobClassId),
minCount(minCount),
maxCount(maxCount)
{}
};
typedef std::vector<MobSpawnerData> MobList;
protected:
Biome();
Biome* setName(const std::string& name);
Biome* setLeafColor(int leafColor);
Biome* setColor(int color);
Biome* setSnowCovered();
Biome* clearMobs(bool friendlies = true, bool waterFriendlies = true, bool enemies = true);
MobList _enemies;
MobList _friendlies;
MobList _waterFriendlies;
static MobList _emptyMobList;
public:
static int defaultTotalEnemyWeight;
static int defaultTotalFriendlyWeight;
virtual ~Biome() {}
static void recalc();
static void initBiomes();
static void teardownBiomes();
virtual Feature* getTreeFeature(Random* random);
virtual Feature* getGrassFeature(Random* random);
static Biome* getBiome(float temperature, float downfall);
static Biome* _getBiome(float temperature, float downfall);
virtual float adjustScale(float scale);
virtual float adjustDepth(float depth);
virtual int getSkyColor(float temp);
virtual MobList& getMobs(const MobCategory& category);
virtual float getCreatureProbability();
std::string name;
int color;
char topMaterial;
char material;
int leafColor;
private:
static Biome* map[64*64];
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__Biome_H__*/

View File

@@ -0,0 +1,11 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeInclude_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeInclude_H__
#include "Biome.h"
#include "FlatBiome.h"
#include "ForestBiome.h"
#include "RainforestBiome.h"
#include "SwampBiome.h"
#include "TaigaBiome.h"
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeInclude_H__*/

View File

@@ -0,0 +1,178 @@
#include "BiomeSource.h"
#include "Biome.h"
#include "../Level.h"
#include "../ChunkPos.h"
const float BiomeSource::zoom = 2 * 1;
const float BiomeSource::tempScale = zoom / 80.0f;
const float BiomeSource::downfallScale = zoom / 40.0f;
const float BiomeSource::noiseScale = 1 / 4.0f;
BiomeSource::BiomeSource()
: temperatureMap(NULL),
downfallMap(NULL),
noiseMap(NULL),
lenTemperatures(0),
lenDownfalls(0),
lenNoises(0),
lenBiomes(0),
temperatures(NULL),
downfalls(NULL),
noises(NULL),
biomes(NULL)
{
biomes = new Biome*[16*16];
}
BiomeSource::BiomeSource( Level* level )
: rndTemperature(level->getSeed() * 9871),
rndDownfall(level->getSeed() * 39811),
rndNoise(level->getSeed() * 543321),
lenTemperatures(0),
lenDownfalls(0),
lenNoises(0),
lenBiomes(0),
temperatures(NULL),
downfalls(NULL),
noises(NULL),
biomes(NULL)
{
temperatureMap = new PerlinSimplexNoise(&rndTemperature, 4);
downfallMap = new PerlinSimplexNoise(&rndDownfall, 4);
noiseMap = new PerlinSimplexNoise(&rndNoise, 2);
biomes = new Biome*[16*16];
temperatures = new float[16*16];
}
BiomeSource::~BiomeSource() {
LOGI("Deleting biome maps...\n");
delete temperatureMap;
delete downfallMap;
delete noiseMap;
LOGI("Deleting biome data arrays...\n");
delete[] temperatures;
delete[] downfalls;
delete[] noises;
delete[] biomes;
}
Biome* BiomeSource::getBiome( const ChunkPos& chunk )
{
return getBiome(chunk.x << 4, chunk.z << 4);
}
Biome* BiomeSource::getBiome( int x, int z )
{
return getBiomeBlock(x, z, 1, 1)[0];
}
//float BiomeSource::getTemperature( int x, int z )
//{
// temperatures = temperatureMap->getRegion(temperatures, x, z, 1, 1, tempScale, tempScale, 0.5f);
// return temperatures[0];
//}
Biome** BiomeSource::getBiomeBlock( int x, int z, int w, int h )
{
biomes = getBiomeBlock(biomes, x, z, w, h);
return biomes;
}
Biome** BiomeSource::getBiomeBlock( Biome** biomes__, int x, int z, int w, int h )
{
//for (int i = 0; i < w*h; ++i) biomes__[i] = Biome::tundra;
//const int size = w * h;
//if (lenBiomes < size) {
// //printf("changing to size: %d (was %d). %d, %d (%d, %d)\n", size, lenBiomes, x, z, w, h);
// if (biomes) delete[] biomes;
// biomes = new Biome*[size];
// lenBiomes = size;
//}
temperatures = temperatureMap->getRegion(temperatures, x, z, w, w, tempScale, tempScale, 0.25f);
downfalls = downfallMap->getRegion(downfalls, x, z, w, w, downfallScale, downfallScale, 0.3333f);
noises = noiseMap->getRegion(noises, x, z, w, w, noiseScale, noiseScale, 0.588f);
int pp = 0;
for (int yy = 0; yy < w; yy++) {
for (int xx = 0; xx < h; xx++) {
float noise = (noises[pp] * 1.1f + 0.5f);
float split2 = 0.01f;
float split1 = 1 - split2;
float temperature = (temperatures[pp] * 0.15f + 0.7f) * split1 + noise * split2;
split2 = 0.002f;
split1 = 1 - split2;
float downfall = (downfalls[pp] * 0.15f + 0.5f) * split1 + noise * split2;
temperature = 1 - ((1 - temperature) * (1 - temperature));
if (temperature < 0) temperature = 0;
if (downfall < 0) downfall = 0;
if (temperature > 1) temperature = 1;
if (downfall > 1) downfall = 1;
temperatures[pp] = temperature;
downfalls[pp] = downfall;
// System.out.println(downfall);
biomes[pp++] = Biome::getBiome(temperature, downfall);
}
}
return biomes;
}
float* BiomeSource::getTemperatureBlock( /*float* temperatures__, */int x, int z, int w, int h )
{
//LOGI("gTempBlock: 1\n");
//const int size = w * h;
//if (lenTemperatures < size) {
// if (temperatures) delete[] temperatures;
// temperatures = new float[size];
// lenTemperatures = size;
//}
float * ot = temperatures;
temperatures = temperatureMap->getRegion(temperatures, x, z, w, h, tempScale, tempScale, 0.25f);
noises = noiseMap->getRegion(noises, x, z, w, h, noiseScale, noiseScale, 0.588f);
if (ot != temperatures) {
LOGI("tmp ptr changed\n");
}
int pp = 0;
for (int yy = 0; yy < w; yy++) {
for (int xx = 0; xx < h; xx++) {
float noise = (noises[pp] * 1.1f + 0.5f);
float split2 = 0.01f;
float split1 = 1 - split2;
float temperature = (temperatures[pp] * 0.15f + 0.7f) * split1 + noise * split2;
temperature = 1 - ((1 - temperature) * (1 - temperature));
if (temperature < 0) temperature = 0;
if (temperature > 1) temperature = 1;
temperatures[pp] = temperature;
pp++;
}
}
// System.out.println(min+", "+max);
return temperatures;
}
//float* BiomeSource::getDownfallBlock( /*float* downfalls__,*/ int x, int z, int w, int h )
//{
// //const int size = w * h;
// //if (lenDownfalls < size) {
// // delete[] downfalls;
// // downfalls = new float[size];
// // lenDownfalls = size;
// //}
//
// downfalls = downfallMap->getRegion(downfalls, x, z, w, w, downfallScale, downfallScale, 0.5f);
// return downfalls;
//}

View File

@@ -0,0 +1,62 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeSource_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeSource_H__
//package net.minecraft.world.level.biome;
#include "../../../util/Random.h"
#include "../levelgen/synth/PerlinNoise.h"
typedef PerlinNoise PerlinSimplexNoise;
class Level;
class Biome;
class ChunkPos;
class BiomeSource
{
protected:
BiomeSource();
public:
BiomeSource(Level* level);
virtual ~BiomeSource();
float* temperatures;
float* downfalls;
float* noises;
int lenTemperatures;
int lenDownfalls;
int lenNoises;
int lenBiomes;
virtual Biome* getBiome(const ChunkPos& chunk);
virtual Biome* getBiome(int x, int z);
//virtual float getTemperature(int x, int z);
// Note: The arrays returned here are temporary in the meaning that their
// contents might change in the future. If you need to SAVE the
// values, do a shallow copy to an array of your own.
virtual float* getTemperatureBlock(/*float* temperatures, */ int x, int z, int w, int h);
//virtual float* getDownfallBlock(/*float* downfalls, */int x, int z, int w, int h);
virtual Biome** getBiomeBlock(int x, int z, int w, int h);
private:
virtual Biome** getBiomeBlock(Biome** biomes, int x, int z, int w, int h);
Biome** biomes;
PerlinSimplexNoise* temperatureMap;
PerlinSimplexNoise* downfallMap;
PerlinSimplexNoise* noiseMap;
Random rndTemperature;
Random rndDownfall;
Random rndNoise;
static const float zoom;
static const float tempScale;
static const float downfallScale;
static const float noiseScale;
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__BiomeSource_H__*/

View File

@@ -0,0 +1,11 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__FlatBiome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__FlatBiome_H__
//package net.minecraft.world.level.biome;
#include "Biome.h"
class FlatBiome: public Biome {
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__FlatBiome_H__*/

View File

@@ -0,0 +1,24 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__ForestBiome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__ForestBiome_H__
//package net.minecraft.world.level.biome;
#include "Biome.h"
#include "../levelgen/feature/TreeFeature.h"
#include "../levelgen/feature/BirchFeature.h"
class ForestBiome: public Biome
{
public:
Feature* getTreeFeature(Random* random) {
if (random->nextInt(5) == 0) {
return new BirchFeature();
}
if (random->nextInt(3) == 0) {
//return new BasicTree();
}
return new TreeFeature(false);
}
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__ForestBiome_H__*/

View File

@@ -0,0 +1,21 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__RainforestBiome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__RainforestBiome_H__
//package net.minecraft.world.level.biome;
#include "Biome.h"
#include "../../../util/Random.h"
#include "../levelgen/feature/TreeFeature.h"
class RainforestBiome: public Biome
{
public:
Feature* getTreeFeature(Random* random) {
if (random->nextInt(3) == 0) {
//return new BasicTree();
}
return new TreeFeature(false);
}
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__RainforestBiome_H__*/

View File

@@ -0,0 +1,11 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__SwampBiome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__SwampBiome_H__
//package net.minecraft.world.level.biome;
#include "Biome.h"
class SwampBiome: public Biome {
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__SwampBiome_H__*/

View File

@@ -0,0 +1,22 @@
#ifndef NET_MINECRAFT_WORLD_LEVEL_BIOME__TaigaBiome_H__
#define NET_MINECRAFT_WORLD_LEVEL_BIOME__TaigaBiome_H__
//package net.minecraft.world.level.biome;
#include "Biome.h"
#include "../../../util/Random.h"
#include "../levelgen/feature/PineFeature.h"
#include "../levelgen/feature/SpruceFeature.h"
class TaigaBiome: public Biome
{
public:
Feature* getTreeFeature(Random* random) {
if (random->nextInt(3) == 0) {
return new PineFeature();
}
return new SpruceFeature();
}
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_BIOME__TaigaBiome_H__*/