So I want to design a turret style weapon.

Started by Flabort, May 28, 2014, 02:34:11 AM

Previous topic - Next topic

Flabort

Let's say I have my images, and a bullet scripted.

The bullet has the variables $XTar, $YTar, and $speed, assuming that the weapon will set these vars for the bullet. The bullet sets all it's own consts so that the weapon script doesn't have to handle that; just create the core and set the destination.

So if I have a base image and a barrel, and want the barrel to rotate before firing...
I can't get a clue from dissecting other player's scripts for it.

Planetfall in particular, if you see this, let's also assume I want this to be compatible with your "UnitRider" script; any specific variables or lines I should include in the code to ensure this? Anyone else doesn't have to answer this part.

Basically:
How does I gun?
My maps: Top scores: Sugarplum, Cryz Dal, Cryz Torri, Cryz Bohz (Click fetch scores, page courtesy of kwinse)

Flabort

Oh, and I forgot to say what kind of targeting.
Let's say I want it to always fire randomly in a 60 degree arc towards the nearest player unit, and since the turret picks the destination coords, it has to set the range the bullet goes, too; lets say $range:15
And that it fires even if there isn't a unit in range. Every so often.

$range:15
$ArcRange:30 #in either direction from the center; deviation, not a limit on range
$rate:30
$turn rate:0.2

#and from here on I'm kind of stuck.
My maps: Top scores: Sugarplum, Cryz Dal, Cryz Torri, Cryz Bohz (Click fetch scores, page courtesy of kwinse)

Grayzzur

The "base model" CRPL turret is the Chop Raider turret in Virgil's Alpha mission Chimera. Pull the CRGun.crpl and CRBullet.crpl scripts from there and see how it handles rotating and barrel recoil. He did a blog entry on it back before the game was released. http://knucklecracker.com/blog/index.php/2013/01/chimera/
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

J

You can't use <space> in variable names, so use turn_rate or turnRate instead of turn rate.

Flabort

#4
Grayzzur: I'll take a look at it then, thanks.

Quote from: J on May 28, 2014, 02:17:35 PM
You can't use <space> in variable names, so use turn_rate or turnRate instead of turn rate.
Gourd darn it, that's what happens when you put up a placeholder without thinking.

Edit:
After studying that script for... 4 hours, I have part of my own:

Spoiler
$Range:15
$DeviationArc:30
$RateOfFire:45
$TurnRate:0.2
$Image:"CustomImage65"
$BarrelImage:"CustomImage66"
$FlashImage:"CustomImage67"
$ProjectileSpeed:10

once
self "Main" <-Image SetImage
self "Barrel" <-BarrelImage SetImage
self "Barrel" 0 SetImageRotation
self "Flash" <-FlashImage SetImage
self "Flash" 255 255 255 0 SetImageColor
<-DeviationArc pi 180 div mul ->RadArc
<-RateOfFire SetTimer0
0 ->Flashed
endonce

@FindUnitDir ->DesiredAngle #Outputs desired image rotation for barrel: direction of nearest unit.
@BarrelRotate #Requires input of desired rotation.
GetTimer0 eq0 if
@FireWeapon #Creation of bullet, setting of target, barrelflash
endif
<-Flashed eq0 not if
@SettleFlash
endif



:FindUnitDir
0 ->playerunit
self 999999 GetUnitsInRange 0 do
->TempID
<-TempID GetUnitType ->Type
<-Type "POWERZONE" eq <-Type "TECHARTIFACT" eq or <-Type "MESSAGEARTIFACT" eq <-Type "SHIELDKEY" eq or or not if
<-TempID ->playerunit
<-TempID CONST_COORDX GetUnitAttribute ->PlayerX
<-TempID CONST_COORDY GetUnitAttribute ->PlayerY
endif
loop
CurrentY <-PlayerY sub ->VerticalTrig
<-PlayerX CurrentX sub ->HorizTrig
<-VerticalTrig <-HorizTrig atan2
#Leaves a value on the stack, make sure to use it


:BarrelRotate
self "Barrel" GetImageRotation <-DesiredAngle ShortestAngle ->DesiredRot
<-DesiredRot <-RadArc add <-DesiredRot <-RadArc sub sub RandFloat mul <-DesiredRot <-RadArc sub add ->RealRot
<-RealRot <-TurnRate gt if
<-TurnRate ->RealRot
else
<-RealRot <-TurnRate -1 mul lt if
<-TurnRate -1 mul ->RealRot
endif
endif

self "Barrel" GetImageRotation <-RealRot add ->RealRot
self "Barrel" <-RealRot SetImageRotation

:FireWeapon
self "Flash" self "Barrel" GetImageRotation SetImageRotation
self "Flash" 255 255 255 255 SetImageColor
255 ->Flashed

self "Flash" GetImageRotation ->FireAngle
<-Range ->HypoTrig
<-Range ->VerticalTrig
#Now I'm stuck again. Here I need to use two lines and an angle between to form a triangle to find my target coordinates.
#
# ->XTar
# ->YTar
"CRPLCORE" CurrentCoords CreateUnit ->Bullet
<-Bullet "GunAmmo.crpl" AddScriptToUnit
<-Bullet "GunAmmo.crpl" "XTar" <-XTar SetScriptVar
<-Bullet "GunAmmo.crpl" "YTar" <-YTar SetScriptVar
<-Bullet "GunAmmo.crpl" "Speed" <-ProjectileSpeed SetScriptVar
<-RateOfFire SetTimer0

:SettleFlash
<-Flashed 50 lt if
0 ->Flashed
else
<-Flashed 3 div ->Flashed
endif
self "Flash" 255 255 255 <-Flashed SetImageColor
[close]

Right now I need to figure out the part in the comments near the bottom.
Trigonometry. The first thing you forget out of high school.
My maps: Top scores: Sugarplum, Cryz Dal, Cryz Torri, Cryz Bohz (Click fetch scores, page courtesy of kwinse)

Grayzzur

It sounds like the main difference will be in how you choose a target.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

Flabort

#6
And I've figured that part out through a stroke of luck.

Spoiler
$Range:15
$DeviationArc:30
$RateOfFire:45
$TurnRate:0.2
$Image:"CustomImage65"
$BarrelImage:"CustomImage66"
$FlashImage:"CustomImage67"
$ProjectileSpeed:10

once
self "Main" <-Image SetImage
self "Barrel" <-BarrelImage SetImage
self "Barrel" 0 SetImageRotation
self "Flash" <-FlashImage SetImage
self "Flash" 255 255 255 0 SetImageColor
<-DeviationArc pi 180 div mul ->RadArc
<-RateOfFire SetTimer0
0 ->Flashed
endonce

@FindUnitDir ->DesiredAngle #Outputs desired image rotation for barrel: direction of nearest unit.
@BarrelRotate #Requires input of desired rotation.
GetTimer0 eq0 if
@FireWeapon #Creation of bullet, setting of target, barrelflash
endif
<-Flashed eq0 not if
@SettleFlash
endif



:FindUnitDir
0 ->playerunit
self 999999 GetUnitsInRange 0 do
->TempID
<-TempID GetUnitType ->Type
<-Type "POWERZONE" eq <-Type "TECHARTIFACT" eq or <-Type "MESSAGEARTIFACT" eq <-Type "SHIELDKEY" eq or or not if
<-TempID ->playerunit
<-TempID CONST_COORDX GetUnitAttribute ->PlayerX
<-TempID CONST_COORDY GetUnitAttribute ->PlayerY
endif
loop
CurrentY <-PlayerY sub ->VerticalTrig
<-PlayerX CurrentX sub ->HorizTrig
<-VerticalTrig <-HorizTrig atan2
#Leaves a value on the stack, make sure to use it


:BarrelRotate
self "Barrel" GetImageRotation <-DesiredAngle ShortestAngle ->DesiredRot
<-DesiredRot <-RadArc add <-DesiredRot <-RadArc sub sub RandFloat mul <-DesiredRot <-RadArc sub add ->RealRot
<-RealRot <-TurnRate gt if
<-TurnRate ->RealRot
else
<-RealRot <-TurnRate -1 mul lt if
<-TurnRate -1 mul ->RealRot
endif
endif

self "Barrel" GetImageRotation <-RealRot add ->RealRot
self "Barrel" <-RealRot SetImageRotation

:FireWeapon
self "Flash" self "Barrel" GetImageRotation SetImageRotation
self "Flash" 255 255 255 255 SetImageColor
255 ->Flashed

self "Flash" GetImageRotation ->FireAngle
<-Range ->HypoTrig
pi 2 div ->squareAngle
<-HypoTrig <-squareAngle sin div <-FireAngle sin div CurrentY add ->TarY
<-HypoTrig <-squareAngle <-FireAngle sub sin div <-FireAngle sin div CurrentX add ->TarY

"CRPLCORE" CurrentCoords CreateUnit ->Bullet
<-Bullet "GunAmmo.crpl" AddScriptToUnit
<-Bullet "GunAmmo.crpl" "XTar" <-XTar SetScriptVar
<-Bullet "GunAmmo.crpl" "YTar" <-YTar SetScriptVar
<-Bullet "GunAmmo.crpl" "Speed" <-ProjectileSpeed SetScriptVar
<-RateOfFire SetTimer0

:SettleFlash
<-Flashed 50 lt if
0 ->Flashed
else
<-Flashed 3 div ->Flashed
endif
self "Flash" 255 255 255 <-Flashed SetImageColor
[close]
Now for a test.

Edit: Typo resulted in noncompile. Fixed edit, compiled.

Edit2:..... it doesn't seem to work right now. I'll have to check why. Tomorrow or the next day.

Edit3: Ammoscript:
Spoiler
$XTar:0
$YTar:0
$speed:20

once
self CONST_CREATEPZ false SetUnitAttribute
self CONST_DESTROYONDAMAGE true SetUnitAttribute
self CONST_HEALRATE 0 SetUnitAttribute
self CONST_NULLIFIERDAMAGES false SetUnitAttribute
self CONST_SNIPERTARGET true SetUnitAttribute
self CONST_SNIPERIGNORELOS true SetUnitAttribute
endonce

CurrentCoords 1 SetDigitalisGrowth
GetQueuedMoveCount if
<-XTar <-YTar <-speed QueueMove
endif
CurrentX <-XTar eq CurrentY <-YTar eq and if
self 1 Destroy
endif

:destroyed
CurrentX 2 sub ->XInd
CurrentY 2 sub ->YInd
CurrentX 2 add ->XLim
CurrentY 2 add ->YLim
<-XLim <-XInd do
<-YLim <-YInd do
J I 1 SetDigitalisGrowth
loop
loop
[close]
My maps: Top scores: Sugarplum, Cryz Dal, Cryz Torri, Cryz Bohz (Click fetch scores, page courtesy of kwinse)

planetfall

Don't have time to read this in depth, but some things that I noticed:

This:
self 999999 GetUnitsInRange 0 do
Should be this:
CurrentCoords 999999 GetUnitsInRange 0 do

You'll want to put that "once" block on the bullet into an "awake" block. Otherwise you'll have the same issue I did with KIWF (being able to nullify the projectile for a single frame.)

Also, you may want to replace the QueueMove in the bullet with something like this:


CurrentPixelCoords ->y ->x

Self CONST_PIXELCOORDX <-x <-angle cos <-speed mul add SetUnitAttribute
Self CONST_PIXELCOORDY <-y <-angle sin <-speed mul add SetUnitAttribute


Simply because QueueMove can't make it shoot off the map, and it will sit there on top of the gun if it targets a point off the map. You don't have anything that could do this right now, but you did say you wanted it to sometimes shoot randomly.
Pretty sure I'm supposed to be banned, someone might want to get on that.

Quote from: GoodMorning on December 01, 2016, 05:58:30 PM"Build a ladder to the moon" is simple as a sentence, but actually doing it is not.