/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of Penumbra Overture.
*
* Penumbra Overture is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Penumbra Overture is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Penumbra Overture. If not, see .
*/
#include "Inventory.h"
#include "Init.h"
#include "Player.h"
#include "GameItem.h"
#include "GameItemType.h"
#include "GameMessageHandler.h"
#include "SaveHandler.h"
#include "EffectHandler.h"
#include "RadioHandler.h"
#include "Notebook.h"
#include "HapticGameCamera.h"
#include "GlobalInit.h"
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventory::cInventory(cInit *apInit) : iUpdateable("Inventory")
{
mpInit = apInit;
mpDrawer = apInit->mpGame->GetGraphics()->GetDrawer();
mpGfxBackground = mpDrawer->CreateGfxObject("inventory_background.bmp","diffalpha2d");
//mpBatteryMeter = mpDrawer->CreateGfxObject("inventory_battery_meter.bmp","diffalpha2d");
//mpBatteryMeterBar = mpDrawer->CreateGfxObject("inventory_battery_meter_bar.bmp","diffalpha2d");
//mpBagpack = mpDrawer->CreateGfxObject("inventory_backpack.bmp","diffalpha2d");
//mpHealthFrame = mpDrawer->CreateGfxObject("inventory_health_frame.bmp","diffalpha2d");
//mpHealthBack = mpDrawer->CreateGfxObject("inventory_health_background.bmp","diffalpha2d");
//mpHealthMan_Fine = mpDrawer->CreateGfxObject("inventory_health_fine.bmp","diffalpha2d");
//mpHealthMan_Caution = mpDrawer->CreateGfxObject("inventory_health_caution.bmp","diffalpha2d");
//mpHealthMan_Danger = mpDrawer->CreateGfxObject("inventory_health_danger.bmp","diffalpha2d");
//mpHealthTextFrame = mpDrawer->CreateGfxObject("inventory_health_text_slot.bmp","diffalpha2d");
mpFont = mpInit->mpGame->GetResources()->GetFontManager()->CreateFontData("verdana.fnt");
mpContext = hplNew( cInventoryContext, (mpInit) );
mbMessageActive = false;
msMessage = _W("");
mfMessageAlpha =0;
mpMessageBackground = mpDrawer->CreateGfxObject("effect_black.bmp","diffalpha2d");
///////////////////////////////////
//Init normal slots
cInventorySlot *pSlot = NULL;
int lCount=0;
cVector2f vSlotBegin(400 - 77*2.5f, 15 + 69 + 5);
for(float y=0; y<4; ++y)
for(float x=0; x<6; ++x)
{
pSlot = hplNew( cInventorySlot, (mpInit,vSlotBegin + cVector2f(x * 77,y*69),false,lCount++) );
AddWidget(pSlot);
mlstSlots.push_back(pSlot);
}
///////////////////////////////////
//Init equip slots
int lEquipSlot = 0;
//cVector2f vEquipSlotBegin = cVector2f(400 - 77*5,10);
cVector2f vEquipSlotBegin = cVector2f(400 - 77*4.5f,15);
for(float x=0; x<9; ++x)
{
pSlot = hplNew( cInventorySlot, (mpInit,vEquipSlotBegin + cVector2f(x*77,0),true,lCount++) );
AddWidget(pSlot);
mlstSlots.push_back(pSlot);
pSlot->SetEquipIndex(lEquipSlot++);
mvEquipSlots.push_back(pSlot);
}
///////////////////////////////////
//Init other widgests
cInventoryBattery *pBattery = hplNew( cInventoryBattery,(mpInit,
cRect2f(400 - 77*3.5f, 15 + 69 + 5,77,135),
NULL,30.0f) );
AddWidget(pBattery);
cInventoryHealth *pHealth = hplNew( cInventoryHealth, (mpInit,
cRect2f(400 - 77*3.5f, 15 + 69*3 + 5,
77,135),
NULL,30.0f) );
AddWidget(pHealth);
///////////////////////////////////
//Init items types
mvItemTypes.resize(eGameItemType_LastEnum, NULL);
mvItemTypes[eGameItemType_Normal] = hplNew( cGameItemType_Normal,(mpInit) );
mvItemTypes[eGameItemType_Notebook] = hplNew( cGameItemType_Notebook,(mpInit) );
mvItemTypes[eGameItemType_Note] = hplNew( cGameItemType_Note,(mpInit));
mvItemTypes[eGameItemType_Battery] = hplNew( cGameItemType_Battery,(mpInit) );
mvItemTypes[eGameItemType_Flashlight] = hplNew( cGameItemType_Flashlight,(mpInit) );
mvItemTypes[eGameItemType_GlowStick] = hplNew( cGameItemType_GlowStick,(mpInit) );
mvItemTypes[eGameItemType_Flare] = hplNew( cGameItemType_Flare,(mpInit) );
mvItemTypes[eGameItemType_Painkillers] = hplNew( cGameItemType_Painkillers,(mpInit) );
if(mpInit->mbHasHaptics)
mvItemTypes[eGameItemType_WeaponMelee] = hplNew( cGameItemType_WeaponMeleeHaptX,(mpInit) );
else
mvItemTypes[eGameItemType_WeaponMelee] = hplNew( cGameItemType_WeaponMelee,(mpInit) );
mvItemTypes[eGameItemType_Throw] = hplNew( cGameItemType_Throw,(mpInit) );
Reset();
}
cInventory::~cInventory(void)
{
hplDelete( mpContext );
ClearCallbacks();
for(size_t i=0; impGame->GetGraphics()->GetDrawer();
}
void iInventoryWidget::Draw()
{
if(mpGfxObject==NULL) return;
cVector2l vSize = mpGfxObject->GetMaterial()->GetImage(eMaterialTexture_Diffuse)->GetSize();
mpDrawer->DrawGfxObject(mpGfxObject, cVector3f(mRect.x,mRect.y,mfZ),
cVector2f((float)vSize.x, (float)vSize.y),
cColor(1, mpInit->mpInventory->GetAlpha()));
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// INVENTORY SLOT METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventorySlot::cInventorySlot(cInit *apInit, const cVector2f &avPos, bool abEquip, int alIndex)
: iInventoryWidget(apInit, cRect2f(avPos.x, avPos.y,77, 66),NULL, 10.0f)
{
mpGfxObject = mpDrawer->CreateGfxObject("inventory_slot.bmp","diffalpha2d");
mpItem = NULL;
mbEquip = abEquip;
mlIndex = alIndex;
mpGfxBack = NULL;
mpFont = mpInit->mpGame->GetResources()->GetFontManager()->CreateFontData("verdana.fnt");
}
//-----------------------------------------------------------------------
void cInventorySlot::OnDraw()
{
if(mpItem)
{
cVector3f vPos(mRect.x + 4, mRect.y + 4 ,5);
cVector2l vSize = mpItem->GetGfxObject()->GetMaterial()->GetImage(eMaterialTexture_Diffuse)->GetSize();
mpDrawer->DrawGfxObject(mpItem->GetGfxObject(), vPos,
cVector2f((float)vSize.x, (float)vSize.y),
cColor(1, mpInit->mpInventory->GetAlpha()));
cGameItemType *pType = mpInit->mpInventory->GetItemType(mpItem->GetItemType());
if(pType && pType->GetString(mpItem)!=_W(""))
{
tWString sString = pType->GetString(mpItem);
mpFont->Draw(vPos + cVector3f(0,0,1),12,cColor(1,mpInit->mpInventory->GetAlpha()),eFontAlign_Left,
sString.c_str());
}
else if(mpItem->HasCount())
{
mpFont->Draw(vPos + cVector3f(0,0,1),12,cColor(1,mpInit->mpInventory->GetAlpha()),eFontAlign_Left,
_W("%d"),mpItem->GetCount());
}
}
// Equip slot specifics
if(mbEquip)
{
if(mpGfxBack == NULL)
{
mpGfxBack = mpDrawer->CreateGfxObject("inventory_slot_equip"+cString::ToString(mlEquipIndex+1)+".bmp","diffalpha2d");
}
mpDrawer->DrawGfxObject(mpGfxBack,cVector3f(mRect.x,mRect.y,1),cVector2f(77,66),
cColor(1,mpInit->mpInventory->GetAlpha()*0.23f));
/*cVector3f vPos(mRect.x + 2,mRect.y + 3 ,11);
tString sString = cString::ToString(mlEquipIndex+1);
cColor Col(1,1,1,mpInit->mpInventory->GetAlpha());
//mpFont->Draw(vPos,13,Col,eFontAlign_Center,sString.c_str());
//Col = cColor(0,0,0,mpInit->mpInventory->GetAlpha());
mpFont->Draw(vPos+cVector3f(1,1,-1),13,Col,eFontAlign_Center,sString.c_str());
mpFont->Draw(vPos+cVector3f(-1,-1,-1),13,Col,eFontAlign_Center,sString.c_str());*/
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnMouseOver()
{
/////////////////////////////
//Moving item
if(mpInit->mpInventory->GetCurrentItem())
{
cInventoryItem *pCurrentItem = mpInit->mpInventory->GetCurrentItem();
if(mpInit->mpInventory->GetCurrentSlot() == this)
{
cGameItemType *pType = mpInit->mpInventory->GetItemType(pCurrentItem->GetItemType());
tString sShortcutAction = pType->GetShortCutAction(pCurrentItem);
if(sShortcutAction != "")
{
tWString wsName = pCurrentItem->GetGameName();
iAction *pAction = mpInit->mpGame->GetInput()->GetAction(sShortcutAction);
if(pAction) wsName = wsName + _W(" (")+ cString::To16Char(pAction->GetInputName()) +_W(")");
mpInit->mpInventory->SetItemName(wsName);
}
else
{
mpInit->mpInventory->SetItemName(pCurrentItem->GetGameName());
}
mpInit->mpInventory->SetItemDesc(pCurrentItem->GetDescription());
}
else if(mpItem)
{
mpInit->mpInventory->SetItemDesc(_W(""));
tWString sDesc = kTranslate("Inventory", "Combine") +_W(" ")+ pCurrentItem->GetGameName() +_W(" ") +
kTranslate("Inventory", "with") +_W(" ")+mpItem->GetGameName();
mpInit->mpInventory->SetItemName(sDesc);
}
}
/////////////////////////////
//Not moving item
else
{
if(mpItem)
{
cGameItemType *pType = mpInit->mpInventory->GetItemType(mpItem->GetItemType());
tString sShortcutAction = pType->GetShortCutAction(mpItem);
if(sShortcutAction != "")
{
tWString wsName = mpItem->GetGameName();
iAction *pAction = mpInit->mpGame->GetInput()->GetAction(sShortcutAction);
if(pAction) wsName = wsName + _W(" (")+ cString::To16Char(pAction->GetInputName()) +_W(")");
mpInit->mpInventory->SetItemName(wsName);
}
else
{
mpInit->mpInventory->SetItemName(mpItem->GetGameName());
}
mpInit->mpInventory->SetItemDesc(mpItem->GetDescription());
}
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnMouseDown(eMButton aButton)
{
/////////////////////////////////
//Left button
if(aButton == eMButton_Left)
{
if(mpItem!=NULL)
{
mpInit->mpInventory->SetCurrentItem(mpItem);
mpInit->mpInventory->SetCurrentSlot(this);
mpItem = NULL;
cVector2f vOffset = cVector2f(mRect.x + 4, mRect.y + 4) -
mpInit->mpInventory->GetMousePos();
mpInit->mpInventory->SetCurrentItemOffset(vOffset);
}
}
/////////////////////////////////
//Right button
else if(aButton == eMButton_Right)
{
if(mpItem)
{
mpInit->mpInventory->GetContext()->SetActive(true);
mpInit->mpInventory->GetContext()->Setup(mpItem, mpInit->mpInventory->GetMousePos());
}
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnMouseUp(eMButton aButton)
{
/////////////////////////////////
//Left mouse
if(aButton == eMButton_Left)
{
if(mpInit->mpInventory->GetCurrentItem())
{
if(mpItem == NULL)
{
mpItem = mpInit->mpInventory->GetCurrentItem();
}
else
{
tString sCurrentItemName = mpInit->mpInventory->GetCurrentItem()->GetName();
if(mpInit->mpInventory->CheckCombineCallback(mpItem->GetName(),sCurrentItemName, mlIndex))
{
//mpInit->mpInventory->RemoveItem(mpInit->mpInventory->GetCurrentItem());
if(mpInit->mpInventory->GetItem(sCurrentItemName))
mpInit->mpInventory->GetCurrentSlot()->SetItem(mpInit->mpInventory->GetCurrentItem());
}
else
{
mpInit->mpInventory->GetCurrentSlot()->SetItem(mpInit->mpInventory->GetCurrentItem());
}
}
mpInit->mpInventory->SetCurrentItem(NULL);
mpInit->mpInventory->SetCurrentSlot(NULL);
mpInit->mpInventory->SetDroppedInSlot(true);
}
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnDoubleClick(eMButton aButton)
{
/////////////////////////////////
//Left mouse
if(aButton == eMButton_Left)
{
//The player might be holding the item when double clicking.
cInventoryItem *pItem = mpItem;
if(pItem == NULL && mpInit->mpInventory->GetCurrentSlot() == this)
{
pItem = mpInit->mpInventory->GetCurrentItem();
if(pItem){
mpInit->mpInventory->GetCurrentSlot()->SetItem(mpInit->mpInventory->GetCurrentItem());
mpInit->mpInventory->SetCurrentItem(NULL);
mpInit->mpInventory->SetCurrentSlot(NULL);
}
}
if(pItem)
{
cGameItemType *pItemType = mpInit->mpInventory->GetItemType(pItem->GetItemType());
if(pItemType==NULL){
Warning("Itemtype %d does not exist\n",pItem->GetItemType());
return;
}
//Check there is a callback for the item with object = ""
if(mpInit->mpInventory->CheckUseCallback(pItem->GetName(), ""))
{
mpInit->mpInventory->SetActive(false);
}
//Use the action of the item
else if(pItemType->OnAction(pItem, 0)==false)
{
mpInit->mpInventory->SetActive(false);
}
}
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnShortcutDown(int alNum)
{
if(mpItem)
{
cInventorySlot *pSlot = mpInit->mpInventory->GetEquipSlot(alNum);
if(pSlot == this) return;
cInventoryItem *pThisItem = mpItem;
if(pSlot->mpItem) SetItem(pSlot->mpItem);
else SetItem(NULL);
pSlot->SetItem(pThisItem);
}
}
//-----------------------------------------------------------------------
void cInventorySlot::OnUpdate(float afTimeStep)
{
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC ITEM METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventoryItem::cInventoryItem(cInit *apInit)
{
mpInit = apInit;
mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer();
mpGfxObject = NULL;
mpGfxObjectAdditive = NULL;
}
cInventoryItem::~cInventoryItem()
{
if(mpGfxObject) mpDrawer->DestroyGfxObject(mpGfxObject);
if(mpGfxObjectAdditive) mpDrawer->DestroyGfxObject(mpGfxObjectAdditive);
}
//-----------------------------------------------------------------------
bool cInventoryItem::Init(cGameItem *apGameItem)
{
//Init all stuff
msName = apGameItem->GetName();
if(apGameItem->GetImageFile()!="")
{
mpGfxObject = mpDrawer->CreateGfxObject(apGameItem->GetImageFile(),"diffalpha2d");
mpGfxObjectAdditive = mpDrawer->CreateGfxObject(apGameItem->GetImageFile(),"diffadditive2d");
}
else
mpGfxObject = NULL;
msDescription = apGameItem->GetDescription();
msGameName = apGameItem->GetGameName();
mItemType = apGameItem->GetItemType();
msSubType = apGameItem->GetSubType();
msHudModelFile = apGameItem->GetHudModelFile();
msHudModelName = apGameItem->GetHudModelName();
mbCanBeDropped = apGameItem->CanBeDropped();
mbHasCount = apGameItem->HasCount();
mlCount = apGameItem->GetCount();
msEntityFile = apGameItem->GetMeshEntity()->GetSourceFile();
return true;
}
//-----------------------------------------------------------------------
bool cInventoryItem::InitFromFile(const tString &asFile)
{
tString sEntityFile = cString::SetFileExt(asFile,"ent");
tString sPath = mpInit->mpGame->GetResources()->GetFileSearcher()->GetFilePath(sEntityFile);
if(sPath!="")
{
TiXmlDocument *pEntityDoc = hplNew( TiXmlDocument, () );
if(pEntityDoc->LoadFile(sPath.c_str())==false)
{
Error("Couldn't load '%s'!\n",sPath.c_str());
return false;
}
else
{
TiXmlElement *pRootElem = pEntityDoc->FirstChildElement();
TiXmlElement *pMainElem = pRootElem->FirstChildElement("MAIN");
TiXmlElement *pGameElem = pRootElem->FirstChildElement("GAME");
msSubType = cString::ToString(pMainElem->Attribute("Subtype"),"");
tString sImageFile = cString::ToString(pGameElem->Attribute("ImageFile"),"");
mbCanBeDropped = cString::ToBool(pGameElem->Attribute("CanBeDropped"),true);
mbHasCount = cString::ToBool(pGameElem->Attribute("HasCount"),false);
mlCount = cString::ToInt(pGameElem->Attribute("Count"),1);
msHudModelFile = cString::ToString(pGameElem->Attribute("HudModelFile"),"");
msHudModelName = cString::ToString(pGameElem->Attribute("HudModelName"),"");
tString sNameCat = cString::ToString(pGameElem->Attribute("NameCat"),"");
tString sNameEntry = cString::ToString(pGameElem->Attribute("NameEntry"),"");
tString sDescCat = cString::ToString(pGameElem->Attribute("DescCat"),"");
tString sDescEntry = cString::ToString(pGameElem->Attribute("DescEntry"),"");
msGameName = kTranslate(sNameCat, sNameEntry);
msDescription = kTranslate(sDescCat, sDescEntry);
mItemType = cEntityLoader_GameItem::ToItemType(pGameElem->Attribute("ItemType"));
if(sImageFile != "")
{
mpGfxObject = mpDrawer->CreateGfxObject(sImageFile,"diffalpha2d");
mpGfxObjectAdditive = mpDrawer->CreateGfxObject(sImageFile,"diffadditive2d");
}
else
mpGfxObject = NULL;
msEntityFile = sEntityFile;
}
hplDelete( pEntityDoc );
}
else
{
Error("Entity file '%s' was not found!\n",asFile.c_str());
return false;
}
return true;
}
//-----------------------------------------------------------------------
void cInventoryItem::Drop()
{
cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D();
cCamera3D *pCamera = mpInit->mpPlayer->GetCamera();
cMatrixf mtxItem = cMatrixf::Identity;
mtxItem.SetTranslation(pCamera->GetPosition());
iEntity3D* pEntity = pWorld->CreateEntity(msName, mtxItem,msEntityFile, true);
if(pEntity)
{
cMeshEntity *pMesh = static_cast(pEntity);
if(pMesh->GetBody())
{
pMesh->GetBody()->AddImpulse(pCamera->GetForward() * 3.2f);
}
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// INVENTORY BATTERY
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventoryBattery::cInventoryBattery(cInit *apInit, const cRect2f &aRect, cGfxObject* apGfxObject,
float afZ)
: iInventoryWidget(apInit,aRect,apGfxObject,afZ)
{
mpGfxObject = mpDrawer->CreateGfxObject("inventory_slot_double.bmp","diffalpha2d");
mpGfxBatteryMeter = mpDrawer->CreateGfxObject("inventory_battery_meter.bmp","diffalpha2d");
mpGfxBatteryMeterBar = mpDrawer->CreateGfxObject("inventory_battery_meter_bar.bmp","diffalpha2d");
}
cInventoryBattery::~cInventoryBattery()
{
mpDrawer->DestroyGfxObject(mpGfxBatteryMeter);
mpDrawer->DestroyGfxObject(mpGfxBatteryMeterBar);
}
void cInventoryBattery::OnDraw()
{
cVector3f vPos = cVector3f(mRect.x, mRect.y, mfZ+1);
cVector2f vSize(mRect.w, mRect.h);
float fAlpha = mpInit->mpInventory->GetAlpha();
float fPercent = mpInit->mpPlayer->GetPower()/100.0f;
mpDrawer->DrawGfxObject(mpGfxBatteryMeter,vPos,vSize,cColor(1,fAlpha));
mpDrawer->DrawGfxObject(mpGfxBatteryMeterBar,cVector3f(vPos.x+26,vPos.y+16,4),
cVector2f(21,102),
cColor(0,0,0,fAlpha));
mpDrawer->DrawGfxObject(mpGfxBatteryMeterBar,
cVector3f(vPos.x+26,vPos.y+16 + (102*(1-fPercent)),5),
cVector2f(21, 102*fPercent),
cColor( 1.0f-fPercent,fPercent, 0,fAlpha));
//mpFont->Draw(cVector3f(vBatteryPos.x+50, vBatteryPos.y+6,10),20,cColor(0.91f,1,0.91f,mfAlpha),eFontAlign_Left,
//_W("%.0f%%"),mpInit->mpPlayer->GetPower());
}
void cInventoryBattery::OnMouseOver()
{
char sPercent[256];
sprintf(sPercent," %.0f%% ",mpInit->mpPlayer->GetPower());
mpInit->mpInventory->SetItemName(kTranslate("Inventory", "BatteryLevel"));
mpInit->mpInventory->SetItemDesc( kTranslate("Inventory", "BatteryLevelDesc1") +
cString::To16Char(sPercent) +
kTranslate("Inventory", "BatteryLevelDesc2"));
}
void cInventoryBattery::OnUpdate(float afTimeStep)
{
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// INVENTORY HEALTH
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventoryHealth::cInventoryHealth(cInit *apInit, const cRect2f &aRect, cGfxObject* apGfxObject,
float afZ)
: iInventoryWidget(apInit,aRect,apGfxObject,afZ)
{
mpGfxObject = mpDrawer->CreateGfxObject("inventory_slot_double.bmp","diffalpha2d");
mpGfxFine = mpDrawer->CreateGfxObject("inventory_health_fine.bmp","diffalpha2d");
mpGfxCaution = mpDrawer->CreateGfxObject("inventory_health_caution.bmp","diffalpha2d");
mpGfxDanger = mpDrawer->CreateGfxObject("inventory_health_danger.bmp","diffalpha2d");
}
cInventoryHealth::~cInventoryHealth()
{
mpDrawer->DestroyGfxObject(mpGfxFine);
mpDrawer->DestroyGfxObject(mpGfxCaution);
mpDrawer->DestroyGfxObject(mpGfxDanger);
}
void cInventoryHealth::OnDraw()
{
cVector3f vPos = cVector3f(mRect.x, mRect.y, mfZ+1);
cVector2f vSize(mRect.w, mRect.h);
float fAlpha = mpInit->mpInventory->GetAlpha();
float fPercent = mpInit->mpPlayer->GetHealth()/100.0f;
cGfxObject *pGfxMan;
if(fPercent > 0.75f){ pGfxMan = mpGfxFine;
}
else if(fPercent > 0.3f){ pGfxMan = mpGfxCaution;
}
else{ pGfxMan = mpGfxDanger;
}
mpDrawer->DrawGfxObject(pGfxMan,cVector3f(vPos.x+6,vPos.y+6,2),cVector2f(mRect.w-12,mRect.h-12),
cColor( 1.0f-fPercent,fPercent, 0,fAlpha));
}
void cInventoryHealth::OnMouseOver()
{
float fPercent = mpInit->mpPlayer->GetHealth()/100.0f;
tWString wsText;
if(fPercent > 0.75f){
wsText = kTranslate("Inventory","HealthFine");
}
else if(fPercent > 0.3f){
wsText = kTranslate("Inventory","HealthCaution");
}
else{
wsText = kTranslate("Inventory","HealthDanger");
}
mpInit->mpInventory->SetItemName(kTranslate("Inventory", "Health"));
mpInit->mpInventory->SetItemDesc(wsText);
}
void cInventoryHealth::OnUpdate(float afTimeStep)
{
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// INVENTORY CONTEXT METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cInventoryContext::cInventoryContext(cInit *apInit)
{
mpInit = apInit;
mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer();
mbActive = false;
mpGfxBack = mpDrawer->CreateGfxObject("inventory_context_back.bmp","diffalpha2d");
mpGfxCorner11 = mpDrawer->CreateGfxObject("inventory_context_11.bmp","diffalpha2d");
mpGfxCorner12 = mpDrawer->CreateGfxObject("inventory_context_12.bmp","diffalpha2d");
mpGfxCorner21 = mpDrawer->CreateGfxObject("inventory_context_21.bmp","diffalpha2d");
mpGfxCorner22 = mpDrawer->CreateGfxObject("inventory_context_22.bmp","diffalpha2d");
mpGfxRight = mpDrawer->CreateGfxObject("inventory_context_right.bmp","diffalpha2d");
mpGfxLeft = mpDrawer->CreateGfxObject("inventory_context_left.bmp","diffalpha2d");
mpGfxTop = mpDrawer->CreateGfxObject("inventory_context_top.bmp","diffalpha2d");
mpGfxBottom = mpDrawer->CreateGfxObject("inventory_context_bottom.bmp","diffalpha2d");
mvPos.z = 40.0f;
mpFont = mpInit->mpGame->GetResources()->GetFontManager()->CreateFontData("verdana.fnt");
mfRowStart =0;
mfRowSize = 15;
mfColLength = 100;
mlSelectedRow = -1;
mfAlpha = 0.0f;
mpActionVec = NULL;
}
//-----------------------------------------------------------------------
cInventoryContext::~cInventoryContext()
{
}
//-----------------------------------------------------------------------
void cInventoryContext::SetActive(bool abX)
{
mbActive = abX;
if(mbActive)
{
}
else
{
}
}
//-----------------------------------------------------------------------
void cInventoryContext::Draw()
{
if(mfAlpha <= 0.0f || mpActionVec==NULL) return;
float fTotalAlpha = mfAlpha * mpInit->mpInventory->GetAlpha();
mpDrawer->DrawGfxObject(mpGfxBack,mvPos,mvSize,cColor(1,fTotalAlpha));
//Corners
cVector2f vCornerSize(3,3);
mpDrawer->DrawGfxObject(mpGfxCorner11,mvPos - vCornerSize,vCornerSize,cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxCorner21,mvPos + cVector3f(mfColLength, -vCornerSize.y,0),
vCornerSize,cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxCorner12,mvPos + cVector3f(-vCornerSize.x,mvSize.y,0),
vCornerSize,cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxCorner22,mvPos + cVector3f(mvSize.x,mvSize.y,0),
vCornerSize,cColor(1,fTotalAlpha));
//Sides
mpDrawer->DrawGfxObject(mpGfxLeft,mvPos + cVector3f(-vCornerSize.x,0,0),
cVector2f(vCornerSize.x, mvSize.y), cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxRight,mvPos + cVector3f(mvSize.x,0,0),
cVector2f(vCornerSize.x, mvSize.y), cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxTop,mvPos + cVector3f(0,-vCornerSize.y,0),
cVector2f(mvSize.x,vCornerSize.y), cColor(1,fTotalAlpha));
mpDrawer->DrawGfxObject(mpGfxTop,mvPos + cVector3f(0,mvSize.y,0),
cVector2f(mvSize.x,vCornerSize.y), cColor(1,fTotalAlpha));
for(int i=0; i< (int)mpActionVec->size(); i++)
{
cColor Col = mlSelectedRow == i? cColor(0.2f,1.0f,0.2f,mfAlpha) : cColor(0.65f,0.65f,0.65f,fTotalAlpha);
//mpFont->Draw(mvPos + cVector3f(2.0f,(float)i*mfRowSize,1),14,Col,
// eFontAlign_Left,(*mpActionVec)[i].c_str());
}
}
//-----------------------------------------------------------------------
void cInventoryContext::Update(float afTimeStep)
{
////////////////////////////////
// Change alpha
if(mbActive==false)
{
mfAlpha -= 2.5f * afTimeStep;
if(mfAlpha<0) mfAlpha = 0;
return;
}
else
{
mfAlpha += 2.3f * afTimeStep;
if(mfAlpha>1) mfAlpha = 1;
}
mpInit->mpInventory->SetItemDesc(mpItem->GetDescription());
mpInit->mpInventory->SetItemName(mpItem->GetGameName());
///////////////////////////////////////
//Check if the mouse is over any row
cVector2f vMousePos = mpInit->mpInventory->GetMousePos();
mlSelectedRow = -1;
for(int i=0; i< (int)mpActionVec->size(); i++)
{
cRect2f Rect(mvPos.x,mvPos.y + mfRowStart + (float)i * mfRowSize,
mfColLength, mfRowSize);
if(cMath::PointBoxCollision(vMousePos,Rect))
{
mlSelectedRow = i;
break;
}
}
}
//-----------------------------------------------------------------------
void cInventoryContext::OnMouseDown(eMButton aButton)
{
/////////////////////////////////
//Left button
if(aButton == eMButton_Left)
{
if(mlSelectedRow != -1)
{
cGameItemType *pItemType = mpInit->mpInventory->GetItemType(mpItem->GetItemType());
if(pItemType->OnAction(mpItem, mlSelectedRow)==false)
{
mpInit->mpInventory->SetActive(false);
}
}
mbActive = false;
}
/////////////////////////////////
//Right button
else if(aButton == eMButton_Right)
{
mbActive = false;
}
}
//-----------------------------------------------------------------------
void cInventoryContext::OnMouseUp(eMButton aButton)
{
}
//-----------------------------------------------------------------------
void cInventoryContext::Setup(cInventoryItem *apItem, const cVector2f& avPos)
{
mpItem = apItem;
mvPos = avPos;
cGameItemType *pItemType = mpInit->mpInventory->GetItemType(apItem->GetItemType());
mpActionVec = pItemType->GetActions(apItem->CanBeDropped());
mvSize = cVector2f(mfColLength, (float)mpActionVec->size()* mfRowSize + 8);
mRect = cRect2f(mvPos.x, mvPos.y, mvSize.x, mvSize.y);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cInventory::OnStart()
{
}
//-----------------------------------------------------------------------
void cInventory::Update(float afTimeStep)
{
////////////////////////////////
// Change alpha
if(mbActive==false)
{
mfAlpha -= 2.5f * afTimeStep;
if(mfAlpha<0) mfAlpha = 0;
mfMessageAlpha -= 3.1f *afTimeStep;
if(mfMessageAlpha<0) mfMessageAlpha =0;
return;
}
else
{
mfAlpha += 2.3f * afTimeStep;
if(mfAlpha>1) mfAlpha = 1;
}
///////////////////////////////
//Iterate widgets
if(mpContext->IsActive()==false)
{
mbDrawText = false;
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
pWidget->OnUpdate(afTimeStep);
if(cMath::PointBoxCollision(mvMousePos,pWidget->GetRect()))
{
pWidget->OnMouseOver();
}
}
}
/////////////////////
// Context Menu
mpContext->Update(afTimeStep);
/////////////////////
// Inventory message
if(mbMessageActive)
{
mfMessageAlpha += 2.7f *afTimeStep;
if(mfMessageAlpha>1) mfMessageAlpha =1;
}
else
{
mfMessageAlpha -= 3.1f *afTimeStep;
if(mfMessageAlpha<0) mfMessageAlpha =0;
}
/////////////////////
// Text alpha
if(mbDrawText)
{
mfTextAlpha += 2.8f *afTimeStep;
if(mfTextAlpha>1.0f) mfTextAlpha = 1.0f;
}
else
{
mfTextAlpha -= 3.1f *afTimeStep;
if(mfTextAlpha<0.0f) mfTextAlpha = 0.0f;
}
}
//-----------------------------------------------------------------------
void cInventory::Reset()
{
//reset variables
mLastCrossHairState = eCrossHairState_Active;
mbActive = false;
mfAlpha = 0.0f;
mfTextAlpha = 0.0f;
msItemName = _W("");
msItemDesc = _W("");
mpCurrentItem = NULL;
mpCurrentSlot = NULL;
mbCheckingCombineItems = false;
mbMessageActive = false;
mbNoteBookIsActive = false;
//Remove all callbacks
ClearCallbacks();
//Clear all the slots
//Normal
tInventorySlotListIt it = mlstSlots.begin();
for(; it != mlstSlots.end(); ++it)
{
cInventorySlot *pSlot = *it;
pSlot->SetItem(NULL);
}
//Equip
for(size_t i=0; i < mvEquipSlots.size(); ++i)
{
mvEquipSlots[i]->SetItem(NULL);
}
STLMapDeleteAll(m_mapItems);
}
//-----------------------------------------------------------------------
void cInventory::OnDraw()
{
if(mfAlpha<=0.0f) return;
///////////////////////////////
//Draw background
mpDrawer->DrawGfxObject(mpGfxBackground,cVector3f(0,0,0),cVector2f(800,600),cColor(1,mfAlpha));
//Draw backpack and hands
//mpDrawer->DrawGfxObject(mpBagpack,cVector3f(0,600 - (160*sqrt(mfAlpha)),-1),cVector2f(800,160),cColor(1,mfAlpha));
///////////////////////////////
//Draw power remaining:
///////////////////////////////
//Draw health
/*fPercent = mpInit->mpPlayer->GetHealth()/100.0f;
cVector2f vManPos(640,120);
mpDrawer->DrawGfxObject(mpHealthFrame,cVector3f(vManPos.x,vManPos.y,2),cVector2f(150,266),cColor(1,mfAlpha));
mpDrawer->DrawGfxObject(mpHealthBack,cVector3f(vManPos.x,vManPos.y,2),cVector2f(150,266),
cColor((1-fPercent)*0.7f + 0.3f,fPercent*0.7f + 0.3f, 0.3f, mfAlpha));
cGfxObject *pGfxMan;
tWString wsText;
if(fPercent > 0.75f){ pGfxMan = mpHealthMan_Fine;
wsText = kTranslate("Inventory","HealthFine");
}
else if(fPercent > 0.3f){ pGfxMan = mpHealthMan_Caution;
wsText = kTranslate("Inventory","HealthCaution");
}
else{ pGfxMan = mpHealthMan_Danger;
wsText = kTranslate("Inventory","HealthDanger");
}
mpDrawer->DrawGfxObject(pGfxMan,cVector3f(vManPos.x,vManPos.y,2),cVector2f(150,266),cColor(1,mfAlpha));
mpDrawer->DrawGfxObject(mpHealthTextFrame,cVector3f(vManPos.x,vManPos.y+266+10,2),cVector2f(150,66),cColor(1,mfAlpha));
mpFont->Draw(cVector3f(vManPos.x+75,vManPos.y+266+10+4,10),20,cColor(0.91f,1,0.91f,mfAlpha),eFontAlign_Center,
wsText.c_str());*/
///////////////////////////////
//Draw Widgets
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
pWidget->Draw();
pWidget->OnDraw();
}
//////////////////////////////
//Draw Selected item
if(mpCurrentItem)
{
cVector3f vPos(mvMousePos.x + mvCurrentItemOffset.x,
mvMousePos.y + mvCurrentItemOffset.y,15);
cVector2l vSize = mpCurrentItem->GetGfxObject()->GetMaterial()->GetImage(eMaterialTexture_Diffuse)->GetSize();
mpDrawer->DrawGfxObject(mpCurrentItem->GetGfxObject(), vPos,
cVector2f((float)vSize.x, (float)vSize.y),
cColor(1, mpInit->mpInventory->GetAlpha()));
}
//////////////////////////
//Draw context
mpContext->Draw();
//////////////////////////
//Draw message
if(mfMessageAlpha>0)
{
float fMessAlpha = mfAlpha*mfMessageAlpha;
cVector3f vMessPos = cVector3f(40,275,110);
mpDrawer->DrawGfxObject(mpMessageBackground,cVector3f(0,vMessPos.y - 8,vMessPos.z-2),
cVector2f(800,17*4+8*2),cColor(1,1,1,fMessAlpha *0.92f));
mpFont->DrawWordWrap(vMessPos + cVector3f(0,0,0),720,16,17,cColor(1,1,1,fMessAlpha),eFontAlign_Left,
msMessage.c_str());
mpFont->DrawWordWrap(vMessPos + cVector3f(0,1,-1),720,16,17,cColor(0,0,0,fMessAlpha),eFontAlign_Left,
msMessage.c_str());
}
//////////////////////////
//Draw text
if(mpInit->mpRadioHandler->IsActive()==false || mpInit->mbSubtitles==false)
{
float fTextAlpha = mfAlpha*mfTextAlpha * (1- mfMessageAlpha);
mpFont->Draw(cVector3f(400, 460,10),19,cColor(1,1,1,fTextAlpha),eFontAlign_Center,
_W("%ls"),msItemName.c_str());
mpFont->Draw(cVector3f(400+1, 460+1,9),19,cColor(0,0,0,fTextAlpha),eFontAlign_Center,
_W("%ls"),msItemName.c_str());
mpFont->DrawWordWrap(cVector3f(80,480,10),640,16,17,cColor(1,1,1,fTextAlpha),eFontAlign_Left,
msItemDesc.c_str());
mpFont->DrawWordWrap(cVector3f(80+1,480+1,9),640,16,17,cColor(0,0,0,fTextAlpha),eFontAlign_Left,
msItemDesc.c_str());
}
}
//-----------------------------------------------------------------------
void cInventory::SetActive(bool abX)
{
if(mbActive == abX) return;
mbActive = abX;
if(mbActive)
{
if(mpInit->mbHasHaptics)
mpInit->mpPlayer->GetHapticCamera()->SetActive(false);
mLastCrossHairState = mpInit->mpPlayer->GetCrossHairState();
mvMousePos = cVector2f(400,300);
mpInit->mpPlayer->SetCrossHairPos(mvMousePos);
mpInit->mpPlayer->SetCrossHairState(eCrossHairState_Pointer);
}
else
{
if(mpInit->mbHasHaptics)
mpInit->mpPlayer->GetHapticCamera()->SetActive(true);
mpInit->mpPlayer->SetCrossHairState(mLastCrossHairState);
mbMessageActive = false;
}
}
//-----------------------------------------------------------------------
bool cInventory::IsActive()
{
return mbActive;
}
//-----------------------------------------------------------------------
void cInventory::OnInventoryDown()
{
if(mbMessageActive)
{
mbMessageActive = false;
mpInit->mpPlayer->SetCrossHairState(eCrossHairState_Pointer);
return;
}
SetActive(false);
mpInit->mpPlayer->SetCrossHairPos(cVector2f(400,300));
mvMousePos = cVector2f(400,300);
}
//-----------------------------------------------------------------------
void cInventory::AddWidget(iInventoryWidget* apWidget)
{
mlstWidgets.push_back(apWidget);
}
//-----------------------------------------------------------------------
void cInventory::AddItem(cGameItem *apGameItem)
{
tWString sMessage = apGameItem->GetGameName();//kTranslate("Inventory","YouPickedUp") + _W(" ")+apGameItem->GetGameName();
mpInit->mpEffectHandler->GetSubTitle()->Add(sMessage,2.0f,true);
//////////////////////////
//If the item has a count, check if it exists
if(apGameItem->HasCount())
{
cInventoryItem *pFoundItem = NULL;
tInventoryItemMapIt it = m_mapItems.begin();
for(; it != m_mapItems.end(); ++it)
{
cInventoryItem *pItem = it->second;
if( pItem->GetItemType() == apGameItem->GetItemType() &&
pItem->GetSubType() == apGameItem->GetSubType())
{
pFoundItem = pItem;
break;
}
}
if(pFoundItem)
{
pFoundItem->AddCount(apGameItem->GetCount());
CheckPickupCallback(apGameItem->GetName());
return;
}
}
//////////////////////////
//Create item
cInventoryItem *pItem = hplNew( cInventoryItem, (mpInit) );
pItem->Init(apGameItem);
cGameItemType *pType = GetItemType(pItem->GetItemType());
if(pType->OnPickUp(pItem,true)==false)
{
CheckPickupCallback(pItem->GetName());
hplDelete( pItem );
return;
}
m_mapItems.insert(tInventoryItemMap::value_type(pItem->GetName(),pItem));
tInventorySlotListIt it = mlstSlots.begin();
for(; it != mlstSlots.end(); ++it)
{
cInventorySlot *pSlot = *it;
if(pSlot->GetItem()==NULL)
{
pSlot->SetItem(pItem);
CheckPickupCallback(pItem->GetName());
return;
}
}
//TODO: Show message that there is no room for the item.
}
//-----------------------------------------------------------------------
void cInventory::AddItemFromFile(const tString &asName,const tString &asFile, int alSlotIndex)
{
/////////////////////////////////
//Create Item
cInventoryItem *pItem = hplNew( cInventoryItem, (mpInit) );
pItem->SetName(asName);
pItem->InitFromFile(asFile);
cGameItemType *pType = GetItemType(pItem->GetItemType());
if(pType->OnPickUp(pItem,false)==false)
{
CheckPickupCallback(pItem->GetName());
hplDelete( pItem );
return;
}
//////////////////////////
//If the item has a count, check if it exists
if(pItem->HasCount())
{
cInventoryItem *pFoundItem = NULL;
tInventoryItemMapIt it = m_mapItems.begin();
for(; it != m_mapItems.end(); ++it)
{
cInventoryItem *pTempItem = it->second;
if( pTempItem->GetItemType() == pItem->GetItemType() &&
pItem->GetSubType() == pTempItem->GetSubType())
{
pFoundItem = pTempItem;
break;
}
}
if(pFoundItem)
{
pFoundItem->AddCount(pItem->GetCount());
CheckPickupCallback(pItem->GetName());
hplDelete( pItem );
return;
}
}
//////////////////////////
//Add to inventory
m_mapItems.insert(tInventoryItemMap::value_type(pItem->GetName(),pItem));
int lCount=0;
int lCurrentSlot = -1;
tInventorySlotListIt it = mlstSlots.begin();
for(; it != mlstSlots.end(); ++it)
{
cInventorySlot *pSlot = *it;
if( (alSlotIndex <0 && pSlot->GetItem()==NULL && (mpCurrentItem==NULL || mpCurrentSlot != pSlot))
||
(alSlotIndex == lCount))
{
pSlot->SetItem(pItem);
CheckPickupCallback(pItem->GetName());
break;
}
lCount++;
}
}
//-----------------------------------------------------------------------
void cInventory::RemoveItem(cInventoryItem *apItem)
{
tInventorySlotListIt SlotIt = mlstSlots.begin();
for(; SlotIt != mlstSlots.end();SlotIt++)
{
cInventorySlot *pSlot = *SlotIt;
if(pSlot->GetItem() == apItem)
{
pSlot->SetItem(NULL);
}
}
tInventoryItemMapIt it = m_mapItems.begin();
for(; it != m_mapItems.end(); ++it)
{
if(it->second == apItem){
m_mapItems.erase(it);
break;
}
}
if(mpCurrentItem == apItem)
{
mpCurrentItem = NULL;
}
hplDelete( apItem );
}
//-----------------------------------------------------------------------
cInventoryItem *cInventory::GetItem(const tString &asName)
{
tInventoryItemMapIt it = m_mapItems.find(asName);
if(it != m_mapItems.end())
{
return it->second;
}
return NULL;
}
//-----------------------------------------------------------------------
void cInventory::OnMouseDown(eMButton aButton)
{
if(mbMessageActive)
{
mbMessageActive = false;
mpInit->mpPlayer->SetCrossHairState(eCrossHairState_Pointer);
return;
}
//To this to remove context temporarly.
if(aButton == eMButton_Right) return;
/////////////////////////////////
// Context is active
if(mpContext->IsActive())
{
mpContext->OnMouseDown(aButton);
}
/////////////////////////////////
// Normal
else
{
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
if(cMath::PointBoxCollision(mvMousePos,pWidget->GetRect()))
{
pWidget->OnMouseDown(aButton);
}
}
}
}
void cInventory::OnMouseUp(eMButton aButton)
{
/////////////////////////////////
// Context is active
if(mpContext->IsActive())
{
mpContext->OnMouseUp(aButton);
}
/////////////////////////////////
// Normal
else
{
mbDroppedInSlot = false;
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
if(cMath::PointBoxCollision(mvMousePos,pWidget->GetRect()))
{
pWidget->OnMouseUp(aButton);
}
}
/////////////////////////////////////////
// Item is dropped outside of slots or returned to its previous slot.
if(mpCurrentItem && mbDroppedInSlot == false && aButton == eMButton_Left)
{
if(mpCurrentItem->CanBeDropped() && mpCurrentItem->HasCount()==false)
{
mpCurrentItem->Drop();
RemoveItem(mpCurrentItem);
}
else
{
mpInit->mpInventory->GetCurrentSlot()->SetItem(mpInit->mpInventory->GetCurrentItem());
}
mpCurrentItem = NULL;
mpCurrentSlot = NULL;
}
}
}
//-----------------------------------------------------------------------
void cInventory::OnDoubleClick(eMButton aButton)
{
if(mbMessageActive) return;
if(mpContext->IsActive()==false)
{
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
if(cMath::PointBoxCollision(mvMousePos,pWidget->GetRect()))
{
pWidget->OnDoubleClick(aButton);
}
}
}
}
//-----------------------------------------------------------------------
void cInventory::AddMousePos(const cVector2f &avRel)
{
if(mbMessageActive) return;
mvMousePos += avRel;
if(mvMousePos.x < 0) mvMousePos.x =0;
if(mvMousePos.x >= 800) mvMousePos.x =800;
if(mvMousePos.y < 0) mvMousePos.y =0;
if(mvMousePos.y >= 600) mvMousePos.y =600;
mpInit->mpPlayer->SetCrossHairPos(mvMousePos);
}
void cInventory::SetMousePos(const cVector2f &avPos)
{
if(mbMessageActive) return;
mvMousePos = avPos;
mpInit->mpPlayer->SetCrossHairPos(mvMousePos);
}
//-----------------------------------------------------------------------
void cInventory::OnShortcutDown(int alNum)
{
if(mbMessageActive) return;
if(mbActive)
{
tInventoryWidgetListIt it = mlstWidgets.begin();
for(; it != mlstWidgets.end(); ++it)
{
iInventoryWidget *pWidget = *it;
if(cMath::PointBoxCollision(mvMousePos,pWidget->GetRect()))
{
pWidget->OnShortcutDown(alNum);
}
}
}
else
{
cInventoryItem *pItem = mvEquipSlots[alNum]->GetItem();
if(pItem != NULL)
{
//Check there is a callback for the item with object = ""
if(mpInit->mpInventory->CheckUseCallback(pItem->GetName(), ""))
{
return;
}
cGameItemType *pType = mpInit->mpInventory->GetItemType(mvEquipSlots[alNum]->GetItem()->GetItemType());
pType->OnAction(mvEquipSlots[alNum]->GetItem(),0);
}
}
}
//-----------------------------------------------------------------------
void cInventory::SetMessage(const tWString &asMessage)
{
mbMessageActive = true;
msMessage = asMessage;
mpInit->mpPlayer->SetCrossHairState(eCrossHairState_None);
}
//-----------------------------------------------------------------------
void cInventory::AddPickupCallback(const tString &asItem, const tString &asFunction)
{
//Log("Adding callback %s %s\n",asItem.c_str(),asFunction.c_str());
cInventoryPickupCallback *pCallback = hplNew( cInventoryPickupCallback, () );
pCallback->msFunction = asFunction;
pCallback->msItem = asItem;
m_mapPickupCallbacks.insert(tInventoryPickupCallbackMap::value_type(asItem,pCallback));
}
//-----------------------------------------------------------------------
void cInventory::AddUseCallback(const tString &asItem, const tString &asObject, const tString &asFunction)
{
//Check if the item - object combo already exist.
tInventoryUseCallbackMapIt it = m_mapUseCallbacks.find(asItem);
if(it != m_mapUseCallbacks.end())
{
int lCount = (int)m_mapUseCallbacks.count(asItem);
for(int i=0; isecond;
if(pCallback->msObject == asObject)
{
pCallback->msFunction = asFunction;
return;
}
}
}
//Add new.
cInventoryUseCallback *pCallback = hplNew( cInventoryUseCallback,());
pCallback->msFunction = asFunction;
pCallback->msItem = asItem;
pCallback->msObject = asObject;
m_mapUseCallbacks.insert(tInventoryUseCallbackMap::value_type(asItem,pCallback));
}
//-----------------------------------------------------------------------
void cInventory::AddCombineCallback(const tString &asItem1,const tString &asItem2, const tString &asFunction)
{
cInventoryCombineCallback *pCallback = hplNew( cInventoryCombineCallback, () );
pCallback->msFunction = asFunction;
pCallback->msItem1 = asItem1;
pCallback->msItem2 = asItem2;
pCallback->bKillMe = false;
mlstCombineCallbacks.push_back(pCallback);
}
//-----------------------------------------------------------------------
void cInventory::RemovePickupCallback(const tString &asFunction)
{
tInventoryPickupCallbackMapIt it = m_mapPickupCallbacks.begin();
for(; it != m_mapPickupCallbacks.end(); )
{
cInventoryPickupCallback *pCallback = it->second;
if(pCallback->msFunction == asFunction)
{
m_mapPickupCallbacks.erase(it++);
hplDelete( pCallback );
}
else
{
it++;
}
}
}
void cInventory::RemoveUseCallback(const tString &asFunction)
{
tInventoryUseCallbackMapIt it = m_mapUseCallbacks.begin();
for(; it != m_mapUseCallbacks.end(); )
{
cInventoryUseCallback *pCallback = it->second;
if(pCallback->msFunction == asFunction)
{
m_mapUseCallbacks.erase(it++);
hplDelete( pCallback );
}
else
{
it++;
}
}
}
void cInventory::RemoveCombineCallback(const tString &asFunction)
{
tInventoryCombineCallbackListIt it = mlstCombineCallbacks.begin();
for(; it != mlstCombineCallbacks.end(); ++it)
{
cInventoryCombineCallback *pCallback = *it;
if(pCallback->msFunction == asFunction)
{
if(mbCheckingCombineItems)
{
pCallback->bKillMe = true;
}
else
{
mlstCombineCallbacks.erase(it);
hplDelete( pCallback );
}
return;
}
}
}
//-----------------------------------------------------------------------
void cInventory::CheckPickupCallback(const tString &asItem)
{
tInventoryPickupCallbackMapIt it = m_mapPickupCallbacks.find(asItem);
if(it== m_mapPickupCallbacks.end()) return;
cInventoryPickupCallback *pCallback = it->second;
tString sCommand = pCallback->msFunction + "(\""+asItem+"\")";
mpInit->RunScriptCommand(sCommand);
}
//-----------------------------------------------------------------------
bool cInventory::CheckUseCallback(const tString &asItem, const tString &asObject)
{
tInventoryUseCallbackMapIt it = m_mapUseCallbacks.find(asItem);
if(it== m_mapUseCallbacks.end()) return false;
int lItemCount = (int)m_mapUseCallbacks.count(asItem);
tString sCommand="";
for(int i=0; isecond;
if(pCallback->msObject == asObject)
{
sCommand = pCallback->msFunction + "(\""+asItem+"\", \""+asObject+"\")";
break;
}
++it;
}
if(sCommand!="")
{
mpInit->RunScriptCommand(sCommand);
return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cInventory::CheckCombineCallback(const tString &asItem1,const tString &asItem2, int alSlotIndex)
{
cInventoryCombineCallback *pFinalCallback=NULL;
mbCheckingCombineItems = true;
tInventoryCombineCallbackListIt it = mlstCombineCallbacks.begin();
for(; it != mlstCombineCallbacks.end(); ++it)
{
cInventoryCombineCallback *pCallback = *it;
if( (pCallback->msItem1 == asItem1 && pCallback->msItem2 == asItem2) ||
(pCallback->msItem1 == asItem2 && pCallback->msItem2 == asItem1) )
{
pFinalCallback = pCallback;
break;
}
}
mbCheckingCombineItems = false;
if(pFinalCallback)
{
char sString[30];sprintf(sString,"%d",alSlotIndex);
tString sCommand = pFinalCallback->msFunction + "(\""+asItem1+"\", \""+asItem2+"\", "+
cString::ToString(sString,"")+")";
mpInit->RunScriptCommand(sCommand);
return true;
}
else
{
//SetActive(false);
tString sEntry = "CannotCombineItems" + cString::ToString(cMath::RandRectl(1,5));
//mpInit->mpGameMessageHandler->Add(kTranslate("Inventory", sEntry));
SetMessage(kTranslate("Inventory", sEntry));
}
//Check if any callbacks should be killed
for(; it != mlstCombineCallbacks.end(); )
{
cInventoryCombineCallback *pCallback = *it;
if(pCallback->bKillMe)
{
it = mlstCombineCallbacks.erase(it);
hplDelete( pCallback );
}
else
{
++it;
}
}
return false;
}
//-----------------------------------------------------------------------
void cInventory::ClearCallbacks()
{
STLMapDeleteAll(m_mapPickupCallbacks);
STLMapDeleteAll(m_mapUseCallbacks);
STLDeleteAll(mlstCombineCallbacks);
}
//-----------------------------------------------------------------------
void cInventory::SaveToGlobal(cInventory_GlobalSave *apSave)
{
apSave->mbNoteBookActive = mbNoteBookIsActive;
////////////////////////////
//Items
tInventoryItemMapIt ItemIt = m_mapItems.begin();
for(; ItemIt != m_mapItems.end(); ++ItemIt)
{
cInventoryItem *pItem = ItemIt->second;
cInventoryItem_GlobalSave saveItem;
saveItem.msName = pItem->msName;
saveItem.msGameName = pItem->msGameName;
saveItem.msDescription = pItem->msDescription;
saveItem.mItemType = pItem->mItemType;
saveItem.msSubType = pItem->msSubType;
saveItem.msEntityFile = pItem->msEntityFile;
saveItem.msGfxObjectFile = pItem->mpGfxObject->GetSourceFile();
saveItem.msHudModelFile = pItem->msHudModelFile;
saveItem.msHudModelName = pItem->msHudModelName;
saveItem.mbCanBeDropped = pItem->mbCanBeDropped;
saveItem.mbHasCount = pItem->mbHasCount;
saveItem.mlCount = pItem->mlCount;
apSave->mlstItems.Add(saveItem);
}
////////////////////////////
//Equip slots
apSave->mvEquipSlots.Resize(mvEquipSlots.size());
for(size_t i=0; impItem)
apSave->mvEquipSlots[i].msItemName = mvEquipSlots[i]->mpItem->GetName();
else
apSave->mvEquipSlots[i].msItemName = "";
}
////////////////////////////
//Normal slots
tInventorySlotListIt SlotIt = mlstSlots.begin();
for(; SlotIt != mlstSlots.end(); ++SlotIt)
{
cInventorySlot *pSlot = *SlotIt;
cInventorySlot_GlobalSave saveSlot;
if(pSlot->mpItem)
saveSlot.msItemName = pSlot->mpItem->GetName();
else
saveSlot.msItemName = "";
apSave->mlstSlots.Add(saveSlot);
}
}
//-----------------------------------------------------------------------
void cInventory::LoadFromGlobal(cInventory_GlobalSave *apSave)
{
mbNoteBookIsActive = apSave->mbNoteBookActive;
////////////////////////////
//Items
cContainerListIterator ItemIt = apSave->mlstItems.GetIterator();
while(ItemIt.HasNext())
{
cInventoryItem *pItem = hplNew( cInventoryItem, (mpInit) );
cInventoryItem_GlobalSave saveItem = ItemIt.Next();
pItem->msName = saveItem.msName;
pItem->msGameName = saveItem.msGameName;
pItem->msDescription = saveItem.msDescription;
pItem->mItemType = saveItem.mItemType;
pItem->msSubType = saveItem.msSubType;
pItem->msEntityFile = saveItem.msEntityFile;
pItem->mpGfxObject = mpDrawer->CreateGfxObject(saveItem.msGfxObjectFile, "diffalpha2d");
pItem->mpGfxObjectAdditive = mpDrawer->CreateGfxObject(saveItem.msGfxObjectFile,"diffadditive2d");
pItem->msHudModelFile = saveItem.msHudModelFile;
pItem->msHudModelName = saveItem.msHudModelName;
pItem->mbCanBeDropped = saveItem.mbCanBeDropped;
pItem->mbHasCount = saveItem.mbHasCount;
pItem->mlCount = saveItem.mlCount;
m_mapItems.insert(tInventoryItemMap::value_type(pItem->msName,pItem));
}
////////////////////////////
//Equip slots
for(size_t i=0; imvEquipSlots[i].msItemName!="")
mvEquipSlots[i]->mpItem = GetItem(apSave->mvEquipSlots[i].msItemName);
else
mvEquipSlots[i]->mpItem = NULL;
}
////////////////////////////
//Normal slots
cContainerListIterator SlotIt = apSave->mlstSlots.GetIterator();
tInventorySlotListIt SlotListIt = mlstSlots.begin();
while(SlotIt.HasNext())
{
cInventorySlot *pSlot = *SlotListIt;
cInventorySlot_GlobalSave saveSlot = SlotIt.Next();
if(saveSlot.msItemName!="")
pSlot->mpItem = GetItem(saveSlot.msItemName);
else
pSlot->mpItem = NULL;
++SlotListIt;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVE OBJECT STUFF
//////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------
kBeginSerializeBase(cInventoryUseCallback)
kSerializeVar(msItem, eSerializeType_String)
kSerializeVar(msObject, eSerializeType_String)
kSerializeVar(msFunction, eSerializeType_String)
kEndSerialize()
//-------------------------------------------------------------------
kBeginSerializeBase(cInventoryPickupCallback)
kSerializeVar(msItem, eSerializeType_String)
kSerializeVar(msFunction, eSerializeType_String)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cInventoryCombineCallback)
kSerializeVar(msItem1, eSerializeType_String)
kSerializeVar(msItem2, eSerializeType_String)
kSerializeVar(msFunction, eSerializeType_String)
kSerializeVar(bKillMe, eSerializeType_Bool)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cSaveData_cInventory)
kSerializeClassContainer(mlstUseCallbacks,cInventoryUseCallback, eSerializeType_Class)
kSerializeClassContainer(mlstPickupCallbacks,cInventoryPickupCallback, eSerializeType_Class)
kSerializeClassContainer(mlstCombineCallbacks, cInventoryCombineCallback, eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
iSaveObject* cSaveData_cInventory::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler,cGame *apGame)
{
///////////////////////
//Use callbacks
{
cContainerListIterator it = mlstUseCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryUseCallback &temp = it.Next();
gpInit->mpInventory->AddUseCallback(temp.msItem,temp.msObject,temp.msFunction);
}
}
///////////////////////
//Pickup callbacks
{
cContainerListIterator it = mlstPickupCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryPickupCallback &temp = it.Next();
gpInit->mpInventory->AddPickupCallback(temp.msItem,temp.msFunction);
}
}
///////////////////////
//Combine callbacks
{
cContainerListIterator it = mlstCombineCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryCombineCallback &temp = it.Next();
gpInit->mpInventory->AddCombineCallback(temp.msItem1, temp.msItem2, temp.msFunction);
}
}
return NULL;
}
//-----------------------------------------------------------------------
int cSaveData_cInventory::GetSaveCreatePrio()
{
return 4;
}
//-----------------------------------------------------------------------
iSaveData* cInventory::CreateSaveData()
{
cSaveData_cInventory *pData = hplNew( cSaveData_cInventory, () );
//////////////////////
//Use callbacks
{
tInventoryUseCallbackMapIt it = m_mapUseCallbacks.begin();
for(; it != m_mapUseCallbacks.end(); ++it)
{
pData->mlstUseCallbacks.Add(*(it->second));
}
}
//////////////////////
//Pickup callbacks
{
tInventoryPickupCallbackMapIt it = m_mapPickupCallbacks.begin();
for(; it != m_mapPickupCallbacks.end(); ++it)
{
pData->mlstPickupCallbacks.Add(*(it->second));
}
}
//////////////////////
//Combine callbacks
{
tInventoryCombineCallbackListIt it = mlstCombineCallbacks.begin();
for(; it != mlstCombineCallbacks.end(); ++it)
{
pData->mlstCombineCallbacks.Add(*(*it));
}
}
return pData;
}
//-----------------------------------------------------------------------