the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 512 lines 13 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.entity.ai.village.h" 3#include "net.minecraft.world.entity.npc.h" 4#include "net.minecraft.world.entity.animal.h" 5#include "net.minecraft.world.level.h" 6#include "net.minecraft.world.level.tile.h" 7#include "net.minecraft.world.phys.h" 8#include "BasicTypeContainers.h" 9#include "Village.h" 10 11Village::Aggressor::Aggressor(shared_ptr<LivingEntity> mob, int timeStamp) 12{ 13 this->mob = mob; 14 this->timeStamp = timeStamp; 15} 16 17Village::Village() 18{ 19 accCenter = new Pos(0, 0, 0); 20 center = new Pos(0, 0, 0); 21 radius = 0; 22 stableSince = 0; 23 _tick = 0; 24 populationSize = 0; 25 golemCount = 0; 26 noBreedTimer = 0; 27 28 level = NULL; 29} 30 31Village::Village(Level *level) 32{ 33 accCenter = new Pos(0, 0, 0); 34 center = new Pos(0, 0, 0); 35 radius = 0; 36 stableSince = 0; 37 _tick = 0; 38 populationSize = 0; 39 golemCount = 0; 40 noBreedTimer = 0; 41 42 this->level = level; 43} 44 45Village::~Village() 46{ 47 delete accCenter; 48 delete center; 49 for(AUTO_VAR(it, aggressors.begin()); it != aggressors.end(); ++it) 50 { 51 delete *it; 52 } 53} 54 55void Village::setLevel(Level *level) 56{ 57 this->level = level; 58} 59 60void Village::tick(int tick) 61{ 62 this->_tick = tick; 63 updateDoors(); 64 updateAggressors(); 65 if (tick % 20 == 0) countPopulation(); 66 if (tick % 30 == 0) countGolem(); 67 68 int idealGolemCount = populationSize / 10; 69 if (golemCount < idealGolemCount && doorInfos.size() > 20 && level->random->nextInt(7000) == 0) 70 { 71 Vec3 *spawnPos = findRandomSpawnPos(center->x, center->y, center->z, 2, 4, 2); 72 if (spawnPos != NULL) 73 { 74 shared_ptr<VillagerGolem> vg = shared_ptr<VillagerGolem>( new VillagerGolem(level) ); 75 vg->setPos(spawnPos->x, spawnPos->y, spawnPos->z); 76 level->addEntity(vg); 77 ++golemCount; 78 } 79 } 80 81 // 4J - All commented out in java 82 // for (DoorInfo di : doorInfos) { 83 // level.addParticle("heart", di.getIndoorX() + 0.5, di.getIndoorY() + .5f, di.getIndoorZ() + 0.5, 0, 1, 0); 84 // } 85 // 86 // for (int i = 0; i < 8; ++i) 87 // for (int j = 0; j < 8; ++j) 88 // level.addParticle("heart", center.x + 0.5 + i, center.y + .5f, center.z + 0.5 + j, 0, 1, 0); 89 // for (float i = 0; i < Math.PI * 2; i += 0.1) { 90 // int x = center.x + (int) (Math.cos(i) * radius); 91 // int z = center.z + (int) (Math.sin(i) * radius); 92 // level.addParticle("heart", x, center.y + .5f, z, 0, 1, 0); 93 // } 94} 95 96Vec3 *Village::findRandomSpawnPos(int x, int y, int z, int sx, int sy, int sz) 97{ 98 for (int i = 0; i < 10; ++i) 99 { 100 int xx = x + level->random->nextInt(16) - 8; 101 int yy = y + level->random->nextInt(6) - 3; 102 int zz = z + level->random->nextInt(16) - 8; 103 if (!isInside(xx, yy, zz)) continue; 104 if (canSpawnAt(xx, yy, zz, sx, sy, sz)) return Vec3::newTemp(xx, yy, zz); 105 } 106 return NULL; 107} 108 109bool Village::canSpawnAt(int x, int y, int z, int sx, int sy, int sz) 110{ 111 if (!level->isTopSolidBlocking(x, y - 1, z)) return false; 112 113 int startX = x - sx / 2; 114 int startZ = z - sz / 2; 115 for (int xx = startX; xx < startX + sx; xx++) 116 for (int yy = y; yy < y + sy; yy++) 117 for (int zz = startZ; zz < startZ + sz; zz++) 118 if (level->isSolidBlockingTile(xx, yy, zz)) return false; 119 120 return true; 121} 122 123void Village::countGolem() 124{ 125 // Fix - let bots report themselves? 126 vector<shared_ptr<Entity> > *golems = level->getEntitiesOfClass(typeid(VillagerGolem), AABB::newTemp(center->x - radius, center->y - 4, center->z - radius, center->x + radius, center->y + 4, center->z + radius)); 127 golemCount = golems->size(); 128 delete golems; 129} 130 131void Village::countPopulation() 132{ 133 vector<shared_ptr<Entity> > *villagers = level->getEntitiesOfClass(typeid(Villager), AABB::newTemp(center->x - radius, center->y - 4, center->z - radius, center->x + radius, center->y + 4, center->z + radius)); 134 populationSize = villagers->size(); 135 delete villagers; 136 137 if (populationSize == 0) 138 { 139 // forget standing 140 playerStanding.clear(); 141 } 142} 143 144Pos *Village::getCenter() 145{ 146 return center; 147} 148 149int Village::getRadius() 150{ 151 return radius; 152} 153 154int Village::getDoorCount() 155{ 156 return doorInfos.size(); 157} 158 159int Village::getStableAge() 160{ 161 return _tick - stableSince; 162} 163 164int Village::getPopulationSize() 165{ 166 return populationSize; 167} 168 169bool Village::isInside(int xx, int yy, int zz) 170{ 171 return center->distSqr(xx, yy, zz) < radius * radius; 172} 173 174vector<shared_ptr<DoorInfo> > *Village::getDoorInfos() 175{ 176 return &doorInfos; 177} 178 179shared_ptr<DoorInfo> Village::getClosestDoorInfo(int x, int y, int z) 180{ 181 shared_ptr<DoorInfo> closest = nullptr; 182 int closestDistSqr = Integer::MAX_VALUE; 183 //for (DoorInfo dm : doorInfos) 184 for(AUTO_VAR(it, doorInfos.begin()); it != doorInfos.end(); ++it) 185 { 186 shared_ptr<DoorInfo> dm = *it; 187 int distSqr = dm->distanceToSqr(x, y, z); 188 if (distSqr < closestDistSqr) 189 { 190 closest = dm; 191 closestDistSqr = distSqr; 192 } 193 } 194 return closest; 195} 196 197shared_ptr<DoorInfo>Village::getBestDoorInfo(int x, int y, int z) 198{ 199 shared_ptr<DoorInfo> closest = nullptr; 200 int closestDist = Integer::MAX_VALUE; 201 //for (DoorInfo dm : doorInfos) 202 for(AUTO_VAR(it, doorInfos.begin()); it != doorInfos.end(); ++it) 203 { 204 shared_ptr<DoorInfo>dm = *it; 205 206 int distSqr = dm->distanceToSqr(x, y, z); 207 if (distSqr > 16 * 16) distSqr *= 1000; 208 else distSqr = dm->getBookingsCount(); 209 210 if (distSqr < closestDist) 211 { 212 closest = dm; 213 closestDist = distSqr; 214 } 215 } 216 return closest; 217} 218 219bool Village::hasDoorInfo(int x, int y, int z) 220{ 221 return getDoorInfo(x, y, z) != NULL; 222} 223 224shared_ptr<DoorInfo>Village::getDoorInfo(int x, int y, int z) 225{ 226 if (center->distSqr(x, y, z) > radius * radius) return nullptr; 227 //for (DoorInfo di : doorInfos) 228 for(AUTO_VAR(it, doorInfos.begin()); it != doorInfos.end(); ++it) 229 { 230 shared_ptr<DoorInfo> di = *it; 231 if (di->x == x && di->z == z && abs(di->y - y) <= 1) return di; 232 } 233 return nullptr; 234} 235 236void Village::addDoorInfo(shared_ptr<DoorInfo> di) 237{ 238 doorInfos.push_back(di); 239 accCenter->x += di->x; 240 accCenter->y += di->y; 241 accCenter->z += di->z; 242 calcInfo(); 243 stableSince = di->timeStamp; 244} 245 246bool Village::canRemove() 247{ 248 return doorInfos.empty(); 249} 250 251void Village::addAggressor(shared_ptr<LivingEntity> mob) 252{ 253 //for (Aggressor a : aggressors) 254 for(AUTO_VAR(it, aggressors.begin()); it != aggressors.end(); ++it) 255 { 256 Aggressor *a = *it; 257 if (a->mob == mob) 258 { 259 a->timeStamp = _tick; 260 return; 261 } 262 } 263 aggressors.push_back(new Aggressor(mob, _tick)); 264} 265 266shared_ptr<LivingEntity> Village::getClosestAggressor(shared_ptr<LivingEntity> from) 267{ 268 double closestSqr = Double::MAX_VALUE; 269 Aggressor *closest = NULL; 270 //for (int i = 0; i < aggressors.size(); ++i) 271 for(AUTO_VAR(it, aggressors.begin()); it != aggressors.end(); ++it) 272 { 273 Aggressor *a = *it; //aggressors.get(i); 274 double distSqr = a->mob->distanceToSqr(from); 275 if (distSqr > closestSqr) continue; 276 closest = a; 277 closestSqr = distSqr; 278 } 279 return closest != NULL ? closest->mob : nullptr; 280} 281 282shared_ptr<Player> Village::getClosestBadStandingPlayer(shared_ptr<LivingEntity> from) 283{ 284 double closestSqr = Double::MAX_VALUE; 285 shared_ptr<Player> closest = nullptr; 286 287 //for (String player : playerStanding.keySet()) 288 for(AUTO_VAR(it,playerStanding.begin()); it != playerStanding.end(); ++it) 289 { 290 wstring player = it->first; 291 if (isVeryBadStanding(player)) 292 { 293 shared_ptr<Player> mob = level->getPlayerByName(player); 294 if (mob != NULL) 295 { 296 double distSqr = mob->distanceToSqr(from); 297 if (distSqr > closestSqr) continue; 298 closest = mob; 299 closestSqr = distSqr; 300 } 301 } 302 } 303 304 return closest; 305} 306 307void Village::updateAggressors() 308{ 309 //for (Iterator<Aggressor> it = aggressors.iterator(); it.hasNext();) 310 for(AUTO_VAR(it, aggressors.begin()); it != aggressors.end();) 311 { 312 Aggressor *a = *it; //it.next(); 313 if (!a->mob->isAlive() || abs(_tick - a->timeStamp) > 300) 314 { 315 delete *it; 316 it = aggressors.erase(it); 317 //it.remove(); 318 } 319 else 320 { 321 ++it; 322 } 323 } 324} 325 326void Village::updateDoors() 327{ 328 bool removed = false; 329 bool resetBookings = level->random->nextInt(50) == 0; 330 //for (Iterator<DoorInfo> it = doorInfos.iterator(); it.hasNext();) 331 for(AUTO_VAR(it, doorInfos.begin()); it != doorInfos.end();) 332 { 333 shared_ptr<DoorInfo> dm = *it; //it.next(); 334 if (resetBookings) dm->resetBookingCount(); 335 if (!isDoor(dm->x, dm->y, dm->z) || abs(_tick - dm->timeStamp) > 1200) 336 { 337 accCenter->x -= dm->x; 338 accCenter->y -= dm->y; 339 accCenter->z -= dm->z; 340 removed = true; 341 dm->removed = true; 342 343 it = doorInfos.erase(it); 344 //it.remove(); 345 } 346 else 347 { 348 ++it; 349 } 350 } 351 352 if (removed) calcInfo(); 353} 354 355bool Village::isDoor(int x, int y, int z) 356{ 357 int tileId = level->getTile(x, y, z); 358 if (tileId <= 0) return false; 359 return tileId == Tile::door_wood_Id; 360} 361 362void Village::calcInfo() 363{ 364 int s = doorInfos.size(); 365 if (s == 0) 366 { 367 center->set(0, 0, 0); 368 radius = 0; 369 return; 370 } 371 center->set(accCenter->x / s, accCenter->y / s, accCenter->z / s); 372 int maxRadiusSqr = 0; 373 //for (DoorInfo dm : doorInfos) 374 for(AUTO_VAR(it, doorInfos.begin()); it != doorInfos.end(); ++it) 375 { 376 shared_ptr<DoorInfo> dm = *it; 377 maxRadiusSqr = max(dm->distanceToSqr(center->x, center->y, center->z), maxRadiusSqr); 378 } 379 int doorDist= Villages::MaxDoorDist; // Take into local int for PS4 as max takes a reference to the const int there and then needs the value to exist for the linker 380 radius = max(doorDist, (int) sqrt((float)maxRadiusSqr) + 1); 381} 382 383int Village::getStanding(const wstring &playerName) 384{ 385 AUTO_VAR(it,playerStanding.find(playerName)); 386 if (it != playerStanding.end()) 387 { 388 return it->second; 389 } 390 return 0; 391} 392 393int Village::modifyStanding(const wstring &playerName, int delta) 394{ 395 int current = getStanding(playerName); 396 int newValue = Mth::clamp(current + delta, -30, 10); 397 playerStanding.insert(pair<wstring,int>(playerName, newValue)); 398 return newValue; 399} 400 401bool Village::isGoodStanding(const wstring &playerName) 402{ 403 return getStanding(playerName) >= 0; 404} 405 406bool Village::isBadStanding(const wstring &playerName) 407{ 408 return getStanding(playerName) <= -5; 409} 410 411bool Village::isVeryBadStanding(const wstring playerName) 412{ 413 return getStanding(playerName) <= -15; 414} 415 416void Village::readAdditionalSaveData(CompoundTag *tag) 417{ 418 populationSize = tag->getInt(L"PopSize"); 419 radius = tag->getInt(L"Radius"); 420 golemCount = tag->getInt(L"Golems"); 421 stableSince = tag->getInt(L"Stable"); 422 _tick = tag->getInt(L"Tick"); 423 noBreedTimer = tag->getInt(L"MTick"); 424 center->x = tag->getInt(L"CX"); 425 center->y = tag->getInt(L"CY"); 426 center->z = tag->getInt(L"CZ"); 427 accCenter->x = tag->getInt(L"ACX"); 428 accCenter->y = tag->getInt(L"ACY"); 429 accCenter->z = tag->getInt(L"ACZ"); 430 431 ListTag<CompoundTag> *doorTags = (ListTag<CompoundTag> *) tag->getList(L"Doors"); 432 for (int i = 0; i < doorTags->size(); i++) 433 { 434 CompoundTag *dTag = doorTags->get(i); 435 436 shared_ptr<DoorInfo> door = shared_ptr<DoorInfo>(new DoorInfo(dTag->getInt(L"X"), dTag->getInt(L"Y"), dTag->getInt(L"Z"), dTag->getInt(L"IDX"), dTag->getInt(L"IDZ"), dTag->getInt(L"TS"))); 437 doorInfos.push_back(door); 438 } 439 440 ListTag<CompoundTag> *playerTags = (ListTag<CompoundTag> *) tag->getList(L"Players"); 441 for (int i = 0; i < playerTags->size(); i++) 442 { 443 CompoundTag *pTag = playerTags->get(i); 444 playerStanding.insert(pair<wstring,int>(pTag->getString(L"Name"), pTag->getInt(L"S"))); 445 } 446} 447 448void Village::addAdditonalSaveData(CompoundTag *tag) 449{ 450 tag->putInt(L"PopSize", populationSize); 451 tag->putInt(L"Radius", radius); 452 tag->putInt(L"Golems", golemCount); 453 tag->putInt(L"Stable", stableSince); 454 tag->putInt(L"Tick", _tick); 455 tag->putInt(L"MTick", noBreedTimer); 456 tag->putInt(L"CX", center->x); 457 tag->putInt(L"CY", center->y); 458 tag->putInt(L"CZ", center->z); 459 tag->putInt(L"ACX", accCenter->x); 460 tag->putInt(L"ACY", accCenter->y); 461 tag->putInt(L"ACZ", accCenter->z); 462 463 ListTag<CompoundTag> *doorTags = new ListTag<CompoundTag>(L"Doors"); 464 //for (DoorInfo dm : doorInfos) 465 for(AUTO_VAR(it,doorInfos.begin()); it != doorInfos.end(); ++it) 466 { 467 shared_ptr<DoorInfo> dm = *it; 468 CompoundTag *doorTag = new CompoundTag(L"Door"); 469 doorTag->putInt(L"X", dm->x); 470 doorTag->putInt(L"Y", dm->y); 471 doorTag->putInt(L"Z", dm->z); 472 doorTag->putInt(L"IDX", dm->insideDx); 473 doorTag->putInt(L"IDZ", dm->insideDz); 474 doorTag->putInt(L"TS", dm->timeStamp); 475 doorTags->add(doorTag); 476 } 477 tag->put(L"Doors", doorTags); 478 479 ListTag<CompoundTag> *playerTags = new ListTag<CompoundTag>(L"Players"); 480 //for (String player : playerStanding.keySet()) 481 for(AUTO_VAR(it, playerStanding.begin()); it != playerStanding.end(); ++it) 482 { 483 wstring player = it->first; 484 CompoundTag *playerTag = new CompoundTag(player); 485 playerTag->putString(L"Name", player); 486 playerTag->putInt(L"S", it->second); 487 playerTags->add(playerTag); 488 } 489 tag->put(L"Players", playerTags); 490 491} 492 493void Village::resetNoBreedTimer() 494{ 495 noBreedTimer = _tick; 496} 497 498bool Village::isBreedTimerOk() 499{ 500 // prevent new villagers if a villager was killed by a mob within 3 501 // minutes 502 return noBreedTimer == 0 || (_tick - noBreedTimer) >= (SharedConstants::TICKS_PER_SECOND * 60 * 3); 503} 504 505void Village::rewardAllPlayers(int amount) 506{ 507 //for (String player : playerStanding.keySet()) 508 for(AUTO_VAR(it, playerStanding.begin()); it != playerStanding.end(); ++it) 509 { 510 modifyStanding(it->first, amount); 511 } 512}