Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsCog Forum → Smart, predictive aiming...
Smart, predictive aiming...
2004-11-08, 7:51 PM #1
I'm working on a custom auto-turret. It's supposed to act like a manned turret, but for use in singleplayer (so it's not acctually manned). I have most of it working good, except I'm having one problem with it.

I want it to be able to calculate the lead on trajectory, and be able to use that to actually hit the player. This is all good and easy, but then I started to wonder about how well this would work with a rocket turret. Obviously, an intelligently manned turret would be aiming at the targets feet when firing explosive rounds.

Can anyone help me in finding a good method to determine the lead-on distance + the vector of the ground at the projected lead-on position? I've thought of a few ways, and even gotten suggestions on similiar problems, but I'd like to be able to use this without modifying any class cogs. I'd like it to be as standalone as possible.

One idea I have is to create an invisible template (one affected by gravity like a thermdet or seq or shrapnel) at the lead on vector, give it time to drop to the ground, then fire the projectile at the template.

Perhaps creating a ghost, setting it to a high mass/affected by gravity, and using that same method I just posted might work. I predict, though, that there's a better way to do this rather than my quick hack method.


Any Ideas?
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2004-11-09, 1:39 AM #2
I'm a bit confused...Are you asking how to calculate lead shot trajectory for slow moving projectiles, or can you already do that and want it to just shoot near the ground/feet?
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2004-11-09, 11:45 AM #3
Get the position you'll be firing at, and do some Vmath to it:

PlayerFeetPos=VectorSub(FirePos, VectorSet(0, 0, -0.2));

That should fire at where the feet will be. If not, raise the -0.2 or lower it.
-Hell Raiser
2004-11-09, 4:09 PM #4
But then you'll get really stupid AI that shoots at rocks 20 feet in front of him instead of your player. You should create an overwrite system where, if there's obstructions, he goes for second best and aims for the head, or just doesn't fire at all, depending on if the player is completelly covered or whatnot.

JediKirby
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-11-09, 4:40 PM #5
What do people with splash weapons do? Fire at surfaces around the player. :) Get any AI do do that, and we'd have something. ;)
-Hell Raiser
2004-11-09, 10:17 PM #6
What do you mean?
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2004-11-10, 9:10 AM #7
Yeah, lead shooting? We already have that.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2004-11-10, 1:19 PM #8
I want it to shoot at the ground in front of the victim. If he's jumping down a slope, I want the shot to hit the ground where he's about to land. I'd obviously put a check in to see if the predicted shot will be within a short distance of the target, though.

That'd be a cool feature to add to R-Bots, once it gets figured out. Especially if the code to see if there's an obstruction gets written too. I'm gonna be home in a little bit so I can try out my ideas.
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2004-11-10, 2:17 PM #9
Simple vector math and calculus, really. Except I suck at both, so here's SaberMaster's tutorial:

http://www.geocities.com/sabersdomain/tutorials/leadin.html
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2004-11-10, 2:36 PM #10
I meant a rock in front of the turreter, sorry.
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-11-10, 7:16 PM #11
Quote:
Originally posted by jEDIkIRBY
I meant a rock in front of the turreter, sorry.


In that case, the view would be blocked by the rock and it wouldn't fire at all. It's not really an AI issue.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2004-11-10, 9:55 PM #12
Code:
super = loadtemplate("+seqchrg2");
 testme = CreateThing(super, player);
	 stopthing(testme);
	 SetLifeLeft(testme, 99999);
	 SetThingModel(testme, dark);
	 SetThingMass(testme, 9999999999);
	 SetPhysicsFlags(testme, 0x883);
 	 //ApplyForce(testme, '0 0 -300');
	 SetThingVel(testme, VectorScale('0 0 -300000', 99999999));
	 Sleep(0.1);
	 footsec = GetThingSector(testme);
	 footvec = GetThingPos(testme);
         foo = CreateThingAtPos(ghostey, footsec, footvec, '0 0 0');
	 jksettarget(foo);


Here's some hack-jobbish code that accomplishes what I set out to do. I'd like to come up with a better way, though, and still keep it plug-n-play. If I could eliminate the use for the sequencer, and just apply the force to the ghost, that'd work perfectly. But during my 5 minutes of testing, I couldn't get the ghost to move so I did it this way. At least now you can see what I'm trying to do, now any good ideas on how to do it better?

I like this code, too, because I can just run a check to see if the turret haslos on the "foo" object, and if not then don't fire. This would be useful for when a player is jumping from somewhere (such as a ledge) to behind some cover that's lower than him. Since I wouldn't be able to bulls-eye him unless it was a short distance shot, and I can't see his landing-position (behind cover), just don't shoot. If the distance from the "foo" object is great enough to where the splash damage of the weapon won't hit the target, then don't fire also.

Any other ideas that would make it seem more realistic?
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2004-11-11, 7:42 AM #13
Why not just add a negative z vector into the leadon vector?
_ _ _____________ _ _
Wolf Moon
Cast Your Spell On Me
Beware
The Woods At Night
The Wolf Has Come
2004-11-11, 1:36 PM #14
Quote:
Originally posted by _XxWrAiTHxX_
Uh idea, instead of the seqcharge, how about a walkplayer? I dont know.


In my experience, creating and deleting walkplayers often will crash the game. Feel free, anyone, to correct me if this isn't actuallly true and it was probably just my buggy code.

Quote:
Why not just add a negative z vector into the leadon vector?


Because I want it to always hit the floor. In my test, I did the huge ledge gap in BGJ, and it returned the position of the ground way below me. In the actual cog, the weapon won't fire in such a case (or it will, with a random err-vec put on so it won't always bulls-eye the target). I want this functionality, because not all terrain is flat.
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2004-11-11, 11:25 PM #15
BUMP....and
a quick confusion on my part, someone straighten me out...

Hypothetical situation, as the code here differs slightly from my own, but it's inherently the same

veldif=VectorSub(GetThingVel(projectile), GetThingVel(target));
speed=VectorLen(veldif);
distance=VectorDist(GetThingPos(target), GetThingPos(projectile));
time=distance / speed;
moved=VectorScale(GetThingVel(target), time);
meetpos=VectorAdd(GetThingPos(target), moved);

Using *_seifer_*'s code, meetpos is the position the bullet should meet the moving target.
Code:
lvec=VectorNorm(VectorSub(meetpos, GetThingPos(projectile)));
SetThingLook(projectile, lvec);
projspeed=VectorLen(GetThingVel(projectile));
SetThingVel(projectile, VectorScale(lvec, projspeed));


That's the code to make the projectile aim at meetpos (straight from seifer).

Ok, then using this bit of code (or some similiar)

Code:
super = loadtemplate("+seqchrg2");
 testme = CreateThing(super, target);
	 stopthing(testme);
	 SetLifeLeft(testme, 99999);
	 SetThingModel(testme, dark);
	 SetThingMass(testme, 9999999999);
	 SetPhysicsFlags(testme, 0x883);
	 SetThingVel(testme, VectorScale('0 0 -300000', 99999999));
	 Sleep(0.01);
	 footvec = GetThingPos(testme); //ultimately, the vector returned that is the ground however far beneath the target


Ok, now let me set up the situation. Using similiar code, the turret is targetting me (the player). I'm on a slanted ramp heading down, and the turret has a profile view of me. I jump at the top of the ramp, trying to clear the rest. The first batch of code predicts where I would be if I wasn't arcing in jump. Since the turret sees that I'm not attached to the ground, it runs the second set of code to see where the ground is beneath me, so it can aim at it. Obvious problem, though;
Since I'm jumping down the sloped ramp, the ground level where I am gonna land will not the at the same elevation I was at when the turret checked. I thought of trying to try my mine-drop method from the "meetpos" the first batch of code finds. The problem with this, though, is that I'd need to use CreateThingAtPos, but I don't have the sector I need to use that verb. I could use the FindSectorAtPos cog that is in the datamaster, but I'd rather find another way altogether that is a little more simple. I'm not the best at math, so I thought maybe you 'ians could help me out with it.

While I was typing this up, though, I just thought of something. If I just used SetThingPos(Sequencer, MeetPos); and let it drop, that should predict the grounds elevation below meetpos, right? Any reason that won't work?

Unfortunatly, I'm in a big rush (if you can't tell by the typos), and I won't even be able to test till late tomorrow...
Any insights or help would be appreciated.

Also, I don't want to be dropping invisible mines in the finished version. So if I end up being stuck with this code, I want to be able to drop an invisible, massive template. Ideas on this?
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2004-11-12, 8:34 PM #16
SetThingPos() will NOT update the sector of the thing. So if you move the mine to a different sector, it'll drop through the floor into oblivion. (I'm pretty sure thats what would happen)

To get around this, you could always FireProjectile() a dummy ghost at '0 0 0' from the player, set the LVec of that dummy ghost to where the ExpectedPos of the player would be, then FireProjectile() from that dummy ghost VectorSet(0, VectorDist(ExpectedPos, GetThingPos(Dummy))

Something like this would help you alot:

Code:
Dummy=FireProjectile(Player, DummyGhost, -1, -1, '0 0 0', '0 0 0', 0, 0, 0, 0);
SetThingLook(Dummy, VectorSub(ExpectedPos, GetThingPos(Dummy));
Dist=VectorDist(GetThingPos(Dummy), ExpectedPos);
DropMine=FireProjectile(Player, Mine, -1, -1, VectorSet(0, Dist, 0), '0 0 0', 0, 0, 0, 0);


FireProjectile will place the thing in the correct sector no matter the fireoffset, so it's a yummy verb. :)

On your template, would this cog be running in a level, or would it be a mod or what? You could just make a new template and stuff it in the level or static.jkl
-Hell Raiser

↑ Up to the top!