shingouki2002 Posted June 15, 2016 Share Posted June 15, 2016 I'm trying to run a script that will run when the player kills an enemy. The main goal is that when the NPC dies it will add a token to their corpse via "Add Leveled List On Death" perk entry point. The token will then run a script that will check what type of enemy was killed, based on if they have a certain keyword in their keyword list. If it finds the keyword, it will advance various quest stages based on who was killed. So for example if a ghoul is killed, it calls one quest stage. If a molerat is killed it calls another, and so on. So far, I managed to get a token onto dead enemies, and made the quest but I can't seem to get the keyword aspect working. This code doesn't seem to work. Any idea why? Got the general idea from a suggestion Cipscis made on the subject for Skyrim, but I cant get farther than this for whatever reason. Please help? Scriptname RegirWhichEnemyWasKilledScript extends ObjectReference Const Quest Property pEnemyKilled Auto Const ObjectReference rContainer Event OnInit() rContainer = GetContainer() if rContainer.HasKeyword(ActorTypeMolerat) pEnemyKilled.SetStage(20) endif EndEvent Link to comment Share on other sites More sharing options...
demonofsarila Posted June 15, 2016 Share Posted June 15, 2016 Might be dumb questions:Are you sure the token is running your script? Via a debug message or whateverYou've set and filled all the properties for the keywords you need?Are you sure the container is actually the same as the enemy? Like that it isn't some how abstracted or different or something weird. I mean yeah it's all references, but if the container isn't quite the enemy that would be an issue. A script I wrote uses hasKeyword like if(akTargetRef.HasKeyword(ActorTypeSuperMutant)), but not from "inside" the enemy. Mine gets ObjectReference akTargetRef from a perk active thing. Link to comment Share on other sites More sharing options...
Ashnal Posted June 15, 2016 Share Posted June 15, 2016 There's a much better way to do this. No need for tokens. Use the Entry Point "Apply Combat Hit Spell" Then just create a spell and magic effect. Put a condition on the effect that checks IsDead == 1. Attach a script that extends ActiveMagicEffect. In the OnEffectStart() Event, do your setstage. Link to comment Share on other sites More sharing options...
shingouki2002 Posted June 16, 2016 Author Share Posted June 16, 2016 (edited) There's a much better way to do this. No need for tokens. Use the Entry Point "Apply Combat Hit Spell" Then just create a spell and magic effect. Put a condition on the effect that checks IsDead == 1. Attach a script that extends ActiveMagicEffect. In the OnEffectStart() Event, do your setstage.Awesome I'll try this too. I did manage to get it working with tokens in a slightly different way, but I'll try this as well.To add onto this though, I have a new problem. I want to add a perk to the player when a certain number of Kills are reached, but for some reason this code doesn't work. It tells me that the variable isn't defined for the perk. But I really cant seem to figure out why/how to fix it. Any ideas? Scriptname RegirEnemyKilledScript extends Quest Int Property nMoleRatsKilled Auto ; Increment Molerats Killed Function IncrementKilled(int numKilled = 1) ;trying to default this parameter to 1 in case no value is passed. But to also allow larger values to be passed in. nMoleRatsKilled += numKilled Debug.Notification ("You killed " + nMoleRatsKilled + " Molerats so far.") ;Debug testing for num counted. if (nMoleRatsKilled == 5 ) Debug.MessageBox("You killed 5 Molerats! You're a Molerat Killer!") Game.GetPlayer().AddPerk(MoleRatKiller) ; <--- This is the line that doesnt work. My perk is named MoleRatKiller in the Object Window endif EndFunction Edited June 16, 2016 by shingouki2002 Link to comment Share on other sites More sharing options...
Ashnal Posted June 16, 2016 Share Posted June 16, 2016 (edited) There's a much better way to do this. No need for tokens. Use the Entry Point "Apply Combat Hit Spell" Then just create a spell and magic effect. Put a condition on the effect that checks IsDead == 1. Attach a script that extends ActiveMagicEffect. In the OnEffectStart() Event, do your setstage.Awesome I'll try this too. I did manage to get it working with tokens in a slightly different way, but I'll try this as well.To add onto this though, I have a new problem. I want to add a perk to the player when a certain number of Kills are reached, but for some reason this code doesn't work. It tells me that the variable isn't defined for the perk. But I really cant seem to figure out why/how to fix it. Any ideas? Scriptname RegirEnemyKilledScript extends Quest Int Property nMoleRatsKilled Auto ; Increment Molerats Killed Function IncrementKilled(int numKilled = 1) ;trying to default this parameter to 1 in case no value is passed. But to also allow larger values to be passed in. nMoleRatsKilled += numKilled Debug.Notification ("You killed " + nMoleRatsKilled + " Molerats so far.") ;Debug testing for num counted. if (nMoleRatsKilled == 5 ) Debug.MessageBox("You killed 5 Molerats! You're a Molerat Killer!") Game.GetPlayer().AddPerk(MoleRatKiller) ; <--- This is the line that doesnt work. My perk is named MoleRatKiller in the Object Window endif EndFunctionOh that one's easy :smile: You need to define the perk you want to add as a property. Perk Property MoleratKiller Auto Generally speaking, any time you need to work with a CK object in Papyrus that isn't provided by an event parameter, you need to bring it in as a property. This applies to things like GlobalVariables, Spells, Items, and Perks. Here, I'll fix up your quest script a little. Scriptname RegirEnemyKilledScript extends Quest Int nMoleRatsKilled = 0 Perk Property MoleRatKiller Auto ; Increment Molerats Killed Function IncrementKilled(int numKilled = 1) ;trying to default this parameter to 1 in case no value is passed. But to also allow larger values to be passed in. nMoleRatsKilled += numKilled Debug.Notification ("You killed " + nMoleRatsKilled + " Molerats so far.") ;Debug testing for num counted. if (nMoleRatsKilled == 5 ) Debug.MessageBox("You killed 5 Molerats! You're a Molerat Killer!") Game.GetPlayer().AddPerk(MoleRatKiller) endif EndFunction Any particular reason why you're dropping tokens on death to increment? Seems like a terribly roundabout way to do that. In fact I thought of an even simpler way to handle this. Just set the player as an alias in your quest. Then attach a script to the PlayerAlias. The Script wil listen for the Actor.OnKill(Actor akVictim) Event. That event passes in the Victim as a parameter, so whenever the Player kills soemthing you just check and increment. Like so: ScriptName MoleRatKillerPayerRefAlias Extends ReferenceAlias Quest Property RegirEnemyKilledScript Auto ActorBase Property MoleratActorBase Auto Event OnKill(Actor akVictim) if (akVictim.GetActorBase() == MoleratActorBase) RegirEnemyKilledScript.IncrementKilled() EndIf EndEvent Edited June 16, 2016 by Ashnal Link to comment Share on other sites More sharing options...
KataPUMB Posted June 16, 2016 Share Posted June 16, 2016 (edited) Why dont juts use OnDeath() Event. Go to the npc you wanna have the event running and add the script. You can put the stage as an Int and edit it as a property so you only have one script. Then to count how many you have killed just use a Script in the quest.Something like this: Scriptname EnemyKilledScript extends Actor Int Property StageInt Auto Int Property ID Auto ; 0=molerat, 1=synth, 2=deathclaw for example Quest Property myQuest Auto Event OnDeath(Actor akKiller) if (akKiller == Game.GetPlayer()) myQuest.setstage(StageInt) myQuest.ScriptToCount.count(ID) ;for example, and this script can handle when you can add the perk to the player that you can do just with a game.getplayer().addperk(perk) endIf endEvent Edited June 16, 2016 by KataPUMB Link to comment Share on other sites More sharing options...
Ashnal Posted June 16, 2016 Share Posted June 16, 2016 Why dont juts use OnDeath() Event. Go to the npc you wanna have the event running and add the script. You can put the stage as an Int and edit it as a property so you only have one script. Then to count how many you have killed just use a Script in the quest.Something like this: Scriptname EnemyKilledScript extends Actor Int Property StageInt Auto Int Property ID Auto ; 0=molerat, 1=synth, 2=deathclaw for example Quest Property myQuest Auto Event OnDeath(Actor akKiller) if (akKiller == Game.GetPlayer()) myQuest.setstage(StageInt) myQuest.ScriptToCount.count(ID) ;for example, and this script can handle when you can add the perk to the player that you can do just with a game.getplayer().addperk(perk) endIf endEvent Problem with that approach is that you'd have to go to each ref in the cells you want it to apply to and attach it. From what I saw, OP wnated a generic molerat slaying quest where it could be ANY molerat, not specific ones. Attaching that script to the ActorBase in the CK is just a recipe for making it incompatible with a lot of other mods. Quest aliases are the way to go here IMO. Whether you alias the targets or the player. Link to comment Share on other sites More sharing options...
MasterMagnus Posted June 16, 2016 Share Posted June 16, 2016 In the CK when setting up refs isn't *ANY* a valid Cell you can reference? I see it in the list at any rate. Link to comment Share on other sites More sharing options...
KataPUMB Posted June 16, 2016 Share Posted June 16, 2016 No, just add it to the base npcs, for example the "EncMolerat01Template", that is the template of the lvled molerat and share scripts and all the properties. I think that the only ones that don't inherit scripts are the legendray enemies but...The other way i see to implement this easyly is with the OnKill() Event in a quest with the player as alias... but to determinate what's killing... well it may be complicated... maybe with a GetRace()? Yea... Link to comment Share on other sites More sharing options...
Ashnal Posted June 17, 2016 Share Posted June 17, 2016 No, just add it to the base npcs, for example the "EncMolerat01Template", that is the template of the lvled molerat and share scripts and all the properties. I think that the only ones that don't inherit scripts are the legendray enemies but...The other way i see to implement this easyly is with the OnKill() Event in a quest with the player as alias... but to determinate what's killing... well it may be complicated... maybe with a GetRace()? Yea...It's not hard at all. akVictim.GetActorBase() == ActorBaseYoureCheckingFor Link to comment Share on other sites More sharing options...
Recommended Posts