World.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. Vector3 move = limitMove(*e, e->getVelocity());
  55. e->move(move);
  56. }
  57. }
  58. Vector3 World::limitMove(const Entity& e, Vector3 move) const {
  59. CollisionBox box = e.getCollisionBox();
  60. List<CollisionBox> boxes = getBoxes(box.expand(move));
  61. if(boxes.getLength() == 0) {
  62. return move;
  63. }
  64. Vector3 realMove;
  65. constexpr float step = 0.05f;
  66. while(move[0] != 0.0f || move[1] != 0.0f || move[2] != 0.0f) {
  67. Vector3 old = realMove;
  68. if(move[0] > step) {
  69. realMove[0] += step;
  70. move[0] -= step;
  71. } else if(move[0] < -step) {
  72. realMove[0] -= step;
  73. move[0] += step;
  74. } else if(move[0] != 0.0f) {
  75. realMove[0] += move[0];
  76. move[0] = 0.0f;
  77. }
  78. CollisionBox moved = box.offset(realMove);
  79. for(const CollisionBox& box : boxes) {
  80. if(box.collidesWith(moved)) {
  81. move[0] = 0.0f;
  82. realMove = old;
  83. break;
  84. }
  85. }
  86. old = realMove;
  87. if(move[1] > step) {
  88. realMove[1] += step;
  89. move[1] -= step;
  90. } else if(move[1] < -step) {
  91. realMove[1] -= step;
  92. move[1] += step;
  93. } else if(move[1] != 0.0f) {
  94. realMove[1] += move[1];
  95. move[1] = 0.0f;
  96. }
  97. moved = box.offset(realMove);
  98. for(const CollisionBox& box : boxes) {
  99. if(box.collidesWith(moved)) {
  100. move[1] = 0.0f;
  101. realMove = old;
  102. break;
  103. }
  104. }
  105. old = realMove;
  106. if(move[2] > step) {
  107. realMove[2] += step;
  108. move[2] -= step;
  109. } else if(move[2] < -step) {
  110. realMove[2] -= step;
  111. move[2] += step;
  112. } else if(move[2] != 0.0f) {
  113. realMove[2] += move[2];
  114. move[2] = 0.0f;
  115. }
  116. moved = box.offset(realMove);
  117. for(const CollisionBox& box : boxes) {
  118. if(box.collidesWith(moved)) {
  119. move[2] = 0.0f;
  120. realMove = old;
  121. break;
  122. }
  123. }
  124. }
  125. return realMove;
  126. }