/* * 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; } //-----------------------------------------------------------------------