Player.cpp 8.2 KB

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