AimAngTurret

From GMod Wiki

Jump to: navigation, search
Warning 64.pngThis page needs to be edited as it contains information that is unclear or incorrect. Improvement can be discussed on the talk page. Find more pages that need work here.
Details: None given.

Welcome to the ultimate AngForce tutorial :)

Contents


Starting up

Ok, for this contraption, we will need Wiremod, PHX3 would help :).

So what do I need?

For this contraption, we will use an expression2, a turret and a phx3 1x1 plate.

Setting up

Ok first, Go into the wire tool tab and under Wired-Control and select expression 2. Now press your secondary key(Right-Click as default) and the expression2 code editor will pop up. Ok now, we will need a code... wait ONE code? Not enough, why using one code when we can have 3 ways of doing stuff, or even all at a time :)

In this tutorial I'll explain the 3, and how to use 2 of them together, but to use 3, will come on something more advanced ;)

The first way

Lets start by the targeting system that uses chat:

@name AngForce Turret
@inputs 
@outputs Fire
@persist Pitch Yaw Roll Target:entity Ang:angle Plate:entity ArrayChat:array
 
runOnTick(1)
runOnChat(1)
 
ArrayChat=owner():lastSaid():explode(" ")
Plate=entity():isWeldedTo()
 
Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()
 
if(chatClk(owner())&ArrayChat:string(1)=="/t")
{
Target=findPlayerByName(ArrayChat:string(2))
}
 
Ang=(-ang(Pitch,Yaw,Roll)*Plate:mass())
 
Plate:applyAngForce(Ang + $Ang * 5)
 
if(Target){Fire=1}else{Fire=0}

The Wiring

Ok, now that this is done, we will need to see whats the front part of our plate, once that is done, place the expression 2 in the middle of the plate and a wire turret on the front part of it (right in the middle).

After this, wire the turret to the expression2:fire and you're done :).

Test time! To see if it's working say on chat /t targetname(or part of it) and the expression2 will start shooting at it until you target someone else, delete it or /t somethingimpossible which will target world (null target, won't fire)

Wow.. what the hell

Now its time for you to say... wow, my head hurts! what does all that means?

Well, get ready for explanation :)

@name AngForce Turret
@inputs
@outputs Fire
@persist Pitch Yaw Roll Target:entity Ang:angle Plate:entity ArrayChat:array

Here we set the variables for the expression2 to use and its name (inputs can be removed as we are not using any).

runOnTick(1)
runOnChat(1)

Here we tell the expression2 to update every game tick and everytime chat is used.

ArrayChat=owner():lastSaid():explode(" ")

Here we tell the expression2 that the array ArrayChat is made of the strings in your last speak in chat, divided by a space (" ").

Plate=entity():isWeldedTo()

Here the entity Plate becomes the phx3 1x1 plate you placed the expression2 on (I presume).

Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()

Ok, here is where we set our angles to the angles of the target relative to the plate, as pitch is well.. the elevation between the plate and target, Yaw is.. lets say the rotation and has we don't need roll, we just make it the current roll of the plate.

if(chatClk(owner())&ArrayChat:string(1)=="/t")
{
Target=findPlayerByName(ArrayChat:string(2))
}

This is our targeting system, let me explain it statement by statement: chatClk(owner()) returns true when the owner is the one who talked on chat, so it will only execute once. After that, we check if the first string before the first space is /t and in case both these are true, the code within the {} is executed, which basically sets the Target to the player found with the name or part of the name in the second string after the first space.

Ang=(-ang(Pitch,Yaw,Roll)*Plate:mass())

Here we define the angle to the negative angles that we retrieved, otherwise it will try to aim back instead of at the target and then multiply it to make some decent rotating speed.

Plate:applyAngForce(Ang + $Ang * 5)

Here is where it happens, the expression applies force to the Plate making it point towards your target :)

if(Target){Fire=1}else{Fire=0}

Here we tell the turret to fire as soon as the target is valid.

The second way

Ok, for this, there is no need of explanation and it's really easy to implement with the first way:

if(owner():keyAttack2()){Target=owner():aimEntity()}

Basically, when the owner presses secondary attack key (default as mouse2).

If you want to implement this into the other code, add it to the end, if you just want this one, delete

if(chatClk(owner())&ArrayChat:string(1)=="/t")
{
Target=findPlayerByName(ArrayChat:string(2))
}

And place this there.

The third way

Third way? Another one oh my god!

Hey hey take it easy, this is way more advanced than all of this, because its all of this plus you can target with your aim, it points where you look and fire if your target is valid or then switch back into the normal one.

Ok, first make sure you have the following code in your expression2:

@name AngForce Turret
@inputs 
@outputs Fire
@persist Pitch Yaw Roll Target:entity Ang:angle Plate:entity ArrayChat:array
 
runOnTick(1)
runOnChat(1) 
 
ArrayChat=owner():lastSaid():explode(" ")
Plate=entity():isWeldedTo()
 
Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()
 
if(chatClk(owner())&ArrayChat:string(1)=="/t")
{
Target=findPlayerByName(ArrayChat:string(2))
}
 
Ang=(-ang(Pitch,Yaw,Roll)*Plate:mass())
 
Plate:applyAngForce(Ang + $Ang * 5)
 
if(Target){Fire=1}else{Fire=0}

The edits we will do are simple, first add FireMode at the end of @persist, it should look like this:

@persist Pitch Yaw Roll Target:entity Ang:angle Plate:entity ArrayChat:array FireMode

Now, by the line where it says

Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()

Make it so it will be the following:

if(FireMode==1){
Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()
}
elseif(FireMode==2){
Pitch=Plate:elevation(owner():aimPos())
Yaw=Plate:bearing(owner():aimPos())
Roll=Plate:angles():roll()
}

Ok so here, we tell the expression2 that if the firemode is 1, it will be target based, else it will be based on your aim. For this, we will need to edit when it fires and so, where it says

if(Target){Fire=1}else{Fire=0}

It should become

if(FireMode==1){
if(Target){Fire=1}else{Fire=0}
}
if(FireMode==2){
if(owner():aimEntity()){Fire=1}else{Fire=0}
}

Ok so here, it makes the same for FireMode 1 as it did before, but now, if the firemode is 2 it will fire when the owner is looking at a valid entity (player, prop, npc, etc).

Wait, but now, we need a way to change firemode! If you like the simple way, switch FireMode to inputs and wire it to a toggled numpad input / button, value on 2, value off 1 but that is just too simple :p

So for our other way, we will add the follow at the line after runOnTick(1):

if(first()){FireMode=1}

Put 1 or 2 there depending on what you want the default firemode to be. This code only executes at the first time the expression2 runs.

Now, by the end of the expression2 add the following

if(chatClk(owner())&ArrayChat:string(1)=="/firemode")
{
if(ArrayChat:string(2):toNumber()<3&ArrayChat:string(2):toNumber()>0){
FireMode=ArrayChat:string(2):toNumber()
}
else{FireMode=FireMode}
}

Here we make so that when the player says /firemode on chat and the number after the first space is valid and beetween 0 and 3 (it's 1 or 2) the FireMode will be changed to that one.

By the end, your code should look like the following:

@name AngForce Turret
@inputs 
@outputs Fire
@persist Pitch Yaw Roll Target:entity Ang:angle Plate:entity ArrayChat:array FireMode
 
runOnTick(1)
runOnChat(1)
 
if(owner():keyAttack2()){Target=owner():aimEntity()}
 
if(first()){FireMode=1}
 
ArrayChat=owner():lastSaid():explode(" ")
Plate=entity():isWeldedTo()
 
if(FireMode==1){
Pitch=Plate:elevation(Target:pos())
Yaw=Plate:bearing(Target:pos())
Roll=Plate:angles():roll()
}
elseif(FireMode==2){
Pitch=Plate:elevation(owner():aimPos())
Yaw=Plate:bearing(owner():aimPos())
Roll=Plate:angles():roll()
}
 
if(chatClk(owner())&ArrayChat:string(1)=="/t")
{
Target=findPlayerByName(ArrayChat:string(2))
}
 
Ang=(-ang(Pitch,Yaw,Roll)*Plate:mass())
 
Plate:applyAngForce(Ang + $Ang * 5)
 
if(Target){Fire=1}else{Fire=0}
 
if(chatClk(owner())&ArrayChat:string(1)=="/firemode")
{
if(ArrayChat:string(2):toNumber()<3&ArrayChat:string(2):toNumber()>0){
FireMode=ArrayChat:string(2):toNumber()
}
else{FireMode=FireMode}
}

Credits

Disclaimer

This content is full user written and was not stole in any chance from anyone.

This tutorial's code was not made in real time with expression2 compiler, all errors obtained should be sent to me.

Email: [email protected]
Facepunch user: Emperus

I hope I wrote this in clear English and without much grammar fails, any questions about the code, suggestions or other should be sent to me using the contacts above, thank you.

Personal tools
Namespaces
Variants
Actions
Navigation
Lua Scripting
Functions
Hooks
Toolbox