4jcraft/Minecraft.World/Blocks/PumpkinTile.cpp
2026-03-21 15:52:50 -05:00

188 lines
9.1 KiB
C++

#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.entity.animal.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.h"
#include "PumpkinTile.h"
#include "../Entities/Mob.h"
#include "../Entities/Mobs/SnowMan.h"
#include "../Entities/MobCategory.h"
const std::wstring PumpkinTile::TEXTURE_FACE = L"pumpkin_face";
const std::wstring PumpkinTile::TEXTURE_LANTERN = L"pumpkin_jack";
PumpkinTile::PumpkinTile(int id, bool lit)
: DirectionalTile(id, Material::vegetable, false) {
iconTop = NULL;
iconFace = NULL;
setTicking(true);
this->lit = lit;
}
Icon* PumpkinTile::getTexture(int face, int data) {
if (face == Facing::UP) return iconTop;
if (face == Facing::DOWN) return iconTop;
if (data == DIR_NORTH && face == Facing::NORTH) return iconFace;
if (data == DIR_EAST && face == Facing::EAST) return iconFace;
if (data == DIR_SOUTH && face == Facing::SOUTH) return iconFace;
if (data == DIR_WEST && face == Facing::WEST)
return iconFace;
else
return icon;
}
void PumpkinTile::onPlace(Level* level, int x, int y, int z) {
Tile::onPlace(level, x, y, z);
if (level->getTile(x, y - 1, z) == Tile::snow_Id &&
level->getTile(x, y - 2, z) == Tile::snow_Id) {
if (!level->isClientSide) {
// 4J - added limit of number of snowmen that can be spawned
if (level->canCreateMore(eTYPE_SNOWMAN, Level::eSpawnType_Egg)) {
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 2, z, 0, 0, Tile::UPDATE_CLIENTS);
std::shared_ptr<SnowMan> snowMan =
std::shared_ptr<SnowMan>(new SnowMan(level));
snowMan->moveTo(x + 0.5, y - 1.95, z + 0.5, 0, 0);
level->addEntity(snowMan);
level->tileUpdated(x, y, z, 0);
level->tileUpdated(x, y - 1, z, 0);
level->tileUpdated(x, y - 2, z, 0);
} else {
// If we can't spawn it, at least give the resources back
Tile::spawnResources(level, x, y, z, level->getData(x, y, z),
0);
Tile::tiles[Tile::snow_Id]->spawnResources(
level, x, y - 1, z, level->getData(x, y - 1, z), 0);
Tile::tiles[Tile::snow_Id]->spawnResources(
level, x, y - 2, z, level->getData(x, y - 2, z), 0);
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 2, z, 0, 0, Tile::UPDATE_CLIENTS);
}
}
for (int i = 0; i < 120; i++) {
level->addParticle(eParticleType_snowshovel,
x + level->random->nextDouble(),
y - 2 + level->random->nextDouble() * 2.5,
z + level->random->nextDouble(), 0, 0, 0);
}
} else if (level->getTile(x, y - 1, z) == Tile::ironBlock_Id &&
level->getTile(x, y - 2, z) == Tile::ironBlock_Id) {
bool xArms = level->getTile(x - 1, y - 1, z) == Tile::ironBlock_Id &&
level->getTile(x + 1, y - 1, z) == Tile::ironBlock_Id;
bool zArms = level->getTile(x, y - 1, z - 1) == Tile::ironBlock_Id &&
level->getTile(x, y - 1, z + 1) == Tile::ironBlock_Id;
if (xArms || zArms) {
if (!level->isClientSide) {
// 4J - added limit of number of golems that can be spawned
if (level->canCreateMore(eTYPE_VILLAGERGOLEM,
Level::eSpawnType_Egg)) {
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 2, z, 0, 0,
Tile::UPDATE_CLIENTS);
if (xArms) {
level->setTileAndData(x - 1, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x + 1, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
} else {
level->setTileAndData(x, y - 1, z - 1, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z + 1, 0, 0,
Tile::UPDATE_CLIENTS);
}
std::shared_ptr<VillagerGolem> villagerGolem =
std::shared_ptr<VillagerGolem>(
new VillagerGolem(level));
villagerGolem->setPlayerCreated(true);
villagerGolem->moveTo(x + 0.5, y - 1.95, z + 0.5, 0, 0);
level->addEntity(villagerGolem);
for (int i = 0; i < 120; i++) {
level->addParticle(
eParticleType_snowballpoof,
x + level->random->nextDouble(),
y - 2 + level->random->nextDouble() * 3.9,
z + level->random->nextDouble(), 0, 0, 0);
}
level->tileUpdated(x, y, z, 0);
level->tileUpdated(x, y - 1, z, 0);
level->tileUpdated(x, y - 2, z, 0);
if (xArms) {
level->tileUpdated(x - 1, y - 1, z, 0);
level->tileUpdated(x + 1, y - 1, z, 0);
} else {
level->tileUpdated(x, y - 1, z - 1, 0);
level->tileUpdated(x, y - 1, z + 1, 0);
}
} else {
// If we can't spawn it, at least give the resources back
Tile::spawnResources(level, x, y, z,
level->getData(x, y, z), 0);
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x, y - 1, z, level->getData(x, y - 1, z), 0);
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x, y - 2, z, level->getData(x, y - 2, z), 0);
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 2, z, 0, 0,
Tile::UPDATE_CLIENTS);
if (xArms) {
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x - 1, y - 1, z,
level->getData(x - 1, y - 1, z), 0);
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x + 1, y - 1, z,
level->getData(x + 1, y - 1, z), 0);
level->setTileAndData(x - 1, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x + 1, y - 1, z, 0, 0,
Tile::UPDATE_CLIENTS);
} else {
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x, y - 1, z - 1,
level->getData(x, y - 1, z - 1), 0);
Tile::tiles[Tile::ironBlock_Id]->spawnResources(
level, x, y - 1, z + 1,
level->getData(x, y - 1, z + 1), 0);
level->setTileAndData(x, y - 1, z - 1, 0, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z + 1, 0, 0,
Tile::UPDATE_CLIENTS);
}
}
}
}
}
}
bool PumpkinTile::mayPlace(Level* level, int x, int y, int z) {
int t = level->getTile(x, y, z);
return (t == 0 || Tile::tiles[t]->material->isReplaceable()) &&
level->isTopSolidBlocking(x, y - 1, z);
}
void PumpkinTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = Mth::floor(by->yRot * 4 / (360) + 2.5) & 3;
level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS);
}
void PumpkinTile::registerIcons(IconRegister* iconRegister) {
iconFace = iconRegister->registerIcon(getIconName() + L"_face_" +
(lit ? L"on" : L"off"));
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
icon = iconRegister->registerIcon(getIconName() + L"_side");
}