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

@@ -4,6 +4,8 @@
#include <string>
#include <optional>

#include "common.h"

namespace Swan {

struct Tile {
@@ -14,20 +16,27 @@ public:
std::string name;
std::string image;
bool isSolid = true;
bool isOpaque = isSolid;
float lightLevel = 0;
std::optional<std::string> droppedItem = std::nullopt;

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

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

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

Tile(ID id, std::string name, const Builder &builder):
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

@@ -62,7 +62,7 @@ public:

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

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

@@ -6,10 +6,19 @@
#include <chrono>
#include <type_traits>
#include <string>
#include <stddef.h>
#include <cstddef>
#include <cstdint>

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
class NonCopyable {
public:

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

@@ -93,7 +93,7 @@ Chunk &WorldPlane::slowGetChunk(ChunkPos pos) {
for (int x = 0; x < CHUNK_WIDTH; ++x) {
Tile::ID id = chunk.getTileID({ x, y });
Tile &tile = world_->getTileByID(id);
if (tile.isSolid) {
if (tile.isOpaque) {
lc.blocks[y * CHUNK_HEIGHT + x] = true;
}
if (tile.lightLevel > 0) {
@@ -124,9 +124,9 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
Tile &oldTile = world_->getTileByID(old);
chunk.setTileID(rp, id);

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

@@ -139,6 +139,10 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
addLight(pos, newTile.lightLevel);
}
}

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

@@ -212,15 +216,6 @@ void WorldPlane::draw(Cygnet::Renderer &rnd) {
(int)floor(pbody.pos.x / CHUNK_WIDTH),
(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 y = -1; y <= 1; ++y) {
auto iter = chunks_.find(pcpos + ChunkPos(x, y));
@@ -250,6 +245,23 @@ void WorldPlane::update(float dt) {
auto ctx = getContext();
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_)
coll->update(ctx, dt);
}

Loading…
Cancel
Save