diff --git a/src/xrGame/UIGameCustom.cpp b/src/xrGame/UIGameCustom.cpp index 7eaa3523524..b905b909d28 100644 --- a/src/xrGame/UIGameCustom.cpp +++ b/src/xrGame/UIGameCustom.cpp @@ -196,7 +196,7 @@ CScriptGameObject* CUIGameCustom::CurrentItemAtCell() if (!IItm) return nullptr; - CGameObject* GO = IItm->cast_game_object(); + CGameObject* GO = smart_cast(IItm); if (GO) return GO->lua_game_object(); diff --git a/src/xrGame/eatable_item.cpp b/src/xrGame/eatable_item.cpp index d69e7108c47..a31bc1a8e6f 100644 --- a/src/xrGame/eatable_item.cpp +++ b/src/xrGame/eatable_item.cpp @@ -86,10 +86,8 @@ bool CEatableItem::Useful() const return false; //проверить не все ли еще съедено - /*Alundaio: Commented out to prevent crash when placing items with 0 remaining uses inside inventory boxes - if (m_iRemainingUses == 0) + if (m_iRemainingUses == 0 && CanDelete()) return false; - */ return true; } diff --git a/src/xrGame/trade.h b/src/xrGame/trade.h index b37c86552b9..21fdf11662a 100644 --- a/src/xrGame/trade.h +++ b/src/xrGame/trade.h @@ -53,13 +53,13 @@ class CTrade bool IsInTradeState() { return TradeState; } void OnPerformTrade(u32 money_get, u32 money_put); - void TransferItem(CInventoryItem* pItem, bool bBuying); + void TransferItem(CInventoryItem* pItem, bool bBuying, bool bFree = false); CInventoryOwner* GetPartner(); CTrade* GetPartnerTrade(); CInventory* GetPartnerInventory(); - u32 GetItemPrice(CInventoryItem* pItem, bool b_buying); + u32 GetItemPrice(CInventoryItem* pItem, bool b_buying, bool bFree = false); void UpdateTrade(); diff --git a/src/xrGame/trade2.cpp b/src/xrGame/trade2.cpp index daed3df9706..fb8393760b2 100644 --- a/src/xrGame/trade2.cpp +++ b/src/xrGame/trade2.cpp @@ -63,11 +63,11 @@ bool CTrade::CanTrade() return true; } -void CTrade::TransferItem(CInventoryItem* pItem, bool bBuying) +void CTrade::TransferItem(CInventoryItem* pItem, bool bBuying, bool bFree) { // сумма сделки учитывая ценовой коэффициент // актер цену не говорит никогда, все делают за него - u32 dwTransferMoney = GetItemPrice(pItem, bBuying); + u32 dwTransferMoney = GetItemPrice(pItem, bBuying, bFree); if (bBuying) { @@ -136,8 +136,11 @@ CInventory& CTrade::GetTradeInv(SInventoryOwner owner) CTrade* CTrade::GetPartnerTrade() { return pPartner.inv_owner->GetTrade(); } CInventory* CTrade::GetPartnerInventory() { return &GetTradeInv(pPartner); } CInventoryOwner* CTrade::GetPartner() { return pPartner.inv_owner; } -u32 CTrade::GetItemPrice(PIItem pItem, bool b_buying) +u32 CTrade::GetItemPrice(PIItem pItem, bool b_buying, bool bFree) { + if (bFree) + return 0; + CArtefact* pArtefact = smart_cast(pItem); // computing base_cost diff --git a/src/xrGame/ui/UIActorMenu.h b/src/xrGame/ui/UIActorMenu.h index 297efe1c95e..041aa8f83b5 100644 --- a/src/xrGame/ui/UIActorMenu.h +++ b/src/xrGame/ui/UIActorMenu.h @@ -204,6 +204,7 @@ class CUIActorMenu : public CUIDialogWnd, public CUIWndCallback void PropertiesBoxForPlaying(PIItem item, bool& b_show); void PropertiesBoxForDrop(CUICellItem* cell_item, PIItem item, bool& b_show); void PropertiesBoxForRepair(PIItem item, bool& b_show); + void PropertiesBoxForDonate(PIItem item, bool& b_show); //Alundaio private: void clear_highlight_lists(); @@ -361,4 +362,5 @@ class CUIActorMenu : public CUIDialogWnd, public CUIWndCallback IC UIHint* get_hint_wnd() { return m_hint_wnd; } void RefreshCurrentItemCell(); + void DonateCurrentItem(CUICellItem* cell_item); //Alundaio: Donate item via context menu while in trade menu }; // class CUIActorMenu diff --git a/src/xrGame/ui/UIActorMenuInventory.cpp b/src/xrGame/ui/UIActorMenuInventory.cpp index 32776385606..81d9ff80018 100644 --- a/src/xrGame/ui/UIActorMenuInventory.cpp +++ b/src/xrGame/ui/UIActorMenuInventory.cpp @@ -498,8 +498,7 @@ bool CUIActorMenu::ToSlot(CUICellItem* itm, bool force_place, u16 slot_id) { return true; // fake, sorry ((( } - - if (slot_id == OUTFIT_SLOT) + else if (slot_id == OUTFIT_SLOT) { CCustomOutfit* pOutfit = smart_cast(iitem); if (pOutfit && !pOutfit->bIsHelmetAvaliable) @@ -785,7 +784,7 @@ void CUIActorMenu::TryHidePropertiesBox() void CUIActorMenu::ActivatePropertiesBox() { TryHidePropertiesBox(); - if (!(m_currMenuMode == mmInventory || m_currMenuMode == mmDeadBodySearch || m_currMenuMode == mmUpgrade)) + if (!(m_currMenuMode == mmInventory || m_currMenuMode == mmDeadBodySearch || m_currMenuMode == mmUpgrade || m_currMenuMode == mmTrade)) { return; } @@ -818,7 +817,14 @@ void CUIActorMenu::ActivatePropertiesBox() { PropertiesBoxForRepair(item, b_show); } - + //Alundaio: Ability to donate item to npc during trade + else if (m_currMenuMode == mmTrade) + { + CUIDragDropListEx* invlist = GetListByType(iActorBag); + if (invlist->IsOwner(cell_item)) + PropertiesBoxForDonate(item, b_show); + } + //-Alundaio if (b_show) { m_UIPropertiesBox->AutoUpdateSize(); @@ -843,8 +849,7 @@ void CUIActorMenu::PropertiesBoxForSlots(PIItem item, bool& b_show) bool bAlreadyDressed = false; u16 cur_slot = item->BaseSlot(); - if (!pOutfit && !pHelmet && cur_slot != NO_ACTIVE_SLOT && !inv.SlotIsPersistent(cur_slot) && - inv.CanPutInSlot(item, cur_slot)) + if (!pOutfit && !pHelmet && cur_slot != NO_ACTIVE_SLOT && !inv.SlotIsPersistent(cur_slot) /*&& inv.CanPutInSlot(item, cur_slot)*/) { m_UIPropertiesBox->AddItem("st_move_to_slot", NULL, INVENTORY_TO_SLOT_ACTION); b_show = true; @@ -1092,6 +1097,22 @@ void CUIActorMenu::PropertiesBoxForUsing(PIItem item, bool& b_show) m_UIPropertiesBox->AddItem(act_str, nullptr, INVENTORY_EAT3_ACTION); b_show = true; } + + //3rd Custom Use action + act_str = READ_IF_EXISTS(pSettings, r_string, section_name, "use3_text", 0); + if (act_str) + { + m_UIPropertiesBox->AddItem(act_str, nullptr, INVENTORY_EAT4_ACTION); + b_show = true; + } + + //4th Custom Use action + act_str = READ_IF_EXISTS(pSettings, r_string, section_name, "use4_text", 0); + if (act_str) + { + m_UIPropertiesBox->AddItem(act_str, nullptr, INVENTORY_EAT5_ACTION); + b_show = true; + } } void CUIActorMenu::PropertiesBoxForPlaying(PIItem item, bool& b_show) @@ -1132,6 +1153,14 @@ void CUIActorMenu::PropertiesBoxForRepair(PIItem item, bool& b_show) } } +//Alundaio: Ability to donate item during trade +void CUIActorMenu::PropertiesBoxForDonate(PIItem item, bool& b_show) +{ + m_UIPropertiesBox->AddItem("st_donate", nullptr, INVENTORY_DONATE_ACTION); + b_show = true; +} +//-Alundaio + void CUIActorMenu::ProcessPropertiesBoxClicked(CUIWindow* w, void* d) { PIItem item = CurrentIItem(); @@ -1147,6 +1176,7 @@ void CUIActorMenu::ProcessPropertiesBoxClicked(CUIWindow* w, void* d) case INVENTORY_TO_SLOT_ACTION: ToSlot(cell_item, true, item->BaseSlot()); break; case INVENTORY_TO_BELT_ACTION: ToBelt(cell_item, false); break; case INVENTORY_TO_BAG_ACTION: ToBag(cell_item, false); break; + case INVENTORY_DONATE_ACTION: DonateCurrentItem(cell_item); break; case INVENTORY_EAT_ACTION: TryUseItem(cell_item); break; case INVENTORY_EAT2_ACTION: { @@ -1178,6 +1208,36 @@ void CUIActorMenu::ProcessPropertiesBoxClicked(CUIWindow* w, void* d) } break; } + case INVENTORY_EAT4_ACTION: + { + CGameObject* GO = smart_cast(item); + const pcstr functor_name = READ_IF_EXISTS(pSettings, r_string, GO->cNameSect(), "use3_functor", 0); + if (functor_name) + { + luabind::functor funct3; + if (ai().script_engine().functor(functor_name, funct3)) + { + if (funct3(GO->lua_game_object())) + TryUseItem(cell_item); + } + } + break; + } + case INVENTORY_EAT5_ACTION: + { + CGameObject* GO = smart_cast(item); + const pcstr functor_name = READ_IF_EXISTS(pSettings, r_string, GO->cNameSect(), "use4_functor", 0); + if (functor_name) + { + luabind::functor funct4; + if (ai().script_engine().functor(functor_name, funct4)) + { + if (funct4(GO->lua_game_object())) + TryUseItem(cell_item); + } + } + break; + } case INVENTORY_DROP_ACTION: { void* d = m_UIPropertiesBox->GetClickedItem()->GetData(); diff --git a/src/xrGame/ui/UIActorMenuTrade.cpp b/src/xrGame/ui/UIActorMenuTrade.cpp index 4ea08c97bd4..a1b33c8e565 100644 --- a/src/xrGame/ui/UIActorMenuTrade.cpp +++ b/src/xrGame/ui/UIActorMenuTrade.cpp @@ -532,3 +532,28 @@ void CUIActorMenu::TransferItems( pTrade->pThis.inv_owner->set_money(pTrade->pThis.inv_owner->get_money(), true); pTrade->pPartner.inv_owner->set_money(pTrade->pPartner.inv_owner->get_money(), true); } + +//Alundaio: Donate current item while in trade menu +void CUIActorMenu::DonateCurrentItem(CUICellItem* cell_item) +{ + if (!m_partner_trade || !m_pTradePartnerList) + return; + + CUIDragDropListEx* invlist = GetListByType(iActorBag); + if (!invlist->IsOwner(cell_item)) + return; + + PIItem item = static_cast(cell_item->m_pData); + if (!item) + return; + + invlist->RemoveItem(cell_item, false); + + m_partner_trade->TransferItem(item, true, true); + + m_pTradePartnerList->SetItem(cell_item); + + SetCurrentItem(nullptr); + UpdateItemsPlace(); +} +//-Alundaio \ No newline at end of file diff --git a/src/xrGame/ui/UIMessages.h b/src/xrGame/ui/UIMessages.h index 89cf24f11e7..66f80cece85 100644 --- a/src/xrGame/ui/UIMessages.h +++ b/src/xrGame/ui/UIMessages.h @@ -95,6 +95,9 @@ enum EUIMessages //Alundaio INVENTORY_EAT2_ACTION, INVENTORY_EAT3_ACTION, + INVENTORY_EAT4_ACTION, + INVENTORY_EAT5_ACTION, + INVENTORY_DONATE_ACTION, //-Alundaio INVENTORY_PLAY_ACTION, INVENTORY_TO_BELT_ACTION,