Player.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #include "Player.h"
  2. #include "Game.h"
  3. #include "ItemFilter.h"
  4. #include "PlayerHand.h"
  5. #include "QuestDialog.h"
  6. Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
  7. : Entity(EntityTypeEnum::PLAYER, location, dimensionId, entityId),
  8. BasicShapedCrafter(3, 3, this, "inventory")
  9. {
  10. for (int i = 0; i < 10; i++)
  11. {
  12. ItemSlot* slot = new ItemSlot("ItemBar", 50, 0, i, 0, ANY_DIRECTION, 0);
  13. itemBar.add(slot);
  14. addSlot(slot);
  15. }
  16. for (int i = 0; i < 30; i++)
  17. {
  18. ItemSlot* slot
  19. = new ItemSlot("Inventory", 50, 0, i + 10, 0, ANY_DIRECTION, 0);
  20. addSlot(slot);
  21. }
  22. leftHandPosition = 0;
  23. maxHP = 10;
  24. maxStamina = 10;
  25. maxHunger = 10;
  26. maxThirst = 10;
  27. setHP(10);
  28. setStamina(10);
  29. setHunger(10);
  30. setThirst(10);
  31. keyState = 0;
  32. jumping = 0;
  33. faceOffset = {0.f, 0.f, 1.5f};
  34. targetDistanceLimit = 4;
  35. maxMovementSpeed = 4;
  36. }
  37. void Player::onTargetChange()
  38. {
  39. NetworkMessage* msg = new NetworkMessage();
  40. ActionTarget::toMessage(zTarget(), dimensionId, msg);
  41. Game::INSTANCE->sendMessage(msg, this);
  42. }
  43. Framework::Text Player::getInventoryUIML()
  44. {
  45. Framework::Text result
  46. = "<dialog id=\"player_inventory\" title=\"Inventory\" width=\"610\" "
  47. "height=\"450\">";
  48. result.append()
  49. << "<craftingGrid id=\"crafting\" margin-top=\"9\" "
  50. "align-top=\"start\" align-left=\"start\" margin-left=\"9\" "
  51. "width=\"282\" height=\"172\" rowSize=\"3\" colSize=\"3\" "
  52. "numOutputSlots=\"1\" target=\""
  53. << getId() << "\"/>"
  54. << "<inventory id=\"inventory\" margin-bottom=\"18\" "
  55. "align-bottom=\"item_bar\" align-left=\"start\" "
  56. "margin-left=\"9\" width=\"592\" height=\"172\" rowSize=\"10\" "
  57. "numSlots=\"30\" slotNameFilter=\"Inventory\" target=\""
  58. << getId() << "\"/>"
  59. << "<inventory id=\"item_bar\" margin-bottom=\"9\" "
  60. "align-bottom=\"end\" align-left=\"start\" margin-left=\"9\" "
  61. "width=\"592\" height=\"52\" rowSize=\"10\" numSlots=\"10\" "
  62. "slotNameFilter=\"ItemBar\" target=\""
  63. << getId() << "\"/>"
  64. << "</dialog>";
  65. return result;
  66. }
  67. Framework::Text Player::getPlayerGUI()
  68. {
  69. Framework::Text result = "<gui id=\"player_gui\">";
  70. result.append()
  71. << "<itemBar id=\"gui_item_bar\" margin-bottom=\"9\" "
  72. "align-bottom=\"end\" align-left=\"center\" width=\"592\" "
  73. "height=\"52\" rowSize=\"10\" slotNameFilter=\"ItemBar\" target=\""
  74. << getId() << "\"/>"
  75. << "<statusBars id=\"gui_status_bars\" margin-bottom=\"9\" "
  76. "align-bottom=\"gui_item_bar\" align-left=\"center\" target=\""
  77. << getId() << "\"/>"
  78. << "</gui>";
  79. return result;
  80. }
  81. void Player::useItemSlot(ItemSlot* zSlot, bool left)
  82. {
  83. if (Entity::useItem(zSlot->zStack() && zSlot->zStack()->zItem()
  84. ? zSlot->zStack()->zItem()->getTypeId()
  85. : ItemTypeEnum::PLAYER_HAND,
  86. (ItemStack*)zSlot->zStack(),
  87. left))
  88. {
  89. zSlot->update();
  90. if (zSlot->zStack())
  91. {
  92. if (zSlot->zStack()->zItem()->getDurability() <= 0)
  93. {
  94. ItemStack* stack = zSlot->takeItemsOut(
  95. zSlot->getNumberOfItems(), NO_DIRECTION);
  96. Item* broken
  97. = stack->zItem()->zItemType()->breakItem(stack->zItem());
  98. if (broken)
  99. {
  100. ItemStack* newStack
  101. = new ItemStack(broken, stack->getSize());
  102. zSlot->addItems(newStack, NO_DIRECTION);
  103. if (newStack->getSize() > 0)
  104. {
  105. Game::INSTANCE->spawnItem(
  106. getLocation(), getDimensionId(), newStack);
  107. }
  108. else
  109. {
  110. newStack->release();
  111. }
  112. }
  113. stack->release();
  114. }
  115. else if (zSlot->zStack()->zItem()->getHp() <= 0)
  116. {
  117. ItemStack* stack = zSlot->takeItemsOut(
  118. zSlot->getNumberOfItems(), NO_DIRECTION);
  119. Array<ItemSlot*> fromSlots;
  120. for (ItemSlot* slot : *this)
  121. {
  122. if (slot != zSlot) fromSlots.add(slot);
  123. }
  124. Array<ItemSlot*> targetSlots;
  125. targetSlots.add(zSlot);
  126. TypeItemFilter filter(stack->zItem()->zItemType());
  127. localTransaction(&fromSlots,
  128. &targetSlots,
  129. &filter,
  130. zSlot->getFreeSpace(),
  131. NO_DIRECTION,
  132. NO_DIRECTION);
  133. stack->release();
  134. }
  135. }
  136. updateSlot(zSlot);
  137. }
  138. }
  139. void Player::setName(Framework::Text name)
  140. {
  141. this->name = name;
  142. }
  143. const char* Player::getName() const
  144. {
  145. return name;
  146. }
  147. void Player::tick(const Dimension* zDimension)
  148. {
  149. if ((keyState | Key::LEFT_HAND_ACTION) == keyState)
  150. useItemSlot(itemBar.get(leftHandPosition), true);
  151. if ((keyState | Key::RIGHT_HAND_ACTION) == keyState)
  152. useItemSlot(itemBar.get(leftHandPosition), false);
  153. return Entity::tick(zDimension);
  154. }
  155. void Player::playerApi(
  156. Framework::StreamReader* zRequest, NetworkMessage* zResponse)
  157. {
  158. char byte;
  159. zRequest->lese(&byte, 1);
  160. switch (byte)
  161. {
  162. case 0:
  163. // stop action
  164. zRequest->lese(&byte, 1);
  165. switch (byte)
  166. {
  167. case 8:
  168. keyState = keyState & ~Key::LEFT_HAND_ACTION;
  169. break;
  170. case 9:
  171. keyState = keyState & ~Key::RIGHT_HAND_ACTION;
  172. break;
  173. }
  174. break;
  175. case 1:
  176. // begin action
  177. zRequest->lese(&byte, 1);
  178. switch (byte)
  179. {
  180. case 8:
  181. keyState = keyState | Key::LEFT_HAND_ACTION;
  182. break;
  183. case 9:
  184. keyState = keyState | Key::RIGHT_HAND_ACTION;
  185. break;
  186. }
  187. break;
  188. case 2:
  189. // set movement
  190. {
  191. MovementFrame frame;
  192. zRequest->lese((char*)&frame.direction.x, 4);
  193. zRequest->lese((char*)&frame.direction.y, 4);
  194. zRequest->lese((char*)&frame.direction.z, 4);
  195. zRequest->lese((char*)&frame.targetPosition.x, 4);
  196. zRequest->lese((char*)&frame.targetPosition.y, 4);
  197. zRequest->lese((char*)&frame.targetPosition.z, 4);
  198. zRequest->lese((char*)&frame.movementFlags, 4);
  199. zRequest->lese((char*)&frame.duration, 8);
  200. addMovementFrame(frame);
  201. calculateTarget(frame.targetPosition,
  202. frame.direction,
  203. !itemBar.get(leftHandPosition)->isEmpty()
  204. ? itemBar.get(leftHandPosition)->zStack()->zItem()
  205. : 0);
  206. break;
  207. }
  208. case 3:
  209. { // switch item bar position
  210. zRequest->lese((char*)&leftHandPosition, 4);
  211. leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
  212. NetworkMessage* msg = new NetworkMessage();
  213. msg->addressUIElement("gui_item_bar");
  214. char* message = new char[5];
  215. message[0] = 3; // set selected slot
  216. *(int*)(message + 1) = leftHandPosition;
  217. msg->setMessage(message, 5);
  218. Game::INSTANCE->sendMessage(msg, this);
  219. break;
  220. }
  221. case 4:
  222. {
  223. Game::INSTANCE->zUIController()->addDialog(
  224. new UIDialog("player_inventory",
  225. getId(),
  226. new Framework::XML::Element(getInventoryUIML())));
  227. break;
  228. }
  229. case 5:
  230. {
  231. // request gui
  232. Text uiml = getPlayerGUI();
  233. int msgSize = 6 + uiml.getLength();
  234. char* msg = new char[msgSize];
  235. msg[0] = 2; // gui message
  236. msg[1] = 2; // set gui
  237. *(int*)(msg + 2) = uiml.getLength();
  238. memcpy(msg + 6, uiml.getText(), uiml.getLength());
  239. zResponse->setMessage(msg, msgSize);
  240. break;
  241. }
  242. case 6:
  243. { // inventory transaction
  244. bool isEntity;
  245. zRequest->lese((char*)&isEntity, 1);
  246. Inventory* source;
  247. if (isEntity)
  248. {
  249. int id;
  250. zRequest->lese((char*)&id, 4);
  251. source = Game::INSTANCE->zEntity(id, dimensionId);
  252. }
  253. else
  254. {
  255. int dim;
  256. Framework::Vec3<int> pos;
  257. zRequest->lese((char*)&dim, 4);
  258. zRequest->lese((char*)&pos.x, 4);
  259. zRequest->lese((char*)&pos.y, 4);
  260. zRequest->lese((char*)&pos.z, 4);
  261. source = Game::INSTANCE->zBlockAt(pos, dim);
  262. }
  263. int sourceSlotId;
  264. zRequest->lese((char*)&sourceSlotId, 4);
  265. zRequest->lese((char*)&isEntity, 1);
  266. Inventory* target;
  267. if (isEntity)
  268. {
  269. int id;
  270. zRequest->lese((char*)&id, 4);
  271. target = Game::INSTANCE->zEntity(id, dimensionId);
  272. }
  273. else
  274. {
  275. int dim;
  276. Framework::Vec3<int> pos;
  277. zRequest->lese((char*)&dim, 4);
  278. zRequest->lese((char*)&pos.x, 4);
  279. zRequest->lese((char*)&pos.y, 4);
  280. zRequest->lese((char*)&pos.z, 4);
  281. target = Game::INSTANCE->zBlockAt(pos, dim);
  282. }
  283. if (source && target)
  284. {
  285. int targetSlotId;
  286. zRequest->lese((char*)&targetSlotId, 4);
  287. SpecificSlotFilter filter(sourceSlotId, targetSlotId);
  288. source->interactWith(target, Direction::NO_DIRECTION)
  289. .pushItems(source->zSlot(sourceSlotId)->getNumberOfItems(),
  290. &filter);
  291. }
  292. break;
  293. }
  294. case 7: // craft action
  295. {
  296. bool isEntity;
  297. zRequest->lese((char*)&isEntity, 1);
  298. BasicShapedCrafter* target;
  299. if (isEntity)
  300. {
  301. int id;
  302. zRequest->lese((char*)&id, 4);
  303. target = dynamic_cast<BasicShapedCrafter*>(
  304. Game::INSTANCE->zEntity(id, dimensionId));
  305. }
  306. else
  307. {
  308. int dim;
  309. Framework::Vec3<int> pos;
  310. zRequest->lese((char*)&dim, 4);
  311. zRequest->lese((char*)&pos.x, 4);
  312. zRequest->lese((char*)&pos.y, 4);
  313. zRequest->lese((char*)&pos.z, 4);
  314. target = dynamic_cast<BasicShapedCrafter*>(
  315. Game::INSTANCE->zRealBlockInstance(pos, dim));
  316. }
  317. if (target) target->applyCurrentRecipie();
  318. break;
  319. }
  320. case 8: // request left hand position
  321. {
  322. NetworkMessage* msg = new NetworkMessage();
  323. msg->addressUIElement("gui_item_bar");
  324. char* message = new char[5];
  325. message[0] = 3; // set selected slot
  326. *(int*)(message + 1) = leftHandPosition;
  327. msg->setMessage(message, 5);
  328. Game::INSTANCE->sendMessage(msg, this);
  329. break;
  330. }
  331. case 9: // open quest dialog
  332. {
  333. Game::INSTANCE->zUIController()->addDialog(
  334. new QuestDialog(getId()));
  335. break;
  336. }
  337. case 10: // request quest graph
  338. {
  339. /*
  340. unsigned char length;
  341. zRequest->lese((char*)&length, 1);
  342. char* collectionName = new char[length + 1];
  343. zRequest->lese(collectionName, length);
  344. collectionName[length] = 0;
  345. Framework::Text uiml
  346. = Game::INSTANCE->zQuestManager()->getQuestGraphUIML(
  347. this, collectionName);
  348. delete[] collectionName;
  349. zRequest->lese((char*)&length, 1);
  350. char* guiId = new char[(int)length + 1];
  351. zRequest->lese(guiId, length);
  352. guiId[(int)length] = 0;
  353. zResponse->addressGui(guiId);
  354. delete[] guiId;
  355. int msgSize = 4 + uiml.getLength();
  356. char* msg = new char[msgSize];
  357. *(int*)msg = uiml.getLength();
  358. memcpy(msg + 4, uiml.getText(), uiml.getLength());
  359. zResponse->setMessage(msg, msgSize);*/
  360. break;
  361. }
  362. case 11: // request quest view
  363. {
  364. /* unsigned char length;
  365. zRequest->lese((char*)&length, 1);
  366. char* questName = new char[length + 1];
  367. zRequest->lese(questName, length);
  368. questName[length] = 0;
  369. Framework::Text uiml
  370. = Game::INSTANCE->zQuestManager()->getQuestViewUIML(
  371. this, questName);
  372. delete[] questName;
  373. zRequest->lese((char*)&length, 1);
  374. char* guiId = new char[(int)length + 1];
  375. zRequest->lese(guiId, length);
  376. guiId[(int)length] = 0;
  377. zResponse->addressGui(guiId);
  378. delete[] guiId;
  379. int msgSize = 4 + uiml.getLength();
  380. char* msg = new char[msgSize];
  381. *(int*)msg = uiml.getLength();
  382. memcpy(msg + 4, uiml.getText(), uiml.getLength());
  383. zResponse->setMessage(msg, msgSize);*/
  384. break;
  385. }
  386. }
  387. }
  388. void Player::onFall(float collisionSpeed)
  389. {
  390. Entity::onFall(collisionSpeed);
  391. gravityMultiplier = 1.f;
  392. jumping = 0;
  393. }
  394. PlayerEntityType::PlayerEntityType()
  395. : EntityType(EntityTypeEnum::PLAYER,
  396. ModelInfo("player", "player.ltdb/player.png", 6))
  397. {}
  398. void PlayerEntityType::loadSuperEntity(
  399. Entity* zEntity, Framework::StreamReader* zReader) const
  400. {
  401. Player* zPlayer = dynamic_cast<Player*>(zEntity);
  402. if (!zPlayer)
  403. throw "PlayerEntityType::loadSuperEntity was called with an entity "
  404. "witch is not an instance of Player";
  405. zReader->lese((char*)&zPlayer->leftHandPosition, 4);
  406. char len;
  407. zReader->lese(&len, 1);
  408. char* name = new char[(int)len + 1];
  409. zReader->lese(name, (int)len);
  410. name[(int)len] = 0;
  411. zPlayer->name = name;
  412. delete[] name;
  413. EntityType::loadSuperEntity(zPlayer, zReader);
  414. }
  415. void PlayerEntityType::saveSuperEntity(
  416. Entity* zEntity, Framework::StreamWriter* zWriter) const
  417. {
  418. Player* zPlayer = dynamic_cast<Player*>(zEntity);
  419. if (!zPlayer)
  420. throw "PlayerEntityType::saveSuperEntity was called with an entity "
  421. "witch is not an instance of Player";
  422. zWriter->schreibe((char*)&zPlayer->leftHandPosition, 4);
  423. char len = (char)textLength(zPlayer->getName());
  424. zWriter->schreibe(&len, 1);
  425. zWriter->schreibe(zPlayer->getName(), (int)len);
  426. EntityType::saveSuperEntity(zEntity, zWriter);
  427. }
  428. Entity* PlayerEntityType::createEntity(
  429. Framework::Vec3<float> position, int dimensionId, int entityId) const
  430. {
  431. return new Player(position, dimensionId, entityId);
  432. }