the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "..\Minecraft.Client\Minecraft.h"
3#include "net.minecraft.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.tile.h"
6#include "net.minecraft.world.level.tile.entity.h"
7#include "net.minecraft.world.entity.h"
8#include "net.minecraft.world.entity.npc.h"
9#include "net.minecraft.world.h"
10#include "MonsterPlacerItem.h"
11#include "Difficulty.h"
12
13
14MonsterPlacerItem::MonsterPlacerItem(int id) : Item(id)
15{
16 setMaxStackSize(16); // 4J-PB brought forward. It is 64 on PC, but we'll never be able to place that many
17 setStackedByData(true);
18 overlay = NULL;
19}
20
21wstring MonsterPlacerItem::getHoverName(shared_ptr<ItemInstance> itemInstance)
22{
23 wstring elementName = getDescription();
24
25 int nameId = EntityIO::getNameId(itemInstance->getAuxValue());
26 if (nameId >= 0)
27 {
28 elementName = replaceAll(elementName,L"{*CREATURE*}",app.GetString(nameId));
29 //elementName += " " + I18n.get("entity." + encodeId + ".name");
30 }
31 else
32 {
33 elementName = replaceAll(elementName,L"{*CREATURE*}",L"");
34 }
35
36 return elementName;
37}
38
39int MonsterPlacerItem::getColor(shared_ptr<ItemInstance> item, int spriteLayer)
40{
41 AUTO_VAR(it, EntityIO::idsSpawnableInCreative.find(item->getAuxValue()));
42 if (it != EntityIO::idsSpawnableInCreative.end())
43 {
44 EntityIO::SpawnableMobInfo *spawnableMobInfo = it->second;
45 if (spriteLayer == 0) {
46 return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor1 );
47 }
48 return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor2 );
49 }
50 return 0xffffff;
51}
52
53bool MonsterPlacerItem::hasMultipleSpriteLayers()
54{
55 return true;
56}
57
58Icon *MonsterPlacerItem::getLayerIcon(int auxValue, int spriteLayer)
59{
60 if (spriteLayer > 0)
61 {
62 return overlay;
63 }
64 return Item::getLayerIcon(auxValue, spriteLayer);
65}
66
67// 4J-PB - added for dispenser
68shared_ptr<Entity> MonsterPlacerItem::canSpawn(int iAuxVal, Level *level, int *piResult)
69{
70 shared_ptr<Entity> newEntity = EntityIO::newById(iAuxVal, level);
71 if (newEntity != NULL)
72 {
73 bool canSpawn = false;
74
75 switch(newEntity->GetType())
76 {
77 case eTYPE_CHICKEN:
78 if(level->canCreateMore( eTYPE_CHICKEN, Level::eSpawnType_Egg) )
79 {
80 canSpawn = true;
81 }
82 else
83 {
84 *piResult=eSpawnResult_FailTooManyChickens;
85 }
86 break;
87 case eTYPE_WOLF:
88 if(level->canCreateMore( eTYPE_WOLF, Level::eSpawnType_Egg) )
89 {
90 canSpawn = true;
91 }
92 else
93 {
94 *piResult=eSpawnResult_FailTooManyWolves;
95 }
96 break;
97 case eTYPE_VILLAGER:
98 if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Egg) )
99 {
100 canSpawn = true;
101 }
102 else
103 {
104 *piResult=eSpawnResult_FailTooManyVillagers;
105 }
106 break;
107 case eTYPE_MUSHROOMCOW:
108 if(level->canCreateMore(eTYPE_MUSHROOMCOW, Level::eSpawnType_Egg) )
109 {
110 canSpawn = true;
111 }
112 else
113 {
114 *piResult=eSpawnResult_FailTooManyMooshrooms;
115 }
116 break;
117 case eTYPE_SQUID:
118 if(level->canCreateMore( eTYPE_SQUID, Level::eSpawnType_Egg) )
119 {
120 canSpawn = true;
121 }
122 else
123 {
124 *piResult=eSpawnResult_FailTooManySquid;
125 }
126 break;
127 default:
128 if( (newEntity->GetType() & eTYPE_ANIMALS_SPAWN_LIMIT_CHECK) == eTYPE_ANIMALS_SPAWN_LIMIT_CHECK)
129 {
130 if( level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg ) )
131 {
132 canSpawn = true;
133 }
134 else
135 {
136 // different message for each animal
137
138 *piResult=eSpawnResult_FailTooManyPigsCowsSheepCats;
139 }
140 }
141 else if( (newEntity->GetType() & eTYPE_MONSTER) == eTYPE_MONSTER)
142 {
143 // 4J-PB - check if the player is trying to spawn an enemy in peaceful mode
144 if(level->difficulty==Difficulty::PEACEFUL)
145 {
146 *piResult=eSpawnResult_FailCantSpawnInPeaceful;
147 }
148 else if(level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg) )
149 {
150 canSpawn = true;
151 }
152 else
153 {
154 *piResult=eSpawnResult_FailTooManyMonsters;
155 }
156 }
157 break;
158 }
159
160 if(canSpawn)
161 {
162 return newEntity;
163 }
164 }
165
166 return nullptr;
167}
168
169bool 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)
170{
171 if (level->isClientSide)
172 {
173 return true;
174 }
175
176 int tile = level->getTile(x, y, z);
177
178#ifndef _CONTENT_PACKAGE
179 if(app.DebugSettingsOn() && tile == Tile::mobSpawner_Id)
180 {
181 // 4J Stu - Force adding this as a tile update
182 level->setTile(x,y,z,0);
183 level->setTile(x,y,z,Tile::mobSpawner_Id);
184 shared_ptr<MobSpawnerTileEntity> mste = dynamic_pointer_cast<MobSpawnerTileEntity>( level->getTileEntity(x,y,z) );
185 if(mste != NULL)
186 {
187 mste->setEntityId( EntityIO::getEncodeId(itemInstance->getAuxValue()) );
188 return true;
189 }
190 }
191#endif
192
193 x += Facing::STEP_X[face];
194 y += Facing::STEP_Y[face];
195 z += Facing::STEP_Z[face];
196
197 double yOff = 0;
198 // 4J-PB - missing parentheses added
199 if (face == Facing::UP && (tile == Tile::fence_Id || tile == Tile::netherFence_Id))
200 {
201 // special case
202 yOff = .5;
203 }
204
205 int iResult=0;
206 bool spawned = spawnMobAt(level, itemInstance->getAuxValue(), x + .5, y + yOff, z + .5, &iResult) != NULL;
207
208 if(bTestUseOnOnly)
209 {
210 return spawned;
211 }
212
213 if (spawned)
214 {
215 if (!player->abilities.instabuild)
216 {
217 itemInstance->count--;
218 }
219 }
220 else
221 {
222 // some negative sound effect?
223 //level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
224 switch(iResult)
225 {
226 case eSpawnResult_FailTooManyPigsCowsSheepCats:
227 player->displayClientMessage(IDS_MAX_PIGS_SHEEP_COWS_CATS_SPAWNED );
228 break;
229 case eSpawnResult_FailTooManyChickens:
230 player->displayClientMessage(IDS_MAX_CHICKENS_SPAWNED );
231 break;
232 case eSpawnResult_FailTooManySquid:
233 player->displayClientMessage(IDS_MAX_SQUID_SPAWNED );
234 break;
235 case eSpawnResult_FailTooManyWolves:
236 player->displayClientMessage(IDS_MAX_WOLVES_SPAWNED );
237 break;
238 case eSpawnResult_FailTooManyMooshrooms:
239 player->displayClientMessage(IDS_MAX_MOOSHROOMS_SPAWNED );
240 break;
241 case eSpawnResult_FailTooManyMonsters:
242 player->displayClientMessage(IDS_MAX_ENEMIES_SPAWNED );
243 break;
244 case eSpawnResult_FailTooManyVillagers:
245 player->displayClientMessage(IDS_MAX_VILLAGERS_SPAWNED );
246 break;
247 case eSpawnResult_FailCantSpawnInPeaceful:
248 player->displayClientMessage(IDS_CANT_SPAWN_IN_PEACEFUL );
249 break;
250
251 }
252 }
253
254 return true;
255}
256
257shared_ptr<Entity> MonsterPlacerItem::spawnMobAt(Level *level, int mobId, double x, double y, double z, int *piResult)
258{
259 if (EntityIO::idsSpawnableInCreative.find(mobId) == EntityIO::idsSpawnableInCreative.end())
260 {
261 return nullptr;
262 }
263
264 shared_ptr<Entity> newEntity = nullptr;
265
266 for (int i = 0; i < SPAWN_COUNT; i++)
267 {
268 newEntity = canSpawn(mobId, level, piResult);
269
270 shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(newEntity);
271 if (mob)
272 {
273 newEntity->moveTo(x, y, z, Mth::wrapDegrees(level->random->nextFloat() * 360), 0);
274 newEntity->setDespawnProtected(); // 4J added, default to being protected against despawning (has to be done after initial position is set)
275 mob->yHeadRot = mob->yRot;
276 mob->yBodyRot = mob->yRot;
277
278 mob->finalizeMobSpawn();
279 level->addEntity(newEntity);
280 mob->playAmbientSound();
281 }
282 }
283
284 return newEntity;
285}
286
287void MonsterPlacerItem::registerIcons(IconRegister *iconRegister)
288{
289 Item::registerIcons(iconRegister);
290 overlay = iconRegister->registerIcon(L"monsterPlacer_overlay");
291}