123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- #include "Player.h"
- #include "ArrayUtils.h"
- #include "Block.h"
- #include "Chat.h"
- #include "Game.h"
- #include "ItemFilter.h"
- #include "ItemStack.h"
- #include "PlayerHand.h"
- #include "QuestDialog.h"
- #include "UIController.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);
- setJumpSpeed(5.f);
- 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(), dimensionId, 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, bool left)
- {
- if (Entity::useItem(zSlot->zStack() && zSlot->zStack()->zItem()
- ? zSlot->zStack()->zItem()->getTypeId()
- : ItemTypeEnum::PLAYER_HAND,
- (ItemStack*)zSlot->zStack(),
- left))
- {
- zSlot->update();
- if (zSlot->zStack())
- {
- if (zSlot->zStack()->zItem()->getDurability() <= 0)
- {
- ItemStack* stack = zSlot->takeItemsOut(
- zSlot->getNumberOfItems(), NO_DIRECTION);
- Item* broken
- = stack->zItem()->zItemType()->breakItem(stack->zItem());
- if (broken)
- {
- ItemStack* newStack
- = new ItemStack(broken, stack->getSize());
- zSlot->addItems(newStack, NO_DIRECTION);
- if (newStack->getSize() > 0)
- {
- Game::INSTANCE->spawnItem(
- getLocation(), getDimensionId(), newStack);
- }
- else
- {
- newStack->release();
- }
- }
- stack->release();
- }
- else if (zSlot->zStack()->zItem()->getHp() <= 0)
- {
- ItemStack* stack = zSlot->takeItemsOut(
- zSlot->getNumberOfItems(), NO_DIRECTION);
- Framework::Array<ItemSlot*> fromSlots;
- for (ItemSlot* slot : *this)
- {
- if (slot != zSlot) fromSlots.add(slot);
- }
- Framework::Array<ItemSlot*> targetSlots;
- targetSlots.add(zSlot);
- TypeItemFilter filter;
- filter.setType(stack->zItem()->zItemType());
- localTransaction(&fromSlots,
- &targetSlots,
- &filter,
- zSlot->getFreeSpace(),
- NO_DIRECTION,
- NO_DIRECTION);
- stack->release();
- }
- }
- updateSlot(zSlot);
- }
- }
- 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), true);
- if ((keyState | Key::RIGHT_HAND_ACTION) == keyState)
- useItemSlot(itemBar.get(leftHandPosition), false);
- 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,
- !itemBar.get(leftHandPosition)->isEmpty()
- ? itemBar.get(leftHandPosition)->zStack()->zItem()
- : 0);
- break;
- }
- case 3:
- { // switch item bar position
- zRequest->lese((char*)&leftHandPosition, 4);
- leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
- NetworkMessage* msg = new NetworkMessage();
- msg->addressUIElement("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:
- {
- Game::INSTANCE->zUIController()->addDialog(
- new UIDialog("player_inventory",
- getId(),
- new Framework::XML::Element(getInventoryUIML())));
- break;
- }
- case 5:
- {
- // request gui
- Framework::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, dimensionId);
- }
- 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, 0);
- }
- 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, dimensionId);
- }
- 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, 0);
- }
- 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, dimensionId));
- }
- 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->addressUIElement("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 9: // open quest dialog
- {
- Game::INSTANCE->zUIController()->addDialog(
- new QuestDialog(getId()));
- break;
- }
- case 10: // fall damage
- {
- float speed = 0.f;
- zRequest->lese((char*)&speed, 4);
- onFall(speed);
- break;
- }
- }
- }
- void Player::onFall(float collisionSpeed)
- {
- Entity::onFall(collisionSpeed);
- // TODO: check validity
- }
- void Player::onDeath()
- {
- this->setHP(this->getMaxHP());
- Game::INSTANCE->zChat()->broadcastMessage(
- name + " died!", Chat::CHANNEL_INFO);
- // TODO: respown
- }
- PlayerEntityType::PlayerEntityType()
- : EntityType("Player",
- new ModelInfo("entities.m3/player",
- toArray("entities.ltdb/player.png", 6),
- 0,
- 1.f))
- {}
- 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)Framework::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);
- }
|