the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 378 lines 9.7 kB view raw
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 "HitResult.h" 11#include "SpawnEggItem.h" 12#include "Difficulty.h" 13 14 15SpawnEggItem::SpawnEggItem(int id) : Item(id) 16{ 17 setMaxStackSize(16); // 4J-PB brought forward. It is 64 on PC, but we'll never be able to place that many 18 setStackedByData(true); 19 overlay = NULL; 20} 21 22wstring SpawnEggItem::getHoverName(shared_ptr<ItemInstance> itemInstance) 23{ 24 wstring elementName = getDescription(); 25 26 int nameId = EntityIO::getNameId(itemInstance->getAuxValue()); 27 if (nameId >= 0) 28 { 29 elementName = replaceAll(elementName,L"{*CREATURE*}",app.GetString(nameId)); 30 //elementName += " " + I18n.get("entity." + encodeId + ".name"); 31 } 32 else 33 { 34 elementName = replaceAll(elementName,L"{*CREATURE*}",L""); 35 } 36 37 return elementName; 38} 39 40int SpawnEggItem::getColor(shared_ptr<ItemInstance> item, int spriteLayer) 41{ 42 AUTO_VAR(it, EntityIO::idsSpawnableInCreative.find(item->getAuxValue())); 43 if (it != EntityIO::idsSpawnableInCreative.end()) 44 { 45 EntityIO::SpawnableMobInfo *spawnableMobInfo = it->second; 46 if (spriteLayer == 0) { 47 return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor1 ); 48 } 49 return Minecraft::GetInstance()->getColourTable()->getColor( spawnableMobInfo->eggColor2 ); 50 } 51 return 0xffffff; 52} 53 54bool SpawnEggItem::hasMultipleSpriteLayers() 55{ 56 return true; 57} 58 59Icon *SpawnEggItem::getLayerIcon(int auxValue, int spriteLayer) 60{ 61 if (spriteLayer > 0) 62 { 63 return overlay; 64 } 65 return Item::getLayerIcon(auxValue, spriteLayer); 66} 67 68// 4J-PB - added for dispenser 69shared_ptr<Entity> SpawnEggItem::canSpawn(int iAuxVal, Level *level, int *piResult) 70{ 71 shared_ptr<Entity> newEntity = EntityIO::newById(iAuxVal, level); 72 if (newEntity != NULL) 73 { 74 bool canSpawn = false; 75 76 switch(newEntity->GetType()) 77 { 78 case eTYPE_CHICKEN: 79 if(level->canCreateMore( eTYPE_CHICKEN, Level::eSpawnType_Egg) ) 80 { 81 canSpawn = true; 82 } 83 else 84 { 85 *piResult=eSpawnResult_FailTooManyChickens; 86 } 87 break; 88 case eTYPE_WOLF: 89 if(level->canCreateMore( eTYPE_WOLF, Level::eSpawnType_Egg) ) 90 { 91 canSpawn = true; 92 } 93 else 94 { 95 *piResult=eSpawnResult_FailTooManyWolves; 96 } 97 break; 98 case eTYPE_VILLAGER: 99 if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Egg) ) 100 { 101 canSpawn = true; 102 } 103 else 104 { 105 *piResult=eSpawnResult_FailTooManyVillagers; 106 } 107 break; 108 case eTYPE_MUSHROOMCOW: 109 if(level->canCreateMore(eTYPE_MUSHROOMCOW, Level::eSpawnType_Egg) ) 110 { 111 canSpawn = true; 112 } 113 else 114 { 115 *piResult=eSpawnResult_FailTooManyMooshrooms; 116 } 117 break; 118 case eTYPE_SQUID: 119 if(level->canCreateMore( eTYPE_SQUID, Level::eSpawnType_Egg) ) 120 { 121 canSpawn = true; 122 } 123 else 124 { 125 *piResult=eSpawnResult_FailTooManySquid; 126 } 127 break; 128 case eTYPE_BAT: 129 if(level->canCreateMore( eTYPE_BAT, Level::eSpawnType_Egg) ) 130 { 131 canSpawn = true; 132 } 133 else 134 { 135 *piResult=eSpawnResult_FailTooManyBats; 136 } 137 break; 138 default: 139 if ( eTYPE_FLAGSET(eTYPE_ANIMALS_SPAWN_LIMIT_CHECK, newEntity->GetType()) ) 140 { 141 if( level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg ) ) 142 { 143 canSpawn = true; 144 } 145 else 146 { 147 // different message for each animal 148 149 *piResult=eSpawnResult_FailTooManyPigsCowsSheepCats; 150 } 151 } 152 // 4J: Use eTYPE_ENEMY instead of monster (slimes and ghasts aren't monsters) 153 else if(newEntity->instanceof(eTYPE_ENEMY)) 154 { 155 // 4J-PB - check if the player is trying to spawn an enemy in peaceful mode 156 if(level->difficulty==Difficulty::PEACEFUL) 157 { 158 *piResult=eSpawnResult_FailCantSpawnInPeaceful; 159 } 160 else if(level->canCreateMore( newEntity->GetType(), Level::eSpawnType_Egg) ) 161 { 162 canSpawn = true; 163 } 164 else 165 { 166 *piResult=eSpawnResult_FailTooManyMonsters; 167 } 168 } 169#ifndef _CONTENT_PACKAGE 170 else if(app.DebugArtToolsOn()) 171 { 172 canSpawn = true; 173 } 174#endif 175 break; 176 } 177 178 if(canSpawn) 179 { 180 return newEntity; 181 } 182 } 183 184 return nullptr; 185} 186 187bool SpawnEggItem::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) 188{ 189 if (level->isClientSide) 190 { 191 return true; 192 } 193 194 int tile = level->getTile(x, y, z); 195 196#ifndef _CONTENT_PACKAGE 197 if(app.DebugArtToolsOn() && tile == Tile::mobSpawner_Id) 198 { 199 // 4J Stu - Force adding this as a tile update 200 level->removeTile(x,y,z); 201 level->setTileAndData(x,y,z,Tile::mobSpawner_Id, 0, Tile::UPDATE_ALL); 202 shared_ptr<MobSpawnerTileEntity> mste = dynamic_pointer_cast<MobSpawnerTileEntity>( level->getTileEntity(x,y,z) ); 203 if(mste != NULL) 204 { 205 mste->setEntityId( EntityIO::getEncodeId(itemInstance->getAuxValue()) ); 206 return true; 207 } 208 } 209#endif 210 211 x += Facing::STEP_X[face]; 212 y += Facing::STEP_Y[face]; 213 z += Facing::STEP_Z[face]; 214 215 double yOff = 0; 216 if (face == Facing::UP && (Tile::tiles[tile] != NULL && Tile::tiles[tile]->getRenderShape() == Tile::SHAPE_FENCE)) 217 { 218 // special case 219 yOff = .5; 220 } 221 222 int iResult=0; 223 shared_ptr<Entity> result = spawnMobAt(level, itemInstance->getAuxValue(), x + .5, y + yOff, z + .5, &iResult); 224 225 if(bTestUseOnOnly) 226 { 227 return result != NULL; 228 } 229 230 if (result != NULL) 231 { 232 // 4J-JEV: SetCustomName is a method for Mob not LivingEntity; so change instanceof to check for Mobs. 233 if ( result->instanceof(eTYPE_MOB) && itemInstance->hasCustomHoverName() ) 234 { 235 dynamic_pointer_cast<Mob>(result)->setCustomName(itemInstance->getHoverName()); 236 } 237 if ( !player->abilities.instabuild ) 238 { 239 itemInstance->count--; 240 } 241 } 242 else 243 { 244 DisplaySpawnError(player, iResult); 245 } 246 247 return true; 248} 249 250shared_ptr<ItemInstance> SpawnEggItem::use(shared_ptr<ItemInstance> itemInstance, Level *level, shared_ptr<Player> player) 251{ 252 if (level->isClientSide) return itemInstance; 253 254 HitResult *hr = getPlayerPOVHitResult(level, player, true); 255 if (hr == NULL) 256 { 257 delete hr; 258 return itemInstance; 259 } 260 261 if (hr->type == HitResult::TILE) 262 { 263 int xt = hr->x; 264 int yt = hr->y; 265 int zt = hr->z; 266 267 if (!level->mayInteract(player, xt, yt, zt,0)) 268 { 269 delete hr; 270 return itemInstance; 271 } 272 if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) return itemInstance; 273 274 if (level->getMaterial(xt, yt, zt) == Material::water) 275 { 276 int iResult=0; 277 shared_ptr<Entity> result = spawnMobAt(level, itemInstance->getAuxValue(), xt, yt, zt, &iResult); 278 if (result != NULL) 279 { 280 // 4J-JEV: SetCustomName is a method for Mob not LivingEntity; so change instanceof to check for Mobs. 281 if ( result->instanceof(eTYPE_MOB) && itemInstance->hasCustomHoverName() ) 282 { 283 dynamic_pointer_cast<Mob>(result)->setCustomName(itemInstance->getHoverName()); 284 } 285 if (!player->abilities.instabuild) 286 { 287 itemInstance->count--; 288 } 289 } 290 else 291 { 292 SpawnEggItem::DisplaySpawnError(player, iResult); 293 } 294 } 295 } 296 return itemInstance; 297} 298 299shared_ptr<Entity> SpawnEggItem::spawnMobAt(Level *level, int auxVal, double x, double y, double z, int *piResult) 300{ 301 int mobId = auxVal; 302 int extraData = 0; 303 304 //4J Stu - Enable spawning specific entity sub-types 305 mobId = auxVal & 0xFFF; 306 extraData = auxVal >> 12; 307 308 if (EntityIO::idsSpawnableInCreative.find(mobId) == EntityIO::idsSpawnableInCreative.end()) 309 { 310 return nullptr; 311 } 312 313 shared_ptr<Entity> newEntity = nullptr; 314 315 for (int i = 0; i < SPAWN_COUNT; i++) 316 { 317 newEntity = canSpawn(mobId, level, piResult); 318 319 // 4J-JEV: DynCasting to Mob not LivingEntity; so change instanceof to check for Mobs. 320 if ( newEntity != NULL && newEntity->instanceof(eTYPE_MOB) ) 321 { 322 shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(newEntity); 323 newEntity->moveTo(x, y, z, Mth::wrapDegrees(level->random->nextFloat() * 360), 0); 324 newEntity->setDespawnProtected(); // 4J added, default to being protected against despawning (has to be done after initial position is set) 325 mob->yHeadRot = mob->yRot; 326 mob->yBodyRot = mob->yRot; 327 328 mob->finalizeMobSpawn(NULL, extraData); 329 level->addEntity(newEntity); 330 mob->playAmbientSound(); 331 } 332 } 333 334 return newEntity; 335} 336 337void SpawnEggItem::registerIcons(IconRegister *iconRegister) 338{ 339 Item::registerIcons(iconRegister); 340 overlay = iconRegister->registerIcon(getIconName() + L"_overlay"); 341} 342 343void SpawnEggItem::DisplaySpawnError(shared_ptr<Player> player, int result) 344{ 345 // some negative sound effect? 346 //level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); 347 switch(result) 348 { 349 case eSpawnResult_FailTooManyPigsCowsSheepCats: 350 player->displayClientMessage(IDS_MAX_PIGS_SHEEP_COWS_CATS_SPAWNED ); 351 break; 352 case eSpawnResult_FailTooManyChickens: 353 player->displayClientMessage(IDS_MAX_CHICKENS_SPAWNED ); 354 break; 355 case eSpawnResult_FailTooManySquid: 356 player->displayClientMessage(IDS_MAX_SQUID_SPAWNED ); 357 break; 358 case eSpawnResult_FailTooManyBats: 359 player->displayClientMessage(IDS_MAX_BATS_SPAWNED); 360 break; 361 case eSpawnResult_FailTooManyWolves: 362 player->displayClientMessage(IDS_MAX_WOLVES_SPAWNED ); 363 break; 364 case eSpawnResult_FailTooManyMooshrooms: 365 player->displayClientMessage(IDS_MAX_MOOSHROOMS_SPAWNED ); 366 break; 367 case eSpawnResult_FailTooManyMonsters: 368 player->displayClientMessage(IDS_MAX_ENEMIES_SPAWNED ); 369 break; 370 case eSpawnResult_FailTooManyVillagers: 371 player->displayClientMessage(IDS_MAX_VILLAGERS_SPAWNED ); 372 break; 373 case eSpawnResult_FailCantSpawnInPeaceful: 374 player->displayClientMessage(IDS_CANT_SPAWN_IN_PEACEFUL ); 375 break; 376 377 } 378}