EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Skill.cpp
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: Bloody.Rabbit
24 Rewrite: Allan
25 */
26 
27 #include "eve-server.h"
28 
29 #include "character/Character.h"
30 #include "character/Skill.h"
32 
33 /*
34  * SKILL__ERROR
35  * SKILL__WARNING
36  * SKILL__MESSAGE
37  * SKILL__INFO
38  * SKILL__DEBUG
39  * SKILL__TRACE
40  */
41 
42 Skill::Skill(uint32 _skillID, const ItemType& _type, const ItemData& _data)
43 : InventoryItem(_skillID, _type, _data)
44 {
45 }
46 
48 {
49  return InventoryItem::Load<Skill>(skillID );
50 }
51 
53 {
55  if ( skillID == 0 )
56  return SkillRef(nullptr);
57 
58  SkillRef skillRef(Skill::Load(skillID));
59  if (skillRef.get() == nullptr) {
60  // make error msg here for failure to load skill?
61  return SkillRef(nullptr);
62  }
63 
64  skillRef->SaveItem();
65  return skillRef;
66 }
67 
69  return (flag() == flagSkillInTraining);
70 }
71 
73  return EvEMath::Skill::LevelForPoints(currentSP, GetAttribute(AttrSkillTimeConstant).get_uint32());
74 }
75 
78 }
79 
81 {
82  uint32 currentSP(GetAttribute(AttrSkillPoints).get_uint32());
83  if (flag() == flagSkill)
84  return currentSP;
85 
86  if (startTime == 0)
87  return currentSP;
88 
89  if (startTime > GetFileTimeNow())
90  return currentSP;
91 
93  if (level > EvESkill::MAXSKILLLEVEL)
95 
97  // at this point, the skill is in training. calculate accumulated sp and return
98  uint32 delta(0);
99  uint32 timeElapsed((GetFileTimeNow() - startTime) / EvE::Time::Second);
100  if (timeElapsed > 60) {
101  // skill in training - return updated SP based on elapsed training
102  delta = (timeElapsed /60) * ch->GetSPPerMin(this);
103  currentSP += delta;
104  }
105 
106  _log(SKILL__TRACE, "Skill::GetCurrentSP() for %s is %u - delta: %u, elapsed time: %us", \
107  name(), currentSP, delta, timeElapsed);
108 
109  return currentSP;
110 }
111 
113 {
115  if (level > EvESkill::MAXSKILLLEVEL)
116  return 0;
117 
118  if (curTime == 0)
119  curTime = GetFileTimeNow();
120 
121  // get full sp needed for next level
122  uint32 remainingSP(GetSPForLevel(level) - GetAttribute(AttrSkillPoints).get_uint32());
123 
124  float timeLeft((ch->GetEndOfTraining() - curTime) / EvE::Time::Second);
125  // if remaining time > 1m, subtract spm from total to get remaining
126  if (timeLeft > 60)
127  remainingSP -= ((timeLeft /60) * ch->GetSPPerMin(this));
128 
129  return remainingSP;
130 }
131 
133 {
135  if (level > EvESkill::MAXSKILLLEVEL)
136  return 0;
137 
138  // get full sp needed for next level
139  uint32 remainingSP(GetSPForLevel(level) - GetAttribute(AttrSkillPoints).get_uint32());
140  // divide by spm to get time and convert to seconds
141  uint32 timeLeft((remainingSP /ch->GetSPPerMin(this)) * 60);
142 
143  if (startTime == 0)
144  return timeLeft;
145 
146  uint32 delta = (uint32)ceil((GetFileTimeNow() - startTime) / EvE::Time::Second);
147  if (delta < 1)
148  return timeLeft;
149 
150  // this skill is currently training. subtract accumulated time from total and return
151  return timeLeft - delta;
152 }
153 
155 {
156  if (!isSingleton())
157  ChangeSingleton(true);
158  if (GetAttribute(AttrSkillLevel).get_type() != evil_number_int) {
159  _log(SKILL__INFO, "Skill %s level type != int. Fixing...", name());
161  }
162  if (GetAttribute(AttrSkillPoints).get_type() != evil_number_int) {
163  _log(SKILL__INFO, "Skill %s sp type != int. Fixing...", name());
165  }
166 }
167 
169 {
170  if (is_log_enabled(SKILL__MESSAGE))
171  _log(SKILL__MESSAGE, "Begin SP check for %s. level %u: CurrentSP: %u", \
172  name(), GetAttribute(AttrSkillLevel).get_uint32(), GetAttribute(AttrSkillPoints).get_uint32());
173 
175  return;
176 
177  uint8 level(GetAttribute(AttrSkillLevel).get_uint32() + 1);
178  if (level > EvESkill::MAXSKILLLEVEL) {
179  level = EvESkill::MAXSKILLLEVEL;
180  SetAttribute(AttrSkillLevel, level, false);
181  }
182  uint32 spThisLevel(GetSPForLevel(level -1));
183  uint32 spCurrent(GetAttribute(AttrSkillPoints).get_uint32());
184  if (spCurrent < spThisLevel) {
185  _log(SKILL__WARNING, "Skill %s points low. Updating from %u to %u", name(), spCurrent, spThisLevel);
186  SetAttribute(AttrSkillPoints, spThisLevel, false);
187  // hit it again to be sure it's fixed
188  VerifySP();
189  return;
190  }
191  uint32 spNextLevel(GetSPForLevel(level));
192  if (spCurrent > spNextLevel) {
194  if (level > 4) {
195  _log(SKILL__WARNING, " %s - Skillpoints high for L5. Updating SP from %u to %u.", \
196  name(), spCurrent, spNextLevel);
197  } else {
198  _log(SKILL__WARNING, " %s - Skillpoints high. Updating level from %u to %u and SP from %u to %u.", \
199  name(), level -1, level, spCurrent, spNextLevel);
200  }
201  SetAttribute(AttrSkillPoints, spNextLevel, false);
202  // hit it again to be sure it's fixed
203  VerifySP();
204  }
205 }
206 
208  bool test(true);
209  EvilNumber skillID(0);
210  if (HasAttribute(AttrRequiredSkill1, skillID)) {
212  test = false;
213  if (HasAttribute(AttrRequiredSkill2, skillID)) {
215  test = false;
216  if (HasAttribute(AttrRequiredSkill3, skillID)) {
218  test = false;
219  if (HasAttribute(AttrRequiredSkill4, skillID)) {
221  test = false;
222  }
223  }
224  }
225  }
226 
227  return test;
228 }
229 
231  bool test(true);
232  EvilNumber skillID(0);
233  if (iRef->HasAttribute(AttrRequiredSkill1, skillID)) {//Primary Skill
234  if ( iRef->GetAttribute(AttrRequiredSkill1Level) > cRef->GetSkillLevel(skillID.get_uint32()))
235  test = false;
236  if (iRef->HasAttribute(AttrRequiredSkill2, skillID)) {//Secondary Skill
237  if ( iRef->GetAttribute(AttrRequiredSkill2Level) > cRef->GetSkillLevel(skillID.get_uint32()))
238  test = false;
239  if (iRef->HasAttribute(AttrRequiredSkill3, skillID)) {//Tertiary Skill
240  if ( iRef->GetAttribute(AttrRequiredSkill3Level) > cRef->GetSkillLevel(skillID.get_uint32()))
241  test = false;
242  if (iRef->HasAttribute(AttrRequiredSkill4, skillID)) {//Quarternary Skill
243  if ( iRef->GetAttribute(AttrRequiredSkill4Level) > cRef->GetSkillLevel(skillID.get_uint32()))
244  test = false;
245  if (iRef->HasAttribute(AttrRequiredSkill5, skillID)) {//Quinary Skill
246  if ( iRef->GetAttribute(AttrRequiredSkill5Level) > cRef->GetSkillLevel(skillID.get_uint32()))
247  test = false;
248  if (iRef->HasAttribute(AttrRequiredSkill6, skillID)) {//Senary Skill
249  if ( iRef->GetAttribute(AttrRequiredSkill6Level) > cRef->GetSkillLevel(skillID.get_uint32()))
250  test = false;
251  }
252  }
253  }
254  }
255  }
256  }
257 
258  return test;
259 }
unsigned __int8 uint8
Definition: eve-compat.h:46
bool SkillPrereqsComplete(Character &ch)
Definition: Skill.cpp:207
#define _log(type, fmt,...)
Definition: logsys.h:124
bool HasAttribute(const uint16 attrID) const
bool IsTraining()
Definition: Skill.cpp:68
uint8 GetSPPerMin(Skill *skill)
Definition: Character.cpp:559
static bool FitModuleSkillCheck(InventoryItemRef item, CharacterRef ch)
Definition: Skill.cpp:230
Skill(uint32 _skillID, const ItemType &_type, const ItemData &_data)
Definition: Skill.cpp:42
void VerifySP()
Definition: Skill.cpp:168
static SkillRef Spawn(ItemData &data)
Definition: Skill.cpp:52
this is a class that kinda mimics how python polymorph's numbers.
Definition: EvilNumber.h:59
const char * name()
uint32 GetSPForLevel(uint8 level)
Definition: Skill.cpp:76
uint32 PointsAtLevel(uint8 level, float rank)
Definition: EvEMath.cpp:17
EvilNumber EvilZero
Definition: EvilNumber.cpp:32
#define is_log_enabled(type)
Definition: logsys.h:78
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type()() itemID() copy() materialLevel()()() itemID() itemID Fits selected item to active ship() skillID(level)-gives skillID to specified level." ) COMMAND( online
bool isSingleton() const
Definition: InventoryItem.h:96
uint8 LevelForPoints(uint32 currentSP, uint8 rank)
Definition: EvEMath.cpp:25
RefPtr< Skill > SkillRef
Definition: ItemRef.h:57
int64 GetEndOfTraining()
Definition: Character.cpp:624
uint32 get_uint32()
Definition: EvilNumber.cpp:173
const uint8 MAXSKILLLEVEL
Definition: EvEMath.h:19
void SetAttribute(uint16 attrID, int num, bool notify=true)
X * get() const
Definition: RefPtr.h:213
static SkillRef Load(uint32 skillID)
Definition: Skill.cpp:47
bool ChangeSingleton(bool singleton, bool notify=false)
unsigned __int32 uint32
Definition: eve-compat.h:50
uint32 GetCurrentSP(Character *ch, int64 startTime=0)
Definition: Skill.cpp:80
EVEItemFlags flag() const
uint8 GetLevelForSP(uint32 currentSP)
Definition: Skill.cpp:72
double GetFileTimeNow()
Definition: utils_time.cpp:84
signed __int64 int64
Definition: eve-compat.h:51
static uint32 CreateItemID(ItemData &data)
EvilNumber GetAttribute(const uint16 attrID) const
int8 GetSkillLevel(uint16 skillTypeID, bool zeroForNotInjected=true) const
Definition: Character.cpp:575
uint32 GetRemainingSP(Character *ch, int64 curTime=0)
Definition: Skill.cpp:112
void VerifyAttribs()
Definition: Skill.cpp:154
uint32 GetTrainingTime(Character *ch, int64 startTime=0)
Definition: Skill.cpp:132
Reference-counting-based smart pointer.
Definition: RefPtr.h:133