Jump to content

[LE] To skilled modders: pls Help to find and fix problem


myav

Recommended Posts

Hi people.

 

I'm trying to find the way to decrease aggression of NPC during combat, after some conditions and their result: spell with "script type" magic effect (that to decrease his attemps to attack).

 

I chose the best variant (as I thought), and i don't understand, why it don't works...

Scriptname frivolity extends activemagiceffect

actor selfactor
ActorBase MyBase

Event onInit(); (i have tried Event onEffectStart too)

selfactor = GetTargetActor()
MyBase = selfactor.GetActorBase()
Combatstyle csStyle = MyBase.GetCombatStyle()
; also, i have tried: 
; Form csForm = MyBase.GetCombatStyle() as Form
; Combatstyle csStyle = csForm as Combatstyle
csStyle.SetOffensiveMult(0.10)
; native offensivemult was 0.6, so i try to decrease number of attack attemps
selfactor.StopCombat()
MyBase.SetCombatStyle(csStyle)
selfactor.StopCombat()
selfactor.EvaluatePackage()
EndEvent

I read that actorbase is locked while combat, and impossible to change combatstyle during combat. So, it is main reason why i have used stopcombat() and only after this - changes.

 

But... All my variants don't work.. NPC ignore changes and continue to fight with offensivemult 0.6.

 

If you are skilled on this part of coding, pls help how to fix this code or pls suggest other variants of code that to decrease attemps of attacks of npc, while NPC have this magic effect.

 

Variant, to change confidence is not good too, because it force npc to flee (but i want only to decrease offensive attacks, without running and flee)

Edited by myav
Link to comment
Share on other sites

I do not have any knowledge of combatstyle scripting, but next could help you.

 

frivolityMGEFScript

 

Scriptname frivolityMGEFScript extends ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/8248088-to-skilled-modders-pls-help-to-find-and-fix-problem/

; SKSE does not provide CombatStyle properties as of yet, you may need to use formlists
  FormList PROPERTY csList auto                  ; have to be create and filled by CK
  ; getAt(0) = OneHanded
  ; getAt(1) = TwoHanded

  GlobalVariable PROPERTY gGroup_Saved auto      ; have to be create/filled
  GlobalVariable PROPERTY gOff_Saved auto        ; have to be create/filled
  GlobalVariable PROPERTY gDef_Saved auto        ; have to be create/filled

  Actor target


; -- EVENTs --
; https://www.creationkit.com/index.php?title=GetCombatStyle_-_ActorBase
; https://www.creationkit.com/index.php?title=SetCombatStyle_-_ActorBase

EVENT OnEffectStart(Actor akTarget, Actor akCaster)
    target = akTarget
    actorBase AB = akTarget.GetActorBase()

IF (SKSE.GetVersion() == 0)
    self.Dispel()
    RETURN    ; - STOP -    SKSE not found!!
ENDIF
;=====================
    float[] a = new Float[3]
    float f
    
    int i = csList.Find(AB.GetCombatStyle() as Form)

IF (i >= 0)
    a[0] = AB.GetCombatStyle().GetGroupOffensiveMult()
    IF (gGroup_Saved.GetValue() == 0.0)                  ; first time store
        gGroup_Saved.SetValue( a[0] )                    ; original value
    ENDIF
    Debug.Notification("cs group multiplier is " +a[0])

    ; this works in conjunction with the defensive mult.
    a[1] = AB.GetCombatStyle().GetOffensiveMult()
    IF (gOff_Saved.GetValue() == 0.0)                    ; first time store
        gOff_Saved.SetValue( a[1] )                      ; original value
    ENDIF
    Debug.Notification("cs offensive multiplier is " +a[1])
    
    a[2] = AB.GetCombatStyle().GetDefensiveMult()
    IF (gDef_Saved.GetValue() == 0.0)                   ; first time store
        gDef_Saved.SetValue( a[2] )                     ; original value
    ENDIF
    Debug.Notification("cs defensive multiplier is " +a[2])

    target.EvaluatePackage()
    target.StopCombat()
    target.StopCombatAlarm()


; *** Note: Group Offensive Mult - This will over-ride the offensive multiplier.
; The more actors that are attacking the player, the less offensive they will be, based on this mult.
; The higher the mult, the more offensive they will be in groups.

    f = a[1] * 0.5                                     ; same as set offensive
    AB.GetCombatStyle().SetGroupOffensiveMult(f)
;;;    AB.GetCombatStyle().SetGroupOffensiveMult(0.0)  ; or try ZERO for group


    ; higher the number, the more likely a character will attack,
    ; the more often they will attack, and the more often they will power attack.
    ; native offensivemult was 0.6, so i try to decrease number of attack attemps

    f = a[1] * 0.5
    AB.GetCombatStyle().SetOffensiveMult(f)           ; aggressive lower by 50%


    ; higher the number, a character will block more often,
    ; hold their block up longer, and bash more often if they are capable to do so.

    f = a[2] * 1.25
    AB.GetCombatStyle().SetDefensiveMult(f)           ; defensive 25% higher
ENDIF

;;;    target.EvaluatePackage()
;;;    target.StartCombat(Game.GetPlayer())
ENDEVENT


;/ ***
Scriptname CombatStyle extends Form Hidden
; SKSE extension
; https://www.creationkit.com/index.php?title=Combat_Style

; functions related to the General Tab values
float Function GetOffensiveMult() native
float Function GetDefensiveMult() native
float Function GetGroupOffensiveMult() native
float Function GetAvoidThreatChance() native
float Function GetMeleeMult() native
float Function GetRangedMult() native
float Function GetMagicMult() native
float Function GetShoutMult() native
float Function GetStaffMult() native
float Function GetUnarmedMult() native

Function SetOffensiveMult(float mult) native
Function SetDefensiveMult(float mult) native
Function SetGroupOffensiveMult(float mult) native
Function SetAvoidThreatChance(float chance) native
Function SetMeleeMult(float mult) native
Function SetRangedMult(float mult) native
Function SetMagicMult(float mult) native
Function SetShoutMult(float mult) native
Function SetStaffMult(float mult) native
Function SetUnarmedMult(float mult) native

; functions related to the Melee tab values
float Function GetMeleeAttackStaggeredMult() native
float Function GetMeleePowerAttackStaggeredMult() native
float Function GetMeleePowerAttackBlockingMult() native
float Function GetMeleeBashMult() native
float Function GetMeleeBashRecoiledMult() native
float Function GetMeleeBashAttackMult() native
float Function GetMeleeBashPowerAttackMult() native
float Function GetMeleeSpecialAttackMult() native
bool Function GetAllowDualWielding() native

Function SetMeleeAttackStaggeredMult(float mult) native
Function SetMeleePowerAttackStaggeredMult(float mult) native
Function SetMeleePowerAttackBlockingMult(float mult) native
Function SetMeleeBashMult(float mult) native
Function SetMeleeBashRecoiledMult(float mult) native
Function SetMeleeBashAttackMult(float mult) native
Function SetMeleeBashPowerAttackMult(float mult) native
Function SetMeleeSpecialAttackMult(float mult) native
Function SetAllowDualWielding(bool allow) native
*** /;

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

ReDragon2013, thanks for your attempt to help. but your example does not work :sad: just like mine ((

 

In the game all notifications appeared (about group, offense, defense) and this means that NPC have received magic effect, and script was launched, because all notifications was inside event onEffectStart, and all they - appears.

 

But was 0 changes on AI.

 

For testing i even set:

AB.GetCombatStyle().SetGroupOffensiveMult(0.0)
AB.GetCombatStyle().SetOffensiveMult(0.0) 

that completelly stop NPC attacks. And on notifications (when i summon other the same npc) was written that his offense and defense is 0 from the beginning. But this don't works... npc have attacked me each second (and i understand that their AI didn't receive changes from actorbase).

 

So, i still need help. Why does all this not work?

 

CombatStyle inside ActorBase was really changed and i get notifications about this. But NPC have ignored all this. Current npc and the next summoned.

 

How i test changes:

 

mod alternate start (that to start new game and to skip intro), all other mods - disabled.

 

then console commands:

 

tgm

player.placeatme 00037bfc (bandit with combatstyle csHumanMissle)

 

then combat was started, and durting combat: console, click enemy and:

 

addspell (spellid)

 

then i get notifications about combatstyle variables and bandit stop combat for second (stopcombat - works) and after 1 sec, bandit start combat again

 

but 0 changes to AI. with offense 0.0 and group offense 0.0 bandit have attacked each second (also. the same was with offense 0.1 and groupoffense 0.1 as my first version of the script)

 

i kill him and summon other bandit. on notifications i read that offense is 0.0 from the beginning (changes on actorbase during previous bandit)

 

but again - 0 changes to AI. the next bandit have attacked me each second too.

 

So... SKSE CombatStyle changes are broken? or during combat is impossible to change actorbase without bugs even with stopcombat? Or needed more commands that AI re-read their actorbase? or i miss something important which don't allow to change AI?

 

Heeeeeelp((

 

I really need to find a way to reduce NPC aggression during battle (without neutral stance and without flee)

Edited by myav
Link to comment
Share on other sites

maxarturo,

 

1. was used stopcombat and stopcombatalert, this don't works that to remove lock?

2. next summoned (the same) actor was with 0.0 offense from the beginning (before the combat starts, because was changed their actorbase during previous actor). But why again 0 changes to AI ?

Edited by myav
Link to comment
Share on other sites

I also don't have any experience with scripting "combatstyle", but there are a few things that i do know that are relevant.

1) Combat Styles are locked for the duration of combat, if an Actor is in combat when this is called their combat style will not change.

2) "EvaluatePackage" will not modify npc's AI behavior like combat and pathing. You need to use "ResetAI".

3) "ResetAI" clears/resets all current AI behaviors from an actor like combat and pathing.


The following is not directly relevant to your issue, but...


4) Codes, Enents, Function that were not used (or used for one or two simple things in game) by Bethesda when the game was created are incomplete or they were never fully polished.

Here are a few examples from my experience:

a - "OnTranslationComplete()" will not fire anything !, the only few things that it actually executes are, if the script is in the same object that will call the function: Self.Disable() - Self.Delete()

but it will not call it in other objects + It'll not call any other functions like: Enable() - Activate() - PlaceAtMe() - MoveTo()... etc.


The only function that it will always fire is changing state: GoToState()


b - TranslateTo(), SplineTranslateToRef(), SplineTranslateToRefNode(), TranslateToRef() they all have the same issue, when translation starts the mesh that is been translated to will STOP receiving light from light sources (light bulbs).

Although, if you leave the cell and then return (unload - load cell), everything will be normal.

This is clearly bad coding and bad game construction from Bethesda part.



The point of this example is that you might need to run some tests, like:

1) Enable / Disable the actor before or/and after the Combat Style has or will change.

2) unload / load the cell your actor is in to see/check if the actor does or does not change combat style.


And any other test you might think off, so if the issue is in the game engine/code, then you will need to try and find a workaround like i did with the "OnTranslationComplete()" and "TranslateTo()" issues.


I don't know if any of this can actually help you, but this is the only thing i can do at the moment.


Merry Christmas and Happy New Year !.

Edited by maxarturo
Link to comment
Share on other sites

maxarturo, when i use selfactor.resetai() or target.resetai() and then - other code, after reset, during battle - game crashes in 70% of situations, i don't know why...

 

From my personal testing, resetai works only from console use (without problems). If you know where is problem (mb here is better command that to reset ai, or needed conditions that to be safe) pls write.

 

P.S.: i'll check enable/disable and load/unload, will it help that to change "AI combatstyle" or not - in some hours

Edited by myav
Link to comment
Share on other sites

You need to give the game engine some time to actually reset AI and not call immediately another function while reset AI is been executed on the actor.

It needs a few seconds, but i haven't timed it, this also needs testing, a wild guess is around 1.5 to 2.5 seconds, but i could be wrong.

Link to comment
Share on other sites

What is wrong with this life?!!! only failures :sad:

 

Testing 1:

target.ResetAI()
utility.wait(3.00)

and 0 code after

 

again crash... so - waiting does not save the situation, I think that command must be written differently. But this is not important, i can use reset with console during testing.

 

Testing 2:

 

a). console command: tdetect (so - no combat)

b). changed offense of combatstyle to 0.05

c). selected bandit and console: resetai (also, was checked variant, without ResetAI)

 

And.. Fail... Actorbase have received changes, but AI have ignored them

 

P.S.: i think that it is possible that was changed only form inside Formlist, but actorbase - have ignored script.

 

Testing 3:

 

I have changed combatstyle of NPC without battle and go out

i left cell (house), then i go inside other house that was reload of cells - 2 times, then i came back

 

And.... Again 0 changes. Written (notification) offensivemult 0.05 but AI attacks with offensivemult 0.6 (each second)

 

so.. version of maxarturo, (to reload cells) was tested and again - without result ((

 

How people have used SetOffense 5 years when it does not work? ...

 

Who have experience with successful combatstyle changes? (not only notification that variable was changed, real battle AI attack frequency must be changed too)

 

please help and write what i miss ... (

Edited by myav
Link to comment
Share on other sites

Why don't you check one of those mods that have successfully done this to get an idea on how they did it.

Checking and learning from them is not considered stealing, if you dont copy/paste their codes.


But i suspect that you are referring to followers mods which their scripts target a specific actor and they don't use actor base or formlists, but Actor REF.


* A big part of modding is a continuous research and search for workarounds, you are not the only one that have failed repeatedly.

I can not even tell you how many times i have been in your position, only to discover in the end that what i'm trying to do it just can not be done...

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...