Code:
Group Vars
float Property EngageDistance = 4000.0000 Auto
float Property UpdateInterval = 20.0000 Auto
ActorValue Property AVHealth Auto Const Mandatory
ActorValue Property AVAggro Auto Const Mandatory
ActorValue Property AVConfidence Auto Const Mandatory
ActorValue Property AVPerception Auto Const Mandatory
ActorValue Property AVAgility Auto Const Mandatory
ActorValue Property AVEndurance Auto Const Mandatory
ActorValue Property AVStrength Auto Const Mandatory
EndGroup
Group Identifier
Weapon Property FatMan Auto Const Mandatory
Weapon Property SuperMutantSuiciderBomb Auto Const Mandatory
Keyword Property EncTypeLegendary Auto Const Mandatory
Keyword Property THEW_KEY_StatsOnce Auto Const Mandatory
Faction Property THEW_FAC_ControllableActor Auto Const Mandatory
Race Property HumanRace Auto Const Mandatory
Race Property FeralGhoulRace Auto Const Mandatory
Race Property FeralGhoulGlowingRace Auto Const Mandatory
Race Property VertibirdRace Auto Const Mandatory
Race Property YaoGuaiRace Auto Const Mandatory
Race Property DeathClawRace Auto Const Mandatory
Race Property SuperMutantRace Auto Const Mandatory
Race Property SupermutantBehemothRace Auto Const Mandatory
Faction Property PotentialCompanionFaction Auto Const Mandatory
Faction Property BrotherhoodofSteelFaction Auto Const Mandatory
Faction Property GunnerFaction Auto Const Mandatory
Faction Property WorkshopNPCFaction Auto Const Mandatory
Faction Property WorkshopCaravanFaction Auto Const Mandatory
Faction Property TriggermanFaction Auto Const Mandatory
Faction Property TheForgedFaction Auto Const Mandatory
Faction Property SecurityDiamondCity Auto Const Mandatory
Faction Property RailroadFaction Auto Const Mandatory
Faction Property RaiderFaction Auto Const Mandatory
Faction Property MinutemenFaction Auto Const Mandatory
Faction Property InstituteFaction Auto Const Mandatory
Faction Property ChildrenOfAtomFaction Auto Const Mandatory
Faction Property CaravanFaction Auto Const Mandatory
Faction Property AlienFaction Auto Const Mandatory
Faction Property BugFaction Auto Const Mandatory
Faction Property CreatureFaction Auto Const Mandatory
Faction Property FeralGhoulFaction Auto Const Mandatory
Faction Property MutantHoundFaction Auto Const Mandatory
Faction Property RadScorpionFaction Auto Const Mandatory
Faction Property MirelurkFaction Auto Const Mandatory
Faction Property RobotFaction Auto Const Mandatory
Faction Property SuperMutantFaction Auto Const Mandatory
Faction Property SynthFaction Auto Const Mandatory
Faction Property VertibirdFaction Auto Const Mandatory
Faction Property ViciousDogFaction Auto Const Mandatory
Faction Property TurretFaction Auto Const Mandatory
Faction Property YaoGuaiFaction Auto Const Mandatory
Faction Property DeathclawFaction Auto Const Mandatory
EndGroup
; Actor-Identifiers
actor Player
actor MySelf
int PlayerLevel
; Actor-Flags
bool disabledWhenFar = false
bool blindWhenFar = false
bool isDisabled = false
bool isBlind = false
int randomId = 0
; Actor Stats
ActorStats originalStats
ActorStats targetStats
; To Do
; - Moeglichst performante, einfache und failsafe Identifizierungen
; - Special-Goodies fuer einige Typen
; - Nicht nur Stats, auch KI und Kampfstil verbessern
; - Debug-Funktionen fuer bestimmte Typen
; Moeglich Identifier
; IsInPowerArmor()
; HasPerk()
; HasSpell()
; HasMagicEffectWithKeyword()
; HasMagicEffect(
; IsPlayerTeammate()
; IsInFaction(n)
; GetLevel()
; HasKeyword()
; WornHasKeyword()
; Initialize effects
Event OnEffectStart(Actor Target, Actor Caster)
MySelf = Target
Player = Game.GetPlayer()
if isEnhanceable()
; Variablen initialisieren
Player = Game.GetPlayer()
PlayerLevel = Player.GetLevel()
; Originale Stats speichern
originalStats = getStats()
; Zielstats ermitteln
targetStats = getTargetStats()
; Actor aufmotzen
enhanceActor()
; Spezielle Gegner werden entweder deaktiviert oder blind gemacht, wenn sie weit weg sind.
; Das soll verhindern, dass grosse Bossgegner bereits alle anderen oder sogar sich selbst gekillt haben.
if shouldBeBlindWhenFar()
debugTraceFlag("blind")
blindWhenFar = true
blindWhenFar()
elseif shouldBeDisabledWhenFar()
debugTraceFlag("disabled")
disabledWhenFar = true
disableWhenFar()
endif
; Start Stats
debugTrace("startstats")
; Zu Debug-Zwecken
RegisterForRemoteEvent(MySelf, "OnDeath")
endif
EndEvent
; Achtung: Der Magic Effect muss das No death dipspell-Flag auf false haben!
Event OnEffectFinish(Actor akTarget, Actor akCaster)
; End Stats
debugTrace("endstats")
endEvent
; UpdateTimer
Event OnTimer(int aiTimerID)
if disabledWhenFar
disableWhenFar()
elseif blindWhenFar
blindWhenFar()
endif
EndEvent
; Abchecken, ob der Actor überhaupt kontrolliert werden sollte.
bool function isEnhanceable()
if !MySelf.HasKeyword(THEW_KEY_StatsOnce)
MySelf.AddKeyword(THEW_KEY_StatsOnce)
Race MyRace = MySelf.GetRace()
if MySelf == Player
return false
elseif MySelf.IsDead()
return false
elseif MySelf.IsInFaction(PotentialCompanionFaction)
return false
elseif MySelf.HasKeyword(EncTypeLegendary)
return true
elseif MyRace == HumanRace
return true
elseif MyRace == SuperMutantRace
return true
elseif MyRace == SuperMutantBehemothRace
return true;
elseif MyRace == FeralGhoulRace
return true
elseif MyRace == FeralGhoulGlowingRace
return true
elseif MyRace == VertibirdRace
return true
elseif MyRace == YaoGuaiRace
return true
elseif MyRace == DeathClawRace
return true
elseif MySelf.IsInFaction(RadScorpionFaction)
return true
endif
endif
return false;
endfunction
; Normalen Gegnern erst Aufmerksamkeit geben, wenn sie nahe sind.
; Nicht behandeln, wenn sie aus irgendeinem Grund disabled sind.
bool function shouldBeBlindWhenFar()
if Player.IsInInterior()
return false
elseif MySelf.IsDisabled()
return false
elseif MySelf.IsInFaction(RaiderFaction)
return true
elseif MySelf.IsInFaction(GunnerFaction)
return true
elseif MySelf.IsInFaction(TheForgedFaction)
return true
elseif MySelf.IsInFaction(FeralGhoulFaction)
return true
elseif MySelf.IsInFaction(SynthFaction)
return true
elseif MySelf.IsInFaction(SuperMutantFaction) && MySelf.GetRace() != SuperMutantBehemothRace
return true
endif
return false;
endfunction
; Supergegner erst aktivieren, wenn sie nahe sind.
; Nicht behandeln, wenn sie aus irgendeinem Grund disabled sind.
bool function shouldBeDisabledWhenFar()
if Player.IsInInterior()
return false
elseif MySelf.IsDisabled()
return false
elseif MySelf.GetRace() == SuperMutantBehemothRace
return true
elseif MySelf.GetItemCount(SuperMutantSuiciderBomb) > 0
return true
elseif MySelf.GetItemCount(FatMan) > 0 ; Variable erstellen
return true
endif
return false
endfunction
; Control actor's distance and enable him when near
function disableWhenFar()
bool nearBy = MySelf.GetDistance(Player) < EngageDistance
if nearBy
if isDisabled
MySelf.Enable()
debugTraceFlag("enabled")
isDisabled = false
endif
else
if !isDisabled
MySelf.Disable()
isDisabled = true
endif
StartTimer(updateInterval)
endif
endfunction
; Control actor's distance and enable him when near
function blindWhenFar()
bool nearBy = MySelf.GetDistance(Player) < EngageDistance
if nearBy
if isBlind
MySelf.SetValue(AVPerception, targetStats.perception) ; Ziel-Aufmerksamkeit setzen
MySelf.SetValue(AVAggro, originalStats.aggression) ; Originale Aggression wiederherstellen
debugTraceFlag("notblind")
isBlind = false
endif
else
if !isBlind
MySelf.SetValue(AVPerception, 1) ; Aufmerksamkeit auf Distanz runter(Actors sehen keine entfernten Gegner)
MySelf.SetValue(AVAggro, 2) ; Aggression auf Distanz runter auf Aggressiv(kloppen sich nur mit eindeutigen Gegnern)
isBlind = true
endif
StartTimer(updateInterval)
endif
endfunction
; Actor-Stats Datentyp
struct ActorStats
int level = 3
float health = 1.0
float endurance = 1.0
float strength = 1.0
float perception = 1.0
float agility = 1.0
float aggression = 1.0
endstruct
; Originale Stats ermitteln
ActorStats function getStats()
ActorStats stats = new ActorStats
stats.level = MySelf.GetLevel()
stats.health = MySelf.GetValue(AVHealth)
stats.endurance = MySelf.GetValue(AVEndurance)
stats.strength = MySelf.GetValue(AVStrength)
stats.perception = MySelf.GetValue(AVPerception)
stats.agility = MySelf.GetValue(AVAgility)
stats.aggression = MySelf.GetValue(AVAggro)
return stats
endfunction
; Ziel-Stats basierend auf Level und Gegner-Typen ermitteln
; Hier werden ausschliesslich direkte Kampf-Stats gesetzt.
ActorStats function getTargetStats()
int level = PlayerLevel
float modifier = 1.1
ActorStats stats = new ActorStats
stats.health = getTargetHealth(level, modifier)
stats.endurance = getTargetStat(level, modifier)
stats.strength = getTargetStat(level, modifier)
stats.agility = getTargetStat(level, modifier)
return stats
endfunction
; Ziel-Gesundheit ermitteln
float function getTargetHealth(int level, float modifier)
float targetValue = 200.0
return targetValue
endfunction
; Ziel-Stat ermitteln
float function getTargetStat(int level, float modifier)
float targetValue = 5.0
return targetValue
endfunction
; Actor verbessern
; Vorerst nur Stats, später auch KI.
function enhanceActor()
if targetStats.health > originalStats.health
MySelf.SetValue(AVHealth, targetStats.health)
endif
if targetStats.endurance > originalStats.endurance
MySelf.SetValue(AVEndurance, targetStats.endurance)
endif
if targetStats.strength > originalStats.strength
MySelf.SetValue(AVStrength, targetStats.strength)
endif
if targetStats.agility > originalStats.agility
MySelf.SetValue(AVAgility, targetStats.agility)
endif
endfunction
; Debug-Ausgabe
function debugTrace (string traceType)
ActorStats stats = getStats()
string trace = "THEW -Statscontrol - Actor " + getFormId() + " - "
if traceType == "blind"
trace += "Set to blind"
elseif traceType == "notblind"
trace += "Is not blind anymore"
elseif traceType == "disabled"
trace += "Set to disabled"
elseif traceType == "enabled"
trace += " Set to enabled"
elseif traceType == "startstats"
trace += "On Init - Level: " + stats.level + " Health: " + stats.health + " Perception: " + stats.perception + " Endurance: " + stats.endurance + " Strength: " + stats.strength
elseif traceType == "endstats"
trace += "On Death - Level: " + stats.level + " Health: " + stats.health + " Perception: " + stats.perception + " Endurance: " + stats.endurance + " Strength: " + stats.strength
endif
Debug.Trace(trace)
endfunction
; Generiert eine mehr oder weniger eindeutige ID, um im Log zusaemmenhaengende Werte finden zu können.
string function getFormId ()
return MySelf.GetFormID()
endfunction