Advertisement
CUgopEntity

Inventory.cpp

Jan 23rd, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.37 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "inventory.h"
  3. #include "actor.h"
  4. #include "trade.h"
  5.  
  6. // CInventoryItem class ///////////////////////////////////////////////////////////////////////////////
  7.  
  8. CInventoryItem::CInventoryItem() {
  9.     m_weight = 100.f;
  10.     m_slot = 0xffffffff;
  11.     m_belt = false;
  12.     m_showHUD = true;
  13.     m_pInventory = NULL;
  14.     m_drop = false;
  15.     m_ruck = true;
  16. }
  17.  
  18. CInventoryItem::~CInventoryItem() {}
  19.  
  20. void CInventoryItem::Load(LPCSTR section) {
  21.     inherited::Load(section);
  22.  
  23.     m_name = pSettings->r_string(section, "inv_name");
  24.     m_nameShort = pSettings->r_string(section, "inv_name_short");
  25.     NameComplex();
  26.     m_weight = pSettings->r_float(section, "inv_weight");
  27.  
  28.     m_cost = pSettings->r_u32(section, "cost");
  29. }
  30.  
  31. const char* CInventoryItem::Name() {
  32.     return m_name;
  33. }
  34.  
  35. const char* CInventoryItem::NameShort() {
  36.     return m_nameShort;
  37. }
  38.  
  39. char* CInventoryItem::NameComplex() {
  40.     const char *l_name = Name();
  41.     if(l_name) strcpy(m_nameComplex, l_name); else m_nameComplex[0] = 0;
  42.     for(PPIItem l_it = m_subs.begin(); l_it != m_subs.end(); l_it++) {
  43.         const char *l_subName = (*l_it)->NameShort();
  44.         if(l_subName) strcpy(&m_nameComplex[strlen(m_nameComplex)], l_subName);
  45.     }
  46.     return m_nameComplex;
  47. }
  48.  
  49. bool CInventoryItem::Useful() {
  50.     // Если IItem нельзя использовать, вернуть false
  51.     return true;
  52. }
  53.  
  54. bool CInventoryItem::Attach(PIItem pIItem, bool force) {
  55.     // Аргумент force всегда равен false
  56.     // наследник должен изменить его на true
  57.     // если данный IItem МОЖЕТ быть к нему присоединен,
  58.     // и вызвать return CInventoryItem::Attach(pIItem, force);
  59.     if(force) {
  60.         m_subs.insert(m_subs.end(), pIItem);
  61.         return true;
  62.     } else return false;
  63. }
  64.  
  65. bool CInventoryItem::Detach(PIItem pIItem, bool force) {
  66.     // Аргумент force всегда равен true
  67.     // наследник должен изменить его на false
  68.     // если данный IItem НЕ МОЖЕТ быть отсоединен,
  69.     // и вызвать return CInventoryItem::Detach(pIItem, force);
  70.     if(force) {
  71.         if(m_subs.erase(std::find(m_subs.begin(), m_subs.end(), pIItem)) != m_subs.end()) {
  72.             return true;
  73.         }
  74.         return false;
  75.     }
  76.     else return false;
  77. }
  78.  
  79. bool CInventoryItem::DetachAll() {
  80.     if(!m_pInventory || std::find(m_pInventory->m_ruck.begin(), m_pInventory->m_ruck.end(), this) == m_pInventory->m_ruck.end()) return false;
  81.     for(PPIItem l_it = m_subs.begin(); l_it != m_subs.end(); l_it++) {
  82.         Detach(*l_it);
  83.         //m_pInventory->m_ruck.insert(m_pInventory->m_ruck.end(), *l_it);
  84.         (*l_it)->DetachAll();
  85.     }
  86.     return true;
  87. }
  88.  
  89. bool CInventoryItem::Activate() {
  90.     // Вызывается при активации слота в котором находится объект
  91.     // Если объект может быть активирован вернуть true, иначе false
  92.     return false;
  93. }
  94.  
  95. void CInventoryItem::Deactivate() {
  96.     // Вызывается при деактивации слота в котором находится объект
  97. }
  98.  
  99. void CInventoryItem::Drop() {
  100.     if(m_pInventory) m_drop = true;
  101.  
  102. }
  103.  
  104. s32 CInventoryItem::Sort(PIItem pIItem) {
  105.     // Если нужно разместить IItem после this - вернуть 1, если
  106.     // перед - -1. Если пофиг то 0.
  107.     return 0;
  108. }
  109.  
  110. bool CInventoryItem::Merge(PIItem pIItem) {
  111.     // Если удалось слить вместе вернуть true
  112.     return false;
  113. }
  114.  
  115. // CInventory class ///////////////////////////////////////////////////////////////////////////////
  116.  
  117. void MergeSame(TIItemList &itemList) {
  118.     PPIItem l_it = itemList.begin(), l_it2;
  119.     while(l_it != itemList.end()) {
  120.         l_it2 = l_it; l_it2++;
  121.         while(l_it2 != itemList.end()) {
  122.             (*l_it2)->Merge(*l_it);
  123.             if(!(*l_it)->Useful()) break;
  124.             l_it2++;
  125.         }
  126.         if(!(*l_it)->Useful()) (*l_it)->Drop();
  127.         l_it++;
  128.     }
  129. }
  130.  
  131. void SortRuckAndBelt(CInventory *pInventory) {
  132.     for(int i = 0; i < 2; i++) {
  133.         TIItemList &l_list = i?pInventory->m_ruck:pInventory->m_belt;
  134.         PPIItem l_it = l_list.begin(), l_it2, l_first, l_last, l_erase;
  135.         while(l_it != l_list.end()) {
  136.             l_first = l_last = l_it; l_last++;
  137.             while((l_last != l_list.end()) && ((*l_first)->Sort(*l_last) > 0)) l_last++;
  138.             l_it2 = l_last;
  139.             while(l_it2 != l_list.end()) {
  140.                 l_erase = l_list.end();
  141.                 s32 l_sort = (*l_first)->Sort(*l_it2);
  142.                 if(l_sort > 0) {
  143.                     l_list.insert(l_last, *l_it2); l_erase = l_it2;
  144.                 } else if(l_sort < 0) {
  145.                     l_first = l_list.insert(l_first, *l_it2); l_erase = l_it2;
  146.                 }
  147.                 l_it2++;
  148.                 if(l_erase != l_list.end()) l_list.erase(l_erase);
  149.             }
  150.             l_it++;
  151.         }
  152.         MergeSame(l_list);
  153.     }
  154. }
  155.  
  156. CInventory::CInventory() {
  157.     m_takeDist = pSettings->r_float("inventory","take_dist"); // 2.f;
  158.     m_maxWeight = pSettings->r_float("inventory","max_weight"); // 40.f;
  159.     m_maxRuck = pSettings->r_s32("inventory","max_ruck"); // 50;
  160.     m_maxBelt = pSettings->r_s32("inventory","max_belt"); // 15;
  161.     u32 l_slotsNum = pSettings->r_s32("inventory","slots"); // 7;           // 6 слотов оружия и слот одежды/защиты.
  162.     m_slots.resize(l_slotsNum);
  163.     m_activeSlot = m_nextActiveSlot = 0xffffffff;
  164.     u32 i = 0; string256 temp;
  165.     do {
  166.         sprintf(temp, "slot_name_%d", i+1);
  167.         if(i < m_slots.size() && pSettings->line_exist("inventory",temp)) {
  168.             m_slots[i].m_name = pSettings->r_string("inventory",temp);
  169.             i++;
  170.         } else break;
  171.     } while(true);
  172.     m_pTarget = NULL;
  173. }
  174.  
  175. CInventory::~CInventory() {}
  176.  
  177. bool CInventory::Take(CGameObject *pObj) {
  178.     CInventoryItem *l_pIItem = dynamic_cast<CInventoryItem*>(pObj);
  179.     //if(l_pIItem && l_pIItem->Useful() && (l_pIItem->m_weight + TotalWeight() < m_maxWeight) && (m_ruck.size() < m_maxRuck) && (m_all.find(l_pIItem) == m_all.end())) {
  180.     if(m_all.find(l_pIItem) != m_all.end())
  181.     {
  182.         Debug.fatal("Item already exist in inventory: %s(%s)",pObj->cName(),pObj->cNameSect());
  183.     }
  184.     if(l_pIItem && l_pIItem->Useful() && (l_pIItem->m_weight + TotalWeight() < m_maxWeight) && (m_all.find(l_pIItem) == m_all.end())) {
  185.         l_pIItem->m_pInventory = this;
  186.         l_pIItem->m_drop = false;
  187.         m_all.insert(l_pIItem);
  188.         if(l_pIItem->m_ruck) m_ruck.insert(m_ruck.end(), l_pIItem); SortRuckAndBelt(this);
  189.         TIItemList l_subs; l_subs.insert(l_subs.end(), l_pIItem->m_subs.begin(), l_pIItem->m_subs.end());
  190.         while(l_subs.size()) {
  191.             l_pIItem = *l_subs.begin();
  192.             l_pIItem->m_pInventory = this;
  193.             m_all.insert(l_pIItem);
  194.             l_subs.insert(l_subs.end(), l_pIItem->m_subs.begin(), l_pIItem->m_subs.end());
  195.             l_subs.erase(l_subs.begin());
  196.         }
  197.         if(!Slot(l_pIItem)) {
  198.             if(l_pIItem->m_slot < 0xffffffff) {
  199.                
  200.                 /*if(!m_slots[l_pIItem->m_slot].m_pIItem) {
  201.                     Slot(l_pIItem);
  202.                     return true;
  203.                 } else*/
  204.                 if(m_slots[l_pIItem->m_slot].m_pIItem->Attach(l_pIItem)) {
  205.                     m_ruck.erase(std::find(m_ruck.begin(), m_ruck.end(), l_pIItem));
  206.                     return true;
  207.                 } else if(m_ruck.size() > m_maxRuck || !l_pIItem->m_ruck) {
  208.                     if(Belt(l_pIItem)) return true;
  209.                     else return !Drop(l_pIItem);
  210.                 }
  211.             } else if(m_ruck.size() > m_maxRuck) {
  212.                 if(Belt(l_pIItem)) return true;
  213.                 else return !Drop(l_pIItem);
  214.             }
  215.         } else if(m_activeSlot == 0xffffffff) Activate(l_pIItem->m_slot);
  216.         return true;
  217.     }
  218.     return false;
  219. }
  220.  
  221. bool CInventory::Drop(CGameObject *pObj) {
  222.     CInventoryItem *l_pIItem = dynamic_cast<CInventoryItem*>(pObj);
  223.     if(l_pIItem && (m_all.find(l_pIItem) != m_all.end()) && Ruck(l_pIItem)) {
  224.         m_ruck.erase(std::find(m_ruck.begin(), m_ruck.end(), l_pIItem)); m_all.erase(l_pIItem);
  225.         l_pIItem->m_pInventory = NULL;
  226.         TIItemList l_subs; l_subs.insert(l_subs.end(), l_pIItem->m_subs.begin(), l_pIItem->m_subs.end());
  227.         while(l_subs.size()) {
  228.             l_pIItem = *l_subs.begin();
  229.             l_pIItem->m_pInventory = NULL;
  230.             m_all.erase(l_pIItem);
  231.             l_subs.insert(l_subs.end(), l_pIItem->m_subs.begin(), l_pIItem->m_subs.end());
  232.             l_subs.erase(l_subs.begin());
  233.         }
  234.         return true;
  235.     }
  236.     return false;
  237. }
  238.  
  239. bool CInventory::DropAll() {
  240.     PSPIItem l_it;
  241.     for(l_it = m_all.begin(); l_it != m_all.end(); l_it++) {
  242.         PIItem l_pIItem = *l_it;
  243.         Ruck(l_pIItem); l_pIItem->Drop();
  244.     }
  245.     return true;
  246. }
  247.  
  248. void CInventory::ClearAll() {
  249.     PSPIItem l_it;
  250.     for(l_it = m_all.begin(); l_it != m_all.end(); l_it++) {
  251.         PIItem l_pIItem = *l_it;
  252.         Ruck(l_pIItem);
  253.     }
  254.     m_ruck.clear();
  255.     m_all.clear();
  256. }
  257.  
  258. bool CInventory::Slot(PIItem pIItem) {
  259.     if(pIItem->m_slot < m_slots.size()) {
  260.         //if(m_slots[pIItem->m_slot].m_pIItem && !Belt(m_slots[pIItem->m_slot].m_pIItem)) Ruck(m_slots[pIItem->m_slot].m_pIItem);
  261.         if(!m_slots[pIItem->m_slot].m_pIItem) {
  262.             m_slots[pIItem->m_slot].m_pIItem = pIItem;
  263.             PPIItem l_it = std::find(m_ruck.begin(), m_ruck.end(), pIItem); if(l_it != m_ruck.end()) m_ruck.erase(l_it);
  264.             return true;
  265.         } else {
  266.             if(m_slots[pIItem->m_slot].m_pIItem->Attach(pIItem)) {
  267.                 PPIItem l_it = std::find(m_ruck.begin(), m_ruck.end(), pIItem); if(l_it != m_ruck.end()) m_ruck.erase(l_it);
  268.                 return true;
  269.             }
  270.         }
  271.     } else {
  272.         for(u32 i = 0; i < m_slots.size(); i++) if(m_slots[i].m_pIItem && m_slots[i].m_pIItem->Attach(pIItem)) {
  273.             PPIItem l_it = std::find(m_ruck.begin(), m_ruck.end(), pIItem); if(l_it != m_ruck.end()) m_ruck.erase(l_it);
  274.             return true;
  275.         }
  276.     }
  277.     return false;//Belt(pIItem);
  278. }
  279.  
  280. bool CInventory::Belt(PIItem pIItem) {
  281.     if(!pIItem || !pIItem->m_belt) return false;
  282.     if(m_belt.size() == m_maxBelt) return false;
  283.     if(std::find(m_belt.begin(), m_belt.end(), pIItem) != m_belt.end()) return true;
  284.     if((pIItem->m_slot < m_slots.size()) && (m_slots[pIItem->m_slot].m_pIItem == pIItem)) {
  285.         if(m_activeSlot == pIItem->m_slot) Activate(0xffffffff);
  286.         m_slots[pIItem->m_slot].m_pIItem = NULL;
  287.     }
  288.     PPIItem l_it = std::find(m_ruck.begin(), m_ruck.end(), pIItem); if(l_it != m_ruck.end()) m_ruck.erase(l_it);
  289.     m_belt.insert(m_belt.end(), pIItem); SortRuckAndBelt(this);
  290.     return true;
  291. }
  292.  
  293. bool CInventory::Ruck(PIItem pIItem) {
  294.     if(!pIItem || !pIItem->m_ruck) return false;
  295.     if(std::find(m_ruck.begin(), m_ruck.end(), pIItem) != m_ruck.end()) return true;
  296.     if((pIItem->m_slot < m_slots.size()) && (m_slots[pIItem->m_slot].m_pIItem == pIItem)) {
  297.         if(m_activeSlot == pIItem->m_slot) Activate(0xffffffff);
  298.         m_slots[pIItem->m_slot].m_pIItem = NULL;
  299.     }
  300.     PPIItem l_it = std::find(m_belt.begin(), m_belt.end(), pIItem); if(l_it != m_belt.end()) m_belt.erase(l_it);
  301.     m_ruck.insert(m_ruck.end(), pIItem); SortRuckAndBelt(this);
  302.     return true;
  303. }
  304.  
  305. bool CInventory::Activate(u32 slot) {
  306.     if(/*(slot == 0xffffffff) || */(slot == m_activeSlot) || (slot < m_slots.size() && !m_slots[slot].m_pIItem)) return false;
  307.     if(m_activeSlot < m_slots.size()) {
  308.         m_slots[m_activeSlot].m_pIItem->Deactivate();
  309.         if(slot < m_slots.size()) m_nextActiveSlot = slot;
  310.         else  m_activeSlot = slot;
  311.     } else if(m_slots[slot].m_pIItem->Activate()) {
  312.         m_activeSlot = slot;
  313.     }
  314.     return false;
  315. }
  316.  
  317. PIItem CInventory::ActiveItem()const{
  318.     return m_activeSlot < m_slots.size() ? m_slots[m_activeSlot].m_pIItem : NULL;
  319. }
  320.  
  321. bool CInventory::Action(s32 cmd, u32 flags) {
  322.     if(m_activeSlot < m_slots.size() && m_slots[m_activeSlot].m_pIItem && m_slots[m_activeSlot].m_pIItem->Action(cmd, flags)) return true;
  323.     switch(cmd) {
  324.         case kWPN_1 :
  325.         case kWPN_2 :
  326.         case kWPN_3 :
  327.         case kWPN_4 :
  328.         case kWPN_5 :
  329.         case kWPN_6 : {
  330.             if(flags&CMD_START) {
  331.                 if((int)m_activeSlot == cmd - kWPN_1) m_slots[cmd - kWPN_1].m_pIItem->Action(kWPN_NEXT, CMD_START);
  332.                 else Activate(cmd - kWPN_1);
  333.                 return true;
  334.             }
  335.         } break;
  336.         case kUSE : {
  337.             if(flags&CMD_START && m_pTarget && m_pTarget->Useful()) {
  338.                 // Generate event
  339.                 CActor *l_pA = dynamic_cast<CActor*>(m_pOwner);
  340.                 if(l_pA) {
  341.                     NET_Packet P;
  342.                     l_pA->u_EventGen(P,GE_OWNERSHIP_TAKE,l_pA->ID());
  343.                     P.w_u16(u16(m_pTarget->ID()));
  344.                     l_pA->u_EventSend(P);
  345.                 }
  346.             }
  347.         } break;
  348.     }
  349.     return false;
  350. }
  351.  
  352. void CInventory::Update(u32 deltaT) {
  353.     if((m_nextActiveSlot < m_slots.size()) && (m_activeSlot == 0xffffffff || !m_slots[m_activeSlot].m_pIItem->getVisible())) {
  354.         if(m_slots[m_nextActiveSlot].m_pIItem) {
  355.             if(m_slots[m_nextActiveSlot].m_pIItem->Activate()) {
  356.                 m_activeSlot = m_nextActiveSlot;
  357.                 m_nextActiveSlot = 0xffffffff;
  358.             } else if(!m_slots[m_activeSlot].m_pIItem->Activate()) {
  359.                 m_activeSlot = m_nextActiveSlot = 0xffffffff;
  360.             }
  361.         } else m_activeSlot = m_nextActiveSlot = 0xffffffff;
  362.     }
  363.     // Смотрим, что тут можно подобрать
  364.     CActor *l_pA = dynamic_cast<CActor*>(m_pOwner);
  365.     if(l_pA) {
  366.         l_pA->setEnabled(false);
  367.         Collide::ray_query  l_rq;
  368.         if(g_pGameLevel->ObjectSpace.RayPick(Device.vCameraPosition, Device.vCameraDirection, m_takeDist, l_rq)) m_pTarget = dynamic_cast<PIItem>(l_rq.O);
  369.         else m_pTarget = NULL;
  370.         l_pA->setEnabled(true);
  371.     }
  372.     //
  373.     for(int i = 0; i < 2; i++) {
  374.         TIItemList &l_list = i?m_ruck:m_belt;
  375.         PPIItem l_it = l_list.begin();
  376.         while(l_it != l_list.end()) {
  377.             PIItem l_pIItem = *l_it;
  378.             if(l_pIItem->m_drop) {
  379.                 l_pIItem->m_drop = false;
  380.                 if(l_pIItem->H_Parent()) {
  381.                     NET_Packet P;
  382.                     l_pIItem->u_EventGen(P, GE_OWNERSHIP_REJECT, l_pIItem->H_Parent()->ID());
  383.                     P.w_u16(u16(l_pIItem->ID()));
  384.                     l_pIItem->u_EventSend(P);
  385.                 } else Drop(l_pIItem);
  386.             }
  387.             l_it++;
  388.         }
  389.     }
  390. }
  391.  
  392. PIItem CInventory::Same(const PIItem pIItem) {
  393.     for(PPIItem l_it = m_belt.begin(); l_it != m_belt.end(); l_it++) {
  394.         PIItem l_pIItem = *l_it;
  395.         //if((l_pIItem != pIItem) && (l_pIItem->SUB_CLS_ID == pIItem->SUB_CLS_ID)) return l_pIItem;
  396.         if((l_pIItem != pIItem) && !strcmp(l_pIItem->cNameSect(), pIItem->cNameSect())) return l_pIItem;
  397.     }
  398.     return NULL;
  399. }
  400.  
  401. PIItem CInventory::SameSlot(u32 slot) {
  402.     if(slot == 0xffffffff) return NULL;
  403.     for(PPIItem l_it = m_belt.begin(); l_it != m_belt.end(); l_it++) {
  404.         PIItem l_pIItem = *l_it;
  405.         if(l_pIItem->m_slot == slot) return l_pIItem;
  406.     }
  407.     return NULL;
  408. }
  409.  
  410. PIItem CInventory::Get(const char *name, bool bSearchRuck) {
  411.     TIItemList &l_list = bSearchRuck ? m_ruck : m_belt;
  412.     for(PPIItem l_it = l_list.begin(); l_it != l_list.end(); l_it++) {
  413.         PIItem l_pIItem = *l_it;
  414.         if(!strcmp(l_pIItem->cNameSect(), name) && l_pIItem->Useful()) return l_pIItem;
  415.     }
  416.     return NULL;
  417. }
  418.  
  419. PIItem CInventory::Get(const u16 id, bool bSearchRuck) {
  420.     TIItemList &l_list = bSearchRuck ? m_ruck : m_belt;
  421.     for(PPIItem l_it = l_list.begin(); l_it != l_list.end(); l_it++) {
  422.         PIItem l_pIItem = *l_it;
  423.         if(l_pIItem->ID() == id) return l_pIItem;
  424.     }
  425.     return NULL;
  426. }
  427.  
  428. f32 CInventory::TotalWeight() {
  429.     f32 l_weight = 0;
  430.     for(PSPIItem l_it = m_all.begin(); l_it != m_all.end(); l_it++) l_weight += (*l_it)->m_weight;
  431.     return l_weight;
  432. }
  433.  
  434. void CInventory::Clear()
  435. {
  436.     m_all.clear();
  437.     m_ruck.clear();
  438.     m_belt.clear();
  439. }
  440.  
  441. u32 CInventory::dwfGetSameItemCount(LPCSTR caSection)
  442. {
  443.     u32         l_dwCount = 0;
  444.     TIItemList  &l_list = m_ruck;
  445.     for(PPIItem l_it = l_list.begin(); l_it != l_list.end(); l_it++) {
  446.         PIItem  l_pIItem = *l_it;
  447.         if (!strcmp(l_pIItem->cNameSect(), caSection))
  448.             l_dwCount++;
  449.     }
  450.     return      (l_dwCount);
  451. }
  452.  
  453. // CInventorySlot class //////////////////////////////////////////////////////////////////////////
  454.  
  455. CInventorySlot::CInventorySlot() {
  456.     m_pIItem = NULL;
  457. }
  458.  
  459. CInventorySlot::~CInventorySlot() {}
  460.  
  461.  
  462. ///////////////////////////////////////////////////////////////////////////////////////////////////
  463. // CInventoryOwner class //////////////////////////////////////////////////////////////////////////
  464. CInventoryOwner::CInventoryOwner() {
  465.     m_inventory.m_pOwner = this;
  466.     m_trade     = NULL;
  467.     m_dwMoney   = 0;
  468.     m_tRank     = eStalkerRankNone;
  469. }
  470.  
  471. CInventoryOwner::~CInventoryOwner()
  472. {
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement