namespace Swan { | namespace Swan { | ||||
// TODO: Switch to struct | |||||
class Item { | class Item { | ||||
public: | public: | ||||
struct Builder { | struct Builder { | ||||
}; | }; | ||||
Item(const ResourceManager &resources, const Builder &builder): | Item(const ResourceManager &resources, const Builder &builder): | ||||
name_(builder.name), image_(resources.getImage(builder.image)), | |||||
maxStack_(builder.maxStack) {} | |||||
name(builder.name), image(resources.getImage(builder.image)), | |||||
maxStack(builder.maxStack) {} | |||||
const std::string name_; | |||||
const ImageResource &image_; | |||||
const int maxStack_; | |||||
const std::string name; | |||||
const ImageResource ℑ | |||||
const int maxStack; | |||||
static std::unique_ptr<Item> createInvalid(Context &ctx); | static std::unique_ptr<Item> createInvalid(Context &ctx); | ||||
// a complete ImageResource for a headless server, but for now, this will suffice. | // a complete ImageResource for a headless server, but for now, this will suffice. | ||||
protected: | protected: | ||||
Item(const Builder &builder): | Item(const Builder &builder): | ||||
name_(builder.name), image_(*(ImageResource *)this), | |||||
maxStack_(builder.maxStack) {} | |||||
name(builder.name), image(*(ImageResource *)this), | |||||
maxStack(builder.maxStack) {} | |||||
}; | }; | ||||
} | } |
namespace Swan { | namespace Swan { | ||||
// TODO: Switch to struct | |||||
class Tile { | |||||
struct Tile { | |||||
public: | public: | ||||
using ID = uint16_t; | using ID = uint16_t; | ||||
}; | }; | ||||
Tile(const ResourceManager &resources, const Builder &builder): | Tile(const ResourceManager &resources, const Builder &builder): | ||||
name_(builder.name), image_(resources.getImage(builder.image)), | |||||
isSolid_(builder.isSolid), lightLevel_(builder.lightLevel), | |||||
droppedItem_(builder.droppedItem) {} | |||||
const std::string name_; | |||||
const ImageResource &image_; | |||||
const bool isSolid_; | |||||
const float lightLevel_; | |||||
const std::optional<std::string> droppedItem_; | |||||
name(builder.name), image(resources.getImage(builder.image)), | |||||
isSolid(builder.isSolid), lightLevel(builder.lightLevel), | |||||
droppedItem(builder.droppedItem) {} | |||||
const std::string name; | |||||
const ImageResource ℑ | |||||
const bool isSolid; | |||||
const float lightLevel; | |||||
const std::optional<std::string> droppedItem; | |||||
static std::unique_ptr<Tile> createInvalid(const ResourceManager &ctx); | static std::unique_ptr<Tile> createInvalid(const ResourceManager &ctx); | ||||
static std::unique_ptr<Tile> createAir(const ResourceManager &ctx); | static std::unique_ptr<Tile> createAir(const ResourceManager &ctx); |
} | } | ||||
SDL_Rect dest{x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE}; | SDL_Rect dest{x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE}; | ||||
SDL_RenderCopy(rnd, tile->image_.texture_.get(), nullptr, &dest); | |||||
SDL_RenderCopy(rnd, tile->image.texture_.get(), nullptr, &dest); | |||||
} | } | ||||
} | } | ||||
// Merge | // Merge | ||||
count_ += st.count_; | count_ += st.count_; | ||||
if (count_ > item_->maxStack_) { | |||||
st.count_ = count_ - item_->maxStack_; | |||||
count_ = item_->maxStack_; | |||||
if (count_ > item_->maxStack) { | |||||
st.count_ = count_ - item_->maxStack; | |||||
count_ = item_->maxStack; | |||||
} else { | } else { | ||||
st.count_ = 0; | st.count_ = 0; | ||||
st.item_ = nullptr; | st.item_ = nullptr; |
game_(game), random_(rand_seed), resources_(game->win_) { | game_(game), random_(rand_seed), resources_(game->win_) { | ||||
std::unique_ptr<Tile> invalidTile = Tile::createInvalid(resources_); | std::unique_ptr<Tile> invalidTile = Tile::createInvalid(resources_); | ||||
tilesMap_[invalidTile->name_] = 0; | |||||
tilesMap_[invalidTile->name] = 0; | |||||
// tiles_ is empty, so pushing back now will ensure invalid_tile | // tiles_ is empty, so pushing back now will ensure invalid_tile | ||||
// ends up at location 0 | // ends up at location 0 | ||||
for (auto t: mod.buildTiles(resources_)) { | for (auto t: mod.buildTiles(resources_)) { | ||||
Tile::ID id = tiles_.size(); | Tile::ID id = tiles_.size(); | ||||
tilesMap_[t->name_] = id; | |||||
tilesMap_[t->name] = id; | |||||
tiles_.push_back(std::move(t)); | tiles_.push_back(std::move(t)); | ||||
} | } | ||||
for (auto i: mod.buildItems(resources_)) { | for (auto i: mod.buildItems(resources_)) { | ||||
items_[i->name_] = std::move(i); | |||||
items_[i->name] = std::move(i); | |||||
} | } | ||||
for (auto fact: mod.getWorldGens()) { | for (auto fact: mod.getWorldGens()) { |
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.isSolid) { | |||||
lc.blocks[y * CHUNK_HEIGHT + x] = true; | lc.blocks[y * CHUNK_HEIGHT + x] = true; | ||||
} | } | ||||
if (tile.lightLevel_ > 0) { | |||||
lc.light_sources[{ x, y }] = tile.lightLevel_; | |||||
if (tile.lightLevel > 0) { | |||||
lc.lightSources[{ x, y }] = tile.lightLevel; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (id != old) { | if (id != old) { | ||||
Tile &newTile = world_->getTileByID(id); | Tile &newTile = world_->getTileByID(id); | ||||
Tile &oldTile = world_->getTileByID(old); | Tile &oldTile = world_->getTileByID(old); | ||||
chunk.setTileID(rp, id, newTile.image_.texture_.get()); | |||||
chunk.setTileID(rp, id, newTile.image.texture_.get()); | |||||
chunk.markModified(); | chunk.markModified(); | ||||
if (!oldTile.isSolid_ && newTile.isSolid_) { | |||||
if (!oldTile.isSolid && newTile.isSolid) { | |||||
lighting_->onSolidBlockAdded(pos); | lighting_->onSolidBlockAdded(pos); | ||||
} else if (oldTile.isSolid_ && !newTile.isSolid_) { | |||||
} else if (oldTile.isSolid && !newTile.isSolid) { | |||||
lighting_->onSolidBlockRemoved(pos); | lighting_->onSolidBlockRemoved(pos); | ||||
} | } | ||||
if (newTile.lightLevel_ != oldTile.lightLevel_) { | |||||
if (oldTile.lightLevel_ > 0) { | |||||
removeLight(pos, oldTile.lightLevel_); | |||||
if (newTile.lightLevel != oldTile.lightLevel) { | |||||
if (oldTile.lightLevel > 0) { | |||||
removeLight(pos, oldTile.lightLevel); | |||||
} | } | ||||
if (newTile.lightLevel_ > 0) { | |||||
addLight(pos, newTile.lightLevel_); | |||||
if (newTile.lightLevel > 0) { | |||||
addLight(pos, newTile.lightLevel); | |||||
} | } | ||||
} | } | ||||
} | } |
for (int y = (int)floor(body.top() + epsilon); y <= (int)floor(body.bottom() - epsilon); ++y) { | for (int y = (int)floor(body.top() + epsilon); y <= (int)floor(body.bottom() - epsilon); ++y) { | ||||
int lx = (int)floor(body.left() + epsilon); | int lx = (int)floor(body.left() + epsilon); | ||||
Tile &left = plane.getTile({ lx, y }); | Tile &left = plane.getTile({ lx, y }); | ||||
if (left.isSolid_) { | |||||
if (left.isSolid) { | |||||
body.pos.x = (float)lx + 1.0; | body.pos.x = (float)lx + 1.0; | ||||
collided = true; | collided = true; | ||||
break; | break; | ||||
int rx = (int)floor(body.right() - epsilon); | int rx = (int)floor(body.right() - epsilon); | ||||
Tile &right = plane.getTile({ rx, y }); | Tile &right = plane.getTile({ rx, y }); | ||||
if (right.isSolid_) { | |||||
if (right.isSolid) { | |||||
body.pos.x = (float)rx - body.size.x; | body.pos.x = (float)rx - body.size.x; | ||||
collided = true; | collided = true; | ||||
break; | break; | ||||
for (int x = (int)floor(body.left() + epsilon); x <= (int)floor(body.right() - epsilon); ++x) { | for (int x = (int)floor(body.left() + epsilon); x <= (int)floor(body.right() - epsilon); ++x) { | ||||
int ty = (int)floor(body.top() + epsilon); | int ty = (int)floor(body.top() + epsilon); | ||||
Tile &top = plane.getTile({ x, ty }); | Tile &top = plane.getTile({ x, ty }); | ||||
if (top.isSolid_) { | |||||
if (top.isSolid) { | |||||
body.pos.y = (float)ty + 1.0; | body.pos.y = (float)ty + 1.0; | ||||
collided = true; | collided = true; | ||||
break; | break; | ||||
int by = (int)floor(body.bottom() - epsilon); | int by = (int)floor(body.bottom() - epsilon); | ||||
Tile &bottom = plane.getTile({ x, by }); | Tile &bottom = plane.getTile({ x, by }); | ||||
if (bottom.isSolid_) { | |||||
if (bottom.isSolid) { | |||||
body.pos.y = (float)by - body.size.y; | body.pos.y = (float)by - body.size.y; | ||||
collided = true; | collided = true; | ||||
phys.onGround = true; | phys.onGround = true; |