Remote shield emitter

Started by Dook, July 10, 2014, 09:55:05 AM

Previous topic - Next topic

Dook

Had an idea where you'd have an enemy unit that technically did nothing but had a unique ID, then another unit that would put up a shield that the player can't land or build units on. When the unique ID unit count reaches zero the shield emitter unit would either be destroyed or become inoperative. The idea is to protect an inhibitor with a shield till all remote shield relays are destroyed. This should be possible right? if any one has some generous free time to make a script i'd be much appreciative. also would it be possible to have the remote relays emit a slight transparent beam to the shield emitter? or some other slight graphical effect? Idea being the player would intuitively know what the remote relays are doing with out having the need to explain anything.

If script requests are frowned upon then i apologize in advance.

stewbasic

I'll try to put a script together tonight (unless someone beats me to it :P).

ParkourPenguin

#2
I don't believe script requests are frowned upon. I know I don't mind- I love making scripts!  :D

Anyways, I put together a couple scripts that can do what you asked. Here's a short description of both of them:

AntiUnitShield.crpl:

This is the thing that generates the shield that won't allow player units to land or be built. Please take note of the fact that it uses SetCellOccupiedCount to do this, and I've had some bugs dealing with that "shield" persisting even after the CRPL tower is destroyed. I think I've gotten rid of most of those bugs, but if you come across any, please let me know.
Here's a list and a description of all the variables:









radiusThe shield is shaped like a circle, and this variable sets the radius of that circle in tiles.
maxAmmoThe tower uses ammo to keep track of whether or not it's receiving power from any other towers. Set this value to negative if you want unlimited ammo (it never turns off until it's destroyed).
initialAmmoThis is how much ammo is initially given to the tower. The ammo depletes at a rate of 1 ammo per second, assuming no other tower is supplying it with ammo.
effectThe tower creates an effect around the circle to show the player what area it covers. This sets what effect is displayed. Click here to see a list of all available effects.
effectSpeedThis is the magnitude of the tangential velocity of the effect (aka its speed) in pixels per frame as it moves around the circle.
numOfEffectsThis represents how many effects are displayed around the outside of the circle. They are automatically evenly spaced around it.
effectFrameSkipThe CRPL tower will skip this many frames between updating the effects around the tower. If you notice any lag when using these scripts, try increasing this value.


AntiUnitShieldBattery.crpl:

This will supply ammo to whatever tower you specify. It has effects built into it that should travel in a straight line to the tower it is supplying ammo to. Please note that when the main tower that's generating the shield is destroyed, any towers that are supplying it energy will also be destroyed.

Also, I didn't change any unit attributes on this tower, so if you want them changed from their default values, make sure to do that in the "Properties" menu when clicking on the CRPL tower.

Again, here's a list and a description of all the variables:









targetXThe X-Coordinate of the tower it is supposed to supply energy to. This only has to be set once.
targetYThe Y-Coordinate of the tower it is supposed to supply energy to. This only has to be set once.
rateHow much ammo it supplies to the tower every second. Note that the tower depletes ammo when running at a rate of 1 ammo per second.
effectThis sets what effect is displayed as it travels in a line from itself to the target tower. Click here to see a list of all available effects.
numOfEffectsThe maximum number of effects that travel along the line at once.
effectSpeedHow fast the effect goes in pixels per frame.
effectFrameSkipThe CRPL tower will skip this many frames between updating the effects around the tower. If you notice any lag when using these scripts, try increasing this value.


I tried to find and fix as many bugs as I could, but it's pretty late where I am now and I'm tired. In case I missed any, please tell me about them so I can fix them.

If you have any questions, please don't hesitate to ask. I'm always happy to help! :)
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Dook

wow awesome. exactly what i had in mind. nice work!

did a bit of testing and did get the bug of persisting shield.
Though everything else seems to be working.
as soon as the shield batterys go down the ammo quickly dissipates and the effects turn off. shield still remains though.

ParkourPenguin

I found a couple bugs. One dealing with the infinite ammo thing not working- apparently you can't pass a negative value into CONST_MAXAMMO, but I got that fixed by switching that out with the local variable, which actually makes more sense than getting CONST_MAXAMMO.

Beyond that, I found a glitch where the shield wouldn't correctly update if the unit was moved around. This is probably the cause of the persisting shield you were getting. I believe that's fixed now.

You can download the updated version of my script from my previous post. Please let me know if the persisting shield glitch causes you any more trouble.
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Dook

new bug cropped up. looks like a blank error code box right next to the antishieldemitter core. 1 line thick but no text. shield still persists if u move it around enough. but it works when i placed it then didn't touch it again

Grayzzur

in the AntiUnitShield.crpl file, near the top, if you change "ShowTraceLog" to "HideTraceLog" that trace log box will go away.

The trace log and trace commands are great for debugging a script -- not so much for a finished map!

:)

And yes, this is absolutely the right place to put script requests. As you've discovered, there are plenty of helpful people on this forum willing to give it a go.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

ParkourPenguin

#7
My apologies- I didn't even notice that the trace log was still showing. I've updated the script to not show it anymore.

As for the persisting shield bug, I haven't noticed it at all. If you're able to replicate it, please let me know, and list step-by-step everything you do. That will help me fix it.

Edit:
I think I might have found something. I forgot to set the radius of deleting the previous shield when the tower was moved, so the default radius should work, but anything larger would cause the shield to stay. I've updated the script again with this fix.
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Dook


Dook

Script is working great and just as i envisioned. thank you. Sense you helped me this far i was wondering if you would want to possibly contribute a bit more? As of now the map is basically complete save the art aspects which i'll do last (terrain and units). Testing it out i realized the nature of the antiunitsheild script lends its self to be able to do a 2 phase map. 1st phase clearing away preplaced units and shield batterys. The 2nd phase could be when the shield goes down a new threat emerges. Something more difficult to give a player with a set up base an actual challenge. Got plenty of spots in the center of the map for CRPL cores. I was thinking maybe some sort of cannon that spits creeper emitters randomly around the map. Although if you got a better idea or some script collecting dust you want to bust out i'm definitely open to suggestions.

If i'm imposing to much trust me now worries. although if you do want to help, take your time, i'm in no rush.

Image to the map so u can see the general idea. again art aspects not done yet.

ParkourPenguin

#10
No worries. As I said previously, I love making scripts!  ;)

By the way, your map looks awesome so far. I love all the detail in the terrain, and with all the CRPL, it looks like it's going to be quite an interesting challenge.

With regards to your request, I made a mortar script a couple days ago that's effectively the creeper's version of the player's mortar. I just had to modify it a little bit for it to spawn an emitter when the projectile lands. Here's a description of both of the scripts required to make this work:

CreeperMortar.crpl:

Not much to say here. Just attach this to a CRPL tower, set all the variables, and it works. I've been playing around with this for a while, and I think I've debugged mostly everything I can, so you shouldn't encounter any bugs.

While this isn't a markedly intricate script, it does have quite a few variables for you to set. Here is a description of each of them:
















mortarIntervalHow many frames the mortar should wait before firing again.
mortarPayloadThe amount of creeper spawned in when the projectile fired by the mortar lands. Set to 0 to not spawn any creeper.
mortarTargetXThe X-Coordinate of the area the mortar is firing at.
mortarTargetYThe Y-Coordinate of the area the mortar is firing at.
mortarTargetRadiusThis is the radius of the circle the mortar's projectile is certain to land in. For example, if this is set to 10, the mortar's projectile could land at X,Y and every tile in a 10-tile radius from it. If this is set to 0, it will always land at X,Y. Note that there is a statistically higher chance for the projectile to hit at the center than at the edge of the circle.
spawnedEmitterProductionAmtThe amount of creeper the emitter will produce when it spawns in after the projectile lands. Set this to 0 if you want emitters to not spawn in when the projectile lands. Also, note that an emitter will not spawn if a unit is already at that tile, so they can't stack.
spawnedEmitterProductionIntervalThe number of frames between each creeper production of the spawned-in emitter.
projectileImageThe location of the image assigned to the projectile as it flies through the air.
projectileSpeedHow fast the projectile goes through the air. If this is set to 0, the tower will not fire any projectiles, and will instead always produce creeper (see triggerRange below).
projectileAngularVelocityThis is the amount of "spin" assigned to the projectile.
projectileUpdateDelayHow quickly the projectile's image is updated as it flies through the air. You should increase this value only if you notice lag when using this script.
triggerRangeIf player units get in a certain range of the CRPL tower this script is attached to, the tower will switch from firing projectiles to producing creeper. This is the maximum range required to trigger this effect. Note that if projectileSpeed is set to 0, this tower will always produce creeper regardless of whether or not there are any units in range.
emitIntervalThe number of frames between each creeper production of this tower.
emitAmountHow much creeper is produced by this tower when it activates.


MortarShell.crpl:

This script is automatically attached to the projectile fired by the actual mortar tower. While you shouldn't attach this to anything normally, feel free to if you want. It's variables should be self-explanatory, especially after reading the previous script's variables; however, if you have any questions about them, just ask, and I'll be more than willing to help!


Just note that with these scripts, you can change the variables in here at any time with another CRPL tower by using SetScriptVar. For instance, if you ever want a mortar to stop creating emitters, just simply set spawnedEmitterProductionAmt to 0 with another CRPL tower.


If you're looking for something else to add, the first script I made was a landmine script. You can click here to go to that topic. Just be warned- you can easily make a player rage if you don't tell him/her about the possibility of landmines.

I'm sure a bunch of other people also have scripts you could implement into your map. Take a look around the forums- you're bound to find something you'd love.

Anyways, if you find any glitches or bugs in any of these scripts, please tell me, and I will try to fix them as soon as I can. Good luck with finishing that map!
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Dook

ah very nice. looks like what i had in mind. i'll get a crakin on the map

Dook

The mortars work as described. I see you are pointing me in the direction towards turning them off for phase one (prior to batterys being destroyed). I added SetScriptVar("spawnedEmitterProductionAmt" 0) under "once" in the AntiUnitShieldBattery script in hopes that once all batterys are destroyed the spawned emitter production amount reverts back to the set value in the placed CRPL core. not sure if it works that way though. And regardless i failed at even turning them off  :'( .

ParkourPenguin

Well, according to the SetScriptVar wiki page, SetScriptVar takes 4 arguments to work: Unit UID, script name, var name, and var value.

Unit UID is simply a unique integer assigned to each unit. I do not believe there is any way for two units to have the same UID on the same map. You can get this value by using GetUnitAt. GetUnitAt is fairly simple- give it an X-Coordinate and a Y-Coordinate, and it will give you the UID of whatever unit may be there.

Script name should be fairly straightforward- it's the name of the script that contains the value you want to modify. In this case, it should be "CreeperMortar.crpl".

Var name is also straightforward- it's the name of the variable you want to modify. This should be "spawnedEmitterProductionAmt".

Var value is what you want the variable to be. In the case of where you want to disable spawning emitters, this should be 0. If you do want them to spawn emitters, however, then this should be something greater than 0.

As an example, let's say a CRPL tower with CreeperMortar.crpl attached to it is at X,Y. This is roughly what you should do to set the variable:
GetUnitAt(<-X <-Y) ->mortarUID
SetScriptVar(<-mortarUID "CreeperMortar.crpl" "spawnedEmitterProductionAmt" 0)


However, as stated previously, this will prevent mortars from spawning in emitters.

But, if you want the mortars to spawn emitters when all of the batteries are destroyed, there may be an easier way to do this. Instead of checking whether or not all the batteries are destroyed, you can check if the shield is down from the mortars themselves via GetScriptVar (works very similar to how SetScriptVar works, only excludes var value), and if so, allow emitters to be spawned in. You'll have to get the UID of the shield you want to check, of course. Again, assume the shield is at X,Y:
GetUnitAt(<-X <-Y) ->shieldUID
if(GetScriptVar(<-shieldUID "AntiUnitShield.crpl" "isShieldActive") not)  # if the shield is not active, then spawn
    20 ->spawnedEmitterProductionAmt                                      # in emitters that produce 20 creeper.
endif


GetUnitAt(<-X <-Y) ->shieldUID would best be placed somewhere in the once...endonce block of CreeperMortar.crpl. Try right before endonce. Just note that you'll have to manually input the coordinates of the shield you want to check.
You'll have to put the if statement somewhere in CreeperMortar.crpl where it will loop. Try right before :fireMortar and after endif.

Here is what the final thing should look like, with a shield located at X = 125, Y = 50:
Spoiler
# CreeperMortar.crpl
# Created by: ParkourPenguin
# Created on: 7/9/2014
# Last edited: 7/13/2014
# ------------------------------------------
$mortarInterval:450
$mortarPayload:100.0
$mortarTargetX:0
$mortarTargetY:0
$mortarTargetRadius:10.0
$spawnedEmitterProductionAmt:0.0
$spawnedEmitterProductionInterval:15
$projectileImage:"Custom0"
$projectileSpeed:1.5
$projectileAngularVelocity:1.0
$projectileUpdateDelay:0
$triggerRange:0.0
$emitInterval:15
$emitAmount:20.0

once
   self CONST_COUNTSFORVICTORY true SetUnitAttribute
   self CONST_NULLIFIERDAMAGES true SetUnitAttribute
   
   "mortarInterval" @makePos
   "mortarTargetX" @makePos
   "mortarTargetY" @makePos
   "mortarTargetRadius" @makePos
   "spawnedEmitterProductionInterval" @makePos
   "projectileSpeed" @makePos
   "projectileUpdateDelay" @makePos
   "triggerRange" @makePos
   "emitInterval" @makePos
   
   if(<-mortarTargetX MapWidth gte)
      MapWidth 1 sub ->mortarTargetX
   endif
   
   if(<-mortarTargetY MapHeight gte)
      MapHeight 1 sub ->mortarTargetY
   endif

   GetUnitAt(125 50) ->shieldUID

endonce

if(CurrentCoords <-triggerRange GetUnitCountInRange eq0 <-projectileSpeed neq0 and)
   @fireMortar
   <-mortarInterval Delay
else
   @produceCreeper
   <-emitAmmount Delay
endif

if(GetScriptVar(<-shieldUID "AntiUnitShield.crpl" "isShieldActive") not)
    20 ->spawnedEmitterProductionAmt
endif

:fireMortar
RandFloat pi 2 mul mul ->angle
RandFloat <-mortarTargetRadius mul ->dist
<-angle cos <-dist mul floor <-mortarTargetX add ->tX
<-angle sin <-dist mul floor <-mortarTargetY add ->tY
if(<-tX MapWidth gte)
   MapWidth 1 sub 2 mul <-tX sub ->tX
endif
if(<-tY MapHeight gte)
   MapHeight 1 sub 2 mul <-tY sub ->tY
endif

"CRPLCORE" CurrentCoords CreateUnit ->shellID
<-shellID "MortarShell.crpl" AddScriptToUnit
<-shellID "main" <-projectileImage SetImage
<-shellID "MortarShell.crpl" "targetX" <-tX abs SetScriptVar
<-shellID "MortarShell.crpl" "targetY" <-tY abs SetScriptVar
<-shellID "MortarShell.crpl" "payload" <-mortarPayload SetScriptVar
<-shellID "MortarShell.crpl" "emitterProductionAmt" <-spawnedEmitterProductionAmt SetScriptVar
<-shellID "MortarShell.crpl" "emitterProductionInterval" <-spawnedEmitterProductionInterval SetScriptVar
<-shellID "MortarShell.crpl" "speed" <-projectileSpeed SetScriptVar
<-shellID "MortarShell.crpl" "angularVelocity" <-projectileAngularVelocity SetScriptVar
<-shellID "MortarShell.crpl" "updateDelay" <-projectileUpdateDelay SetScriptVar

:produceCreeper
CurrentCoords <-emitAmmount
if(CurrentCoords GetCreeper 0 gt)
    SetCreeper
else
   AddCreeper
endif

:makePos
dup
<-! 0 lt if
   dup <-! neg swap ->!
else
   pop
endif
[close]

If you would like any more help with trying to figure out how to do something, don't hesitate to ask!
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Dook

You have been very helpful. thank you. i'll have to also set the projectile speed to zero to prevent it from firing and revert it to producing creeper only during phase 1. which should just be as simple as entering 1.5 ->projectileSpeed under the if statement. with this method i can also increase its emitter amount when triggered by a player coming in range during phase 2. very cool.