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 "net.minecraft.world.entity.item.h"
3#include "net.minecraft.world.entity.projectile.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.item.h"
8#include "ItemDispenseBehaviors.h"
9
10/* Arrow */
11
12shared_ptr<Projectile> ArrowDispenseBehavior::getProjectile(Level *world, Position *position)
13{
14 shared_ptr<Arrow> arrow = shared_ptr<Arrow>(new Arrow(world, position->getX(), position->getY(), position->getZ()));
15 arrow->pickup = Arrow::PICKUP_ALLOWED;
16
17 return arrow;
18}
19
20/* ThrownEgg */
21
22shared_ptr<Projectile> EggDispenseBehavior::getProjectile(Level *world, Position *position)
23{
24 return shared_ptr<Projectile>(new ThrownEgg(world, position->getX(), position->getY(), position->getZ()));
25}
26
27
28/* Snowball */
29
30shared_ptr<Projectile> SnowballDispenseBehavior::getProjectile(Level *world, Position *position)
31{
32 return shared_ptr<Projectile>(new Snowball(world, position->getX(), position->getY(), position->getZ()));
33}
34
35
36/* Exp Bottle */
37
38shared_ptr<Projectile> ExpBottleDispenseBehavior::getProjectile(Level *world, Position *position)
39{
40 return shared_ptr<Projectile>(new ThrownExpBottle(world, position->getX(), position->getY(), position->getZ()));
41}
42
43float ExpBottleDispenseBehavior::getUncertainty()
44{
45 return AbstractProjectileDispenseBehavior::getUncertainty() * .5f;
46}
47
48float ExpBottleDispenseBehavior::getPower()
49{
50 return AbstractProjectileDispenseBehavior::getPower() * 1.25f;
51}
52
53
54/* Thrown Potion */
55
56ThrownPotionDispenseBehavior::ThrownPotionDispenseBehavior(int potionValue)
57{
58 m_potionValue = potionValue;
59}
60
61shared_ptr<Projectile> ThrownPotionDispenseBehavior::getProjectile(Level *world, Position *position)
62{
63 return shared_ptr<Projectile>(new ThrownPotion(world, position->getX(), position->getY(), position->getZ(), m_potionValue));
64}
65
66float ThrownPotionDispenseBehavior::getUncertainty()
67{
68 return AbstractProjectileDispenseBehavior::getUncertainty() * .5f;
69}
70
71float ThrownPotionDispenseBehavior::getPower()
72{
73 return AbstractProjectileDispenseBehavior::getPower() * 1.25f;
74}
75
76
77/* Potion */
78
79shared_ptr<ItemInstance> PotionDispenseBehavior::dispense(BlockSource *source, shared_ptr<ItemInstance> dispensed)
80{
81 if (PotionItem::isThrowable(dispensed->getAuxValue()))
82 {
83 return ThrownPotionDispenseBehavior(dispensed->getAuxValue()).dispense(source, dispensed);
84 }
85 else
86 {
87 return DefaultDispenseItemBehavior::dispense(source, dispensed);
88 }
89}
90
91
92/* SpawnEggItem */
93
94shared_ptr<ItemInstance> SpawnEggDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
95{
96 FacingEnum *facing = DispenserTile::getFacing(source->getData());
97
98 // Spawn entity in the middle of the block in front of the dispenser
99 double spawnX = source->getX() + facing->getStepX();
100 double spawnY = source->getBlockY() + .2f; // Above pressure plates
101 double spawnZ = source->getZ() + facing->getStepZ();
102
103 int iResult = 0;
104 shared_ptr<Entity> entity = SpawnEggItem::spawnMobAt(source->getWorld(), dispensed->getAuxValue(), spawnX, spawnY, spawnZ, &iResult);
105
106 // 4J-JEV: Added in-case spawn limit is encountered.
107 if (entity == NULL)
108 {
109 outcome = LEFT_ITEM;
110 return dispensed;
111 }
112
113 if (entity->instanceof(eTYPE_MOB) && dispensed->hasCustomHoverName())
114 {
115 dynamic_pointer_cast<Mob>(entity)->setCustomName(dispensed->getHoverName());
116 }
117
118 outcome = ACTIVATED_ITEM;
119
120 dispensed->remove(1);
121 return dispensed;
122}
123
124
125/* Fireworks*/
126
127shared_ptr<ItemInstance> FireworksDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
128{
129 Level *world = source->getWorld();
130 if ( world->countInstanceOf(eTYPE_PROJECTILE,false) >= Level::MAX_DISPENSABLE_PROJECTILES )
131 {
132 outcome = LEFT_ITEM;
133 return dispensed;
134 }
135
136 FacingEnum *facing = DispenserTile::getFacing(source->getData());
137
138 double spawnX = source->getX() + facing->getStepX();
139 double spawnY = source->getBlockY() + .2f;
140 double spawnZ = source->getZ() + facing->getStepZ();
141
142 shared_ptr<FireworksRocketEntity> firework = shared_ptr<FireworksRocketEntity>(new FireworksRocketEntity(world, spawnX, spawnY, spawnZ, dispensed));
143 source->getWorld()->addEntity(firework);
144
145 outcome = ACTIVATED_ITEM;
146
147 dispensed->remove(1);
148 return dispensed;
149}
150
151void FireworksDispenseBehavior::playSound(BlockSource *source, eOUTCOME outcome)
152{
153 // 4J-JEV: This is exactly the same as the default at the moment.
154 //source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
155
156 DefaultDispenseItemBehavior::playSound(source,outcome);
157}
158
159
160/* Fireballs */
161
162shared_ptr<ItemInstance> FireballDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
163{
164 Level *world = source->getWorld();
165 if (world->countInstanceOf(eTYPE_SMALL_FIREBALL,true) >= Level::MAX_DISPENSABLE_FIREBALLS)
166 {
167 outcome = LEFT_ITEM;
168 return dispensed;
169 }
170
171 FacingEnum *facing = DispenserTile::getFacing(source->getData());
172
173 Position *position = DispenserTile::getDispensePosition(source);
174 double spawnX = position->getX() + facing->getStepX() * .3f;
175 double spawnY = position->getY() + facing->getStepX() * .3f;
176 double spawnZ = position->getZ() + facing->getStepZ() * .3f;
177
178 delete position;
179
180 Random *random = world->random;
181
182 double dirX = random->nextGaussian() * .05 + facing->getStepX();
183 double dirY = random->nextGaussian() * .05 + facing->getStepY();
184 double dirZ = random->nextGaussian() * .05 + facing->getStepZ();
185
186 world->addEntity(shared_ptr<SmallFireball>(new SmallFireball(world, spawnX, spawnY, spawnZ, dirX, dirY, dirZ)));
187
188 outcome = ACTIVATED_ITEM;
189
190 dispensed->remove(1);
191 return dispensed;
192}
193
194void FireballDispenseBehavior::playSound(BlockSource *source, eOUTCOME outcome)
195{
196 if (outcome == ACTIVATED_ITEM)
197 {
198 source->getWorld()->levelEvent(LevelEvent::SOUND_BLAZE_FIREBALL, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
199 }
200 else
201 {
202 DefaultDispenseItemBehavior::playSound(source, outcome);
203 }
204}
205
206
207/* Boats */
208
209BoatDispenseBehavior::BoatDispenseBehavior() : DefaultDispenseItemBehavior()
210{
211 defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();
212}
213
214BoatDispenseBehavior::~BoatDispenseBehavior()
215{
216 delete defaultDispenseItemBehavior;
217}
218
219shared_ptr<ItemInstance> BoatDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
220{
221 FacingEnum *facing = DispenserTile::getFacing(source->getData());
222 Level *world = source->getWorld();
223
224 // Spawn the boat 'just' outside the dispenser, it overlaps 2 'pixels' now.
225 double spawnX = source->getX() + facing->getStepX() * (1 + 2.0f / 16);
226 double spawnY = source->getY() + facing->getStepY() * (1 + 2.0f / 16);
227 double spawnZ = source->getZ() + facing->getStepZ() * (1 + 2.0f / 16);
228
229 int frontX = source->getBlockX() + facing->getStepX();
230 int frontY = source->getBlockY() + facing->getStepY();
231 int frontZ = source->getBlockZ() + facing->getStepZ();
232 Material *inFront = world->getMaterial(frontX, frontY, frontZ);
233
234 double yOffset;
235
236 // 4J: If we're at limit, just dispense item (instead of adding boat)
237 if (world->countInstanceOf(eTYPE_BOAT, true) >= Level::MAX_XBOX_BOATS)
238 {
239 return defaultDispenseItemBehavior->dispense(source, dispensed);
240 }
241
242 if (Material::water == inFront)
243 {
244 yOffset = 1;
245 }
246 else if (Material::air == inFront && Material::water == world->getMaterial(frontX, frontY - 1, frontZ))
247 {
248 yOffset = 0;
249 }
250 else
251 {
252 return defaultDispenseItemBehavior->dispense(source, dispensed);
253 }
254
255 outcome = ACTIVATED_ITEM;
256
257 shared_ptr<Boat> boat = shared_ptr<Boat>(new Boat(world, spawnX, spawnY + yOffset, spawnZ));
258 world->addEntity(boat);
259
260 dispensed->remove(1);
261 return dispensed;
262}
263
264void BoatDispenseBehavior::playSound(BlockSource *source, eOUTCOME outcome)
265{
266 // 4J-JEV: This is exactly the same as the default at the moment.
267 //source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
268 DefaultDispenseItemBehavior::playSound(source,outcome);
269}
270
271
272/* FilledBucket */
273
274shared_ptr<ItemInstance> FilledBucketDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
275{
276 BucketItem *bucket = (BucketItem *)dispensed->getItem();
277 int sourceX = source->getBlockX();
278 int sourceY = source->getBlockY();
279 int sourceZ = source->getBlockZ();
280
281 FacingEnum *facing = DispenserTile::getFacing(source->getData());
282 if (bucket->emptyBucket(source->getWorld(), sourceX + facing->getStepX(), sourceY + facing->getStepY(), sourceZ + facing->getStepZ()))
283 {
284 dispensed->id = Item::bucket_empty->id;
285 dispensed->count = 1;
286
287 outcome = ACTIVATED_ITEM;
288 return dispensed;
289 }
290
291 return DefaultDispenseItemBehavior::dispense(source, dispensed);
292}
293
294
295/* EmptyBucket */
296
297shared_ptr<ItemInstance> EmptyBucketDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
298{
299 FacingEnum *facing = DispenserTile::getFacing(source->getData());
300 Level *world = source->getWorld();
301
302 int targetX = source->getBlockX() + facing->getStepX();
303 int targetY = source->getBlockY() + facing->getStepY();
304 int targetZ = source->getBlockZ() + facing->getStepZ();
305
306 Material *material = world->getMaterial(targetX, targetY, targetZ);
307 int dataValue = world->getData(targetX, targetY, targetZ);
308
309 Item *targetType;
310 if (Material::water == material && dataValue == 0)
311 {
312 targetType = Item::bucket_water;
313 }
314 else if (Material::lava == material && dataValue == 0)
315 {
316 targetType = Item::bucket_lava;
317 }
318 else
319 {
320 return DefaultDispenseItemBehavior::execute(source, dispensed, outcome);
321 }
322
323 world->removeTile(targetX, targetY, targetZ);
324 if (--dispensed->count == 0)
325 {
326 dispensed->id = targetType->id;
327 dispensed->count = 1;
328 }
329 else if (dynamic_pointer_cast<DispenserTileEntity>(source->getEntity())->addItem(shared_ptr<ItemInstance>(new ItemInstance(targetType))) < 0)
330 {
331 DefaultDispenseItemBehavior::dispense(source, shared_ptr<ItemInstance>(new ItemInstance(targetType)));
332 }
333
334 outcome = ACTIVATED_ITEM;
335 return dispensed;
336}
337
338
339/* Flint and Steel */
340
341shared_ptr<ItemInstance> FlintAndSteelDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
342{
343 outcome = ACTIVATED_ITEM;
344
345 FacingEnum *facing = DispenserTile::getFacing(source->getData());
346 Level *world = source->getWorld();
347
348 int targetX = source->getBlockX() + facing->getStepX();
349 int targetY = source->getBlockY() + facing->getStepY();
350 int targetZ = source->getBlockZ() + facing->getStepZ();
351
352 if (world->isEmptyTile(targetX, targetY, targetZ))
353 {
354 world->setTileAndUpdate(targetX, targetY, targetZ, Tile::fire_Id);
355
356 if (dispensed->hurt(1, world->random))
357 {
358 dispensed->count = 0;
359 }
360 }
361 else if (world->getTile(targetX, targetY, targetZ) == Tile::tnt_Id)
362 {
363 Tile::tnt->destroy(world, targetX, targetY, targetZ, 1);
364 world->removeTile(targetX, targetY, targetZ);
365 }
366 else
367 {
368 outcome = LEFT_ITEM;
369 }
370
371 return dispensed;
372}
373
374void FlintAndSteelDispenseBehavior::playSound(BlockSource *source, eOUTCOME outcome)
375{
376 if (outcome == ACTIVATED_ITEM)
377 {
378 source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
379 }
380 else
381 {
382 source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK_FAIL, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
383 }
384}
385
386
387/* Dye */
388
389shared_ptr<ItemInstance> DyeDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
390{
391 if (dispensed->getAuxValue() == DyePowderItem::WHITE)
392 {
393 FacingEnum *facing = DispenserTile::getFacing(source->getData());
394 Level *world = source->getWorld();
395
396 int targetX = source->getBlockX() + facing->getStepX();
397 int targetY = source->getBlockY() + facing->getStepY();
398 int targetZ = source->getBlockZ() + facing->getStepZ();
399
400 if (DyePowderItem::growCrop(dispensed, world, targetX, targetY, targetZ, false))
401 {
402 if (!world->isClientSide) world->levelEvent(LevelEvent::PARTICLES_PLANT_GROWTH, targetX, targetY, targetZ, 0);
403 outcome = ACTIVATED_ITEM;
404 }
405 else
406 {
407 outcome = LEFT_ITEM;
408 }
409
410
411 return dispensed;
412 }
413 else
414 {
415 return DefaultDispenseItemBehavior::execute(source, dispensed, outcome);
416 }
417}
418
419void DyeDispenseBehavior::playSound(BlockSource *source, eOUTCOME outcome)
420{
421 if (outcome == ACTIVATED_ITEM)
422 {
423 source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
424 }
425 else
426 {
427 source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK_FAIL, source->getBlockX(), source->getBlockY(), source->getBlockZ(), 0);
428 }
429}
430
431
432/* TNT */
433
434shared_ptr<ItemInstance> TntDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
435{
436 FacingEnum *facing = DispenserTile::getFacing(source->getData());
437 Level *world = source->getWorld();
438
439 if( world->newPrimedTntAllowed() && app.GetGameHostOption(eGameHostOption_TNT) )
440 {
441 int targetX = source->getBlockX() + facing->getStepX();
442 int targetY = source->getBlockY() + facing->getStepY();
443 int targetZ = source->getBlockZ() + facing->getStepZ();
444
445 shared_ptr<PrimedTnt> tnt = shared_ptr<PrimedTnt>(new PrimedTnt(world, targetX + 0.5f, targetY + 0.5f, targetZ + 0.5f, nullptr));
446 world->addEntity(tnt);
447
448 outcome = ACTIVATED_ITEM;
449
450 dispensed->count--;
451 }
452 else
453 {
454 outcome = LEFT_ITEM;
455 }
456 return dispensed;
457}