Player.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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::useItemSlot( ItemSlot* zSlot )
  29. {
  30. if( zSlot->zStack() )
  31. {
  32. ItemStack* stack = zSlot->takeItemsOut( 1, NO_DIRECTION );
  33. if( stack )
  34. {
  35. Item* item = stack->extractFromStack();
  36. Entity::useItem( item->zItemType(), item );
  37. if( item->getDurability() > 0 && item->getDamage() < item->getMaxDamage() )
  38. { // put used item back
  39. stack->addToStack( item );
  40. if( !zSlot->numberOfAddableItems( stack, NO_DIRECTION ) )
  41. { // move other items to other space
  42. ItemStack* oldItems = zSlot->takeItemsOut( zSlot->zStack()->getSize(), NO_DIRECTION );
  43. zSlot->addItems( stack, NO_DIRECTION );
  44. addItems( oldItems, NO_DIRECTION );
  45. if( oldItems->getSize() > 0 )
  46. {
  47. // TODO: drop remaining items
  48. }
  49. }
  50. else
  51. zSlot->addItems( stack, NO_DIRECTION );
  52. }
  53. else
  54. { // item is broken
  55. // move other items of the same type to the slot
  56. Array< ItemSlot*> fromSlots;
  57. for( ItemSlot* slot : itemBar )
  58. {
  59. if( slot != zSlot )
  60. fromSlots.add( slot );
  61. }
  62. Array<ItemSlot*> targetSlots;
  63. targetSlots.add( zSlot );
  64. TypeItemFilter filter( item->zItemType() );
  65. localTransaction( &fromSlots, &targetSlots, &filter, zSlot->getFreeSpace() );
  66. // place broken item in inventory
  67. const ItemType* brokenType = item->zItemType()->zBrokenItemType();
  68. if( brokenType )
  69. {
  70. Item* broken = item->zItemType()->breakItem( item );
  71. if( broken )
  72. {
  73. stack->addToStack( broken );
  74. addItems( stack, NO_DIRECTION );
  75. if( stack->getSize() > 0 )
  76. {
  77. // TODO: drop remaining items
  78. }
  79. }
  80. }
  81. item->release();
  82. }
  83. stack->release();
  84. }
  85. }
  86. else
  87. Entity::useItem( PlayerHandItemType::INSTANCE, 0 ); // hand usage
  88. }
  89. void Player::setName( Framework::Text name )
  90. {
  91. this->name = name;
  92. }
  93. const char* Player::getName() const
  94. {
  95. return name;
  96. }
  97. void Player::tick( const Dimension* zDimension )
  98. {
  99. speed = { 0, 0, speed.z };
  100. if( (keyState | Key::MOVE_FRONT) == keyState )
  101. speed += {faceDir.x, faceDir.y, 0};
  102. if( (keyState | Key::MOVE_BACK) == keyState )
  103. speed += {-faceDir.x, -faceDir.y, 0};
  104. if( (keyState | Key::MOVE_RIGHT) == keyState )
  105. {
  106. Vec2<float> norm = { faceDir.x, faceDir.y };
  107. norm.CW90().normalize();
  108. speed += {norm.x, norm.y, 0};
  109. }
  110. if( (keyState | Key::MOVE_LEFT) == keyState )
  111. {
  112. Vec2<float> norm = { faceDir.x, faceDir.y };
  113. norm.CCW90().normalize();
  114. speed += {norm.x, norm.y, 0};
  115. }
  116. Vec2<float> norm = { speed.x, speed.y };
  117. if( norm.getLengthSq() != 0 )
  118. {
  119. norm.normalize();
  120. speed.x = norm.x * 4.f; // 4 blocks per second movement speed
  121. speed.y = norm.y * 4.f;
  122. }
  123. if( (keyState | Key::MOVE_DOWN) == keyState && gravityMultiplier == 0.f )
  124. speed.z = -4.f;
  125. if( (keyState | Key::LEFT_HAND_ACTION) == keyState )
  126. useItemSlot( itemBar.z( leftHandPosition ) );
  127. if( (keyState | Key::RIGHT_HAND_ACTION) == keyState )
  128. useItemSlot( itemBar.z( (leftHandPosition + 1) % itemBar.getEintragAnzahl() ) );
  129. return Entity::tick( zDimension );
  130. }
  131. void Player::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
  132. {
  133. char byte;
  134. zRequest->lese( &byte, 1 );
  135. switch( byte )
  136. {
  137. case 0:
  138. zRequest->lese( &byte, 1 );
  139. switch( byte )
  140. {
  141. case 0:
  142. keyState = keyState & ~Key::MOVE_FRONT;
  143. break;
  144. case 1:
  145. keyState = keyState & ~Key::MOVE_LEFT;
  146. break;
  147. case 2:
  148. keyState = keyState & ~Key::MOVE_BACK;
  149. break;
  150. case 3:
  151. keyState = keyState & ~Key::MOVE_RIGHT;
  152. break;
  153. case 4:
  154. if( gravityMultiplier == 0.f )
  155. speed.z = 0;
  156. keyState = keyState & ~Key::MOVE_DOWN;
  157. break;
  158. case 5:
  159. keyState = keyState & ~Key::ROTATE_LEFT;
  160. break;
  161. case 6:
  162. keyState = keyState & ~Key::ROTATE_RIGHT;
  163. break;
  164. case 7:
  165. if( gravityMultiplier == 0.f )
  166. speed.z = 0;
  167. keyState = keyState & ~Key::MOVE_UP;
  168. break;
  169. case 8:
  170. keyState = keyState & ~Key::LEFT_HAND_ACTION;
  171. break;
  172. case 9:
  173. keyState = keyState & ~Key::RIGHT_HAND_ACTION;
  174. break;
  175. }
  176. break;
  177. case 1:
  178. zRequest->lese( &byte, 1 );
  179. switch( byte )
  180. {
  181. case 0:
  182. keyState = keyState | Key::MOVE_FRONT;
  183. break;
  184. case 1:
  185. keyState = keyState | Key::MOVE_LEFT;
  186. break;
  187. case 2:
  188. keyState = keyState | Key::MOVE_BACK;
  189. break;
  190. case 3:
  191. keyState = keyState | Key::MOVE_RIGHT;
  192. break;
  193. case 4:
  194. keyState = keyState | Key::MOVE_DOWN;
  195. break;
  196. case 5:
  197. keyState = keyState | Key::ROTATE_LEFT;
  198. break;
  199. case 6:
  200. keyState = keyState | Key::ROTATE_RIGHT;
  201. break;
  202. case 7:
  203. if( (keyState | Key::MOVE_UP) != keyState )
  204. {
  205. if( gravityMultiplier > 0 )
  206. {
  207. if( jumping )
  208. {
  209. // TODO: check if flight is enabled
  210. gravityMultiplier = 0;
  211. jumping = 0;
  212. speed.z = 1.5f;
  213. }
  214. else
  215. {
  216. jumping = 1;
  217. speed.z = 5.f;
  218. }
  219. }
  220. else
  221. speed.z = 1.5f;
  222. }
  223. keyState = keyState | Key::MOVE_UP;
  224. break;
  225. case 8:
  226. keyState = keyState | Key::LEFT_HAND_ACTION;
  227. break;
  228. case 9:
  229. keyState = keyState | Key::RIGHT_HAND_ACTION;
  230. break;
  231. }
  232. break;
  233. case 2:
  234. zRequest->lese( (char*)&faceDir.x, 4 );
  235. zRequest->lese( (char*)&faceDir.y, 4 );
  236. zRequest->lese( (char*)&faceDir.z, 4 );
  237. case 3:
  238. zRequest->lese( (char*)&leftHandPosition, 4 );
  239. leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
  240. }
  241. }
  242. void Player::onFall( float collisionSpeed )
  243. {
  244. Entity::onFall( collisionSpeed );
  245. gravityMultiplier = 1.f;
  246. jumping = 0;
  247. }
  248. PlayerEntityType::PlayerEntityType()
  249. : EntityType( ID )
  250. {}
  251. void PlayerEntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const
  252. {}
  253. void PlayerEntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
  254. {}
  255. Entity* PlayerEntityType::createEntity( Framework::Vec3<float> position, int dimensionId, int entityId ) const
  256. {
  257. return new Player( position, dimensionId, entityId );
  258. }