Add infos into target window
[ryzomcore.git] / ryzom / server / src / entities_game_service / death_penalties.cpp
blobc7caecf1dabb89b872846e409b1902faa3d0c5c3
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // precompiled headers must be first
18 #include "stdpch.h"
20 // NeL MISC
21 #include "nel/misc/variable.h"
23 // Local
24 #include "death_penalties.h"
25 #include "player_manager/character.h"
26 #include "phrase_manager/phrase_utilities_functions.h"
27 #include "player_manager/item_service_manager.h"
28 #include "server_share/r2_variables.h"
30 NL_INSTANCE_COUNTER_IMPL(CDeathPenalties);
32 NLMISC::CVariable<bool> DissableDPInRing("egs", "DissableDPInRing", "Enable or dissable DP system in the Ring (should be dissabled unless this provokes bugs", true,0,true);
34 void CDeathPenalties::updataDb(CCharacter& user)
36 if ( _DeathXPToGain == 0 )
37 // user._PropertyDatabase.setProp( "USER:DEATH_XP_MALUS", 255 );
38 CBankAccessor_PLR::getUSER().setDEATH_XP_MALUS(user._PropertyDatabase, 255 );
39 else
40 // user._PropertyDatabase.setProp( "USER:DEATH_XP_MALUS", uint8( 254 * (1 - _CurrentDeathXP / _DeathXPToGain ) ) );
41 CBankAccessor_PLR::getUSER().setDEATH_XP_MALUS(user._PropertyDatabase, checkedCast<uint8>( 254 * (1 - _CurrentDeathXP / _DeathXPToGain ) ) );
44 void CDeathPenalties::addDeath(CCharacter& user, float deathPenaltyFactor )
46 // we don't add death penalty in the ring
47 if (IsRingShard && DissableDPInRing)
49 return;
52 // note that NB death is no more useful, but we keep it in serial until we have a better serial system
53 SKILLS::ESkills expSkill;
54 double maxXP = user.getSkills().getMaxXPToGain(expSkill);
55 _NbDeath++;
57 const double maxMalus = maxXP * user.getSkillBaseValue(expSkill);
58 double xpMalus = ((double)deathPenaltyFactor) * DeathXPFactor * maxMalus;
60 if ( xpMalus + _DeathXPToGain <= maxMalus )
61 _DeathXPToGain += xpMalus;
62 else
64 // cap death xp gain
65 xpMalus -= (maxMalus - _DeathXPToGain);
66 _DeathXPToGain = maxMalus;
68 // remove penalty surplus from already paid back Xp debt
69 if ( _CurrentDeathXP >= xpMalus )
70 _CurrentDeathXP -= xpMalus;
71 else
72 _CurrentDeathXP = 0.0;
74 updataDb(user);
76 if( _CurrentDeathXP || _DeathXPToGain )
78 SM_STATIC_PARAMS_2(params,STRING_MANAGER::integer,STRING_MANAGER::integer);
79 params[0].Int = sint32(10*_CurrentDeathXP);
80 params[1].Int = sint32(10*_DeathXPToGain);
81 CCharacter::sendDynamicSystemMessage( user.getId(),"DEATH_XP_DEATH",params);
85 uint32 CDeathPenalties::updateResorption( CCharacter& user )
87 // we don't add death penalty in the ring
88 if (IsRingShard && DissableDPInRing)
90 return 1800;
93 uint32 currentTime = NLMISC::CTime::getSecondsSince1970();
94 if ( _NbDeath && _BonusUpdateTime!=0 && _BonusUpdateTime<currentTime )
96 SKILLS::ESkills expSkill;
97 double maxXP = user.getSkills().getMaxXPToGain(expSkill);
99 double timeFactor = (double)(currentTime - _BonusUpdateTime) / (60.*60.*24. * user.getDPLossDuration());
101 const double maxMalus = maxXP * user.getSkillBaseValue(expSkill);
102 double xpBonus = ((double)timeFactor) * maxMalus;
104 addXP(user, SKILLS::unknown, xpBonus, xpBonus);
106 _BonusUpdateTime = currentTime;
107 if ( _NbDeath )
108 return 600;
109 else
110 return 1800;
113 void CDeathPenalties::addXP( CCharacter& user, SKILLS::ESkills usedSkill, double & xp )
115 // we don't add death penalty in the ring
116 if (IsRingShard && DissableDPInRing)
118 return;
121 if ( _NbDeath )
123 // we multiply gained xp by used skill level
124 SKILLS::ESkills expSkill;
125 user.getSkills().getMaxXPToGain(expSkill);
126 const double skillBaseValue = user.getSkillBaseValue(expSkill);
127 if (skillBaseValue <= 0)
129 nlwarning("Skill %s base value for char %s is <= 0 !!",SKILLS::toString(expSkill).c_str(), user.getId().toString().c_str());
130 xp = 0;
131 return;
134 double xpBeforeDeathPenalty = xp;
135 double xpUsedForDeathPenalty = xp * _DeathPenaltyFactor;
136 SSkill* skill = user.getSkills().getSkillStruct(usedSkill);
137 if (skill->MaxLvlReached < 250)
138 xpUsedForDeathPenalty *= 0.5f;
140 xp -= xpUsedForDeathPenalty;
142 double tempXp = xpUsedForDeathPenalty * skillBaseValue;
143 addXP(user, usedSkill, tempXp, xpBeforeDeathPenalty);
144 xpUsedForDeathPenalty = tempXp / skillBaseValue;
146 xp += xpUsedForDeathPenalty;
150 void CDeathPenalties::addXP( CCharacter& user, SKILLS::ESkills usedSkill, double & xp, double xpRaw )
152 // we don't add death penalty in the ring
153 if (IsRingShard && DissableDPInRing)
155 return;
158 _CurrentDeathXP += xp;
160 if ( _CurrentDeathXP >= _DeathXPToGain )
162 // no more death penalties, only keep the xp surplus
163 xp = _CurrentDeathXP - _DeathXPToGain;
165 reset(user);
167 PHRASE_UTILITIES::sendDynamicSystemMessage(user.getEntityRowId(), "PROGRESS_DEATH_PENALTY_COMPLETE");
169 // consume SpeedUpDPLoss services
170 while (1)
172 const CStaticItem * form = CItemServiceManager::getInstance()->removePersistentService(ITEM_SERVICE_TYPE::SpeedUpDPLoss, &user);
173 if (form == NULL)
174 break;
176 SM_STATIC_PARAMS_1(params, STRING_MANAGER::item);
177 params[0].SheetId = form->SheetId;
178 PHRASE_UTILITIES::sendDynamicSystemMessage(user.getEntityRowId(), "ITEM_SERVICE_CONSUMED", params);
181 else
183 // Don't send message to user if the xp was penalty resorption
184 if (usedSkill!=SKILLS::unknown)
186 SM_STATIC_PARAMS_4(params, STRING_MANAGER::integer, STRING_MANAGER::skill, STRING_MANAGER::integer, STRING_MANAGER::integer);
187 params[0].Int = sint32(100*xpRaw);
188 params[1].Enum = usedSkill;
189 params[2].Int = sint32(10*xp);
190 params[3].Int = sint32(10*(_DeathXPToGain-_CurrentDeathXP) );
191 PHRASE_UTILITIES::sendDynamicSystemMessage(user.getEntityRowId(), "PROGRESS_DEATH_PENALTY_PAYBACK", params);
194 xp = 0.0;
195 updataDb(user);
199 CDeathPenaltiesTimerEvent::CDeathPenaltiesTimerEvent(CCharacter *parent)
201 _Parent = parent;
204 void CDeathPenaltiesTimerEvent::timerCallback(CTimer* owner)
206 H_AUTO(CDeathPenaltiesTimerEvent);
208 uint32 nextUpdate = _Parent->updateDeathPenaltyResorption();
209 owner->setRemaining(nextUpdate, this);