123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- #include "Player.h"
- #include "Game.h"
- #include "PlayerHand.h"
- #include "ItemFilter.h"
- Player::Player( Framework::Vec3<float> location, int dimensionId, int entityId )
- : Entity( PlayerEntityType::INSTANCE, location, dimensionId, entityId )
- {
- for( int i = 0; i < 9; i++ )
- {
- ItemSlot* slot = new ItemSlot( 50, 0, i, 0, ANY_DIRECTION, 0 );
- itemBar.add( slot );
- addSlot( slot );
- }
- leftHandPosition = 0;
- maxHP = 10;
- currentHP = 10;
- stamina = 10;
- maxStamina = 10;
- hunger = 10;
- maxHunger = 10;
- thirst = 10;
- maxThirst = 10;
- keyState = 0;
- jumping = 0;
- faceOffset = { 0.f, 0.f, 1.5f };
- targetDistanceLimit = 4;
- }
- void Player::afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
- {
- for( auto slot : itemBar )
- {
- if( slot == zSlot )
- {
- needUpdate = 1;
- return;
- }
- }
- }
- void Player::afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
- {
- for( auto slot : itemBar )
- {
- if( slot == zSlot )
- {
- needUpdate = 1;
- return;
- }
- }
- }
- void Player::useItemSlot( ItemSlot* zSlot )
- {
- if( zSlot->zStack() )
- {
- ItemStack* stack = takeItemsOut( zSlot, 1, NO_DIRECTION );
- if( stack )
- {
- Item* item = stack->extractFromStack();
- Entity::useItem( item->zItemType(), item );
- if( item->getDurability() > 0 && item->getDamage() < item->getMaxDamage() )
- { // put used item back
- stack->addToStack( item );
- // TODO: use inventory wrapper to update the cache of the inventory
- if( !zSlot->numberOfAddableItems( stack, NO_DIRECTION ) )
- { // move other items to other space
- ItemStack* oldItems = zSlot->takeItemsOut( zSlot->zStack()->getSize(), NO_DIRECTION );
- zSlot->addItems( stack, NO_DIRECTION );
- addItems( oldItems, NO_DIRECTION );
- if( oldItems->getSize() > 0 )
- {
- // TODO: drop remaining items
- }
- }
- else
- zSlot->addItems( stack, NO_DIRECTION );
- }
- else
- { // item is broken
- // move other items of the same type to the slot
- Array< ItemSlot*> fromSlots;
- for( ItemSlot* slot : itemBar )
- {
- if( slot != zSlot )
- fromSlots.add( slot );
- }
- Array<ItemSlot*> targetSlots;
- targetSlots.add( zSlot );
- TypeItemFilter filter( item->zItemType() );
- localTransaction( &fromSlots, &targetSlots, &filter, zSlot->getFreeSpace() );
- // place broken item in inventory
- const ItemType* brokenType = item->zItemType()->zBrokenItemType();
- if( brokenType )
- {
- Item* broken = item->zItemType()->breakItem( item );
- if( broken )
- {
- stack->addToStack( broken );
- addItems( stack, NO_DIRECTION );
- if( stack->getSize() > 0 )
- {
- // TODO: drop remaining items
- }
- }
- }
- item->release();
- }
- stack->release();
- }
- }
- else
- Entity::useItem( PlayerHandItemType::INSTANCE, 0 ); // hand usage
- }
- void Player::setName( Framework::Text name )
- {
- this->name = name;
- }
- const char* Player::getName() const
- {
- return name;
- }
- void Player::tick( const Dimension* zDimension )
- {
- speed = { 0, 0, speed.z };
- if( (keyState | Key::MOVE_FRONT) == keyState )
- speed += {faceDir.x, faceDir.y, 0};
- if( (keyState | Key::MOVE_BACK) == keyState )
- speed += {-faceDir.x, -faceDir.y, 0};
- if( (keyState | Key::MOVE_RIGHT) == keyState )
- {
- Vec2<float> norm = { faceDir.x, faceDir.y };
- norm.CW90().normalize();
- speed += {norm.x, norm.y, 0};
- }
- if( (keyState | Key::MOVE_LEFT) == keyState )
- {
- Vec2<float> norm = { faceDir.x, faceDir.y };
- norm.CCW90().normalize();
- speed += {norm.x, norm.y, 0};
- }
- Vec2<float> norm = { speed.x, speed.y };
- if( norm.getLengthSq() != 0 )
- {
- norm.normalize();
- speed.x = norm.x * 4.f; // 4 blocks per second movement speed
- speed.y = norm.y * 4.f;
- }
- if( (keyState | Key::MOVE_DOWN) == keyState && gravityMultiplier == 0.f )
- speed.z = -4.f;
- if( (keyState | Key::LEFT_HAND_ACTION) == keyState )
- useItemSlot( itemBar.z( leftHandPosition ) );
- if( (keyState | Key::RIGHT_HAND_ACTION) == keyState )
- useItemSlot( itemBar.z( (leftHandPosition + 1) % itemBar.getEintragAnzahl() ) );
- return Entity::tick( zDimension );
- }
- void Player::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
- {
- char byte;
- zRequest->lese( &byte, 1 );
- switch( byte )
- {
- case 0:
- zRequest->lese( &byte, 1 );
- switch( byte )
- {
- case 0:
- keyState = keyState & ~Key::MOVE_FRONT;
- break;
- case 1:
- keyState = keyState & ~Key::MOVE_LEFT;
- break;
- case 2:
- keyState = keyState & ~Key::MOVE_BACK;
- break;
- case 3:
- keyState = keyState & ~Key::MOVE_RIGHT;
- break;
- case 4:
- if( gravityMultiplier == 0.f )
- speed.z = 0;
- keyState = keyState & ~Key::MOVE_DOWN;
- break;
- case 5:
- keyState = keyState & ~Key::ROTATE_LEFT;
- break;
- case 6:
- keyState = keyState & ~Key::ROTATE_RIGHT;
- break;
- case 7:
- if( gravityMultiplier == 0.f )
- speed.z = 0;
- keyState = keyState & ~Key::MOVE_UP;
- break;
- case 8:
- keyState = keyState & ~Key::LEFT_HAND_ACTION;
- break;
- case 9:
- keyState = keyState & ~Key::RIGHT_HAND_ACTION;
- break;
- }
- break;
- case 1:
- zRequest->lese( &byte, 1 );
- switch( byte )
- {
- case 0:
- keyState = keyState | Key::MOVE_FRONT;
- break;
- case 1:
- keyState = keyState | Key::MOVE_LEFT;
- break;
- case 2:
- keyState = keyState | Key::MOVE_BACK;
- break;
- case 3:
- keyState = keyState | Key::MOVE_RIGHT;
- break;
- case 4:
- keyState = keyState | Key::MOVE_DOWN;
- break;
- case 5:
- keyState = keyState | Key::ROTATE_LEFT;
- break;
- case 6:
- keyState = keyState | Key::ROTATE_RIGHT;
- break;
- case 7:
- if( (keyState | Key::MOVE_UP) != keyState )
- {
- if( gravityMultiplier > 0 )
- {
- if( jumping )
- {
- // TODO: check if flight is enabled
- gravityMultiplier = 0;
- jumping = 0;
- speed.z = 1.5f;
- }
- else
- {
- jumping = 1;
- speed.z = 5.f;
- }
- }
- else
- speed.z = 1.5f;
- }
- keyState = keyState | Key::MOVE_UP;
- break;
- case 8:
- keyState = keyState | Key::LEFT_HAND_ACTION;
- break;
- case 9:
- keyState = keyState | Key::RIGHT_HAND_ACTION;
- break;
- }
- break;
- case 2:
- zRequest->lese( (char*)&faceDir.x, 4 );
- zRequest->lese( (char*)&faceDir.y, 4 );
- zRequest->lese( (char*)&faceDir.z, 4 );
- case 3:
- zRequest->lese( (char*)&leftHandPosition, 4 );
- leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
- needUpdate = 1;
- }
- }
- void Player::onFall( float collisionSpeed )
- {
- Entity::onFall( collisionSpeed );
- gravityMultiplier = 1.f;
- jumping = 0;
- }
- PlayerEntityType::PlayerEntityType()
- : EntityType( ID )
- {}
- void PlayerEntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const
- {
- Player* zPlayer = dynamic_cast<Player*>(zEntity);
- if( !zPlayer )
- throw "PlayerEntityType::loadSuperEntity was called with an entity witch is not an instance of Player";
- zReader->lese( (char*)&zPlayer->leftHandPosition, 4 );
- EntityType::loadSuperEntity( zPlayer, zReader );
- }
- void PlayerEntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
- {
- Player* zPlayer = dynamic_cast<Player*>(zEntity);
- if( !zPlayer )
- throw "PlayerEntityType::saveSuperEntity was called with an entity witch is not an instance of Player";
- zWriter->schreibe( (char*)&zPlayer->leftHandPosition, 4 );
- EntityType::saveSuperEntity( zEntity, zWriter );
- }
- Entity* PlayerEntityType::createEntity( Framework::Vec3<float> position, int dimensionId, int entityId ) const
- {
- return new Player( position, dimensionId, entityId );
- }
|