the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 457 lines 14 kB view raw
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}