Realisic Kill Reactions

Post » Sat Nov 06, 2010 6:12 am

This sounds similar to a bug in http://geck.gamesas.com/index.php/AddItem that was found in Reneer's http://www.fallout3nexus.com/downloads/file.php?id=3628 mod. If I remember correctly, it could be fixed by adding the following to your token script:
ref rContainerBegin OnAdd	set rContainer to GetContainer	rContainer.AddItem Pencil01 1 1	rContainer.RemoveItem Pencil01 1 1End

Cipscis
User avatar
Andy durkan
 
Posts: 3459
Joined: Fri Aug 03, 2007 3:05 pm

Post » Sat Nov 06, 2010 10:45 am

This sounds similar to a bug in AddItem that was found in Reneer's http://www.fallout3nexus.com/downloads/file.php?id=3628 mod. If I remember correctly, it could be fixed by adding the following to your token script:
ref rContainerBegin OnAdd	set rContainer to GetContainer	rContainer.AddItem Pencil01 1 1	rContainer.RemoveItem Pencil01 1 1End

Cipscis


Wow - didn't know that!

Should I use this in any case where I pass an NPC the scripted-token?

Thanks!!

Miax
User avatar
joeK
 
Posts: 3370
Joined: Tue Jul 10, 2007 10:22 am

Post » Sat Nov 06, 2010 3:15 am

Ok, I did a bit of testing and the bug actually has nothing to do with the detection event, it's even still there when the respective line is commented out. The problem is the token, when adding it, it seems that sometimes the actors weapon selection gets messed up. When saving/loading, the actor resets and it works again, and when removing the token and adding a different one you can actually see pretty nicely that there's something not right because this causes every actor to randomly switch weapons.

...


I made a new version that uses lists instead and only adds the token once the actor is dead. I think this is better than the first approach anyway.

So additionally needed are 2 empty form lists RKRDetectionListA and RKRDetectionListB.


Okay, I think I followed all of that :)

When I get a chance I'll add these an and upload a test patch here and we'll see how it goes.

Thanks!
User avatar
Camden Unglesbee
 
Posts: 3467
Joined: Wed Aug 15, 2007 8:30 am

Post » Sat Nov 06, 2010 4:33 pm

Tested things out and posted an update to the nexus. The scripts work really well. I enabled the print-to-console lines again, just in case people want to see what's going on as we test some more.
User avatar
Kirsty Wood
 
Posts: 3461
Joined: Tue Aug 15, 2006 10:41 am

Post » Sat Nov 06, 2010 8:27 am

Well . . . I got the update posted, and tested a bunch in outdoor and indoor situations (springvale is always a nice place to abuse raiders).

Everything is working correctly now in my testing and is really a big improvement. However, the entire mod does raise another question/issue:

Now that detection events are always generated when an actor is killed by the player, there are times when perhaps you 'don't' want a detection event to go off. For example, if someone is asleep, and I one-shot them in the head with a silent weapon, everyone who is nearby will come storming into the room, when it should have been a 'safe' kill.

In looking at the oblivion equivolent, the description suggests that there is a system for communication between the various actors in the cell, so the detection event isn't actually created unless there is Line-of-sight (LOS) (or positive detection state) between the dead guy and another living actor. Would it be possible to add anything to this without a huge processing overhead?

Basically, I wonder if a condition can be added in the token script to only run the CreateDetectionEvent line IF the calling actor (guy who just died) is detected by another actor in the formlist's we setup. Any insight on this?

Also, I didn't think of it until now, but I wonder if we can change the lines that identify the "player" as the killer to recognize anyone in the "player" faction. That way, if you have a companion with a silenced rifle, the detection event would be generated even if they took the killing shot.

Cheers!
User avatar
Jamie Moysey
 
Posts: 3452
Joined: Sun May 13, 2007 6:31 am

Post » Sat Nov 06, 2010 11:47 am

Should I use this in any case where I pass an NPC the scripted-token?
It's been a long time since I tested this bug, and I don't remember if I ever figured out what situation(s) it occurred in. It appears to be fairly consistent though - it should either happen all the time or none of the time with a certain implementation.

If you don't notice the bug in testing, then you shouldn't need to implement the fix.

Cipscis
User avatar
Leah
 
Posts: 3358
Joined: Wed Nov 01, 2006 3:11 pm

Post » Sat Nov 06, 2010 5:39 pm

Well . . . I got the update posted, and tested a bunch in outdoor and indoor situations (springvale is always a nice place to abuse raiders).

Everything is working correctly now in my testing and is really a big improvement. However, the entire mod does raise another question/issue:

Now that detection events are always generated when an actor is killed by the player, there are times when perhaps you 'don't' want a detection event to go off. For example, if someone is asleep, and I one-shot them in the head with a silent weapon, everyone who is nearby will come storming into the room, when it should have been a 'safe' kill.

In looking at the oblivion equivolent, the description suggests that there is a system for communication between the various actors in the cell, so the detection event isn't actually created unless there is Line-of-sight (LOS) (or positive detection state) between the dead guy and another living actor. Would it be possible to add anything to this without a huge processing overhead?

Basically, I wonder if a condition can be added in the token script to only run the CreateDetectionEvent line IF the calling actor (guy who just died) is detected by another actor in the formlist's we setup. Any insight on this?

Also, I didn't think of it until now, but I wonder if we can change the lines that identify the "player" as the killer to recognize anyone in the "player" faction. That way, if you have a companion with a silenced rifle, the detection event would be generated even if they took the killing shot.

Cheers!

I'm not worrying about any processing overhead, if done carefully I don't think this will be an issue. So before adding any new features I'll try to implement some kind of simple FIFO scheduling to limit the number of concurrent executions. Unfortunately I just got a starcraft 2 beta key so I've been playing that a lot during the last few days
User avatar
Katharine Newton
 
Posts: 3318
Joined: Tue Jun 13, 2006 12:33 pm

Post » Sat Nov 06, 2010 8:57 am

I'm not worrying about any processing overhead, if done carefully I don't think this will be an issue. So before adding any new features I'll try to implement some kind of simple FIFO scheduling to limit the number of concurrent executions. Unfortunately I just got a starcraft 2 beta key so I've been playing that a lot during the last few days


Alright . . . let me know if you have any ideas.

I did some testing on the conditions end of things. GetLoS doesn't work once the actor is dead, it always reports a "X can't see Y" in the console. However, the GetDetected function works correctly. we could add this stuff into the script:

global RKRdetectlevel ; configurable global, defaults to zero
global RKRdetectdist ; configurable global, defaults to 2000 units

IN THE TOKEN SCRIPS

short detectval
short ddist

set detectval to ( AliveActorX.getdetected DeadActorY)
set ddist to ( AliveActorX.getdistance DeadActorY)

if ( detectval >= RKRdetectlevel ) && ( ddist <= RKRdetectdist )
actor.createDetectionEvent player 100
endif


Now, what I have no idea how to implement is the system for cycling through all the potential AliveActorX's in the cell and checking the detection level for each of them to the DeadActor. Any thoughts on this?

EDIT: I have another thought. This might involve needing to go back to adding tokens to everyone . . . but one of the issues with how things are now is that when the detection event is triggered, all the actors "rush" to where the killed actor is, which if you think about it doesn't make a whole lot of sense, as the AI basically "runs" into an ambush situation.

What if we change it around so that detection events are generated at the "AliveActors" who detect the killed actor. That way, the "detecting" actors will immediately start searching for the player (since they are already at the detection event location) and it would simulate the alive actors "calling out" other alive guys in the vicinity, who would rush towards their alive friends and start searching rather, rather than foolishly running to the corpse.
User avatar
Cameron Wood
 
Posts: 3384
Joined: Wed Oct 31, 2007 3:01 pm

Post » Sat Nov 06, 2010 10:03 am

Anyone have any thoughts or ideas about how I could implement the rolling LoS/Detection check between the dead actor and others in the cell?
User avatar
Connor Wing
 
Posts: 3465
Joined: Wed Jun 20, 2007 1:22 am

Post » Sat Nov 06, 2010 3:51 am

You could try using a null explosion (with "Ignore LOS Check" unchecked), with a script effect enchantment attached. That's how I tried to trigger the appropriate trespass and assault alarms (with http://geck.gamesas.com/index.php/SendTrespassAlarm and http://geck.gamesas.com/index.php/SendAssaultAlarm) for the Explosive Breach feature in FOOK2. It had some success, but wasn't perfect - it might be worth another look though. Trespass and assault alarms might be useful for your purpose as well.

http://geck.gamesas.com/index.php/Category:Detection is quite a beast, as I'm sure you already realize ;)
User avatar
jason worrell
 
Posts: 3345
Joined: Sat May 19, 2007 12:26 am

Post » Sat Nov 06, 2010 2:48 pm

Anyone have any thoughts or ideas about how I could implement the rolling LoS/Detection check between the dead actor and others in the cell?

Well if anything else fails you could always just use math :)

For every non-dead actor
1. get distance (if too far away directly continue with the the next one)
2. get vector u for the looking direction of the actor (cos actor.angle, sin actor.angle)
3. get vector v for the direction between actor and body (body.x - actor.x, body.y - actor.y)
4. calculate the angle between the u and v: (u.x * v.x + u.y * v.y) / [ sqrt(u.x² + u.y²) * sqrt(v.x² + v.y²) ]

(Better check this again :))

If angle is < then lets say 90 then trigger a detection event.

(Edit: Further thinking)
Then, in the first iteration of the token script this thing with the invisible explosion that causes actors to run for cover could be done (only if any are in LOS of course). So this means anyone who actually witnessed the kill will run for cover. Then for further iterations, the normal detection event creation is used. So you see someone getting shot = you run for cover. You see a dead buddy lying around = you go there and check whats wrong with him
User avatar
Laura-Lee Gerwing
 
Posts: 3363
Joined: Fri Jan 12, 2007 12:46 am

Post » Sat Nov 06, 2010 9:03 am

I'm not worried about the checks for LoS or detection, I can probably figure that part out. What I don't know is how to determine what the "alive" actor references are in order to actually run the calculation. For example, the main quest script stores all the actor ref's in the formlists that were created (right?). How can I then go "through" this formlist and actually check for detection? Does that make sense?
User avatar
Kara Payne
 
Posts: 3415
Joined: Thu Oct 26, 2006 12:47 am

Post » Sat Nov 06, 2010 11:04 am

set iCount to ListGetCount SomeFormListset iIndex to 0Label 1if iIndex < iCount	set rListItem to ListGetNthForm SomeFormList iIndex	; do stuff with rListItem	set iIndex to iIndex + 1	Goto 1endif

Is that what you're looking for?
User avatar
CRuzIta LUVz grlz
 
Posts: 3388
Joined: Fri Aug 24, 2007 11:44 am

Post » Sat Nov 06, 2010 3:42 am

You could try using a null explosion (with "Ignore LOS Check" unchecked), with a script effect enchantment attached.
Unfortunately, this method is actually very slow (http://www.gamesas.com/index.php?/topic/987561-script-optimisation/page__view__findpost__p__14295479). It'd be more efficient to walk through each actor reference and call http://geck.gamesas.com/index.php/GetDistance and possibly http://geck.gamesas.com/index.php/GetLineOfSight on each one. http://geck.gamesas.com/index.php/GetHeadingAngle can be used as well to check if the actor is facing the body.

Cipscis
User avatar
James Baldwin
 
Posts: 3366
Joined: Tue Jun 05, 2007 11:11 am

Post » Sat Nov 06, 2010 11:24 am

Unfortunately, this method is actually very slow (http://www.gamesas.com/index.php?/topic/987561-script-optimisation/page__view__findpost__p__14295479). It'd be more efficient to walk through each actor reference and call http://geck.gamesas.com/index.php/GetDistance and possibly http://geck.gamesas.com/index.php/GetLineOfSight on each one. http://geck.gamesas.com/index.php/GetHeadingAngle can be used as well to check if the actor is facing the body.

Cipscis

Very interesting. Did you happen to run that test with no script effect on the explosion, but just having it do some damage? I'm thinking that it might not be the application of the script effect that slows things down, but all the calculations and checks the engine needs to do to see if the explosion "hit" a particular actor. If that turns out to be the case, it might not be much more efficient to do a ref walk then run GetDistance and GetLOS commands on each actor ref encountered, since I'd assume that's similar to what the engine is doing when an explosion is created. Of course, you'd have more control over what code you ran on each actor ref if doing a ref walk, possibly could even ignore some actors if http://fose.silverlock.org/fose_command_doc.html#GetNumRefs returned a large number.

I didn't see in your thread, but have you ever tested the speed of GetLOS? I'd guess that wouldn't be one of the fastest functions. I've been meaning to use your http://www.fallout3nexus.com/downloads/file.php?id=11239 framework to evaluate some methods in Feng Shui, so I may just test this stuff out too if you haven't already.
User avatar
Josephine Gowing
 
Posts: 3545
Joined: Fri Jun 30, 2006 12:41 pm

Post » Sat Nov 06, 2010 4:58 pm

I can recall testing the relative efficiency of scripted explosions and reference walking while calling http://geck.gamesas.com/index.php/GetDistance on each reference found via reference walking only, and it was still the clear winner. I couldn't find the results of that specific test in the thread though, so I may not have published them.

I'm not sure if I've tested http://geck.gamesas.com/index.php/GetLineOfSight as well, but I would be very surprised if it came close to making reference walking as slow as using scripted http://geck.gamesas.com/index.php/PlaceAtMe explosions.

Cipscis
User avatar
GabiiE Liiziiouz
 
Posts: 3360
Joined: Mon Jan 22, 2007 3:20 am

Post » Sat Nov 06, 2010 11:34 am

I feel like I'm talking to myself here :) I already tested the functionality and options for the condition checks (getLoS, getDetected, etc...). GetLoS doesn't worth with "dead" actors, but the getDetected does, and reports the normal detection values, so I can use that. What I don't know how to do is what is quoted below:

It'd be more efficient to walk through each actor reference and call ... (condition check)


How do I "walk through each actor reference" ?

Thanks!

EDIT: Also, one advantage of using the GetDetected since it can report a range of values is that it can use a global to control the detection threshold for triggering a detection event.
User avatar
Claire Lynham
 
Posts: 3432
Joined: Mon Feb 12, 2007 9:42 am

Post » Sat Nov 06, 2010 11:21 am

How do I "walk through each actor reference" ?

That's what this was directed at:

set iCount to ListGetCount SomeFormListset iIndex to 0Label 1if iIndex < iCount	set rListItem to ListGetNthForm SomeFormList iIndex	; do stuff with rListItem	set iIndex to iIndex + 1	Goto 1endif

Is that what you're looking for?

Because you had said:

... For example, the main quest script stores all the actor ref's in the formlists that were created (right?). How can I then go "through" this formlist and actually check for detection? Does that make sense?


If you don't actually have that formlist you mentioned, you'll need to do this:

set rActor to GetFirstRef 42 ;42 is the TypeCode for NPCLabel 1if IsReference rActor	; do stuff with rActor	set rActor to GetNextRef	Goto 1endif

Someone should probably confirm that's correct (I haven't actually used a http://fose.silverlock.org/fose_command_doc.html#GetFirstRef/http://fose.silverlock.org/fose_command_doc.html#GetNextRef loop before myself), although http://www.cipscis.com/dev/validator/validator.html says it's ok ;) - well, syntactically anyway.
User avatar
Eileen Collinson
 
Posts: 3208
Joined: Thu Dec 28, 2006 2:42 am

Post » Sat Nov 06, 2010 7:27 am

I'm not worried about the checks for LoS or detection, I can probably figure that part out. What I don't know is how to determine what the "alive" actor references are in order to actually run the calculation. For example, the main quest script stores all the actor ref's in the formlists that were created (right?). How can I then go "through" this formlist and actually check for detection? Does that make sense?

Well unless I'm missing the point, I don't see a problem here, since the script already ref walks the actors. So either the existing form lists can be reused, or another ref walk is done (which is probably safer due to concurrency issues?)

The question is rather what type of behaviour to implement.

Unfortunately, this method is actually very slow (http://www.gamesas.com/index.php?/topic/987561-script-optimisation/page__view__findpost__p__14295479). It'd be more efficient to walk through each actor reference and call http://geck.gamesas.com/index.php/GetDistance and possibly http://geck.gamesas.com/index.php/GetLineOfSight on each one. http://geck.gamesas.com/index.php/GetHeadingAngle can be used as well to check if the actor is facing the body.

Cipscis

Oh ok, thanks, I didn't know that theres already a GetHeadingAngle function, that makes things easy.
User avatar
Leticia Hernandez
 
Posts: 3426
Joined: Tue Oct 23, 2007 9:46 am

Post » Sat Nov 06, 2010 4:01 pm

Alright, I updated the token script to incorporate distance + the detection level results. It works pretty well in testing. Essentially, the ref walking section determines which actor has the highest detection level to the freshly dead actor within the detection distance (defined by global RKRDetectDist). Then, every 30-seconds a detection event is generated at the detecting actor. Nifty eh?

Also, I've narrowed down the melee kill problem. Apparently, killing someone with a melee weapon never results in the dead actor receiving the death token. I don't know why that would be the case. Odd.

scn RKRDetectTokenScriptfloat timershort countref actorref actor2short startref objfloat detectvalfloat ddistfloat detectval2float ddist2short AlertOnce;-------------------------------------------------------------------------------------------Begin OnAddset actor to getContainerset start to 1End;-------------------------------------------------------------------------------------------Begin GameModeif start == 0	returnendifif timer > 0	set timer to timer - getSecondsPassed	returnendifset timer to 10set count to count + 1if AlertOnce == 0	set obj to apple	set obj to getFirstRef 200	Label 1	if obj != 0		set detectval to ( obj.getdetected actor )		set ddist to ( obj.getdistance actor )		if ( detectval > detectval2 ) && ( ddist < RKRdetectdist ) 			set detectval2 to detectval			set actor2 to obj		endif		set obj to apple		set obj to getNextRef		goto 1	endif	set AlertOnce to 1endifif ( detectval2 > RKRdetectlevel )		if RKRDebug == 1			PrintToConsole "Creating detection event %.0f" count		endif		actor2.createDetectionEvent player 100	endifendifif count < 3	returnendifremoveMereturnEnd

User avatar
jess hughes
 
Posts: 3382
Joined: Tue Oct 24, 2006 8:10 pm

Post » Sat Nov 06, 2010 11:32 am

Regarding that no tokens are added for melee kills: no idea yet.

I also tried around a bit, basically I did the same you did but instead I used getHeadingAngle, which seems to be worse actually. Other than that you might want to add the depth parameter for ref walking because outdoors, 0 won't be good enough (see the actor walking in the quest script for reference). Also you might want to add a check for dead actors, because they can be skipped right away.

Another point: Currently the polling interval is every 10 seconds, now for "static" detection this worked fine, but if the detection status is used too this might not be perfect (Actor turns back to body, timer reaches 0, no detection, actors turns to body, walks towards it, looks at it for 9 seconds, turns around, next timer event, still no detection).

A simple but effective addition to limit the number of tokens that can be active at the same time:
A token counter I used to track the currently active number of tokens, and new ones are only added by the main script of the maximum is not yet reached. To avoid any inconsistencies with the counter (token scripts can stop running when the actor moves away, so they might not stop and decrement the counter so they block new tokens as long the player doesn't come back and allows them to finish), it's reset 30 seconds after the last token was added.

So 1., in the quest script where the token is added:
Label 1if obj != 0	if obj.getDead == 1		if (listRemoveForm oldList obj) != -1 && obj.isKiller player == 1 && tokenCount < RKRMaxTokenCount			;PrintToConsole "Adding detection token"			set tokenCount to tokenCount + 1			set removeTimer to 30			obj.addItem RKRDetectToken 1		endif	else		obj.listAddReference newList	endif	set obj to apple	set obj to getNextRef	goto 1endif


2. at the end of the quest script:
if removeTimer > 0	set removeTimer to removeTimer - getSecondsPassedelse	set tokenCount to 0endif


3. just before the removeMe in the token script:
if RKRMainQuest.tokenCount > 0	set RKRMainQuest.tokenCount to RKRMainQuest.tokenCount - 1endif


I also tried to simulate that actors run for cover when they discovered a dead body, but I wasn't successful yet. I tried an invisible grenade projectile (didn't work?), and I tried using packages to make them sneak+run, which looked cool but also strange, and they actually stopped caring for anything else, which was probably my fault.
User avatar
Oyuki Manson Lavey
 
Posts: 3438
Joined: Mon Aug 28, 2006 2:47 am

Post » Sat Nov 06, 2010 10:08 am

Hey schlangster,
Could you briefly explain how the cell depth parameter on http://fose.silverlock.org/fose_command_doc.html#GetFirstRef works? I'm assuming it's telling it how far to go in terms of adjacent cells, is that correct?

Also, is http://fose.silverlock.org/fose_command_doc.html#Form_Type_IDs 200 essentially 42 and 43 combined (NPC and Creature)?

We should probably work on adding pages for some of these functions to the GECK Wiki. There's not too much information on http://geck.gamesas.com/index.php/Category:Functions_%28FOSE%29 there so far.
User avatar
Adrian Powers
 
Posts: 3368
Joined: Fri Oct 26, 2007 4:44 pm

Post » Sat Nov 06, 2010 2:59 am

Hey schlangster,
Could you briefly explain how the cell depth parameter on http://fose.silverlock.org/fose_command_doc.html#GetFirstRef works? I'm assuming it's telling it how far to go in terms of adjacent cells, is that correct?

I assume it's the same as in OBSE (http://obse.silverlock.org/obse_command_doc.html). Copy&paste from there:
This function should be used only within a Label/Goto loop and GetNextRef. An optional cell depth can be supplied to specify the number of adjacent cells to scan in exteriors; a cell depth of 1 scans the player's current cell plus 8 adjacent cells, a depth of 2 scans the player's cell plus 25 adjacent cells. By default, inactive references to items which were previously picked up by an actor are ignored; passing 1 for the third parameter will force those references to be included.

Also, is http://fose.silverlock.org/fose_command_doc.html#Form_Type_IDs 200 essentially 42 and 43 combined (NPC and Creature)?

Yes, I think so.
User avatar
Lori Joe
 
Posts: 3539
Joined: Tue Jun 20, 2006 6:10 am

Previous

Return to Fallout 3