Can't seem to make HasKeyword actually check for my Keyword

Post » Thu Jun 21, 2012 9:55 pm

Hi gang,

As usual, I've been wracking my meager brains for longer than I should have, trying valiantly to not have to come begging for the kindly help of generous strangers, but I'm finally ready to give up on this one and hope that someone here can show me what I missed.

The script below is attached to several miscobjects, the idea being that when those objects are hit by a certain spell projectile, they delete themselves and spawn the appropriate critter in their place. Up until now, I've accomplished this by having a separate script for each type of item/critter, but that was inelegant (to say the least) and a real pain to update since I would have to make changes to all of them individually. The idea here is to have one master script for all of the items that will use a conditional to figure which one just got hit so that the correct critter can be spawned.

I decided that HasKeyword would be a pretty straight forward way to ID these, so I came up with this:

Spoiler

Scriptname PDAMActivationMASTERScript extends ObjectReference{Master script for activating inert automata};**This section allows for activation of inert automatons**;These are keywords used by the script to identify the inert unitsKeyword Property PDAMSpiderWarriorKW autoKeyword Property PDAMSpiderTrainerKW autoKeyword Property PDAMSpiderStealthKW autoKeyword Property PDAMSpiderDroneKW autoKeyword Property PDAMSpiderArcaneKW autoKeyword Property PDAMSphereWarriorKW autoKeyword Property PDAMSphereStealthKW autoKeyword Property PDAMSphereGuardianKW autoKeyword Property PDAMSphereArcherKW autoKeyword Property PDAMCenturionKW auto;These properties represent the active units to be spawnedActorBase Property PDAMCenturion  AutoActorBase Property PDAMSpiderArcane AutoActorBase Property PDAMSpiderTrainer  AutoActorBase Property PDAMSpiderDrone  AutoActorBase Property PDAMSpiderStealth  AutoActorBase Property PDAMSpiderWarrior  AutoActorBase Property PDAMSphereArcher  AutoActorBase Property PDAMSphereGuardian  AutoActorBase Property PDAMSphereStealth  AutoActorBase Property PDAMSphereWarrior  Auto;Projectile for the control rod hit detection and target IDProjectile  Property PDAMActivationBolt Autoauto STATE ActivatingEvent OnHit (ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)  If akProjectile == PDAMActivationBolt   If Self.HasKeyword(PDAMCenturionKW)	Self.PlaceActorAtMe(PDAMCenturion)	;spawns inert	Debug.Notification("Centurion Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSpiderArcaneKW) == true	Self.PlaceActorAtMe(PDAMSpiderArcane)	;spawns inert	Debug.Notification("Dynamo Spider Activated!")   ElseIf (Self as Form).HasKeyword(PDAMSpiderTrainerKW ) == true	Self.PlaceActorAtMe(PDAMSpiderTrainer)	;spawns inert	Debug.Notification("Training Spider Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSpiderDroneKW) == true	Self.PlaceActorAtMe(PDAMSpiderDrone)	;spawns inert	Debug.Notification("Spider Drone Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSpiderStealthKW) == true	self.PlaceActorAtMe(PDAMSpiderStealth)	;spawns inert	Debug.Notification("Spider Assassin Activated!")   ElseIf (Self as Form).HasKeyword(PDAMSpiderWarriorKW) == true	self.PlaceActorAtMe(PDAMSpiderWarrior)	;spawns inert	Debug.Notification("Spider Warrior Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSphereArcherKW ) == true	self.PlaceActorAtMe(PDAMSphereArcher)	;spawns inert	Debug.Notification("Sphere Archer Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSphereGuardianKW) == true	self.PlaceActorAtMe(PDAMSphereGuardian)   ;spawns inert	Debug.Notification("Sphere Guardian Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSphereStealthKW ) == true	self.PlaceActorAtMe(PDAMSphereStealth)   ;spawns inert	Debug.Notification("Sphere Assassin Activated!")   ElseIf (Self as Form).HasKeyWord(PDAMSphereWarriorKW) == true	self.PlaceActorAtMe(PDAMSphereWarrior)   ;spawns inert	Debug.Notification("Sphere Warrior Activated!")   EndIf   Self.Delete()		   ;deletes friendly   GoToState("Done")  EndIfEndEventEndStateSTATE Done;Do nothingEndState

Except that it isn't running the part that looks for the keywords, it just deletes the item and nothing else. I've tried writing things out several ways (as you can see by the inconsistencies and unnecessary formalities), all of my variables are assigned in CK and the script compiles without error. I just can't figure out what the heck I'm missing. I've looked up different scripts and threads that use HasKeyword, and I don't see anything wrong with my syntax. As always, I have a suspicion that answer is blazingly obvious, and I'm just still too green at this scripting business to see it staring me in the face.

Anyone have an ideas? Pretty please? :biggrin: I'd be extremely grateful for any guidance or advice.
User avatar
Eliza Potter
 
Posts: 3481
Joined: Mon Mar 05, 2007 3:20 am

Post » Thu Jun 21, 2012 1:58 pm

since you didnt specify, i have to ask: did you put all of the corresponding keywords on your MiscItem base object?


for example, whatever item this script is attached to should have the keyword PDAMCenturionKW in the base object.

then the following code:

If (GetBaseObject().HasKeyword(PDAMCenturionKW))

will return true.


if you didn't put the keywords into the base objects of your MiscItems, then it will skip the entire condition stack since none of those can return true, and only execute the bottom part where it deletes itself and switches to an inert state.
User avatar
Annika Marziniak
 
Posts: 3416
Joined: Wed Apr 18, 2007 6:22 am

Post » Thu Jun 21, 2012 6:50 pm

Hi Amethyst, thanks for the reply!

I should have specified, but yes, each of the miscobjects has the appropriate keyword attached to it. I haven't, however, used GetBaseObject() before in any of my scripting experiments. Is that meaningfully different than calling "Self"? I'll give it a shot and see what happens, either way. :smile:

EDIT: Okay, no. GetBaseObject doesn't make a difference in this case. Still no love. :( Thanks for the ideas, though!
User avatar
kiss my weasel
 
Posts: 3221
Joined: Tue Feb 20, 2007 9:08 am

Post » Thu Jun 21, 2012 7:58 pm

self will call the function as an objectreference (because your script extends objectrefernce script)

getbaseobject() will return your objectreference's base object as a form. HasKeyword() is native to the form script, so this is an ideal way to query for keywords.

even if self.haskeyword() compiles, it is better to query haskeyword against its base object using GetBaseObject().
User avatar
Susan Elizabeth
 
Posts: 3420
Joined: Sat Oct 21, 2006 4:35 pm

Post » Thu Jun 21, 2012 6:37 pm

Interesting... thanks for that, I'll keep it in mind for the future.

For some reason I'm still not getting any action in the conditional section of the script

I'd be grateful for any other ideas anyone might have! :D
User avatar
lauren cleaves
 
Posts: 3307
Joined: Tue Aug 15, 2006 8:35 am

Post » Thu Jun 21, 2012 9:48 pm

this might not make a lick of difference, but I always wrap my if conditions in parenthesis ()
so try
ElseIf ((Self as Form).HasKeyWord(PDAMSphereWarriorKW) == true)

instead of:

ElseIf (Self as Form).HasKeyWord(PDAMSphereWarriorKW) == true
User avatar
mimi_lys
 
Posts: 3514
Joined: Mon Apr 09, 2007 11:17 am

Post » Thu Jun 21, 2012 7:24 pm

Thanks, JediBorg - I've seen that used in other scripts, so I tried it out just for fun, but it didn't make a difference for me.

I'm just completely mystified by this problem. I know I have a lot to learn, but I just can't see any reason for this script to fail like this.
User avatar
Robert DeLarosa
 
Posts: 3415
Joined: Tue Sep 04, 2007 3:43 pm

Post » Thu Jun 21, 2012 10:56 am

i just did a quick test in the CK.

i made a miscItem with keyword Test in the keyword box and attached the following script:

Scriptname AAtest extends ObjectReferenceKeyword Property Test AutoActorBase Property TestActor autoProjectile Property TestAmmo autoEvent OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)If (akProjectile == TestAmmo)  If (GetBaseObject().HasKeyword(Test))   PlaceActorAtMe(TestActor)  EndIf  Delete()EndIfEndEvent


placed the test object in game and shot my projectile at it.

the item disappeared and my test actor appeared



the script works fine. i would double check your properties and objects in the editor, then triple check them
User avatar
Theodore Walling
 
Posts: 3420
Joined: Sat Jun 02, 2007 12:48 pm

Post » Thu Jun 21, 2012 10:50 pm

Okay, now I'm even more mystified, but extremely happy, because everything seems to be working now! I triple-checked EVERYTHING all over again, saw nothing that needed correcting, tested, failed, then decided on a whim to try a clean save and hey-presto everything is wine and roses. 0_o double you tee eff . . . .

Anyway, thanks for indulging me Amethyst (and thanks for the Black Tower mod - huge fan of yours!) - I'll be proud to add your name to the (ever-growing) list of experts who've helped me out while developing this mod. :D
User avatar
Kat Ives
 
Posts: 3408
Joined: Tue Aug 28, 2007 2:11 pm

Post » Thu Jun 21, 2012 10:29 am

oh yeah, you should always test your mod with a clean save first (or use COC from the main menu without loading a save) in addition to testing existing save games (but never test a save game that has old versions of your current stuff embedded into it)

anyways glad it worked out :thumbsup:
User avatar
Mistress trades Melissa
 
Posts: 3464
Joined: Mon Jun 19, 2006 9:28 pm


Return to V - Skyrim