void cWolf::OnRightClicked(cPlayer & a_Player) { if (!IsTame() && !IsAngry()) { if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_BONE) { if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } if (m_World->GetTickRandomNumber(7) == 0) { SetMaxHealth(20); SetIsTame(true); SetOwner(a_Player.GetName()); m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMED); } else { m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMING); } } } else if (IsTame()) { if (a_Player.GetName() == m_OwnerName) // Is the player the owner of the dog? { if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_DYE) { SetCollarColor(15 - a_Player.GetEquippedItem().m_ItemDamage); if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } } else if (IsSitting()) { SetIsSitting(false); } else { SetIsSitting(true); } } } m_World->BroadcastEntityMetadata(*this); }
void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum) { cItem & Dragging = a_Player.GetDraggingItem(); if (Dragging.IsEmpty()) { // Move the item in the dblclicked slot into hand: Dragging = *GetSlot(a_SlotNum, a_Player); cItem EmptyItem; SetSlot(a_SlotNum, a_Player, EmptyItem); } if (Dragging.IsEmpty()) { LOGD("%s DblClicked with an empty hand over empty slot, ignoring", a_Player.GetName().c_str()); return; } // Add as many items from the surrounding area into hand as possible: // First skip full stacks, then if there's still space, process full stacks as well: if (!m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, false)) { m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, true); } m_ParentWindow.BroadcastWholeWindow(); // We need to broadcast, in case the window was a chest opened by multiple players }
void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End) { cItemMap::iterator itr = m_Items.find(a_Player.GetUniqueID()); if (itr == m_Items.end()) { LOGWARNING("Player tossing items (%s) not found in the item map", a_Player.GetName().c_str()); return; } cItems Drops; for (int i = a_Begin; i < a_End; i++) { cItem & Item = itr->second[i]; if (!Item.IsEmpty()) { Drops.push_back(Item); } Item.Empty(); } // for i - itr->second[] double vX = 0, vY = 0, vZ = 0; EulerToVector(-a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2); }
cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { AStringVector Split(StringSplit(a_Command, " ")); if (Split.empty()) { return crUnknownCommand; } CommandMap::iterator cmd = m_Commands.find(Split[0]); if (cmd == m_Commands.end()) { // Command not found // If it started with a slash, ask the plugins if they still want to handle it: if (!a_Command.empty() && (a_Command[0] == '/')) { CommandResult Result = crUnknownCommand; CallHookExecuteCommand(&a_Player, Split, a_Command, Result); return Result; } return crUnknownCommand; } // Ask plugins first if a command is okay to execute the command: CommandResult Result = crBlocked; if (CallHookExecuteCommand(&a_Player, Split, a_Command, Result)) { if (Result == crBlocked) { LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str()); } return Result; } if ( a_ShouldCheckPermissions && !cmd->second.m_Permission.empty() && !a_Player.HasPermission(cmd->second.m_Permission) ) { LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player.GetName().c_str(), Split[0].c_str()); return crNoPermission; } ASSERT(cmd->second.m_Handler != nullptr); if (!cmd->second.m_Handler->ExecuteCommand(Split, &a_Player, a_Command, nullptr)) { return crError; } return crExecuted; }
void cOcelot::OnRightClicked(cPlayer & a_Player) { if (!IsTame()) { if ( IsBegging() && ((a_Player.GetPosition() - GetPosition()).Length() <= 3) ) { cItems Items; GetBreedingItems(Items); if (Items.ContainsType(a_Player.GetEquippedItem().m_ItemType)) { if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } auto & Random = GetRandomProvider(); if (Random.RandBool(1.0 / 3.0)) { // Taming succeeded SetIsBegging(false); SetMaxHealth(20); SetIsTame(true); SetOwner(a_Player.GetName(), a_Player.GetUUID()); SetCatType(static_cast<eCatType>(Random.RandInt<int>(1, 3))); m_World->BroadcastEntityStatus(*this, esWolfTamed); m_World->BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); } else { // Taming failed m_World->BroadcastEntityStatus(*this, esWolfTaming); m_World->BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); } } } else { super::OnRightClicked(a_Player); } } else if (a_Player.GetUUID() == m_OwnerUUID) { super::OnRightClicked(a_Player); SetIsSitting(!IsSitting()); } m_World->BroadcastEntityMetadata(*this); }
void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) { const cItem & HeldItem = a_Player.GetEquippedItem(); cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); WriteString(a_Player.GetName()); WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); Flush(); }
void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) { cCSLock Lock(m_CSPacket); AString PlayerName(a_Player.GetColor()); PlayerName.append(a_Player.GetName()); if (PlayerName.length() > 14) { PlayerName.erase(14); } PlayerName += cChatColor::White; WriteByte ((unsigned char)PACKET_PLAYER_LIST_ITEM); WriteString(PlayerName); WriteBool (a_IsOnline); WriteShort (a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); Flush(); }
void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player) { const cItem & HeldItem = a_Player.GetEquippedItem(); cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); WriteString(a_Player.GetName()); WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); // Player metadata: just use a default metadata value, since the client doesn't like starting without any metadata: WriteByte (0); // Index 0, byte (flags) WriteByte (0); // Flags, empty WriteByte (0x7f); // End of metadata Flush(); }
void cMobHeadEntity::SetOwner(const cPlayer & a_Owner) { if (m_Type != SKULL_TYPE_PLAYER) { return; } m_OwnerName = a_Owner.GetName(); m_OwnerUUID = a_Owner.GetUUID(); const Json::Value & Properties = a_Owner.GetClientHandle()->GetProperties(); for (auto & Node : Properties) { if (Node.get("name", "").asString() == "textures") { m_OwnerTexture = Node.get("value", "").asString(); m_OwnerTextureSignature = Node.get("signature", "").asString(); break; } } }
bool cPluginManager::CallHookChat(cPlayer & a_Player, AString & a_Message) { // Check if the message contains a command, execute it: switch (HandleCommand(a_Player, a_Message, true)) { case crExecuted: { // The command has executed successfully return true; } case crBlocked: { // The command was blocked by a plugin using HOOK_EXECUTE_COMMAND // The plugin has most likely sent a message to the player already return true; } case crError: { // An error in the plugin has prevented the command from executing. Report the error to the player: a_Player.SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); return true; } case crNoPermission: { // The player is not allowed to execute this command a_Player.SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); return true; } case crUnknownCommand: { // This was not a known command, keep processing as a message break; } } // Check if the message is a command (starts with a slash). If it is, we know that it wasn't recognised: if (!a_Message.empty() && (a_Message[0] == '/')) { AStringVector Split(StringSplit(a_Message, " ")); ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long a_Player.SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str())); LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player.GetName().c_str(), a_Message.c_str()); return true; // Cancel sending } FIND_HOOK(HOOK_CHAT); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { if ((*itr)->OnChat(a_Player, a_Message)) { return true; } } return false; }
void cWolf::OnRightClicked(cPlayer & a_Player) { const cItem & EquippedItem = a_Player.GetEquippedItem(); const int EquippedItemType = EquippedItem.m_ItemType; if (!IsTame() && !IsAngry()) { // If the player is holding a bone, try to tame the wolf: if (EquippedItemType == E_ITEM_BONE) { if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } if (GetRandomProvider().RandBool(0.125)) { // Taming succeeded SetMaxHealth(20); SetIsTame(true); SetOwner(a_Player.GetName(), a_Player.GetUUID()); m_World->BroadcastEntityStatus(*this, esWolfTamed); m_World->BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); } else { // Taming failed m_World->BroadcastEntityStatus(*this, esWolfTaming); m_World->BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); } } } else if (IsTame()) { // Feed the wolf, restoring its health, or dye its collar: switch (EquippedItemType) { case E_ITEM_RAW_BEEF: case E_ITEM_STEAK: case E_ITEM_RAW_PORKCHOP: case E_ITEM_COOKED_PORKCHOP: case E_ITEM_RAW_CHICKEN: case E_ITEM_COOKED_CHICKEN: case E_ITEM_ROTTEN_FLESH: { if (m_Health < m_MaxHealth) { Heal(ItemHandler(EquippedItemType)->GetFoodInfo(&EquippedItem).FoodLevel); if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } } break; } case E_ITEM_DYE: { if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? { SetCollarColor(EquippedItem.m_ItemDamage); if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } } break; } default: { if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? { SetIsSitting(!IsSitting()); } } } } m_World->BroadcastEntityMetadata(*this); }
void cWindow::Clicked( cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem ) { cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (a_WindowID != m_WindowID) { LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str()); return; } switch (a_ClickAction) { case caLeftClickOutside: case caRightClickOutside: { if (PlgMgr->CallHookPlayerTossingItem(a_Player)) { // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) return; } if (a_Player.IsGameModeCreative()) { a_Player.TossPickup(a_ClickedItem); } if (a_ClickAction == caLeftClickOutside) { // Toss all dragged items: a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); } else { // Toss one of the dragged items: a_Player.TossHeldItem(); } return; } case caLeftClickOutsideHoldNothing: case caRightClickOutsideHoldNothing: { // Nothing needed return; } case caLeftPaintBegin: OnPaintBegin (a_Player); return; case caRightPaintBegin: OnPaintBegin (a_Player); return; case caLeftPaintProgress: OnPaintProgress(a_Player, a_SlotNum); return; case caRightPaintProgress: OnPaintProgress(a_Player, a_SlotNum); return; case caLeftPaintEnd: OnLeftPaintEnd (a_Player); return; case caRightPaintEnd: OnRightPaintEnd(a_Player); return; default: { break; } } if (a_SlotNum < 0) { // TODO: Other click actions with irrelevant slot number (FS #371) return; } int LocalSlotNum = a_SlotNum; int idx = 0; for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) { if (LocalSlotNum < (*itr)->GetNumSlots()) { (*itr)->Clicked(a_Player, LocalSlotNum, a_ClickAction, a_ClickedItem); return; } LocalSlotNum -= (*itr)->GetNumSlots(); idx++; } LOGWARNING("Slot number higher than available window slots: %d, max %d received from \"%s\"; ignoring.", a_SlotNum, GetNumSlots(), a_Player.GetName().c_str() ); }
void cWindow::Clicked( cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem ) { if (a_WindowID != m_WindowID) { LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str()); return; } switch (a_ClickAction) { case caRightClickOutside: { // Toss one of the dragged items: a_Player.TossItem(true); return; } case caLeftClickOutside: { // Toss all dragged items: a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); return; } case caLeftClickOutsideHoldNothing: case caRightClickOutsideHoldNothing: { // Nothing needed return; } case caLeftPaintBegin: OnPaintBegin (a_Player); return; case caRightPaintBegin: OnPaintBegin (a_Player); return; case caLeftPaintProgress: OnPaintProgress(a_Player, a_SlotNum); return; case caRightPaintProgress: OnPaintProgress(a_Player, a_SlotNum); return; case caLeftPaintEnd: OnLeftPaintEnd (a_Player); return; case caRightPaintEnd: OnRightPaintEnd(a_Player); return; } if (a_SlotNum < 0) { // TODO: Other click actions with irrelevant slot number (FS #371) return; } int LocalSlotNum = a_SlotNum; int idx = 0; for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) { if (LocalSlotNum < (*itr)->GetNumSlots()) { (*itr)->Clicked(a_Player, LocalSlotNum, a_ClickAction, a_ClickedItem); return; } LocalSlotNum -= (*itr)->GetNumSlots(); idx++; } LOGWARNING("Slot number higher than available window slots: %d, max %d received from \"%s\"; ignoring.", a_SlotNum, GetNumSlots(), a_Player.GetName().c_str() ); }