Rizalgar Posted January 17, 2019 Share Posted January 17, 2019 Okay, I'm back, even after I said I wouldn't be. I'm trying to roll Skyrim back into a more RPG style roll based combat system for my mod. I've got the base fundamentals down, but I can't figure out how to actually make an attack miss, or do 0 damage based off the roll. From what I've googled, this may even be impossible. Any insight, my fellow modders? Here's the script I'm working with. Yes, I know I need to change the SetAV for the HP modifier and just do it in the NPC window as a modifier there. On a side note, I also need this same script to determine whether creatures hit the player or not. I thought '0' would be correct, thinking they use Melee attacks, but that doesn't seem to be the case. Scriptname RS_MonsterStat_test extends Actor {Test for monster combat stats} Form Property RS_Formlist_Weapon_All Auto Int Property DefStat Auto Int Property HP Auto Int Property DamMin Auto Int Property DamMax Auto Int Property HitMin Auto Int Property HitMax Auto Event OnInit() RegisterForActorAction(0) EndEvent Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) Int PAB = rsFrameworkMain.GetAttackBonus().GetValue() as Int Int PA = rsFrameworkMain.GetAttackLVL().GetValue() as Int Int PAF = (PA + PAB) self.SetAV("Health", HP) Int Hit = Utility.RandomInt(1,PAF) Int Miss = Utility.RandomInt(1,DefStat) If akAggressor == Game.GetPlayer() If Miss > Hit debug.notification("you miss") Else ;take damage Weapon akSourceWeapon = akSource as Weapon EndIf EndIf EndEvent Event OnActorAction(int actionType, Actor akActor, Form source, int slot) Int Hit = Utility.RandomInt(HitMin, HitMax) Int PDB = rsFrameworkMain.GetDefenceBonus().GetValue() as Int Int PD = rsFrameworkMain.GetDefenceLVL().GetValue() as Int Int PDF = (PD + PDB) Int Damage = Utility.RandomInt(DamMin, DamMax) If Hit > PDF If !source If !slot Game.GetPlayer().DamageActorValue("Health", Damage) Debug.Notification("hit") EndIf EndIf EndIf EndEvent Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 17, 2019 Share Posted January 17, 2019 OnHit event works on the actor being hit. So if you want to know if the player is hit, you need to have the OnHit event on a script attached to the player (preferably through a reference alias on a quest). As far as making an attack miss or do zero damage, no idea. Link to comment Share on other sites More sharing options...
Rizalgar Posted January 17, 2019 Author Share Posted January 17, 2019 (edited) Ooof, gotta be a hard one if even you're stumped Ishara, you've always got a solution. I tinkered around a little bit, and changed the script into this. It doesn't do any damage when the roll is lost, but it also doesn't take any damage when the roll is passed. Any ideas? I can't seem to get the actor value right for the DamageAV. I'm not sure what to use. Scriptname RS_MonsterStat_test extends Actor {Test for monster combat stats} GlobalVariable Property RS_GV_DamageMax Auto GlobalVariable Property RS_GV_DamageMin Auto Int Property DefStat Auto Int Property HP Auto Int Property DamMin Auto Int Property DamMax Auto Int Property HitMin Auto Int Property HitMax Auto Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) Int PAB = rsFrameworkMain.GetAttackBonus().GetValue() as Int Int PA = rsFrameworkMain.GetAttackLVL().GetValue() as Int Int PAF = (PA + PAB) self.SetAV("Health", HP) Int Hit = Utility.RandomInt(1,PAF) Int Miss = Utility.RandomInt(1,DefStat) If akAggressor == Game.GetPlayer() If Miss > Hit debug.notification("you miss") Else Int DamageMin = RS_GV_DamageMin.GetValue() as Int Int DamageMax = RS_GV_DamageMax.GetValue() as Int Int Damage = Utility.RandomInt(DamageMin, DamageMax) RS_Monster_GiantRat_Test.DamageActorValue("Health", Damage) EndIf EndIf EndEvent Event OnActorAction(int actionType, Actor akActor, Form source, int slot) RegisterForActorAction(0) Int Hit = Utility.RandomInt(HitMin, HitMax) Int PDB = rsFrameworkMain.GetDefenceBonus().GetValue() as Int Int PD = rsFrameworkMain.GetDefenceLVL().GetValue() as Int Int PDF = (PD + PDB) Int Damage = Utility.RandomInt(DamMin, DamMax) akActor.SetAV("MeleeDamage", Damage) akActor.SetAV("UnarmedDamage", Damage) If Hit > PDF If !source If !slot Game.GetPlayer().DamageActorValue("Health", Damage) Debug.Notification("hit") EndIf EndIf EndIf EndEvent Edit - Got the 0/Miss formula working with this script. Now if I could actually get the attacker to deal damage.... Scriptname RS_MonsterStat_test extends Actor {Test for monster combat stats} Actor Property RS_Monster_GiantRat_Test Auto GlobalVariable Property RS_GV_DamageMax Auto GlobalVariable Property RS_GV_DamageMin Auto Int Property DefStat Auto Int Property HP Auto Int Property DamMin Auto Int Property DamMax Auto Int Property HitMin Auto Int Property HitMax Auto Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) Int PAB = rsFrameworkMain.GetAttackBonus().GetValue() as Int Int PA = rsFrameworkMain.GetAttackLVL().GetValue() as Int Int PAF = PA * (PAB + 64) Int Hit = Utility.RandomInt(1,PAF) Int Miss = Utility.RandomInt(1,DefStat) Int DamageMin = RS_GV_DamageMin.GetValue() as Int Int DamageMax = RS_GV_DamageMax.GetValue() as Int Int Damage = Utility.RandomInt(DamageMin, DamageMax) If akAggressor == Game.GetPlayer() If Miss > Hit debug.notification("you miss") Else self.DamageActorValue("Health", Damage) EndIf EndIf EndEvent Event OnActorAction(int actionType, Actor akActor, Form source, int slot) RegisterForActorAction(0) Int Hit = Utility.RandomInt(HitMin, HitMax) Int PDB = rsFrameworkMain.GetDefenceBonus().GetValue() as Int Int PD = rsFrameworkMain.GetDefenceLVL().GetValue() as Int Int PDF = (PD + PDB) Int Damage = Utility.RandomInt(DamMin, DamMax) akActor.SetAV("MeleeDamage", Damage) akActor.SetAV("UnarmedDamage", Damage) If Hit > PDF If !source If !slot Game.GetPlayer().DamageActorValue("Health", Damage) Debug.Notification("hit") EndIf EndIf EndIf EndEvent Edit2- Got the creature damage working as well. The experience formula is working on top of that. Everything is working golden. Here's the scripts if anyone is interested in trying to achieve the same thing. The first script goes on the creature, the second goes on a ME attached to a spell added to the creatures attack list. Scriptname RS_MonsterStat_test extends Actor {Test for monster combat stats} GlobalVariable Property RS_GV_DamageMax Auto GlobalVariable Property RS_GV_DamageMin Auto GlobalVariable Property RS_GV_XPMultiplier Auto GlobalVariable Property RS_GV_AttackStyle Auto Int Property DefStat Auto Int Property HP Auto Int Property DamMin Auto Int Property DamMax Auto Int Property HitMin Auto Int Property HitMax Auto Float Property Experience Auto Float Property ExperienceC Auto Bool DoOnce Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) Int AttXP = rsFrameworkMain.GetAttackXP().GetValue() as Int Int StrXP = rsFrameworkMain.GetStrengthXP().GetValue() as Int Int DefXP = rsFrameworkMain.GetDefenceXP().GetValue() as Int Int ConXP = rsFrameworkMain.GetConstitutionXP().GetValue() as Int Int XPM = RS_GV_XPMultiplier.GetValue() as Int Float XPF = Experience * XPM Float XPC = ExperienceC * XPM Int PAB = rsFrameworkMain.GetAttackBonus().GetValue() as Int Int PA = rsFrameworkMain.GetAttackLVL().GetValue() as Int Int PAF = PA * (PAB + 64) Int Hit = Utility.RandomInt(PA,PAF) Int Miss = Utility.RandomInt(1,DefStat) Int DamageMin = RS_GV_DamageMin.GetValue() as Int Int DamageMax = RS_GV_DamageMax.GetValue() as Int Int Damage = Utility.RandomInt(DamageMin, DamageMax) If akAggressor == Game.GetPlayer() If Miss > Hit debug.notification("you miss") Else self.DamageActorValue("Health", Damage) EndIf EndIf If self.isdead() Experience() endif EndEvent Function Experience() debug.notification("experience") Int AttStyle = RS_GV_AttackStyle.GetValue() as Int Int XPM = RS_GV_XPMultiplier.GetValue() as Int Float XPF = Experience * XPM Float XPC = ExperienceC * XPM Float XPCon = (Experience / 2) * XPM If !DoOnce If AttStyle == 0 ;;accurate rsFrameworkMain.rsXPGain("attack", XPF) rsFrameworkMain.rsXPGain("constitution", XPC) ElseIf AttStyle == 1 ;; aggressive rsFrameworkMain.rsXPGain("strength", XPF) rsFrameworkMain.rsXPGain("constitution", XPC) ElseIf AttStyle == 2 ;; defensive rsFrameworkMain.rsXPGain("defence", XPF) rsFrameworkMain.rsXPGain("constitution", XPC) ElseIf AttStyle == 3 ;;controlled rsFrameworkMain.rsXPGain("attack", XPCon) rsFrameworkMain.rsXPGain("strength", XPCon) rsFrameworkMain.rsXPGain("defence", XPCon) rsFrameworkMain.rsXPGain("constitution", XPC) EndIf DoOnce = True EndIf EndFunction Scriptname RS_Weapon_Damage_Test extends ActiveMagicEffect {test for weapon damage} GlobalVariable Property RS_GV_DefenceLVL Auto GlobalVariable Property RS_GV_DefenceBonus Auto Int Property HitMin Auto Int Property HitMax Auto Int Property DamMin Auto Int Property DamMax Auto Event OnEffectStart(Actor akCaster, Actor akTarget) Int Def = RS_GV_DefenceLVL.GetValue() as Int Int DB = RS_GV_DefenceBonus.GetValue() as Int Int DefMin = Def + DB Int DefMax = Def * (DB + 64) Int DefRoll = Utility.RandomInt(DefMin, DefMax) Int Hit = Utility.RandomInt(HitMin, HitMax) Int Damage = Utility.RandomInt(DamMin, DamMax) If Hit > DefRoll akCaster.DamageAV("Health", Damage) EndIf EndEvent Edited January 17, 2019 by Rizalgar Link to comment Share on other sites More sharing options...
Recommended Posts