Player.cpp 9.3 KB

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