123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- #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),
- BasicShapedCrafter(3, 3, this)
- {
- for (int i = 0; i < 10; i++)
- {
- ItemSlot* slot = new ItemSlot("ItemBar", 50, 0, i, 0, ANY_DIRECTION, 0);
- itemBar.add(slot);
- addSlot(slot);
- }
- for (int i = 0; i < 30; i++)
- {
- ItemSlot* slot = new ItemSlot("Inventory", 50, 0, i + 10, 0, ANY_DIRECTION, 0);
- 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;
- }
- }
- }
- Framework::Text Player::getInventoryUIML()
- {
- Framework::Text result = "<dialog id=\"player_inventory\" title=\"Inventory\" width=\"610\" height=\"450\">";
- result += "<craftingGrid id=\"crafting\" margin-top=\"9\" align-top=\"start\" align-left=\"start\" margin-left=\"9\" width=\"272\" height=\"172\" rowSize=\"3\" colSize=\"3\" numOutputSlots=\"1\" target=\"";
- result += getId();
- result += "\"/>";
- result += "<inventory id=\"inventory\" margin-bottom=\"18\" align-bottom=\"item_bar\" align-left=\"start\" margin-left=\"9\" width=\"592\" height=\"172\" rowSize=\"10\" numSlots=\"30\" slotNameFilter=\"Inventory\" target=\"";
- result += getId();
- result += "\"/>";
- result += "<inventory id=\"item_bar\" margin-bottom=\"9\" align-bottom=\"end\" align-left=\"start\" margin-left=\"9\" width=\"592\" height=\"52\" rowSize=\"10\" numSlots=\"10\" slotNameFilter=\"ItemBar\" target=\"";
- result += getId();
- result += "\"/>";
- result += "</dialog>";
- return result;
- }
- 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(), NO_DIRECTION, NO_DIRECTION);
- // 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.get(leftHandPosition));
- if ((keyState | Key::RIGHT_HAND_ACTION) == keyState)
- useItemSlot(itemBar.get((leftHandPosition + 1) % itemBar.getEintragAnzahl()));
- return Entity::tick(zDimension);
- }
- void Player::playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
- {
- char byte;
- zRequest->lese(&byte, 1);
- switch (byte)
- {
- case 0:
- // stop action
- 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:
- // begin action
- 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:
- // switch target direction
- zRequest->lese((char*)&faceDir.x, 4);
- zRequest->lese((char*)&faceDir.y, 4);
- zRequest->lese((char*)&faceDir.z, 4);
- break;
- case 3:
- // switch item bar position
- zRequest->lese((char*)&leftHandPosition, 4);
- leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
- needUpdate = 1;
- break;
- case 4:
- {
- // open inventory
- zResponse->openDialog("player_inventory");
- Text uiml = getInventoryUIML();
- int msgSize = 5 + uiml.getLength();
- char* msg = new char[msgSize];
- msg[0] = 0; // open dialog
- *(int*)(msg + 1) = uiml.getLength();
- memcpy(msg + 5, uiml.getText(), uiml.getLength());
- zResponse->setMessage(msg, msgSize, 1);
- break;
- }
- }
- }
- void Player::onFall(float collisionSpeed)
- {
- Entity::onFall(collisionSpeed);
- gravityMultiplier = 1.f;
- jumping = 0;
- }
- PlayerEntityType::PlayerEntityType()
- : EntityType(ID, ModelInfo("player", "player.ltdb/player.png", 6))
- {}
- 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);
- }
|