World.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <cmath>
  2. #include "common/world/HighMap.h"
  3. #include "common/world/World.h"
  4. #include "utils/Logger.h"
  5. #include "utils/Random.h"
  6. World::World(const BlockRegistry& blockRegistry)
  7. : blockRegistry(blockRegistry), blocks(7, 7), dirty(true) {
  8. }
  9. void World::setBlock(int x, int y, int z, const Block& block) {
  10. blocks.set(x, y, z, block.getId());
  11. }
  12. const Block& World::getBlock(int x, int y, int z) const {
  13. return blockRegistry.getBlock(blocks.get(x, y, z));
  14. }
  15. int World::getSize() const {
  16. return blocks.getSize();
  17. }
  18. int World::getHeight() const {
  19. return blocks.getHeight();
  20. }
  21. void World::addEntity(Entity* e) {
  22. entities.add(e);
  23. }
  24. void World::removeEntity(Entity* e) {
  25. for(int i = 0; i < entities.getLength(); i++) {
  26. if(entities[i] == e) {
  27. entities.removeBySwap(i);
  28. return;
  29. }
  30. }
  31. }
  32. List<CollisionBox> World::getBoxes(const CollisionBox& box) const {
  33. int minX = floorf(box.getMin()[0]);
  34. int minY = floorf(box.getMin()[1]);
  35. int minZ = floorf(box.getMin()[2]);
  36. int maxX = floorf(box.getMax()[0]);
  37. int maxY = floorf(box.getMax()[1]);
  38. int maxZ = floorf(box.getMax()[2]);
  39. List<CollisionBox> boxes;
  40. for(int x = minX; x <= maxX; x++) {
  41. for(int y = minY; y <= maxY; y++) {
  42. for(int z = minZ; z <= maxZ; z++) {
  43. getBlock(x, y, z).addBoxes(
  44. boxes, Vector3(static_cast<float>(x), static_cast<float>(y),
  45. static_cast<float>(z)));
  46. }
  47. }
  48. }
  49. return boxes;
  50. }
  51. void World::tick() {
  52. for(Entity* e : entities) {
  53. e->tick();
  54. if(!e->skip) {
  55. Vector3 move = limitMove(*e, e->getVelocity());
  56. e->move(move);
  57. }
  58. }
  59. }
  60. Vector3 World::limitMove(const Entity& e, Vector3 move) const {
  61. CollisionBox box = e.getCollisionBox();
  62. List<CollisionBox> boxes = getBoxes(box.expand(move));
  63. if(boxes.getLength() == 0) {
  64. return move;
  65. }
  66. Vector3 realMove;
  67. constexpr float step = 0.05f;
  68. while(move[0] != 0.0f || move[1] != 0.0f || move[2] != 0.0f) {
  69. Vector3 old = realMove;
  70. if(move[0] > step) {
  71. realMove[0] += step;
  72. move[0] -= step;
  73. } else if(move[0] < -step) {
  74. realMove[0] -= step;
  75. move[0] += step;
  76. } else if(move[0] != 0.0f) {
  77. realMove[0] += move[0];
  78. move[0] = 0.0f;
  79. }
  80. CollisionBox moved = box.offset(realMove);
  81. for(const CollisionBox& box : boxes) {
  82. if(box.collidesWith(moved)) {
  83. move[0] = 0.0f;
  84. realMove = old;
  85. break;
  86. }
  87. }
  88. old = realMove;
  89. if(move[1] > step) {
  90. realMove[1] += step;
  91. move[1] -= step;
  92. } else if(move[1] < -step) {
  93. realMove[1] -= step;
  94. move[1] += step;
  95. } else if(move[1] != 0.0f) {
  96. realMove[1] += move[1];
  97. move[1] = 0.0f;
  98. }
  99. moved = box.offset(realMove);
  100. for(const CollisionBox& box : boxes) {
  101. if(box.collidesWith(moved)) {
  102. move[1] = 0.0f;
  103. realMove = old;
  104. break;
  105. }
  106. }
  107. old = realMove;
  108. if(move[2] > step) {
  109. realMove[2] += step;
  110. move[2] -= step;
  111. } else if(move[2] < -step) {
  112. realMove[2] -= step;
  113. move[2] += step;
  114. } else if(move[2] != 0.0f) {
  115. realMove[2] += move[2];
  116. move[2] = 0.0f;
  117. }
  118. moved = box.offset(realMove);
  119. for(const CollisionBox& box : boxes) {
  120. if(box.collidesWith(moved)) {
  121. move[2] = 0.0f;
  122. realMove = old;
  123. break;
  124. }
  125. }
  126. }
  127. return realMove;
  128. }