the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 401 lines 9.4 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.entity.h" 3#include "net.minecraft.world.entity.item.h" 4#include "net.minecraft.world.level.h" 5#include "net.minecraft.world.level.tile.h" 6#include "net.minecraft.world.phys.h" 7#include "BaseMobSpawner.h" 8 9BaseMobSpawner::BaseMobSpawner() 10{ 11 spawnPotentials = NULL; 12 spawnDelay = 20; 13 entityId = L"Pig"; 14 nextSpawnData = NULL; 15 spin = oSpin = 0.0; 16 17 minSpawnDelay = SharedConstants::TICKS_PER_SECOND * 10; 18 maxSpawnDelay = SharedConstants::TICKS_PER_SECOND * 40; 19 spawnCount = 4; 20 displayEntity = nullptr; 21 maxNearbyEntities = 6; 22 requiredPlayerRange = 16; 23 spawnRange = 4; 24} 25 26BaseMobSpawner::~BaseMobSpawner() 27{ 28 if(spawnPotentials) 29 { 30 for(AUTO_VAR(it,spawnPotentials->begin()); it != spawnPotentials->end(); ++it) 31 { 32 delete *it; 33 } 34 delete spawnPotentials; 35 } 36} 37 38wstring BaseMobSpawner::getEntityId() 39{ 40 if (getNextSpawnData() == NULL) 41 { 42 if (entityId.compare(L"Minecart") == 0) 43 { 44 entityId = L"MinecartRideable"; 45 } 46 return entityId; 47 } 48 else 49 { 50 return getNextSpawnData()->type; 51 } 52} 53 54void BaseMobSpawner::setEntityId(const wstring &entityId) 55{ 56 this->entityId = entityId; 57} 58 59bool BaseMobSpawner::isNearPlayer() 60{ 61 return getLevel()->getNearestPlayer(getX() + 0.5, getY() + 0.5, getZ() + 0.5, requiredPlayerRange) != NULL; 62} 63 64void BaseMobSpawner::tick() 65{ 66 if (!isNearPlayer()) 67 { 68 return; 69 } 70 71 if (getLevel()->isClientSide) 72 { 73 double xP = getX() + getLevel()->random->nextFloat(); 74 double yP = getY() + getLevel()->random->nextFloat(); 75 double zP = getZ() + getLevel()->random->nextFloat(); 76 getLevel()->addParticle(eParticleType_smoke, xP, yP, zP, 0, 0, 0); 77 getLevel()->addParticle(eParticleType_flame, xP, yP, zP, 0, 0, 0); 78 79 if (spawnDelay > 0) spawnDelay--; 80 oSpin = spin; 81 spin = (int)(spin + 1000 / (spawnDelay + 200.0f)) % 360; 82 } 83 else 84 { 85 if (spawnDelay == -1) delay(); 86 87 if (spawnDelay > 0) 88 { 89 spawnDelay--; 90 return; 91 } 92 93 bool _delay = false; 94 95 for (int c = 0; c < spawnCount; c++) 96 { 97 shared_ptr<Entity> entity = EntityIO::newEntity(getEntityId(), getLevel()); 98 if (entity == NULL) return; 99 100 int nearBy = getLevel()->getEntitiesOfClass( typeid(entity.get()), AABB::newTemp(getX(), getY(), getZ(), getX() + 1, getY() + 1, getZ() + 1)->grow(spawnRange * 2, 4, spawnRange * 2))->size(); 101 if (nearBy >= maxNearbyEntities) 102 { 103 delay(); 104 return; 105 } 106 107 double xp = getX() + (getLevel()->random->nextDouble() - getLevel()->random->nextDouble()) * spawnRange; 108 double yp = getY() + getLevel()->random->nextInt(3) - 1; 109 double zp = getZ() + (getLevel()->random->nextDouble() - getLevel()->random->nextDouble()) * spawnRange; 110 shared_ptr<Mob> mob = entity->instanceof(eTYPE_MOB) ? dynamic_pointer_cast<Mob>( entity ) : nullptr; 111 112 entity->moveTo(xp, yp, zp, getLevel()->random->nextFloat() * 360, 0); 113 114 if (mob == NULL || mob->canSpawn()) 115 { 116 loadDataAndAddEntity(entity); 117 getLevel()->levelEvent(LevelEvent::PARTICLES_MOBTILE_SPAWN, getX(), getY(), getZ(), 0); 118 119 if (mob != NULL) 120 { 121 mob->spawnAnim(); 122 } 123 124 _delay = true; 125 } 126 } 127 128 if (_delay) delay(); 129 } 130} 131 132shared_ptr<Entity> BaseMobSpawner::loadDataAndAddEntity(shared_ptr<Entity> entity) 133{ 134 if (getNextSpawnData() != NULL) 135 { 136 CompoundTag *data = new CompoundTag(); 137 entity->save(data); 138 139 vector<Tag *> *tags = getNextSpawnData()->tag->getAllTags(); 140 for (AUTO_VAR(it, tags->begin()); it != tags->end(); ++it) 141 { 142 Tag *tag = *it; 143 data->put(tag->getName(), tag->copy()); 144 } 145 delete tags; 146 147 entity->load(data); 148 if (entity->level != NULL) entity->level->addEntity(entity); 149 150 // add mounts 151 shared_ptr<Entity> rider = entity; 152 while (data->contains(Entity::RIDING_TAG)) 153 { 154 CompoundTag *ridingTag = data->getCompound(Entity::RIDING_TAG); 155 shared_ptr<Entity> mount = EntityIO::newEntity(ridingTag->getString(L"id"), entity->level); 156 if (mount != NULL) 157 { 158 CompoundTag *mountData = new CompoundTag(); 159 mount->save(mountData); 160 161 vector<Tag *> *ridingTags = ridingTag->getAllTags(); 162 for (AUTO_VAR(it, ridingTags->begin()); it != ridingTags->end(); ++it) 163 { 164 Tag *tag = *it; 165 mountData->put(tag->getName(), tag->copy()); 166 } 167 delete ridingTags; 168 mount->load(mountData); 169 mount->moveTo(rider->x, rider->y, rider->z, rider->yRot, rider->xRot); 170 171 if (entity->level != NULL) entity->level->addEntity(mount); 172 rider->ride(mount); 173 } 174 rider = mount; 175 data = ridingTag; 176 } 177 178 } 179 else if (entity->instanceof(eTYPE_LIVINGENTITY) && entity->level != NULL) 180 { 181 dynamic_pointer_cast<Mob>( entity )->finalizeMobSpawn(NULL); 182 getLevel()->addEntity(entity); 183 } 184 185 return entity; 186} 187 188void BaseMobSpawner::delay() 189{ 190 if (maxSpawnDelay <= minSpawnDelay) 191 { 192 spawnDelay = minSpawnDelay; 193 } 194 else 195 { 196 spawnDelay = minSpawnDelay + getLevel()->random->nextInt(maxSpawnDelay - minSpawnDelay); 197 } 198 199 if ( (spawnPotentials != NULL) && (spawnPotentials->size() > 0) ) 200 { 201 setNextSpawnData( (SpawnData*) WeighedRandom::getRandomItem((Random*)getLevel()->random, (vector<WeighedRandomItem*>*)spawnPotentials) ); 202 } 203 204 broadcastEvent(EVENT_SPAWN); 205} 206 207void BaseMobSpawner::load(CompoundTag *tag) 208{ 209 entityId = tag->getString(L"EntityId"); 210 spawnDelay = tag->getShort(L"Delay"); 211 212 if (tag->contains(L"SpawnPotentials")) 213 { 214 spawnPotentials = new vector<SpawnData *>(); 215 ListTag<CompoundTag> *potentials = (ListTag<CompoundTag> *) tag->getList(L"SpawnPotentials"); 216 217 for (int i = 0; i < potentials->size(); i++) 218 { 219 spawnPotentials->push_back(new SpawnData(potentials->get(i))); 220 } 221 } 222 else 223 { 224 spawnPotentials = NULL; 225 } 226 227 if (tag->contains(L"SpawnData")) 228 { 229 setNextSpawnData(new SpawnData(tag->getCompound(L"SpawnData"), entityId)); 230 } 231 else 232 { 233 setNextSpawnData(NULL); 234 } 235 236 if (tag->contains(L"MinSpawnDelay")) 237 { 238 minSpawnDelay = tag->getShort(L"MinSpawnDelay"); 239 maxSpawnDelay = tag->getShort(L"MaxSpawnDelay"); 240 spawnCount = tag->getShort(L"SpawnCount"); 241 } 242 243 if (tag->contains(L"MaxNearbyEntities")) 244 { 245 maxNearbyEntities = tag->getShort(L"MaxNearbyEntities"); 246 requiredPlayerRange = tag->getShort(L"RequiredPlayerRange"); 247 } 248 249 if (tag->contains(L"SpawnRange")) spawnRange = tag->getShort(L"SpawnRange"); 250 251 if (getLevel() != NULL && getLevel()->isClientSide) 252 { 253 displayEntity = nullptr; 254 } 255} 256 257void BaseMobSpawner::save(CompoundTag *tag) 258{ 259 tag->putString(L"EntityId", getEntityId()); 260 tag->putShort(L"Delay", (short) spawnDelay); 261 tag->putShort(L"MinSpawnDelay", (short) minSpawnDelay); 262 tag->putShort(L"MaxSpawnDelay", (short) maxSpawnDelay); 263 tag->putShort(L"SpawnCount", (short) spawnCount); 264 tag->putShort(L"MaxNearbyEntities", (short) maxNearbyEntities); 265 tag->putShort(L"RequiredPlayerRange", (short) requiredPlayerRange); 266 tag->putShort(L"SpawnRange", (short) spawnRange); 267 268 if (getNextSpawnData() != NULL) 269 { 270 tag->putCompound(L"SpawnData", (CompoundTag *) getNextSpawnData()->tag->copy()); 271 } 272 273 if (getNextSpawnData() != NULL || (spawnPotentials != NULL && spawnPotentials->size() > 0)) 274 { 275 ListTag<CompoundTag> *list = new ListTag<CompoundTag>(); 276 277 if (spawnPotentials != NULL && spawnPotentials->size() > 0) 278 { 279 for (AUTO_VAR(it, spawnPotentials->begin()); it != spawnPotentials->end(); ++it) 280 { 281 SpawnData *data = *it; 282 list->add(data->save()); 283 } 284 } 285 else 286 { 287 list->add(getNextSpawnData()->save()); 288 } 289 290 tag->put(L"SpawnPotentials", list); 291 } 292} 293 294shared_ptr<Entity> BaseMobSpawner::getDisplayEntity() 295{ 296 if (displayEntity == NULL) 297 { 298 shared_ptr<Entity> e = EntityIO::newEntity(getEntityId(), NULL); 299 e = loadDataAndAddEntity(e); 300 displayEntity = e; 301 } 302 303 return displayEntity; 304} 305 306bool BaseMobSpawner::onEventTriggered(int id) 307{ 308 if (id == EVENT_SPAWN && getLevel()->isClientSide) 309 { 310 spawnDelay = minSpawnDelay; 311 return true; 312 } 313 return false; 314} 315 316BaseMobSpawner::SpawnData *BaseMobSpawner::getNextSpawnData() 317{ 318 return nextSpawnData; 319} 320 321void BaseMobSpawner::setNextSpawnData(SpawnData *nextSpawnData) 322{ 323 this->nextSpawnData = nextSpawnData; 324} 325 326BaseMobSpawner::SpawnData::SpawnData(CompoundTag *base) : WeighedRandomItem(base->getInt(L"Weight")) 327{ 328 CompoundTag *tag = base->getCompound(L"Properties"); 329 wstring _type = base->getString(L"Type"); 330 331 if (_type.compare(L"Minecart") == 0) 332 { 333 if (tag != NULL) 334 { 335 switch (tag->getInt(L"Type")) 336 { 337 case Minecart::TYPE_CHEST: 338 type = L"MinecartChest"; 339 break; 340 case Minecart::TYPE_FURNACE: 341 type = L"MinecartFurnace"; 342 break; 343 case Minecart::TYPE_RIDEABLE: 344 type = L"MinecartRideable"; 345 break; 346 } 347 } 348 else 349 { 350 type = L"MinecartRideable"; 351 } 352 } 353 354 this->tag = tag; 355 this->type = _type; 356} 357 358BaseMobSpawner::SpawnData::SpawnData(CompoundTag *tag, wstring _type) : WeighedRandomItem(1) 359{ 360 if (_type.compare(L"Minecart") == 0) 361 { 362 if (tag != NULL) 363 { 364 switch (tag->getInt(L"Type")) 365 { 366 case Minecart::TYPE_CHEST: 367 _type = L"MinecartChest"; 368 break; 369 case Minecart::TYPE_FURNACE: 370 _type = L"MinecartFurnace"; 371 break; 372 case Minecart::TYPE_RIDEABLE: 373 _type = L"MinecartRideable"; 374 break; 375 } 376 } 377 else 378 { 379 _type = L"MinecartRideable"; 380 } 381 } 382 383 this->tag = tag; 384 this->type = _type; 385} 386 387BaseMobSpawner::SpawnData::~SpawnData() 388{ 389 delete tag; 390} 391 392CompoundTag *BaseMobSpawner::SpawnData::save() 393{ 394 CompoundTag *result = new CompoundTag(); 395 396 result->putCompound(L"Properties", tag); 397 result->putString(L"Type", type); 398 result->putInt(L"Weight", randomWeight); 399 400 return result; 401}