mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-28 02:47:12 +00:00
263 lines
9.6 KiB
C++
263 lines
9.6 KiB
C++
#include "../Platform/stdafx.h"
|
|
#include "../../Minecraft.Client/Minecraft.h"
|
|
#include "../Headers/net.minecraft.h"
|
|
#include "../Headers/net.minecraft.world.level.h"
|
|
#include "../Headers/net.minecraft.world.level.tile.h"
|
|
#include "../Headers/net.minecraft.world.level.tile.entity.h"
|
|
#include "../Headers/net.minecraft.world.entity.h"
|
|
#include "../Headers/net.minecraft.world.entity.npc.h"
|
|
#include "../Headers/net.minecraft.world.h"
|
|
#include "MonsterPlacerItem.h"
|
|
#include "../Util/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;
|
|
}
|
|
|
|
std::wstring MonsterPlacerItem::getHoverName(
|
|
std::shared_ptr<ItemInstance> itemInstance) {
|
|
std::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(std::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
|
|
std::shared_ptr<Entity> MonsterPlacerItem::canSpawn(int iAuxVal, Level* level,
|
|
int* piResult) {
|
|
std::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(std::shared_ptr<ItemInstance> itemInstance,
|
|
std::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);
|
|
std::shared_ptr<MobSpawnerTileEntity> mste =
|
|
std::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;
|
|
}
|
|
|
|
std::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;
|
|
}
|
|
|
|
std::shared_ptr<Entity> newEntity = nullptr;
|
|
|
|
for (int i = 0; i < SPAWN_COUNT; i++) {
|
|
newEntity = canSpawn(mobId, level, piResult);
|
|
|
|
std::shared_ptr<Mob> mob = std::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");
|
|
}
|