Need help acquiring target data

Post » Fri May 13, 2011 4:18 pm

I am trying to create a simple AP ammo effect by testing targets for equipped armor and upping the damage if they are wearing power armor. I have the following code block, but it does not work. I am just learning how to use reference variables and form lists. Is there something obvious I missed (beside trying to send a reference variable to a message object)?

	IF AmmoMode == 2 									; If AP ammo loaded		Set Target to GetCrosshairRef		IF Target		ELSE			set Target to player.GetCombatTarget		EndIF		Set Armor to Target.GetEquippedObject 2		IF ListGetFormIndex RepairPowerArmor Armor != -1			setAttackDamage 120 								setweaponCritDamage 180							setweaponCritChance 8 								showmessage xCalArmoredFoe Target				;Debug Message		Else			setAttackDamage 60 								setweaponCritDamage 90							setweaponCritChance 4 							EndIF	EndIF

User avatar
Invasion's
 
Posts: 3546
Joined: Fri Aug 18, 2006 6:09 pm

Post » Fri May 13, 2011 2:47 pm

Two things that came to mind:
1. Make sure that calling the functions for changing the damage by reference is correct in this context
2. I don't think getCrosshairRef/getCombatTarget will work as intented here. You should check if they really return any value for targets that arent directly in front of the player
User avatar
victoria johnstone
 
Posts: 3424
Joined: Sat Oct 14, 2006 9:56 am

Post » Fri May 13, 2011 10:22 am

The code snippet is part of a GameMode block attached to a weapon script, so the damage functions work fine without specific reference.

It is my understanding that the getCrosshairRef/getCombatTarget commands return a base form that can be stored as a reference variable. But as I said, my understanding is a little shaky and the code does not work. Do you have any ideas how I might achieve the results I am seeking?
User avatar
Doniesha World
 
Posts: 3437
Joined: Sun Jan 07, 2007 5:12 pm

Post » Fri May 13, 2011 3:02 pm

getCrosshairRef returns a reference when you're close enough to something to activate it, so unless for melee combat this won't do. I once tried getCombatTarget and it didn't really return anything, and according to the wiki it would return the reference currently targeted via autoaim. I disabled autoaim right before I first started playing fo3, so I don't really know if this function would work, but surely I'm not the only one with autoaim disabled.

I can think of two approaches:
One would be to temporarily set some auto aim variables very high, then use getCombatTarget, then directly set them back. Maybe this works fast enough to get the reference while still not affecting aim.

Other than that, do you know the midas magic mod for oblivion? What's used there is a ray mesh thats positioned and "locked" in front of the player. So this ray extends from the player towards it's looking direction (it's position is constantly updated). The current target is determined by collision detection with this ray. Pretty complicated though. Maybe there's any easier way, I haven't really looked into it further.
User avatar
Claudia Cook
 
Posts: 3450
Joined: Mon Oct 30, 2006 10:22 am

Post » Fri May 13, 2011 3:46 pm

umm.

I think what you mean is more like..... this. Maybe.

create a base effect - - archetype: script
create an object effect
put your base effect into your object effect
put your object effect onto your weapon

your script would be something like this - -

put EFFECT into the dropdown box on the top right of the script editor.

ref targetbegin scripteffectstartset target to getselfif target.getequipped (big badass power armor)     target.damageav health (some amount)endifend


For an in-game example, check the behemoth fire hydrant weapon and its ENCH effect thingie.
User avatar
Katey Meyer
 
Posts: 3464
Joined: Sat Dec 30, 2006 10:14 pm

Post » Fri May 13, 2011 7:52 am

For an in-game example, check the behemoth fire hydrant weapon and its ENCH effect thingie.

Definately, also check the Gauss rifle effect for another example..
ref mySelfBEGIN ScriptEffectStart		set mySelf to getSelf		player.pushActorAway mySelf 10END

Can easily fit the check for power armor in there with added damage if true.
User avatar
Marcus Jordan
 
Posts: 3474
Joined: Fri Jun 29, 2007 1:16 am

Post » Fri May 13, 2011 11:40 am

OK, I'm going to have to do some more cribbing before I can wrap my head around effects and reference functions. It is not entirely clear to me how "Set Target to GetSelf" will reference an enemy in the crosshairs, but I have never examined effects attached to weapons. I suppose the reference would be to whatever the weapon is firing on.

Would the target reference returned by GetSelf be in a form I can subject to the following logic?

Set Armor to Target.GetEquippedObject 2
IF ListGetFormIndex RepairPowerArmor Armor != -1
User avatar
Antony Holdsworth
 
Posts: 3387
Joined: Tue May 29, 2007 4:50 am

Post » Fri May 13, 2011 5:47 am

OK, I'm going to have to do some more cribbing before I can wrap my head around effects and reference functions. It is not entirely clear to me how "Set Target to GetSelf" will reference an enemy in the crosshairs, but I have never examined effects attached to weapons. I suppose the reference would be to whatever the weapon is firing on.

Would the target reference returned by GetSelf be in a form I can subject to the following logic?

Set Armor to Target.GetEquippedObject 2
IF ListGetFormIndex RepairPowerArmor Armor != -1


Yes, but if you are going to use FOSE, you don't need a list. just use something like this:

http://fose.silverlock.org/fose_command_doc.html#IsPowerArmor

Set Armor to Target.GetEquippedObject 2set iPAFlag to IsPowerArmor Armorif (iPAFlag)     do stuff

User avatar
Chloe Botham
 
Posts: 3537
Joined: Wed Aug 30, 2006 12:11 am

Post » Fri May 13, 2011 10:33 am

OK, I'm going to have to do some more cribbing before I can wrap my head around effects and reference functions. It is not entirely clear to me how "Set Target to GetSelf" will reference an enemy in the crosshairs, but I have never examined effects attached to weapons. I suppose the reference would be to whatever the weapon is firing on.

Would the target reference returned by GetSelf be in a form I can subject to the following logic?

Set Armor to Target.GetEquippedObject 2
IF ListGetFormIndex RepairPowerArmor Armor != -1


it does not reference the weapon's aim or the crosshairs, it references whatever the weapon hit.

Think of it this way. The weapon fires, and it hits the target. Because the weapon has an "object effect' assigned to it, it causes the victim to cast a spell on himself. That 'spell' is whatever lives in that effect of yours. So, "set Target to GetSelf" works to grab the ref of the victim.

The best I can suggest is, really, examining Bethesda's existing examples, it becomes much clearer, then.

edit: I would try it this way, customized for whatever other things you needed to check, etc -

set target to getselfif target.getequipped YourFormListWithPowerArmor     target.damageav health SomeValueendif


Fose is overkill for this IMO. It's hard for me to picture FOSE brought in to replace lightweight stuff like checking a single, short formlist.
User avatar
Jesus Sanchez
 
Posts: 3455
Joined: Sun Oct 21, 2007 11:15 am

Post » Fri May 13, 2011 9:17 pm

Thanks Tarrant, that makes sense. I'll have to examine the vanilla examples and play around a bit.

One question pops to mind though. Is ti possible to control an effect so that it only works once per victim rather than stacking per hit, or would the answer to that question be directly related to the effect in question?
User avatar
Damned_Queen
 
Posts: 3425
Joined: Fri Apr 20, 2007 5:18 pm

Post » Fri May 13, 2011 8:16 am

Thanks Tarrant, that makes sense. I'll have to examine the vanilla examples and play around a bit.

One question pops to mind though. Is ti possible to control an effect so that it only works once per victim rather than stacking per hit, or would the answer to that question be directly related to the effect in question?

If the intent is just to neutralize the advantage of the target wearing power armor, then damaging him an extra 50 or whatever per hit would do that. I'm unsure why a once per unique target would be needed, but I'd guess it's possible... To get it right though I'd think it would involve adding the target ref to a list, then comparing each new target (every shot even) to that list before applying damage. Doesn't seem very practical though, or efficient.

@Tarrant - very good explanantion of effects/enchantments
User avatar
Matt Fletcher
 
Posts: 3355
Joined: Mon Sep 24, 2007 3:48 am

Post » Fri May 13, 2011 4:51 pm

Thanks Tarrant, that makes sense. I'll have to examine the vanilla examples and play around a bit.

One question pops to mind though. Is ti possible to control an effect so that it only works once per victim rather than stacking per hit, or would the answer to that question be directly related to the effect in question?


It may be possible to do this but I have not tried it with an object effect, I have only done it with actor effects. It's getting a bit convoluted if you're new to actor effects and so on, I think.

I have a quest script which is running every 3 seconds,and it is tracking follower targets and causes the follower's combat target to cast a spell on itself one time. An example block of code in my quest script looks like this:

			if ButchTarget.IsSpellTarget aaKillcountSpell == 0				ButchTarget.CIOS aaKillcountSpell			endif


The part where it checks for "Follower.IsSpellTarget " seems to be helping to prevent aaKillcountSpell from being run more than one time on the target.

That actor effect has a 5 second "duration" and is a script effect, and the script is entirely in a ScriptEffectUpdate block. This is the script it runs, it is a modified version of a modders resource btw.

short killcountshort xpgainshort levelBEGIN ScriptEffectUpdateif(level)	returnelseif(getdead)	if(getitemcount PhalanxKillToken)		set level to 1		return	endif	set killcount to GetPCMS "Creatures Killed" + GetPCMS "People Killed"	if(killcount <= PhalanxKillQuest.killcount)		set PhalanxKillQuest.killcount to killcount		set level to getlevel		additem PhalanxKillToken 1		if(getiscreature)		else			if(player.hasperk contractkiller)                if(Getav karma >= getgs fAlignGoodMinKarma)                    additem Ear 1                endif                    elseif(player.hasperk lawbringer)                if(Getav karma <= getgs fAlignEvilMaxKarma)                    additem Finger 1                endif                endif		endif		else		set level to getlevel	endifendifend


The killcount token seems to do nothing in itself btw.

If you wanted to try this, I suspect that you would put a much longer duration than 5 seconds on your effect, and, it would not be waiting until the target died to do something. You might want to dispel the effect upon death, in fact.
User avatar
Stephy Beck
 
Posts: 3492
Joined: Mon Apr 16, 2007 12:33 pm

Post » Fri May 13, 2011 5:19 pm

A further note -

See how this is a scripteffectupdate block, and, it starts with this?

BEGIN ScriptEffectUpdateif(level)	return


Scripteffectupdate blocks try to run over and over and over again. They run a couple times in the very first rendered frame they are "cast" and then run once per frame from them on. it's just what they do, they aren't like "scripteffectstart" which only runs once per effect. So, whenever you use a ScriptEffectUpdate block, you have to build your own "Hey I already did my thing, don't do it again" sort of code into it, if that's the function you really need.

I have been finding ScriptEffectUpdate to be very powerful because you can, in effect, build looping code into them, and pretty much no other script form lets you do that. Like

short countbegin scripteffectstart     set count to 1endbegin scripteffectupdate          if count > 10          dispel MyEffect           return     elseif count          set count to count + 1          ; do stuff     endifend


Because of the way scripteffectupdate blocks keep repeating their execution, that code will repeat the ";do stuff" segment of code over a number of frames, until the counter you set up is higher than 10. But you have to really watch the counter to prevent extra runs of the code. Pretend that "dispel" might not make the script effect end right away, and keep the variables in a state where they will continue to deny your finished-block of code after you call that dispel.
User avatar
JeSsy ArEllano
 
Posts: 3369
Joined: Fri Oct 20, 2006 10:51 am

Post » Fri May 13, 2011 5:00 am

My thoughts regarding a "one-time per customer" effect script are based on a desire to use the effect to lower a target's DR. I realize this approach is problematic as the projectile damage is probably calculated without regard to the script effect. Based on the great advice here, I think I'm better off just adding a damage hit and call it a day.

I think that if I can detach my thought process from the bullets, then I should be able to build the effect I want with the ideas presented here.

Thanks for all the input.

PS. RickerHK - I never seem to notice FOSE commands until after I have tried to achieve the same effect by beating my head against a wall. Thanks for the tip.
User avatar
Roberta Obrien
 
Posts: 3499
Joined: Tue Oct 23, 2007 1:43 pm

Post » Fri May 13, 2011 4:51 pm

My thoughts regarding a "one-time per customer" effect script are based on a desire to use the effect to lower a target's DR.


If I were you I would think in more of a macro-sense than this. Specifically, lowering the target's DR, may be a complicated thing to do, but the macro-effect you really want is for the power-armor-wearing target to be taking more damage than he would otherwise. Simply doing that may have the final effect and be much less of a pain in the ass to deal with than trying to spot-create a DR-lowering effect.

I don't even know if you can lower an NPC target's DR via script reliably. Maybe you can, I don't know? But I know you can inflict some extra damage (perhaps mimicing armor-piercing) based upon a conditional (equipped power armor).

In any case if the one does not work, the other options which in effect create what you need are there.
User avatar
Ash
 
Posts: 3392
Joined: Tue Jun 13, 2006 8:59 am

Post » Fri May 13, 2011 2:53 pm

Yah, I pretty much ended up in the same place. Thanks again for the insights and widening my FOV as it were.
User avatar
Joey Bel
 
Posts: 3487
Joined: Sun Jan 07, 2007 9:44 am

Post » Fri May 13, 2011 7:24 pm

Lots of good info here, thanks everyone for sharing.

I had a few thoughts on this and I was wondering if someone could tell me just how far off base I am. I was playing with creating AP ammo by use of a perk that doubles/triples the damage done to targets whose GetArmorAR >= 25, for example. This works but doesn't do all I had hoped. So here is what I'm thinking now. Because the damage being done is weapon specific, formlists can be used to check for damage type (Ballistic, Plasma, Fire...) formlists can also be used to determine the armor type of the target (Metal, Leather, Kevlar, mutated skin...) These two factors can be assigned variables. Use GetAttackDamage to find the base damage of the PCs currently equipped weapon and Target.GetArmorAR gets the Targets armor stats. (would GetHealthPercent Target.GetEquippedObject 2 return the target armors health percent?) Then using SetAttackDamage to (100/(100-TargetAR))*PlayerWeaponBaseDamage would boost weapon damage enough that the amount negated by the armor, no matter what that amount is, would make the damge done to the target the same as the base damage. At this point Damage Type and Armor Type can be calculated as modifiers so leather armor can protect against fire better than metal armor, but vise versa for laser damage. The ultimate goal, for me at least, is to achive an armor rating system similar to the original Fallout armor system, but with the added factor of armor degradation.
User avatar
Jonathan Egan
 
Posts: 3432
Joined: Fri Jun 22, 2007 3:27 pm

Post » Fri May 13, 2011 9:01 am

Great information Tarrant! :goodjob:

This belongs on the WIKI or in a tutorial somewhere!

Cheers,

Miax
User avatar
Ronald
 
Posts: 3319
Joined: Sun Aug 05, 2007 12:16 am

Post » Fri May 13, 2011 8:45 pm

Lots of good info here, thanks everyone for sharing.

(would GetHealthPercent Target.GetEquippedObject 2 return the target armors health percent?)


The FOSE function for GetHealth doesn't return a percentage - it returns the health value programmed in the item. To get the current condition of the armor as a percentage, i've done it like this:

     set rTargetArmor to Target.GetEquippedObject 2     set iArmorBaseHealth to GetBaseHealth rTargetArmor     set fArmorHealth to Target.GetEquippedCurrentHealth 2     set fArmorHealthPerc to (fArmorHealth / iArmorBaseHealth) * 100

User avatar
Jessica Thomson
 
Posts: 3337
Joined: Fri Jul 21, 2006 5:10 am


Return to Fallout 3