EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
AttributeMap.h
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24  Rewrite: Allan
25 */
26 
27 #ifndef __EVE_ATTRIBUTE_MGR__H__INCL__
28 #define __EVE_ATTRIBUTE_MGR__H__INCL__
29 
30 #include "./eve-common.h"
31 
32 #include "inventory/InventoryDB.h"
33 
34 typedef std::map<uint16, EvilNumber> AttrMap;
35 typedef AttrMap::iterator AttrMapItr;
36 typedef AttrMap::const_iterator AttrMapConstItr;
37 
38 class PyTuple;
39 class InventoryItem;
40 
42 {
43 public:
45  ~AttributeMap() noexcept;
46 
47  void SetAttribute(uint16 attrID, EvilNumber& num, bool notify=true);
48  void MultiplyAttribute(uint16 attrID, EvilNumber& num, bool notify=false);
49 
50  EvilNumber GetAttribute(const uint16 attrID) const;
51 
52  bool HasAttribute(const uint16 attrID) const;
53  bool HasAttribute(const uint16 attrID, EvilNumber& value) const;
54 
55  bool Save();
56 
57  void Delete();
58  void DeleteAttribute(uint16 attrID);
59 
60  // load the default attributes that come with the item's typeID
61  bool Load(bool reset=false);
62 
63  /* only save the ship damage and heat. other attribs are calculated when ship activated */
64  void SaveShipState();
65  bool SaveAttributes();
66 
67  void ResetAttribute(uint16 attrID, bool notify=false);
68  void CopyAttributes(std::map<uint16, EvilNumber>& attrMap);
69 
75  AttrMapItr begin();
76 
82  AttrMapItr end();
83 
84 protected:
94  bool Change(uint16 attrID, EvilNumber& old_val, EvilNumber& new_val);
95 
105  bool Add(uint16 attrID, EvilNumber& num);
106 
115  bool SendChanges(PyTuple* attrChange);
116 
118 
120 
121 private:
123 
124 };
125 
126 #endif /* __EVE_ATTRIBUTE_MGR__H__INCL__ */
127 
128 /* self.electronicAttributes = {const.attributeScanGravimetricStrengthBonus: const.attributeScanGravimetricStrength,
129  const.attributeScanLadarStrengthBonus: const.attributeScanLadarStrength,
130  const.attributeScanMagnetometricStrengthBonus: const.attributeScanMagnetometricStrength,
131  const.attributeScanRadarStrengthBonus: const.attributeScanRadarStrength}
132  self.propulsionAttributes = {const.attributePropulsionFusionStrengthBonus: const.attributePropulsionFusionStrength,
133  const.attributePropulsionIonStrengthBonus: const.attributePropulsionIonStrength,
134  const.attributePropulsionMagpulseStrengthBonus: const.attributePropulsionMagpulseStrength,
135  const.attributePropulsionPlasmaStrengthBonus: const.attributePropulsionPlasmaStrength}
136  self.heatAttributes = {'heatAbsorbtionRateHi': 'heatHi',
137  'heatAbsorbtionRateMed': 'heatMed',
138  'heatAbsorbtionRateLow': 'heatLow'}
139 
140  def ApplyAttributeChange(self, ownerID, itemKey, attributeID, time, newValue, oldValue, scatterAttr = True):
141  item = None
142  if self.invitems.has_key(itemKey):
143  item = self.invitems[itemKey]
144  elif self.sublocationsByKey.has_key(itemKey):
145  item = self.sublocationsByKey[itemKey]
146  if item is None or not self.attributesByItemAttribute.has_key(itemKey):
147  if itemKey not in self.attributesByItemAttribute:
148  self.godma.LogInfo('ApplyAttributeChange - item not found', item, ownerID, itemKey, attributeID, time, newValue, oldValue, scatterAttr)
149  return
150  attributeName = cfg.dgmattribs.Get(attributeID).attributeName
151  att = getattr(item, attributeName, 'not there')
152  self.attributesByItemAttribute[itemKey][attributeName] = newValue
153  if attributeName in self.heatAttributes.values():
154  self.UpdateOverloadedAttributesHeat(attributeName, time, newValue)
155  if attributeName in self.heatAttributes.keys():
156  self.UpdateOverloadedAttributesTau(attributeName, time, newValue)
157  if self.chargedAttributeTauCaps.has_key(attributeName):
158  if not self.chargedAttributesByItemAttribute.has_key(itemKey):
159  self.chargedAttributesByItemAttribute[itemKey] = {}
160  self.CreateChargedAttribute(itemKey, attributeName, newValue, time, self.chargedAttributeTauCaps[attributeName])
161  elif self.chargedAttributeTauCapsByMax.has_key(attributeName):
162  for chargeAttName in self.chargedAttributeTauCapsByMax[attributeName]:
163  if self.chargedAttributesByItemAttribute.has_key(itemKey):
164  if self.chargedAttributesByItemAttribute[itemKey].has_key(chargeAttName):
165  self.godma.LogInfo('CHARGEEEEEE')
166  charge = self.GetAttribute(itemKey, chargeAttName)
167  self.CreateChargedAttribute(itemKey, chargeAttName, charge, time, self.chargedAttributeTauCaps[chargeAttName])
168  break
169  elif self.attributesByItemAttribute[itemKey].get(self.chargedAttributeTauCaps[chargeAttName][0]) and self.attributesByItemAttribute[itemKey].get(self.chargedAttributeTauCaps[chargeAttName][1]):
170  self.CreateChargedAttribute(itemKey, chargeAttName, self.attributesByItemAttribute[itemKey][chargeAttName], time, self.chargedAttributeTauCaps[chargeAttName])
171  break
172 
173  elif self.chargedAttributesByTau.has_key(attributeName):
174  for attName in self.chargedAttributesByTau[attributeName]:
175  if self.chargedAttributesByItemAttribute.has_key(itemKey):
176  if self.chargedAttributesByItemAttribute[itemKey].has_key(attName):
177  self.godma.LogInfo('CHARGEEEEEE')
178  charge = self.GetAttribute(itemKey, attName)
179  self.CreateChargedAttribute(itemKey, attName, charge, time, self.chargedAttributeTauCaps[attName])
180  break
181 
182  self.godma.LogInfo('Attribute', attributeName, 'of module', itemKey, 'changed from', oldValue, 'to', newValue, 'value I had was', att)
183  if attributeID in (const.attributeCapacity,
184  const.attributeDroneCapacity,
185  const.attributeShipMaintenanceBayCapacity,
186  const.attributeCorporateHangarCapacity):
187  sm.ScatterEvent('OnCapacityChange', itemKey)
188  elif attributeID == const.attributeQuantity:
189  self.godma.LogInfo('Changing quantity from', att, 'to', newValue)
190  if newValue == att:
191  return
192  locationID, flag, typeID = itemKey
193  currSubLocation = self.GetSubLocation(locationID, flag)
194  if currSubLocation and currSubLocation.typeID != typeID:
195  self.godma.LogWarn("Trying to modify quantity of sublocation that isn't loaded with my type", currSubLocation, itemKey)
196  return
197  if newValue == 0:
198  self.godma.LogInfo('SubLoc.quantityExpelled', itemKey, (oldValue, newValue))
199  locationID, flag = itemKey[0], itemKey[1]
200  if self.sublocationsByLocationFlag.has_key(locationID) and self.sublocationsByLocationFlag[locationID].has_key(flag):
201  del self.sublocationsByLocationFlag[locationID][flag]
202  del self.sublocationsByKey[itemKey]
203  typeOb = cfg.invtypes.Get(typeID)
204  item = blue.DBRow(self.godma.sublocrd, [itemKey,
205  typeID,
206  None,
207  locationID,
208  flag,
209  newValue,
210  typeOb.groupID,
211  typeOb.categoryID,
212  None])
213  sm.ScatterEvent('OnItemChange', item, {const.ixStackSize: oldValue})
214  if attributeID == const.attributeIsOnline:
215  sm.ScatterEvent('OnModuleOnlineChange', item, oldValue, newValue)
216  if newValue == 0 and oldValue == 1:
217  if item.online.isActive:
218  self.godma.LogWarn('Module put offline silently, faking event', itemKey)
219  self.OnGodmaShipEffect(itemKey, const.effectOnline, blue.os.GetSimTime(), 0, 0, [itemKey,
220  item.ownerID,
221  item.locationID,
222  None,
223  None,
224  [],
225  const.effectOnline], None, -1, -1, None, None)
226 
227 
228  def UpdateAttribute(self, itemID, attributes, time):
229  self.attributesByItemAttribute[itemID] = attributes
230  if time is None:
231  time = blue.os.GetSimTime()
232  for k in attributes.iterkeys():
233  if k in self.heatAttributes.values():
234  if not self.overloadedAttributes.has_key(k):
235  self.overloadedAttributes[k] = [0, 0, 0]
236  self.overloadedAttributes[k][0] = attributes[k]
237  self.overloadedAttributes[k][1] = time
238  if k in self.heatAttributes.keys():
239  if not self.overloadedAttributes.has_key(self.heatAttributes[k]):
240  self.overloadedAttributes[self.heatAttributes[k]] = [0, 0, 0]
241  self.overloadedAttributes[self.heatAttributes[k]][2] = attributes[k]
242  if self.chargedAttributeTauCaps.has_key(k):
243  if not self.chargedAttributesByItemAttribute.has_key(itemID):
244  self.chargedAttributesByItemAttribute[itemID] = {}
245  if self.attributesByItemAttribute[itemID].get(self.chargedAttributeTauCaps[k][0]) and self.attributesByItemAttribute[itemID].get(self.chargedAttributeTauCaps[k][1]):
246  self.CreateChargedAttribute(itemID, k, attributes[k], time, self.chargedAttributeTauCaps[k])
247 
248  def CreateChargedAttribute(self, itemID, attribute, value, time, taucap):
249  tau, cap = taucap
250  tauValue = self.GetAttribute(itemID, tau) / 5.0
251  capValue = self.GetAttribute(itemID, cap)
252  self.chargedAttributesByItemAttribute[itemID][attribute] = [value,
253  time,
254  tauValue,
255  capValue]
256  self.godma.LogInfo('CreateChargedAttribute', itemID, attribute, time, self.chargedAttributesByItemAttribute[itemID][attribute])
257 
258  */
bool Change(uint16 attrID, EvilNumber &old_val, EvilNumber &new_val)
internal function to handle the change.
InventoryItem & mItem
Definition: AttributeMap.h:117
void SetAttribute(uint16 attrID, EvilNumber &num, bool notify=true)
void SaveShipState()
void MultiplyAttribute(uint16 attrID, EvilNumber &num, bool notify=false)
bool Add(uint16 attrID, EvilNumber &num)
internal function to handle adding attributes.
AttrMapItr begin()
return the begin iterator of the AttributeMap
this is a class that kinda mimics how python polymorph's numbers.
Definition: EvilNumber.h:59
void DeleteAttribute(uint16 attrID)
Python tuple.
Definition: PyRep.h:567
itemID[count] Create count or of the specified item(from Insider)" ) COMMAND( goto
EvilNumber GetAttribute(const uint16 attrID) const
void ResetAttribute(uint16 attrID, bool notify=false)
AttrMap::iterator AttrMapItr
Definition: AttributeMap.h:35
AttrMap mAttributes
Definition: AttributeMap.h:119
~AttributeMap() noexcept
bool HasAttribute(const uint16 attrID) const
AttrMap::const_iterator AttrMapConstItr
Definition: AttributeMap.h:36
bool Load(bool reset=false)
bool SaveAttributes()
std::map< uint16, EvilNumber > AttrMap
Definition: AttributeMap.h:34
AttributeMap(InventoryItem &item)
AttrMapItr end()
return the end iterator of the AttributeMap
unsigned __int16 uint16
Definition: eve-compat.h:48
InventoryDB m_db
Definition: AttributeMap.h:122
void CopyAttributes(std::map< uint16, EvilNumber > &attrMap)
bool SendChanges(PyTuple *attrChange)
queue the attribute changes into the QueueDestinyEvent system.