ReDragon2013 Posted January 31, 2019 Share Posted January 31, 2019 (edited) Too many scripts, its very hard to to follow you and find out what you want to reach with this. But now back to the base scripts: qlBerserk_ArmorScript Scriptname qlBerserk_ArmorScript extends ObjectReference ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ ; is attached to an armor, which controls the spell "BerserkerArmorBeastChange" ;"This script is to add the spell which trigger the transformation to the player. I need to give a bit more explanations about this. ; So, the mod i'm trying to make is a transformation feature which is casted by a spell. The transformation has chance to make the player "losing control". ; The spell to transform is added to the player when he/she is wearing a certain armor. ; This script (ie. SCRBerserkArmorCheckIfSet) checks if the player has worn the armor properly, then add the spell. ; In addition, this script also contains additional features such as initialising the loose control script (ie. Berserk_Loose_Control_Script) and ; giving chance to transform when getting hit." (qwertypol012) Quest PROPERTY myQuest auto ; the special quest "Berserk_Quest_Loose_Control" Actor player ; for OnHit() ;******************************************************************************* ;* Scheme which summarizes all of above explanations: ;* ;* Player wears the Armor => Transformation Spell added to Player ;* Player cast Transformation Spell => Player enter a Transformation state => Armor unequipped from Player, Armor2 equipped to Player ;* ;* Transformation state: ;* 1. Normal => casted after duration3 end ;* 2. Dangerous => casted when duration3 still run ;* ;* When Player is in Transformation state /and/ if Player is in combat => has chance to Lose Control ;* ;* If Lose Control is not triggered => Transformation state continues until its duration1 end ;* If Lose Control is triggered => Armor2 unequipped from Player, Armor equpped to Player, control taken from Player, ;* Player replaced by NPC Replacer until its duration2 end ;* ;* After duration1 end => Armor2 uneqipped from Player, Armor equipped to Player, Negative Effects casted to Player until its duration3 end ;* After duration2 end => NPC Replacer disabled, give control back to Player, Negative Effects casted to Player until its duration3 end ;* ;* If duration3 still run & Player cast Transformation Spell => Player enter Dangerous Transformation ;* ;* After duration3 end & Player cast Transformation Spell => Player enter Normal Transformation ;* ;* When Player is in Dangerous Transformation & Player getting hit => Severe Damage spell casted to Player ;******************************************************************************************************************************************** ; -- EVENTs -- 1 + "Waiting" + "Action" EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) ; received when this object enters, exits, or changes containers IF (akNewContainer == Game.GetPlayer() as ObjectReference) ELSE gotoState("") ; ### STATE ### RETURN ; - STOP - not into players inventory ENDIF ;--------------------- gotoState("Waiting") ; ### STATE ### IF (myQuest) && !myQuest.IsRunning() myQuest.Start() ENDIF ENDEVENT ;==================================== state Waiting ; for player only ;============ EVENT OnEquipped(Actor akActor) IF ( myQuest ) ELSE Debug.Trace("qlBerserk: OnEquipped(1) - quest property is missing!") RETURN ; - STOP - ENDIF ;--------------------- IF myQuest.IsRunning() ELSE Debug.Trace("qlBerserk: OnEquipped(2) - quest is not running!") RETURN ; - STOP - ENDIF ;--------------------- IF (myQuest as qlBerserk_QuestScript) ELSE Debug.Trace("qlBerserk: OnEquipped(3) - quest script 'qlBerserk_QuestScript' not found!") RETURN ; - STOP - ENDIF ;--------------------- player = akActor gotoState("Action") ; ### STATE ### (myQuest as qlBerserk_QuestScript).myF_Init(akActor, TRUE) ENDEVENT ;======= endState ;==================================== state Action ; for player only ;=========== EVENT OnUnequipped(Actor akActor) IF (myQuest as qlBerserk_QuestScript) ELSE RETURN ; - STOP - ENDIF ;--------------------- gotoState("Waiting") ; ### STATE ### player = None (myQuest as qlBerserk_QuestScript).myF_Init(akActor, False) ENDEVENT EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4) IF player.IsInCombat() ELSE RETURN ; - STOP - not in combat mode (or player is <None>) ENDIF ;--------------------- IF player.IsDead() RETURN ; - STOP - just dead ENDIF ;--------------------- IF (myQuest as qlBerserk_QuestScript) ELSE RETURN ; - STOP - ENDIF ;--------------------- (myQuest as qlBerserk_QuestScript).myF_TryToCast(player, akAggressor) ; BerserkerArmorBeastChange.Cast(player) ENDEVENT ;======= endState qlBerserk_EffectScript Scriptname qlBerserk_EffectScript extends ActiveMagicEffect ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ ; "This script is for warning spell which will be casted when the player is about to lose control." GlobalVariable PROPERTY Berserk_Comp_Dawnguard auto ; DLC1 has been loaded, GetValue() = 1.0 GlobalVariable PROPERTY Berserk_Config_Sounds auto MagicEffect PROPERTY Berserk_Effect_Warningspell auto ; effect that this script should be attached ; switch to something more suitable, such as heartbeat sound Sound PROPERTY UIHealthHeartbeatALPSD auto Sound PROPERTY UIHealthHeartbeatBLPSD auto ImageSpaceModifier PROPERTY DA10HauntingISMDFadeIn auto ImageSpaceModifier PROPERTY DA10HauntingISMDLoop auto ImageSpaceModifier PROPERTY WerewolfWarningImod auto ImageSpaceModifier DLC1AurielsEclipseImod01 Bool bReady ; -- EVENTs -- 2 + "Running" EVENT OnEffectStart(Actor akTarget, Actor akCaster) IF (akTarget == Game.GetPlayer()) ELSE self.Dispel() ; akTarget.DispelSpell(Berserk_Spell_Warningspell) RETURN ; - STOP - target is not the player ENDIF ;--------------------- bReady = TRUE gotoState("Running") ; ### STATE ### RegisterForSingleUpdate(5.0) ; wait 5 seconds, before triggering update event ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) myF_Remove() ENDEVENT ;========================================== State Running ;============ EVENT OnUpdate() IF ( !DLC1AurielsEclipseImod01 ) myF_SetImod01() ENDIF IF myF_IsEffectGone(DA10HauntingISMDFadeIn, 12.0) ; wait three times inside (maximum) RETURN ; - STOP - ENDIF ;--------------------- IF myF_IsEffectGone(DA10HauntingISMDLoop, 16.0) ; wait four times inside (maximum) RETURN ; - STOP - ENDIF ;--------------------- RegisterForSingleUpdate(3.0) ; trigger event again in 3 seconds ENDEVENT ;======= endState ; -- FUNCTIONs -- 4 ;----------------------- FUNCTION myF_SetImod01() ;----------------------- DLC1AurielsEclipseImod01 = WerewolfWarningImod ; *** Dawnguard DLC IF (Berserk_Comp_Dawnguard.GetValue() == 1) form fm = Game.GetFormFromFile(0x02003DCD, "Dawnguard.esm") IF (fm as ImageSpaceModifier) DLC1AurielsEclipseImod01 = fm as ImageSpaceModifier ELSE Debug.Trace("Error: Cannot find Dawnguard imod 'DLC1AurielsEclipseImod01'!") ENDIF ENDIF ; *** End of Dawnguard DLC ENDFUNCTION ;-------------------------------------------------------------- Bool FUNCTION myF_IsEffectGone(ImageSpaceModifier ISM, Float f) ;-------------------------------------------------------------- ISM.Remove() ; probably this is needed here!! ISM.ApplyCrossFade(f) ;;; magicEffect ME = self as MagicEffect ; <-- THIS IS NOT POSSIBLE !!! int i = (f / 4.0) as Int ; loop counter WHILE (i > 0) && Game.GetPlayer().HasMagicEffect(Berserk_Effect_Warningspell) myF_Play() Utility.Wait(4.0) i = i - 1 ENDWHILE IF Game.GetPlayer().HasMagicEffect(Berserk_Effect_Warningspell) Return False ; *** ENDIF ;--------- myF_Remove() Return TRUE ; *T* ENDFUNCTION ;-------------------- FUNCTION myF_Remove() ;-------------------- IF ( !bReady ) RETURN ; - STOP - imods already removed ENDIF ;--------------------- bReady = False gotoState("") ; ### STATE ### DA10HauntingISMDFadeIn.Remove() DA10HauntingISMDLoop.Remove() IF ( DLC1AurielsEclipseImod01 ) DLC1AurielsEclipseImod01.Remove() ENDIF ENDFUNCTION ;------------------ FUNCTION myF_Play() ;------------------ IF ( DLC1AurielsEclipseImod01 ) DLC1AurielsEclipseImod01.Remove() DLC1AurielsEclipseImod01.Apply() ENDIF objectReference playerRef = Game.GetPlayer() as ObjectReference Game.ShakeCamera(afStrength = 1, afDuration = 2) UIHealthHeartbeatBLPSD.Play(playerRef) IF (Berserk_Config_Sounds.GetValue() == 1) && (Utility.RandomInt(1, 4) == 1) ; RandomGrowlSound 25% chance int i = UIHealthHeartbeatALPSD.Play(playerRef) ; i = SoundID1 IF (i > 0) Sound.SetInstanceVolume(i, 0.5) ENDIF ENDIF ENDFUNCTION ;Scriptname Berserk_RefAlias_Playerreplacement_Script extends ReferenceAlias ;Scriptname qlBerserk_PlayerAliasScript extends ReferenceAliasqlBerserk_ReplacementAliasScript Scriptname qlBerserk_ReplacementAliasScript extends ReferenceAlias ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ ; This script is a ref alias for the player replacement when he/she is losing control and being replaced by the NPC replacer. qlBerserk_QuestScript ps ; -- EVENTs -- 5 + "Busy" EVENT OnInit() ps = self.GetOwningQuest() as qlBerserk_QuestScript ENDEVENT EVENT OnDetachedFromCell() myF_Action(0) ENDEVENT EVENT OnDying(Actor akKiller) myF_Action(1, akKiller) ENDEVENT ;Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4) ;;; gotoState("Busy") ; ### STATE ### Utility.Wait(0.1) myF_Action(2) ;;; gotoState("") ; ### STATE ### ENDEVENT EVENT OnObjectEquipped(Form akBaseObject, ObjectReference akReference) IF (akBaseObject as Ammo) myF_Ammo(akBaseObject, TRUE) ENDIF ENDEVENT EVENT OnObjectUnEquipped(Form akBaseObject, ObjectReference akReference) IF (akBaseObject as Ammo) myF_Ammo(akBaseObject, False) ENDIF ENDEVENT ;;==================================== ;state Busy ;;========= ;EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4) ;ENDEVENT ;;======= ;endState ; -- FUNCTIONs -- 2 ;---------------------------------------------- FUNCTION myF_Ammo(Form akBaseObject, Bool bAdd) ;---------------------------------------------- IF ( ps ) ELSE Debug.Trace(" myF_Ammo(" +bAdd+ ") - Error: quest = " + self.GetOwningQuest() + ", script = " +ps) RETURN ; - STOP - ENDIF ;===================== formList fmL = ps.WornAmmoList IF ( fmL ) ELSE Debug.Trace(" myF_Ammo(" +bAdd+ ") - Error: formlist for worn ammo is missing!") RETURN ; - STOP - ENDIF ;--------------------- IF ( bAdd ) fmL.AddForm(akBaseObject) ; gets filled as ammo is equipped by the player ELSE fmL.RemoveAddedForm(akBaseObject) ; gets removed as ammo is unequipped by the player ENDIF ENDFUNCTION ;------------------------------------------ FUNCTION myF_Action(Int i, Actor aRef=None) ;------------------------------------------ IF ( ps ) ELSE Debug.Trace(" myF_Action(" +i+ ") - Error: quest = " + self.GetOwningQuest() + ", script = " +ps) RETURN ; - STOP - ENDIF ;===================== IF (i == 0) ps.update_player_pos() RETURN ; - STOP - detached ENDIF ;--------------------- IF (i == 1) ps.player_replacement_was_killed(self.GetActorReference(), aRef) RETURN ; - STOP - dying ENDIF ;--------------------- IF (i == 2) ps.update_player_health() ;;; RETURN ; - STOP - hit ENDIF ENDFUNCTION ; Scriptname qlMEBerserkerTransformScript extends ActiveMagicEffect; Scriptname qlMEBerserkerTransformDangerScript extends ActiveMagicEffect; Scriptname qlMENegativeEffectsScript extends ActiveMagicEffectqlBerserk_TransformFinishScript Scriptname qlBerserk_TransformFinishScript extends ActiveMagicEffect {set active flag into globalVar for effects 'BerserkerArmorBeastT' and 'BerserkerArmorBeastTDanger'} ; https://forums.nexusmods.com/index.php?/topic/7285811-how-to-script-2-magic-effects-with-different-conditions-and-they-nullify-each-other/ ; Its a replacement for next scripts: ; qlMEBerserkerTransformScript ; 1.0 ; qlMEBerserkerTransformDangerScript ; 1.0 ; qlMENegativeEffectsScript ; 0.0 GlobalVariable PROPERTY MEValueDefiner auto ; its value defines what MEs are active Float PROPERTY EffectValue = 1.0 auto ; [default=1.0], can be different for each effect that script will be attached {set to 0.0 for former used script qlMENegativeEffectsScript} ; -- EVENTs -- EVENT OnEffectStart(Actor akTarget, Actor akCaster) Debug.Trace(" OnEffectStart() - akTarget = " +akTarget+ ", akCaster = " +akCaster+ " " +self) ; debugging only ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) MEValueDefiner.SetValue(EffectValue) ; set the value to activate damage attributes and debuffs ENDEVENT qlBerserk_TransformScript Scriptname qlBerserk_TransformScript extends ActiveMagicEffect {Berserker Armor transformation} ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ Spell PROPERTY BerserkerArmorBeastChange auto Spell PROPERTY BerserkerArmorRevertForm auto Idle PROPERTY IdleVampireLordTransformation auto Explosion PROPERTY FXVampChangeExplosion auto EffectShader PROPERTY Deintegrate auto ; desintegration Armor PROPERTY ArmorBerserkSHelmet auto ; head Armor PROPERTY ArmorBerserkWHelmet auto Armor PROPERTY ArmorBerserkerCuirass auto ; body Armor PROPERTY ArmorBerserkerWCuirass auto Armor PROPERTY ArmorBerserkerWCuirass2 auto Armor PROPERTY ArmorBerserkerGauntlets auto ; hands Armor PROPERTY ArmorBerserkerGauntlets2 auto Armor PROPERTY ArmorBerserkerBoots auto ; legs Armor PROPERTY ArmorBerserkerWBoots auto Armor PROPERTY ArmorBerserkerWBoots2 auto Actor PROPERTY PlayerEquipmentBrsk auto Bool bRemoveGhost ;Bool abIsGhost ; -- EVENTs -- 3 EVENT OnEffectStart(Actor akTarget, Actor akCaster) IF (akTarget == Game.GetPlayer()) ELSE self.Dispel() RETURN ; - STOP - /0 failsafe, player is not the target ENDIF ;--------------------- IF akTarget.IsEquipped(ArmorBerserkerCuirass) && akTarget.IsEquipped(ArmorBerserkerBoots) ELSE ; edited by ReDragon 2019/02/04 self.Dispel() RETURN ; - STOP - /1 failsafe, player does not have any berserker armor ENDIF ;--------------------- IF akTarget.IsGhost() bRemoveGhost = False ; x = 0 as Bool ELSE bRemoveGhost = TRUE ; x = 1 as Bool akTarget.GetActorBase().SetInvulnerable() akTarget.SetGhost() ENDIF ; if abIsGhost == false ; akTarget.SetGhost() ; endif RegisterForAnimationEvent(akTarget as ObjectReference, "SetRace") akTarget.PlayIdle(IdleVampireLordTransformation) akTarget.RestoreActorValue("health", 5000) Utility.Wait(10.0) TransformIfNecessary(akTarget) MakeForm(akTarget) ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) RevertForm(akTarget) ENDEVENT EVENT OnAnimationEvent(ObjectReference akSource, string asEventName) ;; Debug.Trace("VAMPIRE: Getting anim event -- " + akSource + " " + asEventName) IF (asEventName == "SetRace") TransformIfNecessary(akSource as Actor) ENDIF ENDEVENT ; -- FUNCTIONs -- 3 ;------------------------------------------ FUNCTION TransformIfNecessary(Actor player) ;------------------------------------------ IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- UnRegisterForAnimationEvent(player as ObjectReference, "SetRace") player.PlaceAtMe(FXVampChangeExplosion) ; place explosion now IF ( bRemoveGhost ) player.GetActorBase().SetInvulnerable(False) player.SetGhost(False) ENDIF ; if abIsGhost == true ; akTarget.SetGhost(false) ;it is possible that actor will lose ghost status even if his status is ghost by default ; endif ENDFUNCTION ;------------------------------ FUNCTION MakeForm(Actor player) ; outsourced code from OnEffectStart() ;------------------------------ IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- ; if (akTarget.GetWornForm(0x00000008) != none) ; Debug.Messagebox("Gauntlets are equipped") ; else ; Debug.MessageBox("Gauntlets are not equipped or something is wrong") ; endif form fm ; check if gauntlets are being worn or not, then add and equip them to the dummy if they are fm = player.GetWornForm(0x00000008) ; Gauntlets IF (fm as Armor) PlayerEquipmentBrsk.AddItem(fm, absilent=true) PlayerEquipmentBrsk.EquipItem(fm, true, true) ; Debug.MessageBox(Gauntlets) ENDIF ; check if a full head helmet is being worn or not, then add and equip it to the dummy if it is fm = player.GetWornForm(0x00000003) ; HeadHair IF (fm as Armor) PlayerEquipmentBrsk.AddItem(fm, absilent=true) PlayerEquipmentBrsk.EquipItem(fm, true, true) ; else ; Debug.MessageBox("You have nothing equipped on HeadHair") ENDIF ; check if a head only helmet is being worn or not, then add and equip it to the dummy if it is fm = player.GetWornForm(0x00000001) ; Head IF (fm as Armor) PlayerEquipmentBrsk.AddItem(fm, absilent=true) PlayerEquipmentBrsk.EquipItem(fm, true, true) ENDIF ; check if a hair only helmet is being worn or not, then add and equip it to the dummy if it is fm = player.GetWornForm(0x00000002) ; Hair IF (fm as Armor) PlayerEquipmentBrsk.AddItem(fm, absilent=true) PlayerEquipmentBrsk.EquipItem(fm, true, true) ENDIF ; if PlayerEquipmentBrsk.IsEquipped(Gauntlets) ; Debug.MessageBox(PlayerEquipmentBrsk + "has equipped" + Gauntlets) ; else ; Debug.MessageBox(PlayerEquipmentBrsk + "could not equip" + Gauntlets) ; endif ; This was to check if the NPC was equipping the stuff or not... ; PlayerEquipmentBrsk.Moveto(Game.GetPlayer()) player.EquipItem(ArmorBerserkerWBoots2, true, true) player.EquipItem(ArmorBerserkerWCuirass2, true, true) player.EquipItem(ArmorBerserkerGauntlets2, true, true) player.EquipItem(ArmorBerserkWHelmet, true, true) player.AddSpell(BerserkerArmorRevertForm) player.RemoveSpell(BerserkerArmorBeastChange) ENDFUNCTION ;-------------------------------- FUNCTION RevertForm(Actor player) ;-------------------------------- IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- Deintegrate.Play(player) ; *** effectShader Utility.Wait(2.0) player.UnEquipItem(ArmorBerserkerWBoots2, false, true) player.UnEquipItem(ArmorBerserkerWCuirass2, false, true) player.UnEquipItem(ArmorBerserkerGauntlets2, false, true) player.UnEquipItem(ArmorBerserkWHelmet, false, true) player.EquipItem(ArmorBerserkerCuirass, false, true) player.EquipItem(ArmorBerserkerBoots, false, true) form fm ;check if gauntlets are being worn or not fm = PlayerEquipmentBrsk.GetWornForm(0x00000008) ; Gaunlets IF (fm as Armor) player.EquipItem(fm, false, true) ENDIF ;check if a full head helmet is being worn or not fm = PlayerEquipmentBrsk.GetWornForm(0x00000003) ; HeadHair IF (fm as Armor) player.EquipItem(fm, false, true) ENDIF ;check if a head only helmet is being worn or not fm = PlayerEquipmentBrsk.GetWornForm(0x00000001) ; Head IF (fm as Armor) player.EquipItem(fm, false, true) ENDIF ;check if a hair only helmet is being worn or not fm = PlayerEquipmentBrsk.GetWornForm(0x00000002) ; Hair IF (fm as Armor) player.EquipItem(fm, false, true) ENDIF PlayerEquipmentBrsk.RemoveAllItems() ; Dangerous !!! ;Checking if it did remove them again ; PlayerEquipmentBrsk.MoveTo(Game.GetPlayer()) player.AddSpell(BerserkerArmorBeastChange) player.EquipSpell(BerserkerArmorBeastChange, 2) Deintegrate.Stop(player) ; *** player.RemoveSpell(BerserkerArmorRevertForm) player.RemoveItem(ArmorBerserkSHelmet, abSilent=true) player.RemoveItem(ArmorBerserkWHelmet, abSilent=true) player.RemoveItem(ArmorBerserkerWCuirass, abSilent=true) player.RemoveItem(ArmorBerserkerWCuirass2, abSilent=true) player.RemoveItem(ArmorBerserkerGauntlets, abSilent=true) player.RemoveItem(ArmorBerserkerGauntlets2, abSilent=true) player.RemoveItem(ArmorBerserkerWBoots, abSilent=true) player.RemoveItem(ArmorBerserkerWBoots2, abSilent=true) ENDFUNCTION Edited February 4, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted January 31, 2019 Share Posted January 31, 2019 And now the quest script, but you have it already changed. I tried my best to understand the script and functionality. qlBerserk_QuestScript Scriptname qlBerserk_QuestScript extends Quest Conditional ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ ; Based on MTE_Quest_Loose_Control_Script from Moonlight Tales Essentials Overhauled (MTEO) by ubuntufreakdragon, ; most credits go to him for providing a robust base script for lose control functionality ; Huge credits go to ReDragon2013 (Nexusmods member) for helping me A LOT in editing and opimizing the script! ; That guy is really amazing :D ; --------------------------------------------------------------------------------------------------------------- ; qwertypol012 wrote: "I'll post my WIP script here so that people will get a better idea on what i'm working on.. ; ..still currently trying to make Transform Condition System." ;vanilla GlobalVariable PROPERTY GameDaysPassed auto GlobalVariable PROPERTY TimeScale auto Perk PROPERTY AllowShoutingPerk auto ;*ql Idle PROPERTY BleedOutStart auto ;*ql Idle PROPERTY BleedOutStop auto ;*ql Static PROPERTY DwePlatMid01 auto ; to place a marker and moveto Location PROPERTY WhiterunJorrvaskrLocation auto ;++ moved from armor script (ReDragon) ImageSpaceModifier PROPERTY FadeToBlackImod auto ImageSpaceModifier PROPERTY FadeToBlackHoldImod auto ImageSpaceModifier PROPERTY FadeToBlackBackImod auto ImageSpaceModifier PROPERTY IllusionBlueMassiveImod auto ;others ReferenceAlias PROPERTY BerserkerAlias auto GlobalVariable PROPERTY MEValueDefiner auto ;*ql added, its value defines which MGEF is currently active MagicEffect PROPERTY BerserkArmorBeastT auto ;*ql MagicEffect PROPERTY BerserkArmorBeastTDanger auto ;*ql ;;; SCRBerserkArmorB Property BerserkArmorBeastT auto ; ?? ;;; SCRBerserkArmorB Property BerserkArmorBeastTDanger auto ; ?? Perk PROPERTY Berserk_NPC_FallDmg auto ;*ql Spell PROPERTY Berserk_Spell_Warningspell auto ; similar with MTE, but only take visual effects without sound effects, or switch sound effects into something more fitting Spell PROPERTY BerserkerArmorBeastChange auto ;++ moved from armor script (ReDragon) Spell PROPERTY BerserkerLostControlAfterEffects auto ;*ql spell to trigger debuff effects after lost control effect finished Armor PROPERTY ArmorBerserkWHelmet auto ;*ql head Armor PROPERTY ArmorBerserkerWCuirass2 auto ;*ql body Armor PROPERTY ArmorBerserkerGauntlets2 auto ;*ql arms Armor PROPERTY ArmorBerserkerWBoots2 auto ;*ql legs ;++moved all 3 globalVars from armor script (ReDragon) GlobalVariable PROPERTY HealthThreshold_AutoT auto GlobalVariable PROPERTY TargetLvlMult_AutoT auto GlobalVariable PROPERTY RandomChance_AutoT auto ;loose control timings GlobalVariable PROPERTY Berserk_Config_LooseControlBaseTimeMin auto GlobalVariable PROPERTY Berserk_Config_LooseControlBaseTimeMax auto GlobalVariable PROPERTY Berserk_Config_LooseControlCooldownTimeMin auto GlobalVariable PROPERTY Berserk_Config_LooseControlCooldownTimeMax auto ;loose control values GlobalVariable PROPERTY Berserk_Config_LooseControlBaseChance auto GlobalVariable PROPERTY Berserk_Config_LooseControlBaseWeight auto GlobalVariable PROPERTY Berserk_Config_LooseControlMoralWeight auto ; [default value = 1], make sure it's counted correctly in the MCM ;GlobalVariable PROPERTY Berserk_Config_LooseControlKillWeight auto ;*ql obsolete GlobalVariable PROPERTY Berserk_Config_LooseControlDeathtype auto GlobalVariable PROPERTY Berserk_Config_Moral_Warningtime auto ;*ql added ;GlobalVariable PROPERTY Berserk_Config_LooseControlMoral auto ;*ql replaced by next variable GlobalVariable PROPERTY Berserk_LooseControlMoral_Enable auto ; on/off toggle for lost control based on moral ;moral score ;GlobalVariable PROPERTY Berserk_Config_MoralScorebase auto ; OBSOLETE, not used anymore ;GlobalVariable PROPERTY Berserk_Config_Killscoremodifier auto ;*ql removed GlobalVariable PROPERTY Berserk_Config_MoralScoremax auto GlobalVariable PROPERTY Berserk_Config_MoralScoretimemultmax auto ;moral status GlobalVariable PROPERTY Berserk_Moral_Transformed auto ;global storage GlobalVariable PROPERTY Berserk_Moral_Config_GSWerewolf auto ;default 10 GlobalVariable PROPERTY Berserk_Moral_Config_GSNeckBit auto ;default 8 GlobalVariable PROPERTY Berserk_Moral_Config_GSBribe auto ;default 1 GlobalVariable PROPERTY Berserk_Moral_Config_GSIntimidation auto ;default 4 GlobalVariable PROPERTY Berserk_Moral_Config_GSTGQuest auto ;default 5 GlobalVariable PROPERTY Berserk_Moral_Config_GSDBQuest auto ;default 10 GlobalVariable PROPERTY Berserk_Moral_Config_GSDaedricQuest auto ;default 100 GlobalVariable PROPERTY Berserk_Moral_Config_GSPeopleKill auto ;default 2 GlobalVariable PROPERTY Berserk_Moral_Config_GSAnimalKill auto ;default 2 GlobalVariable PROPERTY Berserk_Moral_Config_GSUndeadKill auto ;default -2 GlobalVariable PROPERTY Berserk_Moral_Config_GSDaedraKill auto ;default -4 GlobalVariable PROPERTY Berserk_Moral_Config_GSBunnyKill auto ;default 1 GlobalVariable PROPERTY Berserk_Moral_Config_GSDragonSoul auto ;default -2 GlobalVariable PROPERTY Berserk_Moral_Config_GSShoutLearn auto ;default -4 GlobalVariable PROPERTY Berserk_Moral_Config_GSShoutMaster auto ;default -10 GlobalVariable PROPERTY Berserk_Moral_Config_GSTotalBounty auto ;default 80 GlobalVariable PROPERTY Berserk_Moral_Config_GSItemPickpocket auto ;default 1 GlobalVariable PROPERTY Berserk_Moral_Config_GSTimeJail auto ;default 4 GlobalVariable PROPERTY Berserk_Moral_Config_GSJailEscape auto ;default 10 GlobalVariable PROPERTY Berserk_Moral_Config_GSItemSteal auto ;default 1 GlobalVariable PROPERTY Berserk_Moral_Config_GSAssault auto ;default 60 GlobalVariable PROPERTY Berserk_Moral_Config_GSMurder auto ;default 80 GlobalVariable PROPERTY Berserk_Moral_Config_GSHorseSteal auto ;default 4 GlobalVariable PROPERTY Berserk_Moral_Config_GSTrespass auto ;default 2 ;bounty stage GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage1 auto ;default 1000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage2 auto ;default 2000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage3 auto ;default 3000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage4 auto ;default 4000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage5 auto ;default 5000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage6 auto ;default 6000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage7 auto ;default 7000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage8 auto ;default 8000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage9 auto ;default 9000 GlobalVariable PROPERTY Berserk_Moral_Config_BountyStage10 auto ;default 10000 ;ActorBase[] PROPERTY Berserk_Player_Loose_Controls_Array auto ; array to store actorbases as follow (not using array for now) ;; male ActorBase PROPERTY Berserk_Player_Loose_Controls_Unarmed_M auto ; 0 ActorBase PROPERTY Berserk_Player_Loose_Controls_Melee_M auto ; 1 ActorBase PROPERTY Berserk_Player_Loose_Controls_Ranger_M auto ; 2 ActorBase PROPERTY Berserk_Player_Loose_Controls_Mage_M auto ; 3 ActorBase PROPERTY Berserk_Player_Loose_Controls_Spellsword_M auto ; 4 ;; female ActorBase PROPERTY Berserk_Player_Loose_Controls_Unarmed_F auto ; 5 ActorBase PROPERTY Berserk_Player_Loose_Controls_Melee_F auto ; 6 ActorBase PROPERTY Berserk_Player_Loose_Controls_Ranger_F auto ; 7 ActorBase PROPERTY Berserk_Player_Loose_Controls_Mage_F auto ; 8 ActorBase PROPERTY Berserk_Player_Loose_Controls_Spellsword_F auto ; 9 ;----------------------------------------------------------------- Bool PROPERTY player_has_control = TRUE auto Conditional Bool PROPERTY player_is_loosing_control = False auto Conditional ;----------------------------------------------------------------- FormList PROPERTY Berserk_List_secure_caves auto Formlist PROPERTY WornAmmoList auto Hidden ; starts out empty ;Float killscorebuffresettime = 0.0 ;*ql removed Float Invisibility_originalvalue = 0.0 ;Int killscore = 0 ;*ql removed ;Int killscorebuff = 0 ;*ql removed ;;; Int MoralMax ;*ql added, as a max value for MoralScore, default is 500 Int MoralScore ;*ql added, contains accumulated points from all used game statistics Bool LC_system_active = False Bool singlerun_updating_health = False ; just to block updatespam, required If placed in an OnHit Bool singlerun_updating_pos = False ; just to block updatespam. Actor BerserkerRef ObjectReference PlatRef ; playerAlias script ; ps.update_player_pos() ; ps.player_replacement_was_killed(self.GetActorReference(), aRef) ; ps.update_player_health() ;---------------------------------------------------------------- FUNCTION myF_TryToCast(Actor player, ObjectReference akAggressor) ; external called by "qlBerserk_ArmorScript" only ;---------------------------------------------------------------- IF (akAggressor as Actor) ELSE RETURN ; - STOP - /0 no actor, no cast ENDIF ;--------------------- IF (player.GetActorValuePercentage("Health") > HealthThreshold_AutoT.GetValue()) RETURN ; - STOP - /1 player health is good enough ENDIF ;--------------------- float f = Utility.RandomFloat(1.0, 100.0) IF (f > RandomChance_AutoT.GetValue()) RETURN ; - STOP - /2 no luck this time ENDIF ;--------------------- IF (player.GetCurrentLocation() == WhiterunJorrvaskrLocation) RETURN ; - STOP - /3 special location detected ENDIF ;--------------------- actor aRef = player.GetCombatTarget() Debug.Trace(" myF_TryToCast() - akAggressor = " +akAggressor as Actor+ ", combatTarget = " +aRef) ; debugging only IF ((akAggressor as Actor).GetLevel() < (player.GetLevel() * TargetLvlMult_AutoT.GetValue() as Int)) RETURN ; - STOP - /4 player level is too high ENDIF ;--------------------- BerserkerArmorBeastChange.Cast(player) ENDFUNCTION ;------------------------------------------ FUNCTION myF_Init(Actor player, Bool bInit) ; external called by "qlBerserk_ArmorScript" only ;------------------------------------------ IF ( !bInit ) player.RemoveSpell(BerserkerArmorBeastChange) RETURN ; - STOP - armor unequipped ENDIF ;--------------------- player.AddSpell(BerserkerArmorBeastChange) player.EquipSpell(BerserkerArmorBeastChange, 2) Initialise() ENDFUNCTION ;-------------------- FUNCTION Initialise() ; the LC system until, Force_control_to_player() is called ;-------------------- ; setting up some time until, the loose control check runs first ;If (Berserk_LooseControlMoral_Enable.GetValueInt() == 1) ; currently checked in mainloop ; return ;EndIf ;;; KillScore = 0 ;*ql ; MoralScore=0 ;no more set as an assignment variable, no need to be initialized, ;because it seems that game stats can be tracked & accumulated without using assignment LC_system_active = TRUE RegisterForSingleUpdateGameTime( Utility.RandomFloat(0.25, 0.5) ) ; run first check after a quarter to a half hour ENDFUNCTION ; -- EVENTs -- 2 EVENT OnUpdate() IF ( player_has_control ) RETURN ; - STOP - player has its control back ENDIF ;--------------------- player lost control update_player_pos() ; opdate Player position to loaded cells Utility.Wait(0.1) ; to let the new cell load if any update_player_health() ; run after update pos, as unloaded NPCs have well unknown health values. RegisterForSingleUpdate(2.9) ENDEVENT EVENT OnUpdateGameTime() ; only running while lose control transformations controlled by moral counting running the main rolls IF ( LC_system_active ) ELSE RETURN ; - STOP - /0 system not active ENDIF ;--------------------- IF (Berserk_LooseControlMoral_Enable.GetValue() as Bool) && myF_IsBerserkerArmor(False) && (player_has_control) && (!player_is_loosing_control) Moral_counting() ; applies both in & out of combat IF myF_IsBerserkerArmor(TRUE) Loose_Control_Roll() ; loose control roll only applies in combat ENDIF RETURN ; - STOP - /1 ENDIF ;--------------------- IF (player_is_loosing_control) && myF_IsBerserkerArmor(TRUE) ;make sure to only call this once transformation is complete myF_Dispel() Trigger_control_loss() RETURN ; - STOP - /2 looses control ENDIF ;--------------------- IF ( player_has_control ) RETURN ; - STOP - /3 player has its control back ENDIF ;--------------------- update_player_pos() ;Gaincontrol() ;*ql replaced this by next function ;;; TransformBack() ; removed by ReDragon Force_control_to_player() Berserk_Moral_Transformed.SetValue(0) IF ( LC_system_active ) myF_RegisterForWaitTime(Berserk_Config_LooseControlCooldownTimeMin, Berserk_Config_LooseControlCooldownTimeMax, False) ENDIF ENDEVENT ;----------------------------------------------- Bool FUNCTION myF_IsBerserkerArmor(Bool bCombat) ; internal helper, see OnUpdateGameTime() ;----------------------------------------------- actor player = Game.GetPlayer() IF (bCombat) && !player.IsInCombat() Return False ENDIF ;--------- IF player.HasSpell(BerserkerArmorBeastChange) Return TRUE ENDIF ;--------- IF player.HasMagicEffect(BerserkArmorBeastT) Return TRUE ENDIF ;--------- IF player.HasMagicEffect(BerserkArmorBeastTDanger) Return TRUE ENDIF ;--------- Return False ; either 1 of 3 requirements not fulfilled ENDFUNCTION ;;------------------------------------ ;Int FUNCTION myF_TestBerserkerArmor() ; other approach to give back what is happen with Berserker armor ;;------------------------------------ ; actor player = Game.GetPlayer() ; int i ; ;IF player.HasSpell(BerserkerArmorBeastChange) ; i = 1 ;ENDIF ; ;IF player.HasMagicEffect(BerserkArmorBeastT) ; i = i + 10 ;ENDIF ; ;IF player.HasMagicEffect(BerserkArmorBeastTDanger) ; i = i + 20 ;ENDIF ; ; RETURN i ; 0,1, 10,11, 20,21, 30,31 ;ENDFUNCTION ;-------------------- FUNCTION myF_Dispel() ; internal helper ;-------------------- player_is_loosing_control = False Game.GetPlayer().DispelSpell(Berserk_Spell_Warningspell) ENDFUNCTION ;--------------------------------- FUNCTION Force_control_to_player() ;--------------------------------- UnRegisterForUpdateGameTime() LC_system_active = False myF_Dispel() Gaincontrol() ; Remove any used Imagespace Modifier ;;; KillScore = 0 ;*ql ; MoralScore=0 ;no more set as an assignment variable, no need to be reset, because it seems that game stats can be tracked & accumulated without using assignment ENDFUNCTION ;;----------------------- ;FUNCTION TransformBack() ;*ql added this function ;;----------------------- ; Force_control_to_player() ; ;UnregisterForUpdateGameTime() ; already included in Force_control_to_player() ; Berserk_Moral_Transformed.SetValue(0) ;ENDFUNCTION ; -- FUNCTIONs -- (3) + (3) + 3 + 2 + 9 + 6 ;------------------------------------------------------ Float FUNCTION RealTimeSecondsToGameTimeHours(Float fs) ; convert "Real Time Seconds" to "Game Time Hours" ;------------------------------------------------------ float f = (TimeScale.GetValue() * fs) / 3600.0 ; f = scaledSeconds, fs = realTime RETURN f ENDFUNCTION ;----------------------------------------------------- Float FUNCTION RealTimeSecondsToGameTimeDays(Float fs) ; convert "Real Time Seconds" To "Game Time Days" ;----------------------------------------------------- float f = RealTimeSecondsToGameTimeHours(fs) ; f = scaledSeconds, fs = realTime RETURN (f / 24.0) ENDFUNCTION ;------------------------------------------------------------------------------------- FUNCTION myF_RegisterForWaitTime(GlobalVariable gMin, GlobalVariable gMax, Bool bMoral) ; internal helper ;------------------------------------------------------------------------------------- float fMin = gMin.GetValue() float fMax = gMax.GetValue() float f IF (fMin > fMax) ; failsafe for random next f = fMax fMax = fMin fMin = f ENDIF f = Utility.RandomFloat(RealTimeSecondsToGameTimeHours(fMin), RealTimeSecondsToGameTimeHours(fMax)) ;;; IF ( bKill ) IF ( bMoral ) ;;; int iMax = Berserk_Config_Killscoretimemultmax.GetValueInt() * 100 ; iMax = Maxmult ;;; int i = ((iMax - 100) * KillScore / Berserk_Config_Killscoremax.GetValueInt()) + 100 ; i = KillMult int iMax = Berserk_Config_MoralScoretimemultmax.GetValueInt() * 100 ; iMax = Maxmult int i = ((iMax - 100) * MoralScore / Berserk_Config_MoralScoremax.GetValueInt()) + 100 ; i = MoralMult IF (i > iMax) i = iMax ENDIF f = (i as Float * f) / 100 ; lowest is 20 ingame minutes highest is 160 ingame minutes, this sounds fair ENDIF RegisterForSingleUpdateGameTime(f) ENDFUNCTION ;##################### Skyrim runs each Script only once at a time, internal calls and edits will not break this ;### ThreadControl ############################################################################################# ;##################### read/write to script's own vars is atomic Int mutex_control_status_turn = 0 Int mutex_control_status_number = 0 ;-------------------- FUNCTION mutex_Wait() ; mutex_control_status_wait() ;-------------------- int i = mutex_control_status_number ; i = local_number mutex_control_status_number+= 1 ; increased again and again !!! WHILE (i != mutex_control_status_turn) Utility.Wait(0.1) ENDWHILE ENDFUNCTION ;------------------- FUNCTION mutex_Add() ; mutex_control_status_signal() ;------------------- mutex_control_status_turn+= 1 ; increased again and again !!! ENDFUNCTION ;############## ;### Player ############################################################################################# ;############## 9 ;--------------------- FUNCTION Gaincontrol() ; Player Gain Control ;--------------------- ;; debug.messagebox("controlgain is started") ;; debug.messagebox(player_has_control) mutex_Wait() ; THREADsafe ON IF ( player_has_control ) mutex_Add() RETURN ; - STOP - we can only gain controls once ENDIF ;--------------------- UnRegisterForUpdate() ; == actor player = Game.GetPlayer() player.StopTranslation() ; just to be sure player.MoveTo(BerserkerRef) player.SetAngle(0.0, 0.0, 0.0) ;Debug.SetGodMode(False) Game.SetCameraTarget(player) player.SetActorValue("Invisibility", Invisibility_originalvalue) player.SetAlpha(1.0) ; == PlatRef.DisableNoWait() PlatRef.Delete() PlatRef = None ; == ;;; int i = Berserk_Config_LooseControlDeathtype.GetValueInt() ; i = deathtype ;;; IF (i == 0) player.SetGhost(False) ;;; ENDIF myF_AdjustHealth(player, BerserkerRef.GetActorValue("health")) ; == Game.SetPlayerAiDriven(False) player_has_control = TRUE ; == BerserkerAlias.Clear() BerserkerRef.DisableNoWait() BerserkerRef.Delete() BerserkerRef = None ; (MTE_Quest_Follower_System as MTE_Quest_Follower_System_Script).Update_LC_playerreplacement(None) ;leftover code from MTEO for follower system, not needed here ;; debug.messagebox("controlgain is done") mutex_Add() ; THREADsafe OFF ; == IllusionBlueMassiveImod.Apply() ; *** ql added player.PlayIdle(BleedOutStart) Utility.Wait(1.5) player.PlayIdle(BleedOutStop) MEValueDefiner.SetValue(1) ;set the value to activate damage attributes and debuffs BerserkerLostControlAfterEffects.Cast(player) Initialise() ; *** ENDFUNCTION ;---------------------------------------------------------------------- FUNCTION player_replacement_was_killed(Actor targetRef, Actor akKiller) ; external called by Alias script, without Control ;---------------------------------------------------------------------- ;; debug.messagebox(player_has_control) ;; debug.messagebox(BerserkerRef) ;; debug.messagebox(targetRef) ; the_killed_replacement IF ( !BerserkerRef ) RETURN ; - STOP - just ignore it, None should not die ENDIF ;--------------------- IF (targetRef == BerserkerRef) ELSE RETURN ; - STOP - targetRef != BerserkerRef; just ignore it, its the wrong replacement, maybe an older one not deleted yet, ENDIF ; or something spawned by an external script, at least this should never become True ;--------------------- mutex_Wait() ; THREADsafe ON IF ( player_has_control ) mutex_Add() RETURN ; - STOP - just ignore it, the player has the controls ENDIF ;--------------------- UnRegisterForUpdate() ; == actor player = Game.GetPlayer() player.StopTranslation() ; just to be sure player.MoveTo(BerserkerRef) player.SetAngle(0.0, 0.0, 0.0) ;Debug.SetGodMode(False) Game.SetCameraTarget(player) player.SetActorValue("Invisibility", Invisibility_originalvalue) player.SetAlpha(1.0) ; == PlatRef.DisableNoWait() PlatRef.Delete() PlatRef = None ; == int i = Berserk_Config_LooseControlDeathtype.GetValueInt() ; i = deathtype IF (i == 0) player.SetGhost(False) player.Kill(akKiller) ENDIF ; == Game.SetPlayerAiDriven(False) player_has_control = TRUE ; == BerserkerAlias.Clear() BerserkerRef.DisableNoWait() BerserkerRef.Delete() BerserkerRef = None ; (MTE_Quest_Follower_System as MTE_Quest_Follower_System_Script).Update_LC_playerreplacement(None) ;leftover code from MTEO for follower system, not needed here mutex_Add() ; THREADsafe OFF ; == IF (i == 1) wake_up_in_cave(player) ENDIF ENDFUNCTION ;------------------------------------- FUNCTION wake_up_in_cave(Actor player) ;------------------------------------- ;Debug.SendAnimationEvent(player, "BreviMoonlightTalesRestS1") ;Todo some eye candy anim FadeToBlackImod.Apply() ; >> 1 Utility.Wait(2.1) FadeToBlackImod.PopTo(FadeToBlackHoldImod) ; -> 2 myF_MoveToSecurePlace(player) myF_AdjustHealth(player, 50.0) ; heal you up to 50 health Utility.Wait(0.5) player.SetGhost(False) player = None FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; -> 3 Utility.Wait(3.0) FadeToBlackBackImod.Remove() ; << 3 FadeToBlackHoldImod.Remove() ; << 2 FadeToBlackImod.Remove() ; << 1 ; *** ql added MEValueDefiner.SetValue(1) ;set the value to activate damage attributes and debuffs BerserkerLostControlAfterEffects.Cast(player) ; *** ENDFUNCTION ;------------------------------------------- FUNCTION myF_MoveToSecurePlace(Actor player) ; internal helper ;------------------------------------------- int i = Utility.RandomInt(0, Berserk_List_secure_caves.GetSize() - 1) formlist myList = Berserk_List_secure_caves.GetAt(i) as Formlist ; get a random formlist entry from a formlist objectReference oRef ; oRef = TargetMarker IF ( myList ) oRef = myList.GetAt(0) as ObjectReference ; get the Berserkermarker which is the first object in the cavedata ;; ELSE ;; Debug.Trace(" Formlist not found! " +self) ENDIF IF ( oRef ) player.MoveTo(oRef) ; move player to target marker player.SetAngle(0.0, 0.0, 0.0) ; adjust angles ;; ELSE ;; Debug.Trace(" BersekerMarker is invalid! " +self) ENDIF ENDFUNCTION ;----------------------------------------------- FUNCTION myF_AdjustHealth(Actor player, Float f) ; internal helper ;----------------------------------------------- f = player.GetActorValue("health") - f IF (f > 0) player.DamageActorValue("health", f) RETURN ; - STOP - ENDIF ;--------------------- IF (f == 0) RETURN ; - STOP - just in case ENDIF ;--------------------- player.RestoreActorValue("health", -f) ENDFUNCTION ;------------------------------ FUNCTION update_player_health() ; So the player can monitor his body's health. ;------------------------------ IF ( singlerun_updating_health ) RETURN ; - STOP - ENDIF ;--------------------- singlerun_updating_health = TRUE mutex_Wait() IF ( player_has_control ) mutex_Add() RETURN ; - STOP - just ignore it, the player has the controls ENDIF ;--------------------- update health while Control is Lost myF_AdjustHealth(Game.GetPlayer(), BerserkerRef.GetActorValue("health")) mutex_Add() singlerun_updating_health = False ENDFUNCTION ;--------------------------- FUNCTION update_player_pos() ; So the player can monitor his body even If it's running away. :) ;--------------------------- IF ( singlerun_updating_pos ) RETURN ; - STOP - ENDIF ;--------------------- singlerun_updating_pos = TRUE mutex_Wait() IF ( player_has_control ) mutex_Add() RETURN ; - STOP - just ignore it, the player has the controls ENDIF ;--------------------- update Position while Control is Lost myF_Update() mutex_Add() singlerun_updating_pos = False ENDFUNCTION ;-------------------- FUNCTION myF_Update() ; internal helper, >>> The code of this function should be a bit more optimized <<< ;-------------------- ; Cell.size == 4096 < 10000/sqrt(2) so cell would differ, too. ; Rasikko asked what does it mean? No idea.. actor player = Game.GetPlayer() worldSpace ws = player.GetWorldSpace() bool bOK cell c IF ( BerserkerRef ) c = BerserkerRef.GetParentCell() bOK = (!c) || (c != player.GetParentCell()) ELSE bOK = False ENDIF IF (ws) && (ws == BerserkerRef.GetWorldSpace()) && (player.GetDistance(BerserkerRef as ObjectReference) < 10000) IF (bOK) || (player.GetDistance(BerserkerRef) > 500) myF_Translate(BerserkerRef, 2000.0, False) ENDIF RETURN ; - STOP - we are in the same worldspace wuhu, using translate to. ENDIF ;--------------------- IF (ws) || (bOK) ; Berserker left actual cell, moving Player. ; either we are inside an interior cell or in diffent worldspaces, using moveto player.StopTranslation() ; just to be sure IF ( PlatRef ) PlatRef.DisableNoWait() PlatRef.Delete() PlatRef = None ENDIF player.MoveTo(BerserkerRef) PlatRef = player.PlaceAtMe(DwePlatMid01, 1, TRUE, TRUE) ; place a new plate myF_Translate(player, 1000.0, TRUE) PlatRef.EnableNoWait() ENDIF ENDFUNCTION ;--------------------------------------------------------- FUNCTION myF_Translate(Actor aRef, Float fSpeed, Bool bOK) ; internal helper to shrink parent function stack size ;--------------------------------------------------------- ; speed shouldn't be too big or Skyrim could crash because of loading to much Cells in short time, ; 2000 was ok for Flyable Dragon Races 3 so I will use it. ; Berserker has left loaded space or got too far away from the Player, moving Player. float fx = aRef.GetPositionX() float fy = aRef.GetPositionY() float fz = aRef.GetPositionZ() + 3300.0 float aX = aRef.GetAngleX() float aY = aRef.GetAngleY() float aZ = aRef.GetAngleZ() IF ( bOK ) ; player up into the sky PlatRef.SetPosition(fx, fy, fz - 300.0) PlatRef.SetAngle(0.0, 0.0, 0.0) aRef.TranslateTo(fx,fy,fz, aX,aY,aZ, fSpeed) ; 1000 ELSE ; berserker up into the sky aRef.TranslateTo(fx,fy,fz, aX,aY,aZ, fSpeed) ; 2000 PlatRef.SetPosition(fx, fy, fz - 300.0) PlatRef.SetAngle(0.0, 0.0, 0.0) ENDIF ENDFUNCTION ;;----------------------------------------- ;FUNCTION player_has_killed(Bool bHumanoid) ; OBSOLETE, has killed on something ;;----------------------------------------- ; float f = GameDaysPassed.GetValue() ; ; IF (killscorebuffResetTime < f) ; killscorebuff = 0 ; ENDIF ; ; killscorebuffResetTime = f + RTS_ToGameTimeDays(45.0) ; ; IF ( bHumanoid ) ; bHumanoid = was_humanoid ; KillScore += Berserk_Config_Killscorebase.GetValueInt() + killscorebuff ; killscorebuff+= Berserk_Config_Killscoremodifier.GetValueInt() ; ENDIF ;ENDFUNCTION ;############### ;### Control ############################################################################################# ;############### 6 ;---------------------------- ;FUNCTION Loose_Control_Roll() FUNCTION Moral_counting() ;------------------------ int[] a = new Int[24] ; query stats storage int i ; https://www.creationkit.com/index.php?title=QueryStat_-_Game i = Game.QueryStat("Werewolf Transformations") a[0] = i * Berserk_Moral_Config_GSWerewolf.GetValueInt() ; int WerewolfTransforms i = Game.QueryStat("Necks Bitten") a[1] = i * Berserk_Moral_Config_GSNeckBit.GetValueInt() ; int NecksBitten i = Game.QueryStat("Bribes") a[2] = i * Berserk_Moral_Config_GSBribe.GetValueInt() ; int Bribes i = Game.QueryStat("Intimidations") a[3] = i * Berserk_Moral_Config_GSIntimidation.GetValueInt() ; int Intimidations i = Game.QueryStat("Thieves' Guild Quests Completed") a[4] = i * Berserk_Moral_Config_GSTGQuest.GetValueInt() ; int TGQuests i = Game.QueryStat("The Dark Brotherhood Quests Completed") a[5] = i * Berserk_Moral_Config_GSDBQuest.GetValueInt() ; int DBQuests i = Game.QueryStat("Daedric Quests Completed") a[6] = i * Berserk_Moral_Config_GSDaedricQuest.GetValueInt() ; int DaedricQuests i = Game.QueryStat("Dragon Souls Collected") a[7] = -i * Berserk_Moral_Config_GSDragonSoul.GetValueInt() ; int DragonSouls, has minus value i = Game.QueryStat("Shouts Learned") a[8] = -i * Berserk_Moral_Config_GSShoutLearn.GetValueInt() ; int ShoutsLearned, has minus value i = Game.QueryStat("Shouts Mastered") a[9] = -i * Berserk_Moral_Config_GSShoutMaster.GetValueInt() ; int ShoutsMastered, has minus value i = Game.QueryStat("People Killed") a[10] = i * Berserk_Moral_Config_GSPeopleKill.GetValueInt() ; int PeopleKilled i = Game.QueryStat("Animals Killed") a[11] = i * Berserk_Moral_Config_GSAnimalKill.GetValueInt() ; int AnimalsKilled i = Game.QueryStat("Undead Killed") a[12] = -i * Berserk_Moral_Config_GSUndeadKill.GetValueInt() ; int UndeadKilled, has minus value i = Game.QueryStat("Daedra Killed") a[13] = -i * Berserk_Moral_Config_GSDaedraKill.GetValueInt() ; int DaedraKilled, has minus value i = Game.QueryStat("Bunnies Slaughtered") a[14] = i * Berserk_Moral_Config_GSBunnyKill.GetValueInt() ; int BunniesKilled i = Game.QueryStat("Items Pickpocketed") a[15] = i * Berserk_Moral_Config_GSItemPickpocket.GetValueInt() ; int ItemsPickpocketed i = Game.QueryStat("Times Jailed") a[16] = i * Berserk_Moral_Config_GSTimeJail.GetValueInt() ; int TimesJailed i = Game.QueryStat("Jail Escapes") a[17] = i * Berserk_Moral_Config_GSJailEscape.GetValueInt() ; int JailEscapes i = Game.QueryStat("Items Stolen") a[18] = i * Berserk_Moral_Config_GSItemSteal.GetValueInt() ; int ItemsStolen i = Game.QueryStat("Assaults") a[19] = i * Berserk_Moral_Config_GSAssault.GetValueInt() ; int Assaults i = Game.QueryStat("Murders") a[20] = i * Berserk_Moral_Config_GSMurder.GetValueInt() ; int Murders i = Game.QueryStat("Horses Stolen") a[21] = i * Berserk_Moral_Config_GSHorseSteal.GetValueInt() ; int HorsesStolen i = Game.QueryStat("Trespasses") a[22] = i * Berserk_Moral_Config_GSTrespass.GetValueInt() ; int Tresspasses ;-------- i = Game.QueryStat("Total Lifetime Bounty") float f = Berserk_Moral_Config_GSTotalBounty.GetValue() ; f = BountyMoralMultiplier IF (i < Berserk_Moral_Config_BountyStage1.GetValueInt()) f = 1.0 ; no multiplier ELSEIF (i < Berserk_Moral_Config_BountyStage2.GetValueInt()) ; keep it ELSEIF (i < Berserk_Moral_Config_BountyStage3.GetValueInt()) f *= 2 ELSEIF (i < Berserk_Moral_Config_BountyStage4.GetValueInt()) f *= 3 ELSEIF (i < Berserk_Moral_Config_BountyStage5.GetValueInt()) f *= 4 ELSEIF (i < Berserk_Moral_Config_BountyStage6.GetValueInt()) f *= 5 ELSEIF (i < Berserk_Moral_Config_BountyStage7.GetValueInt()) f *= 6 ELSEIF (i < Berserk_Moral_Config_BountyStage8.GetValueInt()) f *= 7 ELSEIF (i < Berserk_Moral_Config_BountyStage9.GetValueInt()) f *= 8 ELSEIF (i < Berserk_Moral_Config_BountyStage10.GetValueInt()) f *= 9 ;;; ELSEIF (i >= Berserk_Moral_Config_BountyStage10.GetValueInt()) ELSE f *= 10 ENDIF a[23] = i * (f as Int) ; ### Total Bounty ### ;-------- ;;; float MoralityIncrements ; contains accumulated points from all used game statistics ;*; float MoralScore ;*ql, contains accumulated points from all used game statistics i = 0 WHILE (i < a.Length) MoralScore += a[i] i = i + 1 ENDWHILE ;;; Loose_Control_Roll() ; *ql, removed code here, see next function ; *** ql i = Berserk_Config_MoralScoremax.GetValueInt() ; max default is 500 IF (MoralScore >= i) MoralScore = i ; set to max value of MoralScore ENDIF ; *** ENDFUNCTION ;---------------------------- FUNCTION Loose_Control_Roll() ;---------------------------- IF myF_NoControl() player_is_loosing_control = TRUE IF ( LC_system_active ) float f = Utility.RandomFloat(RealTimeSecondsToGameTimeHours(30), RealTimeSecondsToGameTimeHours(60)) RegisterForSingleUpdateGameTime(f) ENDIF IF (Berserk_Config_Moral_Warningtime.GetValue() == 1) Berserk_Spell_Warningspell.Cast(Game.GetPlayer()) ; apply a short visual warning ENDIF RETURN ; - STOP - ENDIF ;--------------------- IF ( LC_system_active ) myF_RegisterForWaitTime(Berserk_Config_LooseControlCooldownTimeMin, Berserk_Config_LooseControlCooldownTimeMax, False) ENDIF ; *** ql ;;; KillScore = KillScore * 9 / 10 ; see also Trigger_control_loss() ; MoralScore = MoralScore * 9 / 10 ; *** ENDFUNCTION ;-------------------------------------------- ;Bool FUNCTION myF_NoControl(Float MoralScore) ; internal helper Bool FUNCTION myF_NoControl() ;---------------------------- float r = Utility.RandomInt(1, 100) as Float ;;; Float chance=(BaseWeight*Berserk_loose_control_base_chance + MoralWeight*Berserk_moral_chance)/(BaseWeight+MoralWeight) ; ------------------------------------------------------------------------------------------------------------------------- int iB = Berserk_Config_LooseControlBaseWeight.GetValueInt() ; iB = BaseWeight int iM = Berserk_Config_LooseControlMoralWeight.GetValueInt() ; iM = MoralWeight IF (iB == 0) && (iM == 0) iB = 1 ; ** ENDIF float f = (iB as Float) * Berserk_Config_LooseControlBaseChance.GetValue() ;-------- float fMC = Berserk_Config_MoralScoremax.GetValue() ; as a max value for MoralScore, default is 500 fMC = MoralScore / fMC * 100.0 ; Berserk_moral_chance IF (fMC >= 100) fMC = 100 ENDIF f = f + (iM as Float) * fMC ; fMC = MoralChance ;-------- f = f / (iB + iM) as Float ; ** we don't want to divide by 0 here ;-------- RETURN (r <= f) ; RandomChance <= chance ENDFUNCTION ;------------------------------ FUNCTION Trigger_control_loss() ; Actually Trigger Control Loss ;------------------------------ Loosecontrol() IF ( LC_system_active ) myF_RegisterForWaitTime(Berserk_Config_LooseControlBaseTimeMin, Berserk_Config_LooseControlBaseTimeMax, TRUE) ENDIF ; *** ql ;;; KillScore = KillScore * 9 / 10 ; *** ENDFUNCTION ;---------------------- FUNCTION Loosecontrol() ;---------------------- ;; debug.messagebox("loosing Controls") mutex_Wait() IF ( !player_has_control ) ; we can only loose controls once mutex_Add() RETURN ; - STOP - ENDIF ;--------------------- actor player = Game.GetPlayer() IF player.IsSprinting() Debug.SendAnimationEvent(player, "SprintStop") ENDIF ;utility.wait(5);waits not necessarary, as we don't run it directly while transforming, like the original mod Game.ForceThirdPerson() ; just to be sure Game.SetPlayerAiDriven(TRUE) ; I don't want to disable the health bar as disableplayercontrols does. ;Game.disableplayercontrols(abLooking=False) ;Debug.SetGodMode(True) player.SetGhost() BerserkerRef = myF_PlaceBerserker(player) ; ### float fx = player.GetPositionX() float fy = player.GetPositionY() float fz = player.GetPositionZ() BerserkerRef.SetPosition(fx, fy, fz) BerserkerRef.Enable() Invisibility_originalvalue = player.GetBaseActorValue("Invisibility") player.SetActorValue("Invisibility", 100) player.SetAlpha(0.0) Utility.Wait(0.2) ; wait a small bit so spells can apply to the replacement ; *** ql added IF player.HasMagicEffect(BerserkArmorBeastT) ;### (BerserkArmorBeastT as SCRBerserkArmorB).RevertForm(player) ELSEIF player.HasMagicEffect(BerserkArmorBeastTDanger) ;### (BerserkArmorBeastTDanger as SCRBerserkArmorB).RevertForm(player) ENDIF utility.wait(0.1) ;wait a small bit so revert form can be finished completely IF (MEValueDefiner.GetValue() == 1) ;get the value for activation of damage attributes and debuffs MEValueDefiner.SetValue(0) ;set the value to deactivate damage attributes and debuffs ENDIF copy_player_stats_to_replacement() ; ### *** not added *** copy_player_gears_to_replacement(player) BerserkerRef.EquipItem(ArmorBerserkerWBoots2, true, true) BerserkerRef.EquipItem(ArmorBerserkerWCuirass2, true, true) BerserkerRef.EquipItem(ArmorBerserkerGauntlets2, true, true) BerserkerRef.EquipItem(ArmorBerserkWHelmet, true, true) BerserkerRef.AddPerk(AllowShoutingPerk) BerserkerRef.AddPerk(Berserk_NPC_FallDmg) ; *** BerserkerAlias.Clear() BerserkerAlias.ForceRefTo(BerserkerRef) ; to attach scripts to the berserker ; (MTE_Quest_Follower_System as MTE_Quest_Follower_System_Script).Update_LC_playerreplacement(BerserkerRef) ;leftover code from MTEO for follower system, not needed here ;For some reason SetAngle() doesnt work for X angle so I'll use TranslateTo to set this angle float aX = player.GetAngleX() float aY = player.GetAngleY() float aZ = player.GetAngleZ() fx = player.GetPositionX() fy = player.GetPositionY() fz = player.GetPositionZ() BerserkerRef.TranslateTo(fx,fy,fz, aX,aY,aZ, 300.0) Game.SetCameraTarget(BerserkerRef) ; MUST be runned on an enabled Object Game.ForceFirstPerson() ; toggle to first person. Force the game to update the camera when we.. Utility.Wait(0.1) Game.ForceThirdPerson() ; force third person IF ( PlatRef ) PlatRef.Delete() PlatRef = None ENDIF PlatRef = player.PlaceAtMe(DwePlatMid01, 1, TRUE, TRUE) PlatRef.SetPosition(fx, fy, fz + 3000.0) PlatRef.SetAngle(0.0, 0.0, 0.0) PlatRef.Enable() aX = player.GetAngleX() aY = player.GetAngleY() aZ = player.GetAngleZ() player.TranslateTo(fx, fy, fz + 3300.0, aX, aY, aZ, 1000.0, 0.0) player_has_control = False RegisterForSingleUpdate(3.0) ; utility.wait(5.0) ; just don't forget to overwrite still active translations (which is quiet unlikly ) in Gaincontrol() ;; debug.messagebox("loosing Controls done") mutex_Add() ; *** ql added Berserk_Moral_Transformed.SetValue(1) ; *** ENDFUNCTION ;---------------------------------------------- Actor FUNCTION myF_PlaceBerserker(Actor player) ; internal helper (non array version) ;---------------------------------------------- bool bFemale = (player.GetActorBase().GetSex() == 1) int i = player.GetEquippedItemType(1) ; right hand actorBase AB ;----------------------- IF (i == 0) || (i == 11) ; unarmed /or/ torch IF (i == 11) weapon w = player.GetEquippedWeapon(False) ; torch in right hand by default player.UnEquipItem(w as Form, False, TRUE) ; unequip it firstly ENDIF IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Unarmed_F ; 0 ELSE AB = Berserk_Player_Loose_Controls_Unarmed_M ENDIF ;--------------------------- ELSEIF (i == 7) || (i == 12) IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Ranger_F ; 7, 12 ELSE AB = Berserk_Player_Loose_Controls_Ranger_M ENDIF ;-------------- ELSEIF (i == 8) IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Spellsword_F ; 8 staff ELSE AB = Berserk_Player_Loose_Controls_Spellsword_M ENDIF ;-------------- ELSEIF (i == 9) IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Mage_F ; 9 spell ELSE AB = Berserk_Player_Loose_Controls_Mage_M ENDIF ;-------------------------- ELSEIF (i >= 1) && (i <= 6) i = player.GetEquippedItemType(0) ; left hand IF (i == 8) || (i == 9) IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Spellsword_F ; ELSE AB = Berserk_Player_Loose_Controls_Spellsword_M ENDIF ELSE IF ( bFemale ) AB = Berserk_Player_Loose_Controls_Melee_F ; 1, 2, 3, 4, 5, 6 ELSE AB = Berserk_Player_Loose_Controls_Melee_M ENDIF ENDIF ENDIF IF ( !AB ) RETURN None ENDIF ;--------- RETURN player.PlaceAtMe(AB, 1, abForcePersist=True, abInitiallyDisabled=True) as Actor ENDFUNCTION ;;---------------------------------------------- ;Actor FUNCTION myF_PlaceBerserker(Actor player) ; internal helper (array version) ; not used for now, i prefer the non array version ;;---------------------------------------------- ; int i = player.GetEquippedItemType(1) ; right hand ; int n = -1 ; IF (i == 0) ; n = 0 ; Berserk_Player_Loose_Controls_Unarmed_M 0 -- 5 Berserk_Player_Loose_Controls_Unarmed_F ; ELSEIF (i == 8) ; n = 4 ; Berserk_Player_Loose_Controls_Spellsword_M 4 -- 9 Berserk_Player_Loose_Controls_Spellsword_F ; ELSEIF (i == 9) ; n = 3 ; Berserk_Player_Loose_Controls_Mage_M 3 -- 8 Berserk_Player_Loose_Controls_Mage_F ; ELSEIF (i == 7) || (i == 12) ; n = 2 ; Berserk_Player_Loose_Controls_Ranger_M 2 -- 7 Berserk_Player_Loose_Controls_Ranger_F ; ELSEIF (i >= 1) && (i <= 6) ; i = player.GetEquippedItemType(0) ; left hand ; IF (i == 8) || (i == 9) ; n = 4 ; Berserk_Player_Loose_Controls_Spellsword_M 4 -- 9 Berserk_Player_Loose_Controls_Spellsword_F ; ELSE ; n = 1 ; Berserk_Player_Loose_Controls_Melee_M 1 -- 6 Berserk_Player_Loose_Controls_Melee_F ; ENDIF ; ENDIF ;IF (n < 0) ; RETURN None ; What is about Torch? ;ENDIF ;;--------- ; IF (player.GetActorBase().GetSex() == 1) ; n = n + 6 ; female actorbase position ; ENDIF ; RETURN player.PlaceAtMe(Berserk_Player_Loose_Controls_Array[n], 1, abForcePersist=True, abInitiallyDisabled=True) as Actor ;ENDFUNCTION ;------------------------------------------ FUNCTION copy_player_stats_to_replacement() ; internal helper, copy Player stats to Loose Control replacement ;------------------------------------------ IF ( !BerserkerRef ) RETURN ; - STOP - ENDIF ;--------------------- string[] a = new string[11] ; a = primevalues + secvalues a[0] = "Health" a[1] = "Stamina" a[2] = "Magicka" a[3] = "UnarmedDamage" a[4] = "DamageResist" a[5] = "DiseaseResist" a[6] = "PoisonResist" a[7] = "FireResist" a[8] = "ElectricResist" a[9] = "FrostResist" a[10]= "MagicResist" actor player = Game.GetPlayer() float f ; f = pval int i = 0 WHILE (i < 3) && (BerserkerRef) f = player.GetBaseActorValue(a[i]) ; get player base actor value BerserkerRef.SetActorValue(a[i], f) float fc = player.GetActorValue(a[i]) player.RestoreActorValue(a[i], 100000) ; to get the modified maxValue f = player.GetActorValue(a[i]) ; get current player max actor value player.DamageActorValue(a[i], f - fc) BerserkerRef.RestoreActorValue(a[i], 100000) ; ------------ float fw = BerserkerRef.GetActorValue(a[i]) BerserkerRef.ModActorValue(a[i], f - fw) BerserkerRef.RestoreActorValue(a[i], 100000) fw = BerserkerRef.GetActorValue(a[i]) BerserkerRef.DamageActorValue(a[i], fw - fc) i = i + 1 ENDWHILE WHILE (i < a.Length) && (BerserkerRef) f = player.GetActorValue(a[i]) ; get current player actor value BerserkerRef.ForceActorValue(a[i], f) ; force that to the berseker i = i + 1 ENDWHILE ENDFUNCTION ;-------------------------------------- Form FUNCTION GetWornAmmo(Actor player) ;*ql, internal helper "copy player gears" ;-------------------------------------- ; https://www.creationkit.com/index.php?title=IsEquipped_-_Actor int i = 0 WHILE (i < WornAmmoList.GetSize()) form fm = WornAmmoList.GetAt(i) IF player.IsEquipped(fm) RETURN fm ; got what we need ENDIF ; ---------- i = i + 1 ENDWHILE RETURN None ; nothing found ENDFUNCTION ;------------------------------ FUNCTION myF_BerserkerAE(Int i) ;------------------------------ form fm fm = player.GetWornForm(i) ; SKSE required !! IF (fm as Armor) BerserkerRef.AddItem(fm, absilent=true) BerserkerRef.EquipItemEx(fm, TRUE, TRUE) ; SKSE required !! ;; Debug.MessageBox("...") ENDIF ENDFUNCTION ;------------------------------------------------------ FUNCTION copy_player_gears_to_replacement(Actor player) ;*ql, copy Player gears to Loose Control replacement ;------------------------------------------------------ IF ( !BerserkerRef ) RETURN ; - STOP - fail earlier ENDIF ;--------------------- form fm weapon w spell sp shout sh ; https://www.creationkit.com/index.php?title=GetWornForm_-_Actor ; https://www.creationkit.com/index.php?title=EquipItemEx_-_Actor myF_BerserkerAE(0x00000200) myF_BerserkerAE(0x00000020) myF_BerserkerAE(0x00000040) ;;; ;;### fm = player.GetWornForm(0x00000200) ; Shield ; IF (fm as Armor) ; BerserkerRef.AddItem(fm, absilent=true) ;;### BerserkerRef.EquipItemEx(fm, TRUE, TRUE) ;;; Debug.MessageBox("...") ; ENDIF ; ;;### fm = player.GetWornForm(0x00000020) ; Amulet ; IF (fm as Armor) ; BerserkerRef.AddItem(fm, absilent=TRUE) ;;### BerserkerRef.EquipItemEx(fm, False, TRUE) ; ENDIF ; ;;### fm = player.GetWornForm(0x00000040) ; Ring ; IF (fm as Armor) ; BerserkerRef.AddItem(fm, absilent=TRUE) ;;### BerserkerRef.EquipItemEx(fm, False, TRUE) ; ENDIF ;;; w = player.GetEquippedWeapon(False) ; right hand IF ( w ) BerserkerRef.AddItem(w as Form, absilent=TRUE) BerserkerRef.EquipItemEx(w as Form, TRUE, TRUE) ; SKSE version does not lose weapon enchantement. ;## BerserkerRef.EquipItem(w as Form, TRUE, TRUE) ;; Debug.MessageBox("...") ENDIF w = player.GetEquippedWeapon(TRUE) ; left hand IF ( w ) BerserkerRef.AddItem(w as Form, absilent=TRUE) BerserkerRef.EquipItemEx(w as Form, TRUE, TRUE) ; SKSE version does not lose weapon enchantement. ;## BerserkerRef.EquipItem(w as Form, TRUE, TRUE) ;; Debug.MessageBox("...") ENDIF fm = GetWornAmmo(player) ; fm = WornAmmo IF ( !BerserkerRef ) RETURN ; - STOP - fail earlier ENDIF ;--------------------- IF ( fm ) ; WornAmmo is valid ammo ;;; int i = player.GetItemCount(fm) BerserkerRef.AddItem(fm, 100, absilent=true); could get count of ammo on player or just give a fixed ammount BerserkerRef.EquipItem(fm, TRUE, TRUE) ; that should last the duration of the berserker status ENDIF ;-------- sp = player.GetEquippedSpell(0) ; left hand spell IF ( sp ) BerserkerRef.AddSpell(sp) BerserkerRef.EquipSpell(sp, 0) ;; Debug.MessageBox("...") ENDIF sp = player.GetEquippedSpell(1) ; right hand spell IF ( sp ) BerserkerRef.AddSpell(sp) BerserkerRef.EquipSpell(sp, 1) ;; Debug.MessageBox("...") ENDIF sp = player.GetEquippedSpell(2) ; other Spell, (3 is instant) IF ( sp ) BerserkerRef.AddSpell(sp) BerserkerRef.EquipSpell(sp, 2) ;; Debug.MessageBox("...") ENDIF sh = player.GetEquippedShout() ; pre selected shout IF ( sh ) BerserkerRef.AddShout(sh) BerserkerRef.EquipShout(sh) ;; Debug.MessageBox("...") ENDIF ENDFUNCTION Link to comment Share on other sites More sharing options...
qwertypol012 Posted February 2, 2019 Author Share Posted February 2, 2019 (edited) Thanks a lot! :smile: Btw i need to ask to confirm several things.1. It seems that you merged qlBerserk_PlayerAliasScript into qlBerserk_ReplacementAliasScript. But i couldn't find the function from qlBerserk_PlayerAliasScript inside qlBerserk_ReplacementAliasScript. So, where did it go? I couldn't find any function about adding severe damage spell into the player in other scrips either.Edit: I think i can simply add it to your new merged script. Yeah, that should work. 2. You merged those 3 smaller other scripts into qlBerserk_TransformFinishScript, then where should it attached to?Previously, they were attached to 3 different magic effects, but now it's merged into a single script, and the last magic effect has different global value than the previous 2 magic effects. How to make it work?Edit: Nvm. Just a trivial issue. I should be able to fix it now. 3. A question regarding this code from qlBerserk_TransformScript: IF akTarget.IsEquipped(ArmorBerserkerCuirass) && akTarget.IsEquipped(ArmorBerserkerBoots) self.Dispel() RETURN ; - STOP - /1 failsafe, player is not the target ENDIF How do it check if the player is not the target? All i can understand is that it checks whether the target is wearing both armors and if so, then dispel the spell. I'm not sure that's what we want, if that's really the case. 4. A question regarding these codes from qlBerserk_QuestScript (under Loosecontrol() function): ; *** ql added IF player.HasMagicEffect(BerserkArmorBeastT) ;### (BerserkArmorBeastT as SCRBerserkArmorB).RevertForm(player) ELSEIF player.HasMagicEffect(BerserkArmorBeastTDanger) ;### (BerserkArmorBeastTDanger as SCRBerserkArmorB).RevertForm(player) ENDIF Note: "SCRBerserkArmorB" has been renamed into "qlBerserk_TransformScript", ie. transformation scriptWhy did you comment it out? Is there something wrong or have them already done by other codes?I added these codes to make the player revert back from transformed state if he/she's losing control. Did i do something wrong in this part? Edited February 4, 2019 by qwertypol012 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted February 4, 2019 Share Posted February 4, 2019 (edited) Answers: 1) It seems that you merged qlBerserk_PlayerAliasScript into qlBerserk_ReplacementAliasScript.No, no .. I renamed this script back (to go along with name convention) because it is not really a PlayerAlias script. 2) you merged 3 smaller scripts into qlBerserk_TransformFinishScriptCannot see any problem here, you have two properties "MEValueDefiner" and "EffectValue", which can be prefilled by CK as you need. 3) about qlBerserk_TransformScript I forgot an "ELSE" here, you asked: "How do it check if the player is not the target?" EVENT OnEffectStart(Actor akTarget, Actor akCaster) IF (akTarget == Game.GetPlayer()) ELSE self.Dispel() RETURN ; - STOP - /0 failsafe, player is not the target ENDIF ;--------------------- from here down to endevent: akTarget == Game.GetPlayer() IF akTarget.IsEquipped(ArmorBerserkerCuirass) && akTarget.IsEquipped(ArmorBerserkerBoots) ELSE ; forgotten last time !!! self.Dispel() RETURN ; - STOP - /1 failsafe, player does not have equipped berserker armor ENDIF ;---------------------4. regarding qlBerserk_QuestScript (under Loosecontrol() function):Note: "SCRBerserkArmorB" has been renamed into "qlBerserk_TransformScript", ie. transformation scriptWhy did you comment it out? Is there something wrong or have them already done by other codes?I added these codes to make the player revert back from transformed state if he/she's losing control. Did i do something wrong in this part? As I wrote at the begin of my preview posting, too many scripts and its not so easy to follow, next should be done here. ; *** ql added IF player.HasMagicEffect(BerserkArmorBeastT) ;### (BerserkArmorBeastT as SCRBerserkArmorB).RevertForm(player) (BerserkArmorBeastT as qlBerserk_TransformScript).RevertForm(player) ELSEIF player.HasMagicEffect(BerserkArmorBeastTDanger) ;### (BerserkArmorBeastTDanger as SCRBerserkArmorB).RevertForm(player) (BerserkArmorBeastTDanger as qlBerserk_TransformScript).RevertForm(player) ENDIF Edited February 4, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
qwertypol012 Posted February 5, 2019 Author Share Posted February 5, 2019 Thanks for clarifying. I thought the same about these, and already did no 3 and 4 you mentioned above. I'll continue it and try it in game. Still need to finish MCM script though. Hopefully it will go smoothly. Once again, thanks a lot for the help! :smile: Link to comment Share on other sites More sharing options...
Recommended Posts