aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/MonsterPlacerItem.cpp
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.World/MonsterPlacerItem.cpp
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.World/MonsterPlacerItem.cpp')
-rw-r--r--Minecraft.World/MonsterPlacerItem.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/Minecraft.World/MonsterPlacerItem.cpp b/Minecraft.World/MonsterPlacerItem.cpp
new file mode 100644
index 00000000..a2970033
--- /dev/null
+++ b/Minecraft.World/MonsterPlacerItem.cpp
@@ -0,0 +1,291 @@
+#include "stdafx.h"
+#include "..\Minecraft.Client\Minecraft.h"
+#include "net.minecraft.h"
+#include "net.minecraft.world.level.h"
+#include "net.minecraft.world.level.tile.h"
+#include "net.minecraft.world.level.tile.entity.h"
+#include "net.minecraft.world.entity.h"
+#include "net.minecraft.world.entity.npc.h"
+#include "net.minecraft.world.h"
+#include "MonsterPlacerItem.h"
+#include "Difficulty.h"
+
+
+MonsterPlacerItem::MonsterPlacerItem(int id) : Item(id)
+{
+ setMaxStackSize(16); // 4J-PB brought forward. It is 64 on PC, but we'll never be able to place that many
+ setStackedByData(true);
+ overlay = NULL;
+}
+
+wstring MonsterPlacerItem::getHoverName(shared_ptr<ItemInstance> itemInstance)
+{
+ wstring elementName = getDescription();
+
+ int nameId = EntityIO::getNameId(itemInstance->getAuxValue());
+ if (nameId >= 0)
+ {
+ elementName = replaceAll(elementName,L"{*CREATURE*}",app.GetString(nameId));
+ //elementName += " " + I18n.get("entity." + encodeId + ".name");
+ }
+ else
+ {
+ elementName = replaceAll(elementName,L"{*CREATURE*}",L"");
+ }
+
+ return elementName;
+}
+
+int MonsterPlacerItem::getColor(shared_ptr<ItemInstance> item, int spriteLayer)
+{
+ AUTO_VAR(it, EntityIO::idsSpawnableInCreative.find(item->getAuxValue()));
+ if (it != EntityIO::idsSpawnableInCreative.end())
+ {
+ EntityIO::SpawnableMobInfo *spawnableMobInfo = it->second;
+ if (spriteLayer == 0) {
+ return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor1 );
+ }
+ return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor2 );
+ }
+ return 0xffffff;
+}
+
+bool MonsterPlacerItem::hasMultipleSpriteLayers()
+{
+ return true;
+}
+
+Icon *MonsterPlacerItem::getLayerIcon(int auxValue, int spriteLayer)
+{
+ if (spriteLayer > 0)
+ {
+ return overlay;
+ }
+ return Item::getLayerIcon(auxValue, spriteLayer);
+}
+
+// 4J-PB - added for dispenser
+shared_ptr<Entity> MonsterPlacerItem::canSpawn(int iAuxVal, Level *level, int *piResult)
+{
+ shared_ptr<Entity> newEntity = EntityIO::newById(iAuxVal, level);
+ if (newEntity != NULL)
+ {
+ bool canSpawn = false;
+
+ switch(newEntity->GetType())
+ {
+ case eTYPE_CHICKEN:
+ if(level->canCreateMore( eTYPE_CHICKEN, Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManyChickens;
+ }
+ break;
+ case eTYPE_WOLF:
+ if(level->canCreateMore( eTYPE_WOLF, Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManyWolves;
+ }
+ break;
+ case eTYPE_VILLAGER:
+ if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManyVillagers;
+ }
+ break;
+ case eTYPE_MUSHROOMCOW:
+ if(level->canCreateMore(eTYPE_MUSHROOMCOW, Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManyMooshrooms;
+ }
+ break;
+ case eTYPE_SQUID:
+ if(level->canCreateMore( eTYPE_SQUID, Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManySquid;
+ }
+ break;
+ default:
+ if( (newEntity->GetType() & eTYPE_ANIMALS_SPAWN_LIMIT_CHECK) == eTYPE_ANIMALS_SPAWN_LIMIT_CHECK)
+ {
+ if( level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg ) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ // different message for each animal
+
+ *piResult=eSpawnResult_FailTooManyPigsCowsSheepCats;
+ }
+ }
+ else if( (newEntity->GetType() & eTYPE_MONSTER) == eTYPE_MONSTER)
+ {
+ // 4J-PB - check if the player is trying to spawn an enemy in peaceful mode
+ if(level->difficulty==Difficulty::PEACEFUL)
+ {
+ *piResult=eSpawnResult_FailCantSpawnInPeaceful;
+ }
+ else if(level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg) )
+ {
+ canSpawn = true;
+ }
+ else
+ {
+ *piResult=eSpawnResult_FailTooManyMonsters;
+ }
+ }
+ break;
+ }
+
+ if(canSpawn)
+ {
+ return newEntity;
+ }
+ }
+
+ return nullptr;
+}
+
+bool MonsterPlacerItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player, Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly)
+{
+ if (level->isClientSide)
+ {
+ return true;
+ }
+
+ int tile = level->getTile(x, y, z);
+
+#ifndef _CONTENT_PACKAGE
+ if(app.DebugSettingsOn() && tile == Tile::mobSpawner_Id)
+ {
+ // 4J Stu - Force adding this as a tile update
+ level->setTile(x,y,z,0);
+ level->setTile(x,y,z,Tile::mobSpawner_Id);
+ shared_ptr<MobSpawnerTileEntity> mste = dynamic_pointer_cast<MobSpawnerTileEntity>( level->getTileEntity(x,y,z) );
+ if(mste != NULL)
+ {
+ mste->setEntityId( EntityIO::getEncodeId(itemInstance->getAuxValue()) );
+ return true;
+ }
+ }
+#endif
+
+ x += Facing::STEP_X[face];
+ y += Facing::STEP_Y[face];
+ z += Facing::STEP_Z[face];
+
+ double yOff = 0;
+ // 4J-PB - missing parentheses added
+ if (face == Facing::UP && (tile == Tile::fence_Id || tile == Tile::netherFence_Id))
+ {
+ // special case
+ yOff = .5;
+ }
+
+ int iResult=0;
+ bool spawned = spawnMobAt(level, itemInstance->getAuxValue(), x + .5, y + yOff, z + .5, &iResult) != NULL;
+
+ if(bTestUseOnOnly)
+ {
+ return spawned;
+ }
+
+ if (spawned)
+ {
+ if (!player->abilities.instabuild)
+ {
+ itemInstance->count--;
+ }
+ }
+ else
+ {
+ // some negative sound effect?
+ //level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
+ switch(iResult)
+ {
+ case eSpawnResult_FailTooManyPigsCowsSheepCats:
+ player->displayClientMessage(IDS_MAX_PIGS_SHEEP_COWS_CATS_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManyChickens:
+ player->displayClientMessage(IDS_MAX_CHICKENS_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManySquid:
+ player->displayClientMessage(IDS_MAX_SQUID_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManyWolves:
+ player->displayClientMessage(IDS_MAX_WOLVES_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManyMooshrooms:
+ player->displayClientMessage(IDS_MAX_MOOSHROOMS_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManyMonsters:
+ player->displayClientMessage(IDS_MAX_ENEMIES_SPAWNED );
+ break;
+ case eSpawnResult_FailTooManyVillagers:
+ player->displayClientMessage(IDS_MAX_VILLAGERS_SPAWNED );
+ break;
+ case eSpawnResult_FailCantSpawnInPeaceful:
+ player->displayClientMessage(IDS_CANT_SPAWN_IN_PEACEFUL );
+ break;
+
+ }
+ }
+
+ return true;
+}
+
+shared_ptr<Entity> MonsterPlacerItem::spawnMobAt(Level *level, int mobId, double x, double y, double z, int *piResult)
+{
+ if (EntityIO::idsSpawnableInCreative.find(mobId) == EntityIO::idsSpawnableInCreative.end())
+ {
+ return nullptr;
+ }
+
+ shared_ptr<Entity> newEntity = nullptr;
+
+ for (int i = 0; i < SPAWN_COUNT; i++)
+ {
+ newEntity = canSpawn(mobId, level, piResult);
+
+ shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(newEntity);
+ if (mob)
+ {
+ newEntity->moveTo(x, y, z, Mth::wrapDegrees(level->random->nextFloat() * 360), 0);
+ newEntity->setDespawnProtected(); // 4J added, default to being protected against despawning (has to be done after initial position is set)
+ mob->yHeadRot = mob->yRot;
+ mob->yBodyRot = mob->yRot;
+
+ mob->finalizeMobSpawn();
+ level->addEntity(newEntity);
+ mob->playAmbientSound();
+ }
+ }
+
+ return newEntity;
+}
+
+void MonsterPlacerItem::registerIcons(IconRegister *iconRegister)
+{
+ Item::registerIcons(iconRegister);
+ overlay = iconRegister->registerIcon(L"monsterPlacer_overlay");
+}