Player.cpp 9.2 KB

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