Skip to content

Commit

Permalink
Implement secret block & doors
Browse files Browse the repository at this point in the history
  • Loading branch information
SmallJoker committed Feb 19, 2023
1 parent 4692e23 commit 02babe1
Show file tree
Hide file tree
Showing 22 changed files with 437 additions and 189 deletions.
Binary file modified assets/textures/pack_owner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 57 additions & 5 deletions src/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ Client::Client(ClientStartData &init)
}

m_nickname = init.nickname;

for (auto &k : m_keys)
k = Environment::Key();
}

Client::~Client()
Expand Down Expand Up @@ -93,11 +90,66 @@ void Client::step(float dtime)

// Run physics engine
if (world.ptr()) {
std::set<blockpos_t> triggered_blocks;
SimpleLock lock(m_players_lock);
for (auto it : m_players) {
it.second->step(dtime);
if (it.first == m_my_peer_id) {
it.second->triggered_blocks = &triggered_blocks;
it.second->step(dtime);
it.second->triggered_blocks = nullptr;
} else {
it.second->step(dtime);
}
}

auto &meta = world->getMeta();
for (auto &kdata : meta.keys) {
kdata.step(dtime);
}

// Process triggers
bool trigger_event = false;
Packet pkt;
pkt.write(Packet2Server::TriggerBlocks);

for (blockpos_t bp : triggered_blocks) {
Block b;
if (!world->getBlock(bp, &b))
continue;

switch (b.id) {
case Block::ID_KEY_R:
case Block::ID_KEY_G:
case Block::ID_KEY_B:
{
int key_id = b.id - Block::ID_KEY_R;
auto &kdata = meta.keys[key_id];
if (kdata.trigger(-1.0f)) {
pkt.write(bp.X);
pkt.write(bp.Y);
}
}
break;
case Block::ID_SECRET:
if (!b.param1) {
b.param1 = true;
world->setBlock(bp, b);
trigger_event = true;
}
break;
}
} // for

if (pkt.size() > 4) {
pkt.write(BLOCKPOS_INVALID); // end

m_con->send(0, 1, pkt);
}

if (trigger_event) {
GameEvent e(GameEvent::C2G_MAP_UPDATE);
sendNewEvent(e);
}
//printf("Client players: %zu\n", m_players.size());
}
}

Expand Down
72 changes: 69 additions & 3 deletions src/client/client_packethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,26 +155,33 @@ void Client::pkt_Leave(Packet &pkt)
sendNewEvent(e);
}

delete player;

if (peer_id == m_my_peer_id) {
for (auto it : m_players) {
delete it.second;
}
m_players.clear();

// Keep myself in the list
m_players.emplace(peer_id, player);
player->setWorld(nullptr);

m_state = ClientState::LobbyIdle;

GameEvent e(GameEvent::C2G_LEAVE);
sendNewEvent(e);
} else {
delete player;
}

}

void Client::pkt_SetPosition(Packet &pkt)
{
SimpleLock lock(m_players_lock);

bool is_respawn = pkt.read<u8>();
bool my_player_affected = false;

while (true) {
peer_t peer_id = pkt.read<peer_t>();
if (!peer_id)
Expand All @@ -189,6 +196,23 @@ void Client::pkt_SetPosition(Packet &pkt)
player->pos = pos;
player->vel = core::vector2df();
}

if (peer_id == m_my_peer_id)
my_player_affected = true;
}

if (!is_respawn || !my_player_affected)
return;

LocalPlayer *player = getPlayerNoLock(m_my_peer_id);
auto out = player->getWorld()->getBlocks(Block::ID_SECRET, [](Block &b) -> bool {
b.param1 = 0;
return true;
});

if (!out.empty()) {
GameEvent e(GameEvent::C2G_MAP_UPDATE);
sendNewEvent(e);
}
}

Expand Down Expand Up @@ -266,7 +290,33 @@ void Client::pkt_PlaceBlock(Packet &pkt)

void Client::pkt_Key(Packet &pkt)
{
// ??
SimpleLock lock(m_players_lock);
LocalPlayer *player = getPlayerNoLock(m_my_peer_id);

bid_t key_id = pkt.read<bid_t>();
bool state = pkt.read<u8>();

bid_t block_id = 0;
switch (key_id) {
case Block::ID_KEY_R:
case Block::ID_KEY_G:
case Block::ID_KEY_B:
block_id = key_id - Block::ID_KEY_R + Block::ID_DOOR_R;
break;
default:
// Unknown key
return;
};

auto out = player->getWorld()->getBlocks(block_id, [state](Block &b) -> bool {
b.param1 = state;
return true;
});

if (!out.empty()) {
GameEvent e(GameEvent::C2G_MAP_UPDATE);
sendNewEvent(e);
}
}

void Client::pkt_GodMode(Packet &pkt)
Expand All @@ -281,6 +331,22 @@ void Client::pkt_GodMode(Packet &pkt)
player->godmode = state;
player->acc = core::vector2df();
}
if (peer_id == m_my_peer_id) {
auto out = player->getWorld()->getBlocks(Block::ID_SECRET, [state](Block &b) -> bool {
if (state)
b.param1++;
else if (b.param1)
b.param1--;
else
return false;
return true;
});

if (!out.empty()) {
GameEvent e(GameEvent::C2G_MAP_UPDATE);
sendNewEvent(e);
}
}
}

void Client::pkt_Deprecated(Packet &pkt)
Expand Down
7 changes: 5 additions & 2 deletions src/core/blockmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ BlockTile BlockProperties::getTile(const Block b) const
case BlockTileCondition::None:
return tiles[0];
}

// Not reachable
return tiles[0];
}

BlockProperties::BlockProperties(BlockDrawType type)
Expand Down Expand Up @@ -150,10 +153,11 @@ void BlockManager::populateTextures(video::IVideoDriver *driver)
printf("BlockManager: Registered textures of %d blocks in %zu packs\n", count, m_packs.size());
}

BlockProperties *BlockManager::getProps(bid_t block_id)
const BlockProperties *BlockManager::getProps(bid_t block_id) const
{
if (block_id >= m_props.size())
return nullptr;

return m_props[block_id];
}

Expand Down Expand Up @@ -288,4 +292,3 @@ u32 BlockManager::getBlockColor(const BlockTile tile) const

return color.color;
}

6 changes: 5 additions & 1 deletion src/core/blockmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct BlockPack {

struct BlockTile {
BlockDrawType type = BlockDrawType::Invalid;
bool have_alpha = false; // false: use BlockDrawType
video::ITexture *texture = nullptr;
u8 texture_offset = 0; // e.g. when specifying a material
};
Expand All @@ -60,6 +61,7 @@ struct BlockProperties {

BlockPack *pack = nullptr;

bool trigger_on_touch = false;
u32 color = 0; // minimap

BlockTile tiles[2]; // normal, active
Expand All @@ -82,10 +84,12 @@ class BlockManager {
BlockManager();
~BlockManager();

void doPackRegistration();

void registerPack(BlockPack *pack);
void populateTextures(video::IVideoDriver *driver);

BlockProperties *getProps(bid_t block_id);
const BlockProperties *getProps(bid_t block_id) const;
BlockPack *getPack(const std::string &name);
const std::vector<BlockPack *> &getPacks() { return m_packs; }
video::ITexture *getMissingTexture() { return m_missing_texture; }
Expand Down
135 changes: 135 additions & 0 deletions src/core/blockmanager_reg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#include "blockmanager.h"
#include "player.h"


// -------------- Block registrations -------------


static BP_STEP_CALLBACK(step_arrow_left)
{
player.acc.X -= Player::GRAVITY_NORMAL;
}

static BP_STEP_CALLBACK(step_arrow_up)
{
player.acc.Y -= Player::GRAVITY_NORMAL;
}

static BP_STEP_CALLBACK(step_arrow_right)
{
player.acc.X += Player::GRAVITY_NORMAL;
}

static BP_STEP_CALLBACK(step_arrow_none)
{
}

static BP_COLLIDE_CALLBACK(onCollide_b10_bouncy)
{
if (dir.X) {
player.vel.X *= -0.4f;
} else if (dir.Y) {
player.vel.Y *= -1.5f;
}
return false;
}

void BlockManager::doPackRegistration()
{
{
BlockPack *pack = new BlockPack("basic");
pack->default_type = BlockDrawType::Solid;
pack->block_ids = { 9, 10, 11, 12, 13, 14, 15 };
g_blockmanager->registerPack(pack);
}

{
BlockPack *pack = new BlockPack("doors");
pack->default_type = BlockDrawType::Solid;
pack->block_ids = { Block::ID_DOOR_R, Block::ID_DOOR_G, Block::ID_DOOR_B };
g_blockmanager->registerPack(pack);

for (bid_t id : pack->block_ids) {
auto props = m_props[id];
props->condition = BlockTileCondition::NotZero;
props->tiles[1].type = BlockDrawType::Action;
props->tiles[1].texture_offset = 3;
}
}

{
BlockPack *pack = new BlockPack("factory");
pack->default_type = BlockDrawType::Solid;
pack->block_ids = { 45, 46, 47, 48, 49 };
g_blockmanager->registerPack(pack);
}

{
BlockPack *pack = new BlockPack("action");
pack->default_type = BlockDrawType::Action;
pack->block_ids = { 0, 1, 2, 3, 4 };
g_blockmanager->registerPack(pack);

m_props[1]->step = step_arrow_left;
m_props[2]->step = step_arrow_up;
m_props[3]->step = step_arrow_right;
m_props[4]->step = step_arrow_none;
}

{
BlockPack *pack = new BlockPack("keys");
pack->default_type = BlockDrawType::Action;
pack->block_ids = { Block::ID_KEY_R, Block::ID_KEY_G, Block::ID_KEY_B };
g_blockmanager->registerPack(pack);

for (bid_t id : pack->block_ids)
m_props[id]->trigger_on_touch = true;
}

// For testing. bouncy blue basic block
m_props[10]->onCollide = onCollide_b10_bouncy;

{
// Spawn block only (for now)
BlockPack *pack = new BlockPack("owner");
pack->default_type = BlockDrawType::Action;
pack->block_ids = { Block::ID_SPAWN, Block::ID_SECRET };
g_blockmanager->registerPack(pack);

auto props = m_props[Block::ID_SECRET];
props->trigger_on_touch = true;
props->condition = BlockTileCondition::NotZero;
props->tiles[0].type = BlockDrawType::Solid;
props->tiles[0].have_alpha = true;
props->tiles[1].type = BlockDrawType::Solid;
props->tiles[1].texture_offset = 1;
}

// Decoration
{
BlockPack *pack = new BlockPack("spring");
pack->default_type = BlockDrawType::Decoration;
pack->block_ids = { 233, 234, 235, 236, 237, 238, 239, 240 };
g_blockmanager->registerPack(pack);
}

// Backgrounds
{
// "basic" or "dark"
BlockPack *pack = new BlockPack("simple");
pack->default_type = BlockDrawType::Background;
pack->block_ids = { 500, 501, 502, 503, 504, 505, 506 };
g_blockmanager->registerPack(pack);
}

/*
Key RGB: 6
Door RGB: 23
Gate RGB: 26
Coin: 100
Coin door: 43
Spawn: 255
Secret (invisible): 50
*/
}

Loading

0 comments on commit 02babe1

Please sign in to comment.