Entity.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. #include "Entity.h"
  2. #include <Globals.h>
  3. #include <math.h>
  4. #include "Game.h"
  5. #include "Globals.h"
  6. Entity::Entity(const EntityType* zType,
  7. Framework::Model3DData* model,
  8. Framework::Model3DTextur* texture,
  9. int id,
  10. Framework::Vec3<float> position,
  11. float maxMovementSpeed,
  12. float gravityMultiplier,
  13. float jumpSpeed,
  14. float size)
  15. : FactoryCraftModel(),
  16. id(id),
  17. zType(zType),
  18. playerControlled(0),
  19. maxMovementSpeed(maxMovementSpeed),
  20. lastFlags(0),
  21. timeSinceSync(0),
  22. gravityMultiplier(gravityMultiplier),
  23. jumpSpeed(jumpSpeed),
  24. speed(0, 0, 0)
  25. {
  26. pos = position;
  27. setModelDaten(model);
  28. setModelTextur(texture);
  29. lastDirection = World::INSTANCE->zKamera()->getDirection();
  30. currentFrame.duration = 0;
  31. rend = 1;
  32. lastFlags = 0;
  33. setSize(size);
  34. }
  35. Entity::~Entity() {}
  36. void Entity::api(char* message)
  37. {
  38. switch (message[0])
  39. {
  40. case 0:
  41. { // add movement frame
  42. MovementFrame frame;
  43. frame.direction.x = *(float*)(message += 1);
  44. frame.direction.y = *(float*)(message += 4);
  45. frame.direction.z = *(float*)(message += 4);
  46. frame.targetPosition.x = *(float*)(message += 4);
  47. frame.targetPosition.y = *(float*)(message += 4);
  48. frame.targetPosition.z = *(float*)(message += 4);
  49. frame.movementFlags = *(int*)(message += 4);
  50. frame.duration = *(double*)(message += 4);
  51. Vec2<float> norm = {0, -1};
  52. this->setDrehungZ((frame.direction.x < 0 ? -1 : 1)
  53. * norm.angle(Vec2<float>(
  54. frame.direction.x, frame.direction.y)));
  55. if (!playerControlled)
  56. {
  57. cs.lock();
  58. movements.add(frame);
  59. cs.unlock();
  60. }
  61. break;
  62. }
  63. case 1:
  64. { // position correction
  65. if (playerControlled)
  66. {
  67. timeSinceSync = 0;
  68. pos.x = *(float*)(message += 1);
  69. pos.y = *(float*)(message += 4);
  70. pos.z = *(float*)(message += 4);
  71. lastDirection = World::INSTANCE->zKamera()->getDirection();
  72. lastFlags = 0;
  73. }
  74. break;
  75. }
  76. }
  77. }
  78. bool Entity::tick(double time)
  79. {
  80. if (!World::INSTANCE || !World::INSTANCE->zKamera()) return 0;
  81. if (playerControlled && GetForegroundWindow() == window->getFensterHandle())
  82. {
  83. bool chunkLoaded = 1;
  84. if (!World::INSTANCE->zChunk(
  85. World::INSTANCE->getChunkCenter((int)pos.x, (int)pos.y)))
  86. {
  87. chunkLoaded = 0;
  88. }
  89. Vec3<float> direction = World::INSTANCE->zKamera()->getDirection();
  90. Vec3<float> lastPos = pos;
  91. int flags = 0;
  92. if ((lastFlags | MOVEMENT_FLAG_JUMP) != lastFlags
  93. && (speed.z == 0.f || (lastFlags | MOVEMENT_FLAG_FLY) == lastFlags))
  94. { // not jumping and not falling
  95. speed = {0, 0, speed.z};
  96. if (GetKeyState('w') & 0x8000 || GetKeyState('W') & 0x8000)
  97. {
  98. flags |= MOVEMENT_FLAG_FORWARD;
  99. speed += {direction.x, direction.y, 0};
  100. }
  101. if (GetKeyState('a') & 0x8000 || GetKeyState('A') & 0x8000)
  102. {
  103. flags |= MOVEMENT_FLAG_LEFT;
  104. Vec2<float> norm = {direction.x, direction.y};
  105. norm.CCW90().normalize();
  106. speed += {norm.x, norm.y, 0};
  107. }
  108. if (GetKeyState('s') & 0x8000 || GetKeyState('S') & 0x8000)
  109. {
  110. flags |= MOVEMENT_FLAG_BACKWARD;
  111. speed += {-direction.x, -direction.y, 0};
  112. }
  113. if (GetKeyState('d') & 0x8000 || GetKeyState('D') & 0x8000)
  114. {
  115. flags |= MOVEMENT_FLAG_RIGHT;
  116. Vec2<float> norm = {direction.x, direction.y};
  117. norm.CW90().normalize();
  118. speed += {norm.x, norm.y, 0};
  119. }
  120. }
  121. else
  122. {
  123. speed = {speed.x, speed.y, speed.z};
  124. }
  125. if ((lastFlags | MOVEMENT_FLAG_FLY) == lastFlags)
  126. { // fly mode
  127. flags |= MOVEMENT_FLAG_FLY;
  128. if (GetKeyState(T_Shift) & 0x8000)
  129. {
  130. if (getTastenStand(T_Strg))
  131. { // end fly
  132. flags &= ~MOVEMENT_FLAG_FLY;
  133. speed.z = 0;
  134. }
  135. else
  136. {
  137. flags |= MOVEMENT_FLAG_DOWN;
  138. speed.z = -maxMovementSpeed;
  139. }
  140. }
  141. else if (GetKeyState(T_Space) & 0x8000)
  142. {
  143. flags |= MOVEMENT_FLAG_UP;
  144. speed.z = maxMovementSpeed;
  145. }
  146. else
  147. {
  148. speed.z = 0;
  149. }
  150. }
  151. else
  152. { // walk mode
  153. if (GetKeyState(T_Space) & 0x8000)
  154. {
  155. if (getTastenStand(T_Strg))
  156. { // begin fly
  157. flags |= MOVEMENT_FLAG_FLY;
  158. speed.z = 0;
  159. }
  160. else if ((flags | MOVEMENT_FLAG_JUMP) != lastFlags
  161. && speed.z == 0.f)
  162. { // begin jump
  163. flags |= MOVEMENT_FLAG_JUMP;
  164. speed.z = jumpSpeed;
  165. }
  166. }
  167. if ((flags | MOVEMENT_FLAG_JUMP) == lastFlags
  168. && (flags | MOVEMENT_FLAG_FLY) != flags)
  169. {
  170. flags |= MOVEMENT_FLAG_JUMP; // keep jumping
  171. }
  172. }
  173. Vec2<float> norm = {speed.x, speed.y};
  174. if (norm.getLengthSq() != 0)
  175. {
  176. norm.normalize();
  177. speed.x = norm.x * maxMovementSpeed;
  178. speed.y = norm.y * maxMovementSpeed;
  179. }
  180. if ((flags | MOVEMENT_FLAG_FLY) != flags)
  181. {
  182. if (chunkLoaded)
  183. {
  184. speed.z -= World::INSTANCE->zDimension()->getGravity()
  185. * gravityMultiplier * (float)time;
  186. }
  187. }
  188. // collision checking
  189. Vec3<float> minP = model->getMinPos();
  190. Vec3<float> maxP = model->getMaxPos();
  191. Vec3<float> worldBoundingBox[8];
  192. worldBoundingBox[0] = applyWorldTransformation(minP);
  193. worldBoundingBox[1]
  194. = applyWorldTransformation({minP.x, minP.y, maxP.z});
  195. worldBoundingBox[2]
  196. = applyWorldTransformation({minP.x, maxP.y, minP.z});
  197. worldBoundingBox[3]
  198. = applyWorldTransformation({maxP.x, minP.y, minP.z});
  199. worldBoundingBox[4]
  200. = applyWorldTransformation({maxP.x, minP.y, maxP.z});
  201. worldBoundingBox[5]
  202. = applyWorldTransformation({maxP.x, maxP.y, minP.z});
  203. worldBoundingBox[6]
  204. = applyWorldTransformation({minP.x, maxP.y, maxP.z});
  205. worldBoundingBox[7] = applyWorldTransformation(maxP);
  206. Vec3<float> worldBoundingBoxFloor[8];
  207. for (int i = 0; i < 8; i++)
  208. {
  209. worldBoundingBoxFloor[i] = Vec3<float>(floor(worldBoundingBox[i].x),
  210. floor(worldBoundingBox[i].y),
  211. floor(worldBoundingBox[i].z));
  212. }
  213. Vec3<float> frameSpeed = speed * (float)time;
  214. bool hasCollided = 0;
  215. for (int m = 0; m < 20; m++)
  216. {
  217. float tf = 1.f;
  218. int collType = 0;
  219. int updateType = 0;
  220. int updateI = 0;
  221. if (frameSpeed.x > 0)
  222. {
  223. for (int i = 0; i < 8; i++)
  224. {
  225. if (abs(frameSpeed.x) >= abs(worldBoundingBoxFloor[i].x
  226. + 1.f - worldBoundingBox[i].x))
  227. {
  228. float xt = (worldBoundingBoxFloor[i].x + 1.f
  229. - worldBoundingBox[i].x)
  230. / frameSpeed.x;
  231. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
  232. if (tmp.y >= worldBoundingBoxFloor[i].y
  233. && tmp.y < worldBoundingBoxFloor[i].y + 1.f
  234. && tmp.z >= worldBoundingBoxFloor[i].z
  235. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  236. {
  237. Block* b = World::INSTANCE->zBlockAt(
  238. Vec3<int>{(int)worldBoundingBoxFloor[i].x + 1,
  239. (int)worldBoundingBoxFloor[i].y,
  240. (int)worldBoundingBoxFloor[i].z});
  241. if (b) // TODO: ignore passable blocks
  242. {
  243. if (xt < tf)
  244. {
  245. tf = xt;
  246. collType = 1;
  247. updateType = 0;
  248. }
  249. hasCollided = 1;
  250. }
  251. else
  252. {
  253. if (xt < tf)
  254. {
  255. tf = xt;
  256. collType = 0;
  257. updateType = 1;
  258. updateI = i;
  259. }
  260. }
  261. }
  262. }
  263. }
  264. }
  265. if (frameSpeed.x < 0)
  266. {
  267. for (int i = 0; i < 8; i++)
  268. {
  269. if (abs(frameSpeed.x) >= abs(
  270. worldBoundingBoxFloor[i].x - worldBoundingBox[i].x))
  271. {
  272. float xt = (worldBoundingBoxFloor[i].x
  273. - worldBoundingBox[i].x)
  274. / frameSpeed.x;
  275. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
  276. if (tmp.y >= worldBoundingBoxFloor[i].y
  277. && tmp.y < worldBoundingBoxFloor[i].y + 1.f
  278. && tmp.z >= worldBoundingBoxFloor[i].z
  279. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  280. {
  281. Block* b = World::INSTANCE->zBlockAt(
  282. Vec3<int>{(int)worldBoundingBoxFloor[i].x - 1,
  283. (int)worldBoundingBoxFloor[i].y,
  284. (int)worldBoundingBoxFloor[i].z});
  285. if (b) // TODO: ignore passable blocks
  286. {
  287. if (xt < tf)
  288. {
  289. tf = xt;
  290. collType = 1;
  291. updateType = 0;
  292. }
  293. hasCollided = 1;
  294. }
  295. else
  296. {
  297. if (xt < tf)
  298. {
  299. tf = xt;
  300. collType = 0;
  301. updateType = 1;
  302. updateI = i;
  303. }
  304. }
  305. }
  306. }
  307. }
  308. }
  309. if (frameSpeed.y > 0)
  310. {
  311. for (int i = 0; i < 8; i++)
  312. {
  313. if (abs(frameSpeed.y) >= abs(worldBoundingBoxFloor[i].y
  314. + 1.f - worldBoundingBox[i].y))
  315. {
  316. float yt = (worldBoundingBoxFloor[i].y + 1.f
  317. - worldBoundingBox[i].y)
  318. / frameSpeed.y;
  319. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
  320. if (tmp.x >= worldBoundingBoxFloor[i].x
  321. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  322. && tmp.z >= worldBoundingBoxFloor[i].z
  323. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  324. {
  325. Block* b = World::INSTANCE->zBlockAt(
  326. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  327. (int)worldBoundingBoxFloor[i].y + 1,
  328. (int)worldBoundingBoxFloor[i].z});
  329. if (b) // TODO: ignore passable blocks
  330. {
  331. if (yt < tf)
  332. {
  333. tf = yt;
  334. collType = 2;
  335. updateType = 0;
  336. }
  337. hasCollided = 1;
  338. }
  339. else
  340. {
  341. if (yt < tf)
  342. {
  343. tf = yt;
  344. collType = 0;
  345. updateType = 2;
  346. updateI = i;
  347. }
  348. }
  349. }
  350. }
  351. }
  352. }
  353. if (frameSpeed.y < 0)
  354. {
  355. for (int i = 0; i < 8; i++)
  356. {
  357. if (abs(frameSpeed.y) >= abs(
  358. worldBoundingBoxFloor[i].y - worldBoundingBox[i].y))
  359. {
  360. float yt = (worldBoundingBoxFloor[i].y
  361. - worldBoundingBox[i].y)
  362. / frameSpeed.y;
  363. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
  364. if (tmp.x >= worldBoundingBoxFloor[i].x
  365. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  366. && tmp.z >= worldBoundingBoxFloor[i].z
  367. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  368. {
  369. Block* b = World::INSTANCE->zBlockAt(
  370. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  371. (int)worldBoundingBoxFloor[i].y - 1,
  372. (int)worldBoundingBoxFloor[i].z});
  373. if (b) // TODO: ignore passable blocks
  374. {
  375. if (yt < tf)
  376. {
  377. tf = yt;
  378. collType = 2;
  379. updateType = 0;
  380. }
  381. hasCollided = 1;
  382. }
  383. else
  384. {
  385. if (yt < tf)
  386. {
  387. tf = yt;
  388. collType = 0;
  389. updateType = 2;
  390. updateI = i;
  391. }
  392. }
  393. }
  394. }
  395. }
  396. }
  397. if (frameSpeed.z > 0)
  398. {
  399. for (int i = 0; i < 8; i++)
  400. {
  401. if (abs(frameSpeed.z) >= abs(worldBoundingBoxFloor[i].z
  402. + 1.f - worldBoundingBox[i].z))
  403. {
  404. float zt = (worldBoundingBoxFloor[i].z + 1.f
  405. - worldBoundingBox[i].z)
  406. / frameSpeed.z;
  407. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
  408. if (zt <= 1.f && tmp.x >= worldBoundingBoxFloor[i].x
  409. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  410. && tmp.y >= worldBoundingBoxFloor[i].y
  411. && tmp.y < worldBoundingBoxFloor[i].y + 1.f)
  412. {
  413. Block* b = World::INSTANCE->zBlockAt(
  414. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  415. (int)worldBoundingBoxFloor[i].y,
  416. (int)worldBoundingBoxFloor[i].z + 1});
  417. if (b) // TODO: ignore passable blocks
  418. {
  419. if (zt < tf)
  420. {
  421. tf = zt;
  422. collType = 3;
  423. }
  424. hasCollided = 1;
  425. }
  426. else
  427. {
  428. if (zt < tf)
  429. {
  430. tf = zt;
  431. collType = 0;
  432. updateType = 3;
  433. updateI = i;
  434. }
  435. }
  436. }
  437. }
  438. }
  439. }
  440. if (frameSpeed.z < 0)
  441. {
  442. for (int i = 0; i < 8; i++)
  443. {
  444. if (abs(frameSpeed.z) >= abs(
  445. worldBoundingBoxFloor[i].z - worldBoundingBox[i].z))
  446. {
  447. float zt = (worldBoundingBoxFloor[i].z
  448. - worldBoundingBox[i].z)
  449. / frameSpeed.z;
  450. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
  451. if (tmp.x >= worldBoundingBoxFloor[i].x
  452. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  453. && tmp.y >= worldBoundingBoxFloor[i].y
  454. && tmp.y < worldBoundingBoxFloor[i].y + 1)
  455. {
  456. Block* b = World::INSTANCE->zBlockAt(
  457. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  458. (int)worldBoundingBoxFloor[i].y,
  459. (int)worldBoundingBoxFloor[i].z - 1});
  460. if (b) // TODO: ignore passable blocks
  461. {
  462. if (zt < tf)
  463. {
  464. tf = zt;
  465. collType = 3;
  466. updateType = 0;
  467. }
  468. hasCollided = 1;
  469. }
  470. else
  471. {
  472. if (zt < tf)
  473. {
  474. tf = zt;
  475. collType = 0;
  476. updateType = 3;
  477. updateI = i;
  478. }
  479. }
  480. }
  481. }
  482. }
  483. }
  484. if (collType == 1)
  485. frameSpeed.x = tf > 0.1f ? frameSpeed.x * (tf - 0.1f) : 0.f;
  486. if (collType == 2)
  487. frameSpeed.y = tf > 0.1f ? frameSpeed.y * (tf - 0.1f) : 0.f;
  488. if (collType == 3)
  489. {
  490. frameSpeed.z = tf > 0.1f ? frameSpeed.z * (tf - 0.1f) : 0.f;
  491. if (speed.z < 0)
  492. {
  493. flags &= ~MOVEMENT_FLAG_JUMP;
  494. if (-speed.z > 2)
  495. {
  496. char message[5];
  497. message[0] = 10;
  498. *(float*)(message + 1) = -speed.z;
  499. World::INSTANCE->zClient()->sendPlayerAction(
  500. message, 5);
  501. }
  502. }
  503. speed.z = 0;
  504. }
  505. if (updateType == 1)
  506. {
  507. if ((int)worldBoundingBoxFloor[updateI].x
  508. <= (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
  509. worldBoundingBoxFloor[updateI].x++;
  510. if ((int)worldBoundingBoxFloor[updateI].x
  511. > (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
  512. worldBoundingBoxFloor[updateI].x--;
  513. }
  514. if (updateType == 2)
  515. {
  516. if ((int)worldBoundingBoxFloor[updateI].y
  517. <= (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
  518. worldBoundingBoxFloor[updateI].y++;
  519. if ((int)worldBoundingBoxFloor[updateI].y
  520. > (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
  521. worldBoundingBoxFloor[updateI].y--;
  522. }
  523. if (updateType == 3)
  524. {
  525. if ((int)worldBoundingBoxFloor[updateI].z
  526. <= (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
  527. worldBoundingBoxFloor[updateI].z++;
  528. if ((int)worldBoundingBoxFloor[updateI].z
  529. > (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
  530. worldBoundingBoxFloor[updateI].z--;
  531. }
  532. if (updateType || collType) continue;
  533. break;
  534. }
  535. pos += frameSpeed;
  536. World::INSTANCE->zKamera()->setPosition(
  537. pos + Vec3<float>(0.f, 0.f, 1.5f));
  538. Model3D* target = World::INSTANCE->getCurrentTarget();
  539. Block* b = target ? dynamic_cast<Block*>(target) : 0;
  540. ((Game*)(Menu*)menuRegister->get("game"))
  541. ->updatePosition(
  542. pos, b != 0, b ? b->getLocation() : Vec3<int>(0, 0, 0));
  543. if (target) target->release();
  544. if (flags != lastFlags || direction != lastDirection
  545. || timeSinceSync >= 1 || hasCollided)
  546. {
  547. if (timeSinceSync > 0)
  548. {
  549. MovementFrame frame;
  550. frame.direction = lastDirection;
  551. frame.targetPosition = lastPos;
  552. frame.movementFlags = lastFlags;
  553. frame.duration = timeSinceSync;
  554. World::INSTANCE->zClient()->sendPlayerMovement(frame);
  555. }
  556. lastFlags = flags;
  557. lastDirection = direction;
  558. timeSinceSync = 0;
  559. }
  560. timeSinceSync += time;
  561. rend = 1;
  562. }
  563. else
  564. {
  565. double totalTime = time;
  566. while (totalTime > 0)
  567. {
  568. if (currentFrame.duration <= 0)
  569. {
  570. if (movements.getEintragAnzahl() > 0)
  571. {
  572. currentFrame = movements.get(0);
  573. cs.lock();
  574. movements.remove(0);
  575. cs.unlock();
  576. }
  577. else
  578. {
  579. break;
  580. }
  581. }
  582. double t = min(currentFrame.duration, totalTime);
  583. pos += (currentFrame.targetPosition - pos)
  584. * (float)(t / currentFrame.duration);
  585. currentFrame.duration -= t;
  586. totalTime -= t;
  587. if (currentFrame.duration <= 0)
  588. {
  589. pos = currentFrame.targetPosition;
  590. }
  591. rend = 1;
  592. }
  593. }
  594. return Model3D::tick(time);
  595. }
  596. int Entity::getId() const
  597. {
  598. return id;
  599. }
  600. const EntityType* Entity::zEntityType() const
  601. {
  602. return zType;
  603. }
  604. void Entity::lock()
  605. {
  606. cs.lock();
  607. }
  608. void Entity::unlock()
  609. {
  610. cs.unlock();
  611. }
  612. void Entity::setPlayerControlled()
  613. {
  614. playerControlled = 1;
  615. World::INSTANCE->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
  616. }