123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- #include "Player.h"
- #include "Game.h"
- #include "ItemFilter.h"
- #include "PlayerHand.h"
- Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
- : Entity(EntityTypeEnum::PLAYER, location, dimensionId, entityId),
- BasicShapedCrafter(3, 3, this, "inventory")
- {
- 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;
- maxStamina = 10;
- maxHunger = 10;
- maxThirst = 10;
- setHP(10);
- setStamina(10);
- setHunger(10);
- setThirst(10);
- keyState = 0;
- jumping = 0;
- faceOffset = {0.f, 0.f, 1.5f};
- targetDistanceLimit = 4;
- maxMovementSpeed = 4;
- }
- void Player::onTargetChange()
- {
- NetworkMessage* msg = new NetworkMessage();
- ActionTarget::toMessage(zTarget(), getCurrentDimensionId(), msg);
- Game::INSTANCE->sendMessage(msg, this);
- }
- Framework::Text Player::getInventoryUIML()
- {
- Framework::Text result
- = "<dialog id=\"player_inventory\" title=\"Inventory\" width=\"610\" "
- "height=\"450\">";
- result.append()
- << "<craftingGrid id=\"crafting\" margin-top=\"9\" "
- "align-top=\"start\" align-left=\"start\" margin-left=\"9\" "
- "width=\"282\" height=\"172\" rowSize=\"3\" colSize=\"3\" "
- "numOutputSlots=\"1\" target=\""
- << getId() << "\"/>"
- << "<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=\""
- << getId() << "\"/>"
- << "<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=\""
- << getId() << "\"/>"
- << "</dialog>";
- return result;
- }
- Framework::Text Player::getPlayerGUI()
- {
- Framework::Text result = "<gui id=\"player_gui\">";
- result.append()
- << "<itemBar id=\"gui_item_bar\" margin-bottom=\"9\" "
- "align-bottom=\"end\" align-left=\"center\" width=\"592\" "
- "height=\"52\" rowSize=\"10\" slotNameFilter=\"ItemBar\" target=\""
- << getId() << "\"/>"
- << "<statusBars id=\"gui_status_bars\" margin-bottom=\"9\" "
- "align-bottom=\"gui_item_bar\" align-left=\"center\" target=\""
- << getId() << "\"/>"
- << "</gui>";
- 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->getTypeId(), item);
- if (item->getHp() > 0)
- {
- if (item->getDurability() > 0)
- { // put used item back
- stack->addToStack(item);
- if (!zSlot->numberOfAddableItems(stack, NO_DIRECTION))
- { // move other items to other space
- ItemStack* oldItems = takeItemsOut(
- zSlot, zSlot->zStack()->getSize(), NO_DIRECTION);
- addItems(zSlot, stack, NO_DIRECTION);
- addItems(oldItems, NO_DIRECTION, 0);
- if (oldItems->getSize() > 0)
- {
- // TODO: drop remaining items
- }
- }
- else
- addItems(zSlot, stack, NO_DIRECTION);
- }
- else
- { // item is broken
- // move other items of the same type to the slot
- Array<ItemSlot*> fromSlots;
- for (ItemSlot* slot : *this)
- {
- 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, 0);
- if (stack->getSize() > 0)
- {
- // TODO: drop remaining items
- }
- }
- }
- item->release();
- }
- }
- else
- item->release();
- stack->release();
- }
- }
- else
- Entity::useItem(ItemTypeEnum::PLAYER_HAND, 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)
- {
- 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, NetworkMessage* zResponse)
- {
- char byte;
- zRequest->lese(&byte, 1);
- switch (byte)
- {
- case 0:
- // stop action
- zRequest->lese(&byte, 1);
- switch (byte)
- {
- 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 8:
- keyState = keyState | Key::LEFT_HAND_ACTION;
- break;
- case 9:
- keyState = keyState | Key::RIGHT_HAND_ACTION;
- break;
- }
- break;
- case 2:
- // set movement
- {
- MovementFrame frame;
- zRequest->lese((char*)&frame.direction.x, 4);
- zRequest->lese((char*)&frame.direction.y, 4);
- zRequest->lese((char*)&frame.direction.z, 4);
- zRequest->lese((char*)&frame.targetPosition.x, 4);
- zRequest->lese((char*)&frame.targetPosition.y, 4);
- zRequest->lese((char*)&frame.targetPosition.z, 4);
- zRequest->lese((char*)&frame.movementFlags, 4);
- zRequest->lese((char*)&frame.duration, 8);
- addMovementFrame(frame);
- calculateTarget(frame.targetPosition, frame.direction);
- break;
- }
- case 3:
- { // switch item bar position
- zRequest->lese((char*)&leftHandPosition, 4);
- leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
- NetworkMessage* msg = new NetworkMessage();
- msg->addressGui("gui_item_bar");
- char* message = new char[5];
- message[0] = 3; // set selected slot
- *(int*)(message + 1) = leftHandPosition;
- msg->setMessage(message, 5);
- Game::INSTANCE->sendMessage(msg, this);
- break;
- }
- case 4:
- {
- // open inventory
- zResponse->openDialog("player_inventory");
- Text uiml = getInventoryUIML();
- int msgSize = 4 + uiml.getLength();
- char* msg = new char[msgSize];
- *(int*)msg = uiml.getLength();
- memcpy(msg + 4, uiml.getText(), uiml.getLength());
- zResponse->setMessage(msg, msgSize);
- break;
- }
- case 5:
- {
- // request gui
- Text uiml = getPlayerGUI();
- int msgSize = 6 + uiml.getLength();
- char* msg = new char[msgSize];
- msg[0] = 2; // gui message
- msg[1] = 2; // set gui
- *(int*)(msg + 2) = uiml.getLength();
- memcpy(msg + 6, uiml.getText(), uiml.getLength());
- zResponse->setMessage(msg, msgSize);
- break;
- }
- case 6:
- { // inventory transaction
- bool isEntity;
- zRequest->lese((char*)&isEntity, 1);
- Inventory* source;
- if (isEntity)
- {
- int id;
- zRequest->lese((char*)&id, 4);
- source = Game::INSTANCE->zEntity(id, getCurrentDimensionId());
- }
- else
- {
- int dim;
- Framework::Vec3<int> pos;
- zRequest->lese((char*)&dim, 4);
- zRequest->lese((char*)&pos.x, 4);
- zRequest->lese((char*)&pos.y, 4);
- zRequest->lese((char*)&pos.z, 4);
- source = Game::INSTANCE->zBlockAt(pos, dim);
- }
- int sourceSlotId;
- zRequest->lese((char*)&sourceSlotId, 4);
- zRequest->lese((char*)&isEntity, 1);
- Inventory* target;
- if (isEntity)
- {
- int id;
- zRequest->lese((char*)&id, 4);
- target = Game::INSTANCE->zEntity(id, getCurrentDimensionId());
- }
- else
- {
- int dim;
- Framework::Vec3<int> pos;
- zRequest->lese((char*)&dim, 4);
- zRequest->lese((char*)&pos.x, 4);
- zRequest->lese((char*)&pos.y, 4);
- zRequest->lese((char*)&pos.z, 4);
- target = Game::INSTANCE->zBlockAt(pos, dim);
- }
- if (source && target)
- {
- int targetSlotId;
- zRequest->lese((char*)&targetSlotId, 4);
- SpecificSlotFilter filter(sourceSlotId, targetSlotId);
- source->interactWith(target, Direction::NO_DIRECTION)
- .pushItems(source->zSlot(sourceSlotId)->getNumberOfItems(),
- &filter);
- }
- break;
- }
- case 7: // craft action
- {
- bool isEntity;
- zRequest->lese((char*)&isEntity, 1);
- BasicShapedCrafter* target;
- if (isEntity)
- {
- int id;
- zRequest->lese((char*)&id, 4);
- target = dynamic_cast<BasicShapedCrafter*>(
- Game::INSTANCE->zEntity(id, getCurrentDimensionId()));
- }
- else
- {
- int dim;
- Framework::Vec3<int> pos;
- zRequest->lese((char*)&dim, 4);
- zRequest->lese((char*)&pos.x, 4);
- zRequest->lese((char*)&pos.y, 4);
- zRequest->lese((char*)&pos.z, 4);
- target = dynamic_cast<BasicShapedCrafter*>(
- Game::INSTANCE->zRealBlockInstance(pos, dim));
- }
- if (target) target->applyCurrentRecipie();
- break;
- }
- case 8: // request left hand position
- {
- NetworkMessage* msg = new NetworkMessage();
- msg->addressGui("gui_item_bar");
- char* message = new char[5];
- message[0] = 3; // set selected slot
- *(int*)(message + 1) = leftHandPosition;
- msg->setMessage(message, 5);
- Game::INSTANCE->sendMessage(msg, this);
- break;
- }
- }
- }
- void Player::onFall(float collisionSpeed)
- {
- Entity::onFall(collisionSpeed);
- gravityMultiplier = 1.f;
- jumping = 0;
- }
- PlayerEntityType::PlayerEntityType()
- : EntityType(EntityTypeEnum::PLAYER,
- 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);
- char len;
- zReader->lese(&len, 1);
- char* name = new char[(int)len + 1];
- zReader->lese(name, (int)len);
- name[(int)len] = 0;
- zPlayer->name = name;
- delete[] name;
- 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);
- char len = (char)textLength(zPlayer->getName());
- zWriter->schreibe(&len, 1);
- zWriter->schreibe(zPlayer->getName(), (int)len);
- EntityType::saveSuperEntity(zEntity, zWriter);
- }
- Entity* PlayerEntityType::createEntity(
- Framework::Vec3<float> position, int dimensionId, int entityId) const
- {
- return new Player(position, dimensionId, entityId);
- }
|