Player.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "Player.h"
  2. #include "Game.h"
  3. #include "PlayerHand.h"
  4. #include "ItemFilter.h"
  5. Player::Player( Framework::Vec3<float> location, int dimensionId, int entityId )
  6. : Entity( PlayerEntityType::INSTANCE, location, dimensionId, entityId )
  7. {
  8. for( int i = 0; i < 9; i++ )
  9. {
  10. ItemSlot* slot = new ItemSlot( 50, 0, i, 0, ANY_DIRECTION, 0 );
  11. itemBar.add( slot );
  12. addSlot( slot );
  13. }
  14. leftHandPosition = 0;
  15. maxHP = 10;
  16. currentHP = 10;
  17. stamina = 10;
  18. maxStamina = 10;
  19. hunger = 10;
  20. maxHunger = 10;
  21. thirst = 10;
  22. maxThirst = 10;
  23. keyState = 0;
  24. jumping = 0;
  25. faceOffset = { 0.f, 0.f, 1.5f };
  26. targetDistanceLimit = 4;
  27. }
  28. void Player::afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
  29. {
  30. for( auto slot : itemBar )
  31. {
  32. if( slot == zSlot )
  33. {
  34. needUpdate = 1;
  35. return;
  36. }
  37. }
  38. }
  39. void Player::afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
  40. {
  41. for( auto slot : itemBar )
  42. {
  43. if( slot == zSlot )
  44. {
  45. needUpdate = 1;
  46. return;
  47. }
  48. }
  49. }
  50. void Player::useItemSlot( ItemSlot* zSlot )
  51. {
  52. if( zSlot->zStack() )
  53. {
  54. ItemStack* stack = takeItemsOut( zSlot, 1, NO_DIRECTION );
  55. if( stack )
  56. {
  57. Item* item = stack->extractFromStack();
  58. Entity::useItem( item->zItemType(), item );
  59. if( item->getDurability() > 0 && item->getDamage() < item->getMaxDamage() )
  60. { // put used item back
  61. stack->addToStack( item );
  62. // TODO: use inventory wrapper to update the cache of the inventory
  63. if( !zSlot->numberOfAddableItems( stack, NO_DIRECTION ) )
  64. { // move other items to other space
  65. ItemStack* oldItems = zSlot->takeItemsOut( zSlot->zStack()->getSize(), NO_DIRECTION );
  66. zSlot->addItems( stack, NO_DIRECTION );
  67. addItems( oldItems, NO_DIRECTION );
  68. if( oldItems->getSize() > 0 )
  69. {
  70. // TODO: drop remaining items
  71. }
  72. }
  73. else
  74. zSlot->addItems( stack, NO_DIRECTION );
  75. }
  76. else
  77. { // item is broken
  78. // move other items of the same type to the slot
  79. Array< ItemSlot*> fromSlots;
  80. for( ItemSlot* slot : itemBar )
  81. {
  82. if( slot != zSlot )
  83. fromSlots.add( slot );
  84. }
  85. Array<ItemSlot*> targetSlots;
  86. targetSlots.add( zSlot );
  87. TypeItemFilter filter( item->zItemType() );
  88. localTransaction( &fromSlots, &targetSlots, &filter, zSlot->getFreeSpace() );
  89. // place broken item in inventory
  90. const ItemType* brokenType = item->zItemType()->zBrokenItemType();
  91. if( brokenType )
  92. {
  93. Item* broken = item->zItemType()->breakItem( item );
  94. if( broken )
  95. {
  96. stack->addToStack( broken );
  97. addItems( stack, NO_DIRECTION );
  98. if( stack->getSize() > 0 )
  99. {
  100. // TODO: drop remaining items
  101. }
  102. }
  103. }
  104. item->release();
  105. }
  106. stack->release();
  107. }
  108. }
  109. else
  110. Entity::useItem( PlayerHandItemType::INSTANCE, 0 ); // hand usage
  111. }
  112. void Player::setName( Framework::Text name )
  113. {
  114. this->name = name;
  115. }
  116. const char* Player::getName() const
  117. {
  118. return name;
  119. }
  120. void Player::tick( const Dimension* zDimension )
  121. {
  122. speed = { 0, 0, speed.z };
  123. if( (keyState | Key::MOVE_FRONT) == keyState )
  124. speed += {faceDir.x, faceDir.y, 0};
  125. if( (keyState | Key::MOVE_BACK) == keyState )
  126. speed += {-faceDir.x, -faceDir.y, 0};
  127. if( (keyState | Key::MOVE_RIGHT) == keyState )
  128. {
  129. Vec2<float> norm = { faceDir.x, faceDir.y };
  130. norm.CW90().normalize();
  131. speed += {norm.x, norm.y, 0};
  132. }
  133. if( (keyState | Key::MOVE_LEFT) == keyState )
  134. {
  135. Vec2<float> norm = { faceDir.x, faceDir.y };
  136. norm.CCW90().normalize();
  137. speed += {norm.x, norm.y, 0};
  138. }
  139. Vec2<float> norm = { speed.x, speed.y };
  140. if( norm.getLengthSq() != 0 )
  141. {
  142. norm.normalize();
  143. speed.x = norm.x * 4.f; // 4 blocks per second movement speed
  144. speed.y = norm.y * 4.f;
  145. }
  146. if( (keyState | Key::MOVE_DOWN) == keyState && gravityMultiplier == 0.f )
  147. speed.z = -4.f;
  148. if( (keyState | Key::LEFT_HAND_ACTION) == keyState )
  149. useItemSlot( itemBar.z( leftHandPosition ) );
  150. if( (keyState | Key::RIGHT_HAND_ACTION) == keyState )
  151. useItemSlot( itemBar.z( (leftHandPosition + 1) % itemBar.getEintragAnzahl() ) );
  152. return Entity::tick( zDimension );
  153. }
  154. void Player::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
  155. {
  156. char byte;
  157. zRequest->lese( &byte, 1 );
  158. switch( byte )
  159. {
  160. case 0:
  161. zRequest->lese( &byte, 1 );
  162. switch( byte )
  163. {
  164. case 0:
  165. keyState = keyState & ~Key::MOVE_FRONT;
  166. break;
  167. case 1:
  168. keyState = keyState & ~Key::MOVE_LEFT;
  169. break;
  170. case 2:
  171. keyState = keyState & ~Key::MOVE_BACK;
  172. break;
  173. case 3:
  174. keyState = keyState & ~Key::MOVE_RIGHT;
  175. break;
  176. case 4:
  177. if( gravityMultiplier == 0.f )
  178. speed.z = 0;
  179. keyState = keyState & ~Key::MOVE_DOWN;
  180. break;
  181. case 5:
  182. keyState = keyState & ~Key::ROTATE_LEFT;
  183. break;
  184. case 6:
  185. keyState = keyState & ~Key::ROTATE_RIGHT;
  186. break;
  187. case 7:
  188. if( gravityMultiplier == 0.f )
  189. speed.z = 0;
  190. keyState = keyState & ~Key::MOVE_UP;
  191. break;
  192. case 8:
  193. keyState = keyState & ~Key::LEFT_HAND_ACTION;
  194. break;
  195. case 9:
  196. keyState = keyState & ~Key::RIGHT_HAND_ACTION;
  197. break;
  198. }
  199. break;
  200. case 1:
  201. zRequest->lese( &byte, 1 );
  202. switch( byte )
  203. {
  204. case 0:
  205. keyState = keyState | Key::MOVE_FRONT;
  206. break;
  207. case 1:
  208. keyState = keyState | Key::MOVE_LEFT;
  209. break;
  210. case 2:
  211. keyState = keyState | Key::MOVE_BACK;
  212. break;
  213. case 3:
  214. keyState = keyState | Key::MOVE_RIGHT;
  215. break;
  216. case 4:
  217. keyState = keyState | Key::MOVE_DOWN;
  218. break;
  219. case 5:
  220. keyState = keyState | Key::ROTATE_LEFT;
  221. break;
  222. case 6:
  223. keyState = keyState | Key::ROTATE_RIGHT;
  224. break;
  225. case 7:
  226. if( (keyState | Key::MOVE_UP) != keyState )
  227. {
  228. if( gravityMultiplier > 0 )
  229. {
  230. if( jumping )
  231. {
  232. // TODO: check if flight is enabled
  233. gravityMultiplier = 0;
  234. jumping = 0;
  235. speed.z = 1.5f;
  236. }
  237. else
  238. {
  239. jumping = 1;
  240. speed.z = 5.f;
  241. }
  242. }
  243. else
  244. speed.z = 1.5f;
  245. }
  246. keyState = keyState | Key::MOVE_UP;
  247. break;
  248. case 8:
  249. keyState = keyState | Key::LEFT_HAND_ACTION;
  250. break;
  251. case 9:
  252. keyState = keyState | Key::RIGHT_HAND_ACTION;
  253. break;
  254. }
  255. break;
  256. case 2:
  257. zRequest->lese( (char*)&faceDir.x, 4 );
  258. zRequest->lese( (char*)&faceDir.y, 4 );
  259. zRequest->lese( (char*)&faceDir.z, 4 );
  260. case 3:
  261. zRequest->lese( (char*)&leftHandPosition, 4 );
  262. leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
  263. needUpdate = 1;
  264. }
  265. }
  266. void Player::onFall( float collisionSpeed )
  267. {
  268. Entity::onFall( collisionSpeed );
  269. gravityMultiplier = 1.f;
  270. jumping = 0;
  271. }
  272. PlayerEntityType::PlayerEntityType()
  273. : EntityType( ID )
  274. {}
  275. void PlayerEntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const
  276. {
  277. Player* zPlayer = dynamic_cast<Player*>(zEntity);
  278. if( !zPlayer )
  279. throw "PlayerEntityType::loadSuperEntity was called with an entity witch is not an instance of Player";
  280. zReader->lese( (char*)&zPlayer->leftHandPosition, 4 );
  281. EntityType::loadSuperEntity( zPlayer, zReader );
  282. }
  283. void PlayerEntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
  284. {
  285. Player* zPlayer = dynamic_cast<Player*>(zEntity);
  286. if( !zPlayer )
  287. throw "PlayerEntityType::saveSuperEntity was called with an entity witch is not an instance of Player";
  288. zWriter->schreibe( (char*)&zPlayer->leftHandPosition, 4 );
  289. EntityType::saveSuperEntity( zEntity, zWriter );
  290. }
  291. Entity* PlayerEntityType::createEntity( Framework::Vec3<float> position, int dimensionId, int entityId ) const
  292. {
  293. return new Player( position, dimensionId, entityId );
  294. }