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