Browse Source

add Swan::random(), call onSpawn on tiles when spawning them

master
Martin Dørum 2 years ago
parent
commit
367143b2ab
4 changed files with 46 additions and 16 deletions
  1. 11
    2
      libswan/include/swan/Tile.h
  2. 1
    1
      libswan/include/swan/World.h
  3. 10
    1
      libswan/include/swan/util.h
  4. 24
    12
      libswan/src/WorldPlane.cc

+ 11
- 2
libswan/include/swan/Tile.h View File

#include <string> #include <string>
#include <optional> #include <optional>


#include "common.h"

namespace Swan { namespace Swan {


struct Tile { struct Tile {
std::string name; std::string name;
std::string image; std::string image;
bool isSolid = true; bool isSolid = true;
bool isOpaque = isSolid;
float lightLevel = 0; float lightLevel = 0;
std::optional<std::string> droppedItem = std::nullopt; std::optional<std::string> droppedItem = std::nullopt;

void (*onSpawn)(const Context &ctx, TilePos pos) = nullptr;
}; };


const ID id; const ID id;
const std::string name; const std::string name;
const bool isSolid; const bool isSolid;
const bool isOpaque;
const float lightLevel; const float lightLevel;
const std::optional<std::string> droppedItem; const std::optional<std::string> droppedItem;


void (*const onSpawn)(const Context &ctx, TilePos pos);

Tile(ID id, std::string name, const Builder &builder): Tile(ID id, std::string name, const Builder &builder):
id(id), name(name), id(id), name(name),
isSolid(builder.isSolid), lightLevel(builder.lightLevel),
droppedItem(builder.droppedItem) {}
isSolid(builder.isSolid), isOpaque(builder.isOpaque),
lightLevel(builder.lightLevel),
droppedItem(builder.droppedItem), onSpawn(builder.onSpawn) {}
}; };


} }

+ 1
- 1
libswan/include/swan/World.h View File



// These things get initialized in the ctor. // These things get initialized in the ctor.
// the above members must be initialized before these. // the above members must be initialized before these.
Game *game_; // TODO: reference, not pointer
Game *game_;
std::mt19937 random_; std::mt19937 random_;
std::vector<ModWrapper> mods_; std::vector<ModWrapper> mods_;
Cygnet::ResourceManager resources_; Cygnet::ResourceManager resources_;

+ 10
- 1
libswan/include/swan/util.h View File

#include <chrono> #include <chrono>
#include <type_traits> #include <type_traits>
#include <string> #include <string>
#include <stddef.h>
#include <cstddef>
#include <cstdint>


namespace Swan { namespace Swan {


inline uint32_t random(uint32_t x) {
x ^= 0x55555555u;
x = ((x >> 16u) ^ x) * 0x45d9f3bu;
x = ((x >> 16u) ^ x) * 0x45d9f3bu;
x = (x >> 16u) ^ x;
return x;
}

// Inherit from this class to make a class non-copyable // Inherit from this class to make a class non-copyable
class NonCopyable { class NonCopyable {
public: public:

+ 24
- 12
libswan/src/WorldPlane.cc View File

for (int x = 0; x < CHUNK_WIDTH; ++x) { for (int x = 0; x < CHUNK_WIDTH; ++x) {
Tile::ID id = chunk.getTileID({ x, y }); Tile::ID id = chunk.getTileID({ x, y });
Tile &tile = world_->getTileByID(id); Tile &tile = world_->getTileByID(id);
if (tile.isSolid) {
if (tile.isOpaque) {
lc.blocks[y * CHUNK_HEIGHT + x] = true; lc.blocks[y * CHUNK_HEIGHT + x] = true;
} }
if (tile.lightLevel > 0) { if (tile.lightLevel > 0) {
Tile &oldTile = world_->getTileByID(old); Tile &oldTile = world_->getTileByID(old);
chunk.setTileID(rp, id); chunk.setTileID(rp, id);


if (!oldTile.isSolid && newTile.isSolid) {
if (!oldTile.isOpaque && newTile.isOpaque) {
lighting_->onSolidBlockAdded(pos); lighting_->onSolidBlockAdded(pos);
} else if (oldTile.isSolid && !newTile.isSolid) {
} else if (oldTile.isOpaque && !newTile.isOpaque) {
lighting_->onSolidBlockRemoved(pos); lighting_->onSolidBlockRemoved(pos);
} }


addLight(pos, newTile.lightLevel); addLight(pos, newTile.lightLevel);
} }
} }

if (newTile.onSpawn) {
newTile.onSpawn(getContext(), pos);
}
} }
} }


(int)floor(pbody.pos.x / CHUNK_WIDTH), (int)floor(pbody.pos.x / CHUNK_WIDTH),
(int)floor(pbody.pos.y / CHUNK_HEIGHT)); (int)floor(pbody.pos.y / CHUNK_HEIGHT));


// Just init one chunk per frame
if (chunkInitList_.size() > 0) {
/*
Chunk *chunk = chunkInitList_.front();
chunkInitList_.pop_front();
chunk->render(ctx, win.renderer_);
TODO */
}

for (int x = -1; x <= 1; ++x) { for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) { for (int y = -1; y <= 1; ++y) {
auto iter = chunks_.find(pcpos + ChunkPos(x, y)); auto iter = chunks_.find(pcpos + ChunkPos(x, y));
auto ctx = getContext(); auto ctx = getContext();
debugBoxes_.clear(); debugBoxes_.clear();


// Just init one chunk per frame
if (chunkInitList_.size() > 0) {
Chunk *chunk = chunkInitList_.front();
chunkInitList_.pop_front();

TilePos base = chunk->pos_ * Vec2i{CHUNK_WIDTH, CHUNK_HEIGHT};
for (int y = 0; y < CHUNK_HEIGHT; ++y) {
for (int x = 0; x < CHUNK_WIDTH; ++x) {
Tile::ID id = chunk->getTileID({x, y});
Tile &tile = world_->getTileByID(id);
if (tile.onSpawn) {
tile.onSpawn(getContext(), base + Vec2i{x, y});
}
}
}
}

for (auto &coll: entColls_) for (auto &coll: entColls_)
coll->update(ctx, dt); coll->update(ctx, dt);
} }

Loading…
Cancel
Save