Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- scriptname XsTrainingMannequin extends ObjectReference
- {Allows the player to train combat skills on an training mannequin or an archery target}
- ;/////////////////////////////////////////////////////////////////////////////
- [[[ History ]]]
- 2012-03-05 15:15: ~Xetrill: Removed PowerAttack and SneakAttack handling
- since it does not register - ever.
- 2012-03-05 15:18: ~Xetrill: Add the states "Ready" and "Busy" as to avoid
- the extreme script spawning that happens if magic (destruction) is used.
- 2012-03-05 16:22: ~Xetrill: removed Ready state, instead use the default
- 'empty state' (BTW: why is it not called 'implicit default state').
- [[[ TODO ]]]
- 2012-03-05 16:11: ~Xetrill: Test whether bash attacks are actually
- detected -- coming through.
- /////////////////////////////////////////////////////////////////////////////;
- ;/////////////////////////////////////////////////////////////////////////////
- / Properties
- /////////////////////////////////////////////////////////////////////////////;
- int property SkillGainMethod = -1 auto
- {OPTIONAL; Determines the method used to advance skills.
- - omitted or -1: random
- - 0: stable - the value of a SkillGain_* property is simply added
- - 1: random - the value of a SkillGain_* property is randomized, ranging from its value halved as minimum to its value doubled as its maximum}
- FormList property MagicKeywordList auto
- {OPTIONAL; if specified allows this mannequin/script to advance the destruction skill too.
- The list must only contain destruction magic specific keywords.}
- ;/////////////////////////////////////////////////////////////////////////////
- / Constants
- /////////////////////////////////////////////////////////////////////////////;
- float property MasteryNoviceMult = 2.0 autoreadonly hidden
- float property MasteryApprenticeMult = 1.8 autoreadonly hidden
- float property MasteryExpertMult = 1.4 autoreadonly hidden
- float property MasteryMasterMult = 1.0 autoreadonly hidden
- int property CriticalBonusChance = 9 autoreadonly hidden
- float property CriticalBonusMult = 2.2 autoreadonly hidden
- float property SkillGain_Magic = 7.0 autoreadonly hidden
- float property SkillGain_Melee = 9.0 autoreadonly hidden
- float property SkillGain_Ranged = 15.0 autoreadonly hidden
- string property Skill_OneHanded = "OneHanded" autoreadonly hidden
- string property Skill_TwoHanded = "TwoHanded" autoreadonly hidden
- string property Skill_Marksman = "Marksman" autoreadonly hidden
- string property Skill_Destruction = "Destruction" autoreadonly hidden
- string property Skill_Block = "Block" autoreadonly hidden
- int property GainType_Default = 1 autoreadonly hidden
- int property GainType_Stable = 0 autoreadonly hidden
- int property GainType_Random = 1 autoreadonly hidden
- int property ItemType_Invalid = -1 autoreadonly hidden
- int property ItemType_Nothing = 0 autoreadonly hidden
- int property ItemType_1HSword = 1 autoreadonly hidden
- ; int property ItemType_1HDagger = 2 autoreadonly hidden
- ; int property ItemType_1HAxe = 3 autoreadonly hidden
- int property ItemType_1HMace = 4 autoreadonly hidden
- int property ItemType_2HSword = 5 autoreadonly hidden
- int property ItemType_2HAxe = 6 autoreadonly hidden
- int property ItemType_Bow = 7 autoreadonly hidden
- int property ItemType_Staff = 8 autoreadonly hidden
- ; int property ItemType_Spell = 9 autoreadonly hidden
- ;/////////////////////////////////////////////////////////////////////////////
- / States
- /////////////////////////////////////////////////////////////////////////////;
- state Busy
- ; intentionally left blank
- endstate
- ;/////////////////////////////////////////////////////////////////////////////
- / Events
- /////////////////////////////////////////////////////////////////////////////;
- event OnHit(ObjectReference aggressor, Form source, Projectile unusedProjectile, \
- bool unusedPowerAttack, bool unusedSneakAttack, bool bashAttack, bool unusedHitBlocked)
- if (aggressor != Game.GetPlayer())
- return
- endif
- GotoState("Busy")
- if (bashAttack)
- Debug.Notification("Bash Attack")
- AdvanceSkill(Skill_Block, SkillGain_Melee)
- GotoState("")
- return
- endif
- int itemType = Game.GetPlayer().GetEquippedItemType(1)
- if (itemType == ItemType_Invalid || itemType == ItemType_Nothing)
- itemType = (aggressor as Actor).GetEquippedItemType(0)
- endif
- if (source as Spell && itemType != ItemType_Staff)
- if (XsUtils.HasAnyKeyword(source, MagicKeywordList))
- AdvanceSkill(Skill_Destruction, SkillGain_Magic)
- endif
- elseif (source as Weapon)
- if (itemType >= ItemType_1HSword && itemType <= ItemType_1HMace)
- AdvanceSkill(Skill_OneHanded, SkillGain_Melee)
- elseif (itemType == ItemType_2HSword || itemType == ItemType_2HAxe)
- AdvanceSkill(Skill_TwoHanded, SkillGain_Melee)
- elseif (itemType == ItemType_Bow)
- AdvanceSkill(Skill_Marksman, SkillGain_Ranged)
- endif
- endif
- GotoState("")
- endevent
- ;/////////////////////////////////////////////////////////////////////////////
- / Functions
- /////////////////////////////////////////////////////////////////////////////;
- float function SkillGainFormular(string skill, float in)
- float out = in
- if (MathEx.Chance(CriticalBonusChance) == 1)
- out *= CriticalBonusMult
- Debug.Notification("Critical Hit")
- endif
- float mastery = Game.GetPlayer().GetActorValuePercentage(skill)
- if (mastery > 0.75)
- out += in * MasteryMasterMult
- elseif (mastery > 0.5)
- out += in * MasteryExpertMult
- elseif (mastery > 0.25)
- out += in * MasteryApprenticeMult
- else
- out += in * MasteryNoviceMult
- endif
- return out
- endfunction
- float function AdvanceSkill_Stable(string skill, float gain)
- return SkillGainFormular(skill, MathEx.MaxF(1.0, gain))
- endfunction
- float function AdvanceSkill_Random(string skill, float gain)
- float min = MathEx.MaxF(1.0, gain / 2.0)
- float max = MathEx.MaxF(1.0, gain * 2.0)
- return SkillGainFormular(skill, Utility.RandomFloat(min, max))
- endfunction
- function AdvanceSkill(string skill, float gain)
- if (SkillGainMethod <= 0)
- SkillGainMethod = GainType_Default
- endif
- if (SkillGainMethod == GainType_Stable)
- gain = AdvanceSkill_Stable(skill, gain)
- elseif (SkillGainMethod == GainType_Random)
- gain = AdvanceSkill_Random(skill, gain)
- endif
- if (gain > 0.0)
- Game.AdvanceSkill(skill, gain)
- endif
- endfunction
- ; Additional, from my XsUtils.psc
- bool function HasAnyKeyword(Form target, FormList keywordList) global
- {Checks whether a target has a keyword in a list of keywords.
- Note: The keywordList can contain other list of keywords.}
- if (keywordList == none || keywordList.GetSize() == 0 || target == none)
- return false
- endif
- int i = 0
- int l = keywordList.GetSize()
- while (i < l)
- Keyword current = keywordList.GetAt(i) as Keyword
- if (current)
- if (target.HasKeyword(current))
- return true
- endif
- elseif (keywordList.GetAt(i) as FormList)
- if (HasAnyKeyword(target, keywordList.GetAt(i) as FormList))
- return true
- endif
- endif
- i += 1
- endwhile
- return false
- endfunction
- ; and finally from MathEx.psc
- int function Min(int v1, int v2) global
- if (v1 > v2)
- return v2
- else
- return v1
- endif
- endfunction
- int function Max(int v1, int v2) global
- if (v1 > v2)
- return v1
- else
- return v2
- endif
- endfunction
- int function Chance(int limit) global
- if (limit > 1)
- return Utility.RandomInt(1, limit)
- else
- return 0
- endif
- endfunction
Advertisement
Add Comment
Please, Sign In to add comment