Untitled
unknown
plain_text
5 months ago
25 kB
2
Indexable
/***********************************************************************/ /** © 2015 CD PROJEKT S.A. All rights reserved. /** THE WITCHER® is a trademark of CD PROJEKT S. A. /** The Witcher game is based on the prose of Andrzej Sapkowski. /***********************************************************************/ import abstract class W3AbilityManager extends IScriptable { import var owner : CActor; import var usedHealthType : EBaseCharacterStats; import var charStats : CCharacterStats; import saved var usedDifficultyMode : EDifficultyMode; import var difficultyAbilities : array< array< name > >; import var ignoresDifficultySettings : bool; private var overhealBonus : float; protected var isInitialized : bool; default isInitialized = false; import protected saved var blockedAbilities : array<SBlockedAbility>; import final function CacheStaticScriptData(); import final function SetInitialStats( diff : EDifficultyMode ) : bool; import final function FixInitialStats( diff : EDifficultyMode ) : bool; import final function HasStat( stat : EBaseCharacterStats ) : bool; import final function StatAddNew( stat : EBaseCharacterStats, optional max : float ); import final function RestoreStat( stat : EBaseCharacterStats ); import final function RestoreStats(); import function GetStat( stat : EBaseCharacterStats, optional skipLock : bool ) : float; import final function GetStatMax( stat : EBaseCharacterStats ) : float; import final function GetStatPercents( stat : EBaseCharacterStats ) : float; import final function GetStats( stat : EBaseCharacterStats, out current : float, out max : float ) : bool; import final function SetStatPointCurrent( stat : EBaseCharacterStats, val : float ); import final function SetStatPointMax( stat : EBaseCharacterStats, val : float ); import final function UpdateStatMax( stat : EBaseCharacterStats ); import final function HasResistStat( stat : ECharacterDefenseStats ) : bool; import final function GetResistStat( stat : ECharacterDefenseStats, out resistStat: SResistanceValue ) : bool; import final function SetResistStat( stat : ECharacterDefenseStats, out resistStat: SResistanceValue ); import final function ResistStatAddNew( stat : ECharacterDefenseStats ); import function RecalcResistStat( stat : ECharacterDefenseStats ); import function GetAttributeValueInternal( attributeName : name, optional tags : array< name > ) : SAbilityAttributeValue; import final function CacheDifficultyAbilities(); import final function UpdateStatsForDifficultyLevel( diff : EDifficultyMode ); import final function UpdateDifficultyAbilities( diff : EDifficultyMode ); import final function GetAllStats_Debug( out stats : array< SBaseStat > ) : bool; import final function GetAllResistStats_Debug( out stats : array< SResistanceValue > ) : bool; public function PostInit(); import private function SetCharacterStats( cStats : CCharacterStats ); public function Init(ownr : CActor, cStats : CCharacterStats, isFromLoad : bool, diff : EDifficultyMode) : bool { var abs : array<name>; var i : int; var dm : CDefinitionsManagerAccessor; isInitialized = false; difficultyAbilities.Clear(); ignoresDifficultySettings = false; CacheStaticScriptData(); SetCharacterStats( cStats ); owner = ownr; dm = theGame.GetDefinitionsManager(); cStats.GetAbilities(abs); for(i=0; i<abs.Size(); i+=1) { if(dm.AbilityHasTag(abs[i], theGame.params.DIFFICULTY_TAG_IGNORE)) { ignoresDifficultySettings = true; break; } } if(!ignoresDifficultySettings) difficultyAbilities.Resize(EnumGetMax('EDifficultyMode')+1); if(!isFromLoad) { usedDifficultyMode = EDM_NotSet; if(!SetInitialStats(diff)) return false; } else { if ( !FixInitialStats(diff) ) { if(!ignoresDifficultySettings) { CacheDifficultyAbilities(); } } } if(!ignoresDifficultySettings && usedDifficultyMode != diff) { UpdateStatsForDifficultyLevel(diff); } return true; } public final function IsInitialized() : bool {return isInitialized;} public function OnOwnerRevived() { var i : int; RestoreStats(); for(i=blockedAbilities.Size()-1; i>=0; i-=1) { if(blockedAbilities[i].timeWhenEnabledd > 0) blockedAbilities.EraseFast(i); } } public final function UsesVitality() : bool { return usedHealthType == BCS_Vitality; } public function UsesEssence() : bool { return usedHealthType == BCS_Essence; } protected function CheckForbiddenAttribute(attName : name) : bool { if( theGame.params.IsForbiddenAttribute(attName) ) { LogAssert(false, "W3AbilityManager.CheckForbiddenAttribute: you are trying to get attribute <<" + attName + ">> in a wrong way - use propper custom function instead!"); return true; } return false; } public function GetAttributeValue(attributeName : name, optional tags : array<name>) : SAbilityAttributeValue { var val : SAbilityAttributeValue; // W3EE - Begin if(CheckForbiddenAttribute(attributeName) && attributeName != 'spell_power') // W3EE - End { val.valueBase = -9999; val.valueAdditive = -9999; val.valueMultiplicative = 100; return val; } return GetAttributeValueInternal(attributeName, tags); } public function GetAbilityAttributeValue(abilityName : name, attributeName : name) : SAbilityAttributeValue { var val : SAbilityAttributeValue; if(CheckForbiddenAttribute(attributeName)) { val.valueBase = -9999; val.valueAdditive = -9999; val.valueMultiplicative = 100; return val; } return charStats.GetAbilityAttributeValue(attributeName, abilityName); } protected function GetNonBlockedSkillAbilitiesList(tags : array<name>) : array<name> { var null : array<name>; return null; } public function CheckBlockedAbilities(dt : float) : float { var i : int; var min : float; min = 1000000; for(i = blockedAbilities.Size()-1; i>=0; i-=1) { if(blockedAbilities[i].timeWhenEnabledd != -1) { blockedAbilities[i].timeWhenEnabledd = MaxF(blockedAbilities[i].timeWhenEnabledd - dt, 0); if(blockedAbilities[i].timeWhenEnabledd == 0) { BlockAbility(blockedAbilities[i].abilityName, false); } else { min = MinF(min, blockedAbilities[i].timeWhenEnabledd); } } } if(min == 1000000) min = -1; return min; } public function BlockAbility(abilityName : name, block : bool, optional cooldown : float) : bool { var i : int; var ab : SBlockedAbility; var min, cnt : float; var ret : bool; if(!IsNameValid(abilityName)) return false; //Kolaris - Block Ability Cleanup if(block) { ab.abilityName = abilityName; if(cooldown > 0) { ab.timeWhenEnabledd = cooldown; min = cooldown; for(i=0; i<blockedAbilities.Size(); i+=1) { if(blockedAbilities[i].timeWhenEnabledd > 0 && blockedAbilities[i].abilityName == abilityName) { min = MinF(min, blockedAbilities[i].timeWhenEnabledd); //theGame.GetGuiManager().ShowNotification("TimeWhenEnabledd: " + blockedAbilities[i].timeWhenEnabledd + "<br>Min: " + min); } } owner.AddTimer('CheckBlockedAbilities', min, , , , true); } else { ab.timeWhenEnabledd = -1; } ab.count = charStats.GetAbilityCount(abilityName); ret = charStats.RemoveAbility(abilityName); blockedAbilities.PushBack(ab); return ret; } else { for(i=0; i<blockedAbilities.Size(); i+=1) { if(blockedAbilities[i].abilityName == abilityName) { if(!block) { cnt = blockedAbilities[i].count; blockedAbilities.Erase(i); if(cnt > 0) charStats.AddAbility(abilityName, cnt); return true; } else { return false; } } } return false; } } import public final function IsAbilityBlocked(abilityName : name) : bool; public function GetPowerStatValue(stat : ECharacterPowerStats, optional abilityTag : name) : SAbilityAttributeValue { var tags : array<name>; if(IsNameValid(abilityTag)) tags.PushBack(abilityTag); // W3EE - Begin /* if ( stat == CPS_Spellpower ) { (GetAttributeValueInternal(PowerStatEnumToName(stat), tags)).valueAdditive /= 2; (GetAttributeValueInternal(PowerStatEnumToName(stat), tags)).valueMultiplicative /= 2; return GetAttributeValueInternal(PowerStatEnumToName(stat), tags); }*/ /*else */return GetAttributeValueInternal(PowerStatEnumToName(stat), tags); // W3EE - End } protected function MutliplyStatBy(stat : EBaseCharacterStats, val : float) { if(val > 0) SetStatPointCurrent(stat, MinF(val * GetStat(stat, true), GetStatMax(stat) ) ); } public function GetResistValue(stat : ECharacterDefenseStats, out points : float, out percents : float) { var pts, prc, charPts, charPerc : SAbilityAttributeValue; var resistStat : SResistanceValue; if ( GetResistStat( stat, resistStat ) ) { charPts = resistStat.points; charPerc = resistStat.percents; } points = CalculateAttributeValue(charPts); percents = MinF(1, CalculateAttributeValue(charPerc)); return; } public final function UsedHPType() : EBaseCharacterStats { return usedHealthType; } public final function ForceSetStat( stat : EBaseCharacterStats, val : float ) { var prev : float; prev = GetStat(stat); SetStatPointCurrent(stat, MinF(GetStatMax(stat), MaxF(0, val)) ); if(prev != GetStat(stat)) { if( stat == BCS_Vitality ) { OnVitalityChanged(); } else if( stat == BCS_Toxicity ) { OnToxicityChanged(); } else if( stat == BCS_Focus ) { OnFocusChanged(); } else if( stat == BCS_Air ) { OnAirChanged(); } else if( stat == BCS_Essence ) { OnEssenceChanged(); } } } protected final function InternalReduceStat(stat : EBaseCharacterStats, amount : float) { SetStatPointCurrent(stat, MaxF( 0, GetStat(stat, true) - MaxF( 0, amount ) ) ); } public final function DrainAir(cost : float, optional delay : float ) { if(cost > 0) { InternalReduceStat(BCS_Air, cost); owner.StartAirRegen(); } if(delay > 0) owner.PauseEffects(EET_AutoAirRegen, 'AirCostDelay', false, delay); } public final function DrainSwimmingStamina(cost : float, optional delay : float ) { if(cost > 0) { InternalReduceStat(BCS_SwimmingStamina, cost); owner.StartSwimmingStaminaRegen(); } if(delay > 0) owner.PauseEffects(EET_AutoSwimmingStaminaRegen, 'SwimmingStaminaCostDelay', false, delay); } public function DrainStamina(action : EStaminaActionType, optional fixedCost : float, optional fixedDelay : float, optional abilityName : name, optional dt : float, optional costMult : float) : float { var cost, delay : float; GetStaminaActionCost(action, cost, delay, fixedCost, fixedDelay, abilityName, dt, costMult); //Kolaris - Stamina Options if( owner == GetWitcherPlayer() && Options().StamCostGlobal() > 0 ) cost *= Options().StamCostGlobal(); if(cost > 0) { InternalReduceStat(BCS_Stamina, cost); owner.StartStaminaRegen(); } if(delay > 0) { if(IsNameValid(abilityName)) owner.PauseStaminaRegen( abilityName, delay ); else owner.PauseStaminaRegen( StaminaActionTypeToName(action), delay ); } return cost; } public function GetStaminaActionCost(action : EStaminaActionType, out cost : float, out delay : float, optional fixedCost : float, optional fixedDelay : float, optional abilityName : name, optional dt : float, optional costMult : float) { var costAtt, delayAtt : SAbilityAttributeValue; if(action == ESAT_FixedValue) { cost = fixedCost; delay = MaxF(0, fixedDelay); } else { GetStaminaActionCostInternal(action, dt > 0.0f, costAtt, delayAtt, abilityName); cost = CalculateAttributeValue(costAtt); delay = CalculateAttributeValue(delayAtt); } //Kolaris - Injury Effects if( ((CNewNPC)owner).GetInjuryManager().HasInjury(EFI_Arms) || ((CNewNPC)owner).GetInjuryManager().HasInjury(EPI_Arms) ) { if( action == ESAT_LightAttack || action == ESAT_HeavyAttack || action == ESAT_SuperHeavyAttack || action == ESAT_Counterattack ) cost *= 1.2f; } if(costMult != 0) { cost *= costMult; } if(dt > 0) { cost *= dt; } } protected function GetStaminaActionCostInternal(action : EStaminaActionType, isPerSec : bool, out cost : SAbilityAttributeValue, out delay : SAbilityAttributeValue, optional abilityName : name) { var costAttributeName, delayAttributeName, attribute : name; var tags : array<name>; var val : SAbilityAttributeValue; cost = val; delay = val; theGame.params.GetStaminaActionAttributes(action, isPerSec, costAttributeName, delayAttributeName); if(action == ESAT_Ability) { if(isPerSec) attribute = theGame.params.STAMINA_COST_PER_SEC_DEFAULT; else attribute = theGame.params.STAMINA_COST_DEFAULT; cost = GetSkillAttributeValue(abilityName, attribute, false, true); delay = GetSkillAttributeValue(abilityName, theGame.params.STAMINA_DELAY_DEFAULT, false, true); } // W3EE - Begin else if( action == ESAT_Parry ) { cost = owner.GetAttributeValue( 'parry_stamina_cost' ); delay.valueBase = 0.5f; delay.valueMultiplicative = 1.f; } else if( action == ESAT_Counterattack ) { cost = owner.GetAttributeValue( 'counter_stamina_cost' ); delay.valueBase = 0.5f; delay.valueMultiplicative = 1.f; } // W3EE - End else { cost = GetAttributeValueInternal(costAttributeName); delay = GetAttributeValueInternal(delayAttributeName); } cost += GetAttributeValueInternal('stamina_cost_modifier'); delay += GetAttributeValueInternal('stamina_delay_modifier'); } public function DrainVigor( abilityName : name, optional dt : float, optional costMult : float, optional overrideValue : float, optional forceDrain : bool ) : bool { var cost, delay, curVigor: float; var ret : bool; curVigor = GetStat(BCS_Focus); GetVigorActionCost(cost, delay, abilityName, dt, costMult, overrideValue, forceDrain); ret = true; if( cost <= curVigor || (cost > curVigor && forceDrain) ) { InternalReduceStat(BCS_Focus, cost); if( cost > curVigor ) ret = false; } else return false; OnFocusChanged(); if( delay ) GetWitcherPlayer().StartRegenTimer(delay); return ret; } public function GetVigorActionCost( out cost : float, out delay : float, abilityName : name, optional dt : float, optional costMult : float, optional overrideValue : float, optional forceDrain : bool ) : float { var costAttr, delayAttr : SAbilityAttributeValue; GetVigorActionCostInternal(dt > 0.f, costAttr, delayAttr, abilityName); cost = CalculateAttributeValue(costAttr); delay = CalculateAttributeValue(delayAttr); if( forceDrain ) cost = overrideValue; cost *= costMult; if( dt ) cost *= dt; return cost; } protected function GetVigorActionCostInternal( perSec : bool, out cost : SAbilityAttributeValue, out delay : SAbilityAttributeValue, abilityName : name ) { var attributeName : name; if( perSec ) attributeName = 'vigor_cost_per_sec'; else attributeName = 'vigor_cost'; cost = GetSkillAttributeValue(abilityName, attributeName, false, true); delay = GetSkillAttributeValue(abilityName, 'vigor_delay', false, true); cost += GetAttributeValueInternal('vigor_cost_modifier'); delay += GetAttributeValueInternal('vigor_delay_modifier'); } public function GetSkillAttributeValue(abilityName: name, attributeName : name, addBaseCharAttribute : bool, addSkillModsAttribute : bool) : SAbilityAttributeValue { var min, max :SAbilityAttributeValue; theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, attributeName, min, max); return GetAttributeRandomizedValue(min, max); } // W3EE - Begin public final function DrainFocus(amount : float, optional dt : float ) { if ( dt > 0 ) InternalReduceStat(BCS_Focus, amount * dt); else InternalReduceStat(BCS_Focus, amount); } // W3EE - End public final function DrainMorale(amount : float ) { InternalReduceStat(BCS_Morale, amount); owner.StartMoraleRegen(); } public final function DrainToxicity(amount : float ) { InternalReduceStat(BCS_Toxicity, amount); OnToxicityChanged(); } public final function DrainVitality(amount : float) { SetStatPointCurrent(BCS_Vitality, MaxF( 0, GetStat(BCS_Vitality) - MaxF(0, amount) )); owner.StartVitalityRegen(); if(GetStat(BCS_Vitality) <= 0 && UsesVitality()) { owner.SignalGameplayEvent( 'Death' ); owner.SetAlive(false); } OnVitalityChanged(); } public final function DrainEssence(amount : float) { SetStatPointCurrent(BCS_Essence, MaxF( 0, GetStat(BCS_Essence) - MaxF(0, amount) ) ); owner.StartEssenceRegen(); if(GetStat(BCS_Essence) <= 0 && UsesEssence()) { owner.SignalGameplayEvent( 'Death' ); owner.SetAlive(false); } OnEssenceChanged(); } public final function AddPanic( amount : float ) { SetStatPointCurrent( BCS_Panic, RoundF(MaxF( 0, GetStat( BCS_Panic ) - amount )) ); owner.StartPanicRegen(); } public function GainStat( stat : EBaseCharacterStats, amount : float ) { var statWithoutLock, statWithLock, lock, max : float; var hadOverheal : bool; var mi, ma : SAbilityAttributeValue; statWithoutLock = GetStat(stat, true); statWithLock = GetStat(stat, false); lock = statWithLock - statWithoutLock; max = GetStatMax(stat); // W3EE - Begin if( stat != BCS_Vitality ) SetStatPointCurrent(stat, MinF( max - lock, statWithoutLock + MaxF(0, amount) ) ); else SetStatPointCurrent(stat, MinF(max, statWithLock + MaxF(0, amount))); // W3EE - End if( stat == BCS_Vitality ) { OnVitalityChanged(); // W3EE - Begin /* if ( (W3PlayerAbilityManager)this && owner == GetWitcherPlayer() && GetWitcherPlayer().HasRunewordActive('Runeword 4 _Stats') && GetWitcherPlayer().IsInCombat() && (statWithoutLock + amount) > max ) { theGame.GetDefinitionsManager().GetAbilityAttributeValue('Runeword 4 _Stats', 'max_bonus', mi, ma); hadOverheal = (overhealBonus > (0.005 * GetStatMax(BCS_Vitality))); overhealBonus += (statWithoutLock + amount) - GetStatMax(stat); overhealBonus = MinF(overhealBonus, max * ma.valueMultiplicative); thePlayer.PlayRuneword4FX(); } */ // W3EE - End } else if( stat == BCS_Toxicity ) OnToxicityChanged(); //Kolaris - Regeneration else if( stat == BCS_Essence ) OnEssenceChanged(); else if( stat == BCS_Focus ) { OnFocusChanged(); if( (W3PlayerAbilityManager)this && owner == GetWitcherPlayer() && amount > 1.f && (statWithoutLock + amount) > max && (GetWitcherPlayer().HasAbility('Glyphword 37 _Stats', true) || GetWitcherPlayer().HasAbility('Glyphword 38 _Stats', true) || GetWitcherPlayer().HasAbility('Glyphword 39 _Stats', true)) ) GetWitcherPlayer().GainStat(BCS_Vitality, ((statWithoutLock + amount) - GetStatMax(stat)) * 200.f); //theGame.GetGuiManager().ShowNotification("Vitality Gained from Vigor: " + ((statWithoutLock + amount) - GetStatMax(stat)) * 200.f); } else if( stat == BCS_Stamina ) { if( (W3PlayerAbilityManager)this && owner == GetWitcherPlayer() && amount > 1.f && (statWithoutLock + amount) > max && (GetWitcherPlayer().HasAbility('Glyphword 37 _Stats', true) || GetWitcherPlayer().HasAbility('Glyphword 38 _Stats', true) || GetWitcherPlayer().HasAbility('Glyphword 39 _Stats', true)) ) GetWitcherPlayer().GainStat(BCS_Vitality, ((statWithoutLock + amount) - GetStatMax(stat)) * 2.f / Options().StamCostGlobal()); //theGame.GetGuiManager().ShowNotification("Vitality Gained from Stamina: " + ((statWithoutLock + amount) - GetStatMax(stat)) * 2.f / Options().StamCostGlobal()); } } public final function IgnoresDifficultySettings() : bool { return ignoresDifficultySettings; } protected function OnVitalityChanged(); protected function OnEssenceChanged(); protected function OnToxicityChanged(); // W3EE - Begin protected function OnFocusChanged(); // W3EE - End protected function OnAirChanged(); public function OnAbilityAdded( abilityName : name ) { OnAbilityChanged( abilityName ); } public function OnAbilityRemoved( abilityName : name ) { // W3EE - Begin /* if( abilityName == 'Runeword 4 _Stats' ) { ResetOverhealBonus(); } */ // W3EE - End OnAbilityChanged( abilityName ); } protected function OnAbilityChanged( abilityName : name ) { var atts, tags : array<name>; var attribute : name; var i,size,stat, j : int; var oldMax, maxVit, maxEss : float; var resistStatChanged, tmpBool : bool; var dm : CDefinitionsManagerAccessor; var val : SAbilityAttributeValue; var buffs : array<CBaseGameplayEffect>; var regenBuff : W3RegenEffect; if(!owner) return; dm = theGame.GetDefinitionsManager(); dm.GetAbilityAttributes(abilityName, atts); resistStatChanged = false; size = atts.Size(); if(dm.AbilityHasTag(abilityName, theGame.params.DIFFICULTY_TAG_IGNORE)) { ignoresDifficultySettings = true; difficultyAbilities.Clear(); usedDifficultyMode = EDM_NotSet; } for(i=0; i<size; i+=1) { attribute = atts[ i ]; if ( ( attribute == 'vitality' && UsesEssence() ) || ( attribute == 'essence' && UsesVitality() ) ) { continue; } stat = StatNameToEnum( attribute ); if(stat != BCS_Undefined) { if(!HasStat(stat)) { StatAddNew(stat); } else { if(abilityName == theGame.params.GLOBAL_ENEMY_ABILITY || abilityName == theGame.params.GLOBAL_PLAYER_ABILITY || abilityName == theGame.params.ENEMY_BONUS_PER_LEVEL) { UpdateStatMax(stat); RestoreStat(stat); } else { oldMax = GetStatMax(stat); UpdateStatMax(stat); MutliplyStatBy(stat, GetStatMax(stat) / oldMax); } } continue; } stat = ResistStatNameToEnum(attribute, tmpBool); if(stat != CDS_None) { if ( HasResistStat( stat ) ) { RecalcResistStat(stat); resistStatChanged = true; } else { ResistStatAddNew(stat); } continue; } stat = RegenStatNameToEnum(attribute); if(stat != CRS_Undefined && stat != CRS_UNUSED) { buffs = owner.GetBuffs(); for(j=0; j<buffs.Size(); j+=1) { regenBuff = (W3RegenEffect)buffs[j]; if(regenBuff) { if(regenBuff.GetRegenStat() == stat && IsBuffAutoBuff(regenBuff.GetEffectType())) { regenBuff.UpdateEffectValue(); break; } } } if( stat == CRS_Essence ) { owner.StartEssenceRegen(); } } if(!ignoresDifficultySettings && attribute == theGame.params.DIFFICULTY_HP_MULTIPLIER) { maxVit = GetStatMax( BCS_Vitality ); maxEss = GetStatMax( BCS_Essence ); if(maxVit > 0) { oldMax = maxVit; UpdateStatMax(BCS_Vitality); MutliplyStatBy(BCS_Vitality, GetStatMax(BCS_Vitality) / oldMax); } if(maxEss > 0) { oldMax = maxEss; UpdateStatMax(BCS_Essence); MutliplyStatBy(BCS_Essence, GetStatMax(BCS_Essence) / oldMax); } continue; } } if(resistStatChanged) { owner.RecalcEffectDurations(); } } public final function GetOverhealBonus() : float { return overhealBonus; } public final function ResetOverhealBonus() { overhealBonus = 0; //Kolaris - Destruction //thePlayer.StopEffect('runeword_4'); } public final function Debug_GetUsedDifficultyMode() : EDifficultyMode { return usedDifficultyMode; } }
Editor is loading...
Leave a Comment