Entity.cpp 24 KB

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