How to set actor conditions "HasBeenEaten"

Post » Wed Jun 20, 2012 10:20 pm

Ok so I'm trying to make it so vampires can feed on dead bodies. I have it working, but you can do it over and over again. So I looked at werewolves and they can only feed on a body once... and it uses the condition "HasBeenEaten" at 0. So I'm assuming it gets set to 1 somehow, yet I cannot find it in the code anywhere.

I'm assuming I will also need to pass the victim in the vampire feed perk fragment code to the vampire quest script. Can someone tell me how to do that?

Here is the fragment. Am I correct in saying that the victim is passed to the StartVampireFeed Function? Yet I cannot find the StartVampireFeed function anywhere so I can't test this. Any help greatly appreciated.

;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment;NEXT FRAGMENT INDEX 10Scriptname PRKF_VampireFeedBeds_000CF02C Extends Perk Hidden;BEGIN FRAGMENT Fragment_0Function Fragment_0(ObjectReference akTargetRef, Actor akActor);BEGIN CODEGame.GetPlayer().StartVampireFeed(aktargetRef as actor)PlayerVampireQuest.VampireFeed();END CODEEndFunction;END FRAGMENT;END FRAGMENT CODE - Do not edit anything between this and the begin commentPlayerVampireQuestScript Property PlayerVampireQuest  Auto 
User avatar
Ruben Bernal
 
Posts: 3364
Joined: Sun Nov 18, 2007 5:58 pm

Post » Wed Jun 20, 2012 1:40 pm

StartVampireFeed is a native function, which means it's defined in the executable not in a script. It's attached to actor script, but it's not defined there. An actor having been eaten by a werewolf is controled by the actor value 08. One of the 10 user defined actor values you can handle by getactorvalue and setactorvalue.

To pass the victim in the fragment, to the vampire quest script, define an actor property in the quest and include in one of the functions as an argument. then define a property of the type your_vampire_quest in the fragment and make a call to the function containing the actor property as (your_vampire_quest as your_vampire_quest_script).functionName(victim) .
User avatar
Austin England
 
Posts: 3528
Joined: Thu Oct 11, 2007 7:16 pm

Post » Wed Jun 20, 2012 12:59 pm

You may have to call StartCannibal(Dead Actor) - though I don't know if it's animation overrides the vampire feed one or not? Maybe if you call it, then immediately call the vampirefeed one?

Here, try this:

DeadActor.SetAV("Variable08",1.0)

Then use that as your condition.
User avatar
Jade Payton
 
Posts: 3417
Joined: Mon Sep 11, 2006 1:01 pm

Post » Thu Jun 21, 2012 1:20 am

StartCannibal() - I came across this while browsing through the papyrus scripting reference.

This function has to be the single greatest name for a function... EVER.

I've seen some pretty funny function names in my years, but this one both had me cracking up in laughter while at the same time thinking:
Actors can feed on other actors!!? AWESOME!

(I never saw the cannibal quest in game)
User avatar
Eibe Novy
 
Posts: 3510
Joined: Fri Apr 27, 2007 1:32 am

Post » Wed Jun 20, 2012 10:16 pm

Ok so I have it compiling, and my debug message is coming up... so my function VampireCorpseFeed is getting called, yet it is not setting the corpse to "hasbeeneaten", because I can still feed on the corpse after I feed on it. I think I am not properly passing the actor through from the fragment to the playervampirequest.

Here is my fragment:
;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment;NEXT FRAGMENT INDEX 10Scriptname PRKF__0100A98D Extends Perk Hidden;BEGIN FRAGMENT Fragment_0Function Fragment_0(ObjectReference akTargetRef, Actor akActor);BEGIN CODEGame.GetPlayer().StartVampireFeed(aktargetRef as actor)PlayerVampireQuest.VampireFeed()PlayerVampireQuest.VampireCorpseFeed(VampireFeedVictim as Actor);END CODEEndFunction;END FRAGMENT;END FRAGMENT CODE - Do not edit anything between this and the begin commentPlayerVampireQuestScript Property PlayerVampireQuest  Auto  Actor Property VampireFeedVictim  Auto 

Here is my function in the vampire quest script:

Function VampireCorpseFeed(Actor VampireFeedVictim);MM this function will mark corpses as "have been eaten"    debug.messagebox("corpse has been fed on, trying to set has been eaten flag")    VampireFeedVictim.SetAV("Variable08",1.0)EndFunction

I have declared in both scripts
actor property VampireFeedVictim Auto

But it does not "auto fill". Can someone explain why sometimes autofill does not add the little icon to it when you tell it to auto fill your new property?
User avatar
Kitana Lucas
 
Posts: 3421
Joined: Sat Aug 12, 2006 1:24 pm

Post » Wed Jun 20, 2012 8:11 pm

StartCannibal() - I came across this while browsing through the papyrus scripting reference. This function has to be the single greatest name for a function... EVER. I've seen some pretty funny function names in my years, but this one both had me cracking up in laughter while at the same time thinking: Actors can feed on other actors!!? AWESOME! (I never saw the cannibal quest in game)

I tried that but I'm having the same problem, the actor is not passing through properly I don't think. I get the debug message, but the victim is not cannibalized. Can someone look at my fragment and tell me how to pass the vampirefeedvictim properly through to my other script?
User avatar
XPidgex Jefferson
 
Posts: 3398
Joined: Fri Sep 08, 2006 4:39 pm

Post » Wed Jun 20, 2012 6:56 pm

this is your problem->
PlayerVampireQuest.VampireCorpseFeed(VampireFeedVictim as Actor)

Why are you passing 'VampireFeedVictim' ? like you mentioned that is just a property that doesn't autofill. The aktargetRef is what your are feeding on right? so that's what you want to mark as 'fed'. your script should look like this:

Game.GetPlayer().StartVampireFeed(aktargetRef as actor)PlayerVampireQuest.VampireFeed()PlayerVampireQuest.VampireCorpseFeed(aktargetRef as Actor)
User avatar
Chloe Yarnall
 
Posts: 3461
Joined: Sun Oct 08, 2006 3:26 am

Post » Wed Jun 20, 2012 2:10 pm

A more Technical explanation:

'VampireFeedVictim' is the name of a parameter in a function:
Function VampireCorpseFeed(Actor VampireFeedVictim)    VampireFeedVictim.DoStuff()EndFunction

That function exists in a completely different real from your fragment. your fragment has no clue what 'VampireFeedVictim' is, in fact you could re-write that function to have a different name. E.g. you could do any of the following:

Function VampireCorpseFeed(Actor VampireFeedVictim)Function VampireCorpseFeed(Actor Bob)Function VampireCorpseFeed(Actor IAmAPrettyLittlePrincess)

And the function would work exactly the same way. You are just telling the game, "this function is going to get an Actor, and in this function we will refer to that Actor as 'Bob', or 'VampireFeedVictim', or 'IamAPrettyLittlePrincess'.

so in your fragment when you call the function and you pass 'akTarget' as in
PlayerVampireQuest.VampireCorpseFeed(aktargetRef as Actor)

You are telling the function, 'hey! I am giving you the actor 'aktargetRef' and i want you to do stuff with it.
And the function is like, 'okay, that's fine, but from here on out I'm calling this actor 'Bob'

If you called

PlayerVampireQuest.VampireCorpseFeed(Game.GetPlayer())

Then the function would be like, 'okay i got the actor 'Game.GetPlayer()' i'm going to call it 'bob' now and do stuff to it.

or course, the name you give the parameter in the function definition has to be the same as what you call it in the function body. I.E. this would not work:

Function VampireCorpseFeed(Actor Bob)    VampireFeedVictim.DoStuff()EndFunction

cause the function would not know who 'VampireFeedVictim' is, but if you did this:
Function VampireCorpseFeed(Actor Bob)    Bob.DoStuff()EndFunction

it would say 'right on' and do stuff.

Aaaannndd now i'm starting to anthropomorphize the scripting engine... yeah, it's bedtime for me :)
User avatar
Calum Campbell
 
Posts: 3574
Joined: Tue Jul 10, 2007 7:55 am

Post » Wed Jun 20, 2012 5:52 pm

this is your problem->
PlayerVampireQuest.VampireCorpseFeed(VampireFeedVictim as Actor)

Why are you passing 'VampireFeedVictim' ? like you mentioned that is just a property that doesn't autofill. The aktargetRef is what your are feeding on right? so that's what you want to mark as 'fed'. your script should look like this:

Game.GetPlayer().StartVampireFeed(aktargetRef as actor)PlayerVampireQuest.VampireFeed()PlayerVampireQuest.VampireCorpseFeed(aktargetRef as Actor)
Thank you for all your help, and the detailed description below, it really helped me. Yet the problem still persists. I am now just trying to play a magic shader on the corpse to tell me IF I am getting the victim passed to the vampire script properly or not, but now it won't compile. Here is my code:

Function VampireCorpseFeed(Actor VampireFeedVictim);MM this function will mark corpses as "have been eaten"    debug.messagebox("corpse has been fed on, trying to set has been eaten flag")    VampireFeedVictim.SetAV("Variable08",1.0)    ;Game.GetPlayer().StartCannibal(VampireFeedVictim);    VampireFeedVictim.PMS VampireFeedVictimShader 10EndFunction

BTW, I tried your code too, the StartCannibal line and it didn't do anything either. My other conditions work on my feed on corpse dialogue so I know I have that set up right. Not sure what the "has been eaten" flag is not working yet, or why I can't get a shader to play. Should I just make a spell to add to the victim instead, and add my effect to the spell? At this point I just want to successfully pass the actor through to my script.

Also, in one other perk I looked at, the werewolf feed perk it passes the actor through the scripts using some "as" command. Like so:

(PlayerWerewolfQuest as PlayerWerewolfChangeScript).Feed(akTargetRef as Actor)

What is happening here? It it telling it which script to use, if there are multiple scripts?
User avatar
Kay O'Hara
 
Posts: 3366
Joined: Sun Jan 14, 2007 8:04 pm

Post » Thu Jun 21, 2012 3:28 am

Have you tried manually reading the AV Variable08 and simply turning off/failing the feed routine if it's set?
User avatar
Bones47
 
Posts: 3399
Joined: Fri Nov 09, 2007 11:15 pm

Post » Wed Jun 20, 2012 8:26 pm

Have you tried manually reading the AV Variable08 and simply turning off/failing the feed routine if it's set?
How do you manually read an AV Variable?
User avatar
Daramis McGee
 
Posts: 3378
Joined: Mon Sep 03, 2007 10:47 am

Post » Wed Jun 20, 2012 9:06 pm

How do you manually read an AV Variable?

if NPCTargetCorpse.GetAV("Variable08") == 1.0   Debug.Notification("You have fed on this corpse already") ; Disallow feedingelse   NPCTargetCorpse.SetAV("Variable08",1.0)   ; Initiate Vampire Feed abilityendif
User avatar
WYatt REed
 
Posts: 3409
Joined: Mon Jun 18, 2007 3:06 pm

Post » Thu Jun 21, 2012 1:08 am

if NPCTargetCorpse.GetAV("Variable08") == 1.0   Debug.Notification("You have fed on this corpse already") ; Disallow feedingelse   NPCTargetCorpse.SetAV("Variable08",1.0)   ; Initiate Vampire Feed abilityendif
Is this assuming NPCTargetCorpse is an actor property fed into the function already?
User avatar
Eileen Müller
 
Posts: 3366
Joined: Fri Apr 13, 2007 9:06 am

Post » Wed Jun 20, 2012 6:37 pm

Is this assuming NPCTargetCorpse is an actor property fed into the function already?

Well in order to feed on an NPC, you need a reference to that NPC, right? Cast it as an Actor, and GetAV() and SetAV() should work just fine.
User avatar
Cathrine Jack
 
Posts: 3329
Joined: Sat Dec 02, 2006 1:29 am

Post » Wed Jun 20, 2012 9:42 pm

Well in order to feed on an NPC, you need a reference to that NPC, right? Cast it as an Actor, and GetAV() and SetAV() should work just fine.
I still think somehow I am not getting my actor passed through properly. I tried your code and it tests as 0 every time. The function doesn't need an actor to still go through the motions.

Here is my fragment:
;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment;NEXT FRAGMENT INDEX 10Scriptname PRKF__0100A98D Extends Perk Hidden;BEGIN FRAGMENT Fragment_0Function Fragment_0(ObjectReference akTargetRef, Actor akActor);BEGIN CODEGame.GetPlayer().StartVampireFeed(akTargetRef as actor)PlayerVampireQuest.VampireFeed()PlayerVampireQuest.VampireCorpseFeed(akTargetRef as Actor);END CODEEndFunction;END FRAGMENT;END FRAGMENT CODE - Do not edit anything between this and the begin commentPlayerVampireQuestScript Property PlayerVampireQuest  Auto  Actor Property VampireFeedVictim  Auto 

Here is my function:
Function VampireCorpseFeed(Actor VampireFeedVictim);MM this function will mark corpses as "have been eaten"    debug.messagebox("corpse has been fed on, trying to set has been eaten flag")    VampireFeedVictim.SetAV("Variable08",1.0)    ;Game.GetPlayer().StartCannibal(VampireFeedVictim);    ;VampireFeedVictim.PMS VampireFeedVictimShader 10    If VampireFeedVictim.GetAV("Variable08!"==1)        Debug.messagebox("setting variable to 1")        VampireFeedVictim.SetAV("Variable08",1.0)    else    Debug.messagebox("variable did not equale 1")endif
User avatar
Pat RiMsey
 
Posts: 3306
Joined: Fri Oct 19, 2007 1:22 am

Post » Thu Jun 21, 2012 1:39 am

Here is my function:
Bool Function AllowVampireCorpseFeed(Actor VampireFeedVictim);MM this function will mark corpses as "have been eaten"	debug.messagebox("corpse has been fed on, trying to set has been eaten flag")	;Game.GetPlayer().StartCannibal(VampireFeedVictim);	;VampireFeedVictim.PMS VampireFeedVictimShader 10	If VampireFeedVictim.GetAV("Variable08") !=1.0		Debug.messagebox("setting variable to 1.0")		VampireFeedVictim.SetAV("Variable08",1.0)	else	   Debug.messagebox("variable did not equal 1.0")endifEndFunction

Fixed. You had some serious typos in there. Like I don't know how that If statement got through with no compile errors...
If VampireFeedVictim.GetAV("Variable08!"==1)


Shouldn't even compile. You have the == condition inside the function call....and the ! for the != inside the quotes...I don't think there's an actor value called "Variable08!"
User avatar
James Baldwin
 
Posts: 3366
Joined: Tue Jun 05, 2007 11:11 am

Post » Wed Jun 20, 2012 1:42 pm

Fixed. You had some serious typos in there. Like I don't know how that If statement got through with no compile errors...
If VampireFeedVictim.GetAV("Variable08!"==1)


Shouldn't even compile. You have the == condition inside the function call....and the ! for the != inside the quotes...I don't think there's an actor value called "Variable08!"
Every single time it says "setting variable to 1" yet I can still feed, and it says it again and again, as if the variable is still 0. I am convinced that the actor is not properly passed through from the fragment to the other script. It's just calling the function without an actor assigned to it.
User avatar
Romy Welsch
 
Posts: 3329
Joined: Wed Apr 25, 2007 10:36 pm

Post » Thu Jun 21, 2012 1:55 am

Ok I might have figured out why I'm having so much trouble. For some reason my property VampireFeedVictim will not auto-fill.

EDIT: Hmmmm now I think that the actor is passing through to the other script, because I added code

VampireFeedVictim.Resurrect()

and the dead body came back to life, so my function DOES know what actor I am feeding on.

I completely removed theVampireFeedVictim property all together it doesn't seem to need it anyway.

So now I'm back to the drawing board for the most part. I need to figure out a way to mark each actor as fed on somehow. I guess I could maybe add a token to them and pray GetItemCount condition is still in there and working.
User avatar
Josh Dagreat
 
Posts: 3438
Joined: Fri Oct 19, 2007 3:07 am

Post » Wed Jun 20, 2012 4:37 pm

In your code to start your vampire feeding, use this:

if AllowFeed(Victim)   StartFeeding(Victim)endif

Then define this function:


Bool Function AllowFeed(Actor Victim) ; this function will mark corpses as "have been eaten" and return whether they were already marked.	String Msg = "Checking Corpse: ")	if !Victim		Debug.Messagebox(MSG+"No victim sent to function")	     Return False	endif	If Victim.GetAV("Variable08") != 1.0		Debug.MessageBox(MSG + "Victim has not been previously drained.")		Victim.SetAV("Variable08", 1.0)		return True	else		Debug.messagebox(MSG + "Victim Already drained.")		Return False	endifEndFunction

That really should work, unless something is preventing the AV from being set, or you're passing a "None" to the variable.
User avatar
N Only WhiTe girl
 
Posts: 3353
Joined: Mon Oct 30, 2006 2:30 pm

Post » Wed Jun 20, 2012 3:03 pm

Create a perk
Add Activation Choice
Label: Feed
Condition:
Player-HasKeyword ActorTypeVampire?
Target-IsDead AND GetAV Variable08 == 0 AND isActor
Script:
StartVampireFeed(akActor)? I guess? Maybe cannibal would be better? I don't know what these native functions do, probably starts the animation.
akActor.SetAV("Variable08", 1.0)

Done, can now feed on dead bodies. This way the Activation won't even show up if you cant feed on the body.
User avatar
amhain
 
Posts: 3506
Joined: Sun Jan 07, 2007 12:31 pm

Post » Thu Jun 21, 2012 4:46 am

Ok I finally got it! HasBeenEaten never worked as a condition. Not sure how the werewolf quest actually marks them as eaten, but the code is commented out where it sets Variable08 in the werewolfchangescript. And apparently HasBeenEaten is NOT variable 08. I simply changed the condition that allows feeding on corpses on my perk from HasBeenEaten == 0 to GetActorValue Variable08 !=1 and it works perfect!

Thanks everyone for your help!
User avatar
casey macmillan
 
Posts: 3474
Joined: Fri Feb 09, 2007 7:37 pm


Return to V - Skyrim