Custom Map #254: Bloom-4. By: First

Started by AutoPost, February 24, 2014, 07:55:05 PM

Previous topic - Next topic

AutoPost

This topic is for discussion of map #254: Bloom-4


Author: First
Size: 162x162

Desc:
Creeper grows like weeds on Bloom-4. Scripts, mechanics and hints posted on the CW3 forum - click View Topic to avail. Leave a comment, too!

First

Here's the script for the game controller tower for this map. It's job is to link up pairs of towers, assigning coords, colors, etc. This tower is mean to be invisible.


# gametower.crpl
# Created on: 2/22/2014 4:09:46 PM
# ------------------------------------------

$Color:"Red"
$Type:"Emitter"
$xLoc:0
$yLoc:0
$xLink:0
$yLink:0

once
CurrentCoords Swap ->xLoc ->yLoc
"
" ->LFCR
CreateList ->NodesColors
"Blue" "Cyan" "Green" "Magenta" "Orange" "Purple" "Red" "Violet" "Yellow" "YellowGreen" <-NodesColors PrependStackToList

#hack a random seed
ElapsedTime 10000 mod 0 do
0 1 RandInt ->dummy
loop
#locate the starting nodes, assign their scripts and inits
CurrentCoords 999 GetEnemyUnitsInRange ->numUnits
CreateList ->NodesUID
<-NodesUID AppendStackToList
#filter out Self
<-NodesUID GetListCount 0 do
<-NodesUID I GetListElement ->currUnit
<-currUnit Self eq if
<-NodesUID I RemoveListElement
endif
loop
0 ->imgCount
while <-NodesUID GetListCount 0 gt repeat
0 <-NodesUID GetListCount RandInt ->which
<-NodesUID <-which GetListElement ->currUnit1
<-NodesUID <-which RemoveListElement
0 <-NodesUID GetListCount RandInt ->which
<-NodesUID <-which GetListElement ->currUnit2
<-NodesUID <-which RemoveListElement
<-NodesColors 0 GetListElement ->Color
<-NodesColors 0 RemoveListElement
<-Color Trace

<-currUnit1 "main" "Custom" <-imgCount Concat SetImage
<-currUnit1 "linktower.crpl" "MyImage" "Custom" <-imgCount Concat SetScriptVar
<-currUnit2 "linktower.crpl" "LinkImage" "Custom" <-imgCount Concat SetScriptVar
<-imgCount 1 add ->imgCount
<-currUnit1 "linktower.crpl" "xLoc" GetScriptVar ->xLoc1
<-currUnit1 "linktower.crpl" "yLoc" GetScriptVar ->yLoc1

<-currUnit2 "main" "Custom" <-imgCount Concat SetImage
<-currUnit1 "linktower.crpl" "LinkImage" "Custom" <-imgCount Concat SetScriptVar
<-currUnit2 "linktower.crpl" "MyImage" "Custom" <-imgCount Concat SetScriptVar
<-imgCount 1 add ->imgCount
<-currUnit2 "linktower.crpl" "xLoc" GetScriptVar ->xLoc2
<-currUnit2 "linktower.crpl" "yLoc" GetScriptVar ->yLoc2

#set up links
<-currUnit1 "linktower.crpl" "xLink" <-xLoc2 SetScriptVar
<-currUnit1 "linktower.crpl" "yLink" <-yLoc2 SetScriptVar
<-currUnit2 "linktower.crpl" "xLink" <-xLoc1 SetScriptVar
<-currUnit2 "linktower.crpl" "yLink" <-yLoc1 SetScriptVar

#colors and types
<-currUnit1 "linktower.crpl" "Color" <-Color SetScriptVar
<-currUnit2 "linktower.crpl" "Color" <-Color SetScriptVar
<-currUnit1 "linktower.crpl" "Type" "Emitter" SetScriptVar
<-currUnit2 "linktower.crpl" "Type" "Spore" SetScriptVar
endwhile

endonce

:awake



First

Here's the script for the linked tower. It's two scripts mashed up (both emitter and spore tower). The timers control the growth, active and death mechanisms. Hmmm... maybe I can post up here the icons I used for the towers.


# linktower.crpl
# Created on: 2/23/2014 12:59:34 AM
# ------------------------------------------

$Color:"Red"
$Type:"Emitter"
$MyImage:"Custom0"
$LinkImage:"Custom1"
$xLoc:0
$yLoc:0
$xLink:0
$yLink:0

#Timer0 - 1 second timer for misc wait states (avoids updating stuff every frame)
#Timer1 - used to time buildout phase of core
#Timer2 - used to time action phase of core (emitting creeper or spores)
#Timer3 -
#isBuilding - True means in buildout phase, False means in production phase
#isInit - Waiting 30 frames for gametotem.crpl to finish assigning the links (to avoid race condition)

once
"
" ->LFCR
False ->isBuilding
False ->isSapling
True ->isInit
30 SetTimer0
#ShowTraceLog
"Init" Trace
#Initialize
60 80 RandInt ->EmStr
1800 2700 RandInt ->EmInitIntFrms
15 45 RandInt ->EmIntFrms
2 5 RandInt ->SpNum
1800 2700 RandInt ->SpInitIntFrms
2700 4500 RandInt ->SpIntFrms
50 100 ->SpStr
endonce

#Init wait is over, begin building
GetTimer0 eq0 <-isInit and if
"Finished Init" Trace
False ->isInit
True ->isBuilding
True ->isSapling
#Start Building
"Emitter" <-Type eq if
<-EmInitIntFrms SetTimer1
else
<-SpInitIntFrms SetTimer1
endif
30 SetTimer0
endif

#Update popuptext for partially built units - showing %build completion and imagesize, until building is finished
GetTimer0 eq0 <-isBuilding and <-isInit not and if
"Building" Trace
"Emitter" <-Type eq if
1.0 <-EmInitIntFrms mul GetTimer1 sub <-EmInitIntFrms div 100.0 mul floor ->percComp
<-percComp 33.3 lt ->isSapling
<-isSapling if
"Fragile " <-Color Concat <-LFCR Concat <-percComp Concat " %" Concat SetPopupText
else
<-Color <-LFCR Concat <-percComp Concat " %" Concat SetPopupText
endif
1.0 <-EmInitIntFrms mul GetTimer1 sub <-SpInitIntFrms div 2.0 0.33333 sub mul 0.33333 add ->imgScale
else
1.0 <-SpInitIntFrms mul GetTimer1 sub <-SpInitIntFrms div 100.0 mul floor ->percComp
<-percComp 33.3 lt ->isSapling
<-isSapling if
"Fragile " <-Color Concat <-LFCR Concat <-percComp Concat " %" Concat SetPopupText
else
<-Color <-LFCR Concat <-percComp Concat " %" Concat SetPopupText
endif
1.0 <-SpInitIntFrms mul GetTimer1 sub <-SpInitIntFrms div 2.0 0.33333 sub mul 0.33333 add ->imgScale
endif
True SetPopupTextAlwaysVisible
Self "main" <-imgScale <-imgScale SetImageScale
30 SetTimer0
else
endif

#Finished Building, start the activity timer
GetTimer1 eq0 <-isInit not and <-isBuilding and if
"Built" Trace
"Emitter" <-Type eq if
<-EmIntFrms SetTimer2
else
<-SpIntFrms SetTimer2
endif
False ->isBuilding
endif

#update the popuptext for fully built units - showing tower activity (strength, spores, etc)
GetTimer0 eq0 <-isBuilding not and <-isInit not and if
"Emitter" <-Type eq if
<-Color <-LFCR Concat "Strength: " Concat <-EmStr Concat <-LFCR Concat "Interval: " Concat <-EmIntFrms 30.0 div 100.0 mul floor 100.0 div Concat " sec" Concat SetPopupText
False SetPopupTextAlwaysVisible
else
GetTimer2 30.0 div 60.0 div floor ->minRemaining
GetTimer2 30.0 div 60.0 mod floor ->secRemaining
<-secRemaining 10 lt if
<-Color <-LFCR Concat <-SpNum Concat " spores" Concat <-LFCR Concat <-minRemaining Concat ":0" Concat <-secRemaining Concat SetPopupText
else
<-Color <-LFCR Concat <-SpNum Concat " spores" Concat <-LFCR Concat <-minRemaining Concat ":" Concat <-secRemaining Concat SetPopupText
endif
False SetPopupTextAlwaysVisible
endif
30 SetTimer0
endif

#Action required timer has expired, emit something
GetTimer2 eq0 <-isBuilding not and <-isInit not and if
"Doing Something" Trace
"Emitter" <-Type eq if
CurrentCoords <-EmStr SetCreeper
<-EmIntFrms SetTimer2
else
<-SpNum 0 do
CurrentCoords RandUnitCoords 1.0 <-SpStr CreateSpore
loop
<-SpIntFrms SetTimer2
endif
endif

#check if my link is dead, if so
#only allow me to start respawn if (1) I am not already respawning and (2) I am not building myself
<-xLink <-yLink GetUnitAt ->linkUnit
<-linkUnit -1 eq  <-isInit not and if
<-isSapling if
#kill myself if I'm currently building - can't survive death of link
Self CONST_CREATEPZ 1 SetUnitAttribute
"POWERZONE" <-xLink <-yLink CreateUnit
Self 0 Destroy
else
#spawn my link back into life if I am currently built - can survive death of link
"Spawning" Trace
"CRPLCORE" <-xLink <-yLink CreateUnit ->currUnit
<-currUnit "linktower.crpl" AddScriptToUnit
<-currUnit "main" <-LinkImage SetImage
<-currUnit "linktower.crpl" "MyImage" <-LinkImage SetScriptVar
<-currUnit "linktower.crpl" "LinkImage" <-MyImage SetScriptVar
CurrentCoords Swap ->x ->y
<-currUnit "linktower.crpl" "xLoc" <-xLink SetScriptVar
<-currUnit "linktower.crpl" "yLoc" <-yLink SetScriptVar
<-currUnit "linktower.crpl" "xLink" <-x SetScriptVar
<-currUnit "linktower.crpl" "yLink" <-y SetScriptVar

<-currUnit "linktower.crpl" "Color" <-Color SetScriptVar
<-Type "Emitter" eq if
<-currUnit "linktower.crpl" "Type" "Spore" SetScriptVar
else
<-currUnit "linktower.crpl" "Type" "Emitter" SetScriptVar
endif
<-currUnit "linktower.crpl" "EmStr" <-EmStr SetScriptVar
<-currUnit "linktower.crpl" "EmInitIntFrms" <-EmInitIntFrms SetScriptVar
<-currUnit "linktower.crpl" "EmIntFrms" <-EmIntFrms SetScriptVar
<-currUnit "linktower.crpl" "SpNum" <-SpNum SetScriptVar
<-currUnit "linktower.crpl" "SpInitIntFrms" <-SpInitIntFrms SetScriptVar
<-currUnit "linktower.crpl" "SpIntFrms" <-SpIntFrms SetScriptVar
<-currUnit "linktower.crpl" "SpStr" <-SpStr SetScriptVar
endif
endif

:awake
#hack stores currentcoords so that the main gametower can use getscriptvar to get my coordinates
CurrentCoords Swap ->xLoc ->yLoc
#clears out the popuptext
"" SetPopupText
"" SetText
#Init imagesize to emulate weed-like growth of the tower
Self "main" 0.33333 0.33333 SetImageScale
Self CONST_CELLHEIGHT 6 SetUnitAttribute
Self CONST_CELLWIDTH 6 SetUnitAttribute
Self CONST_TAKEMAPSPACE 1 SetUnitAttribute
Self CONST_CONNECTABLE 0 SetUnitAttribute
Self CONST_COUNTSFORVICTORY 1 SetUnitAttribute
Self CONST_NULLIFIERDAMAGES 1 SetUnitAttribute
Self CONST_CREATEPZ 0 SetUnitAttribute
Self CONST_CONNECTABLE 0 SetUnitAttribute
Self CONST_REQUESTPACKETS 0 SetUnitAttribute
Self CONST_REQUESTACPACKETS 0 SetUnitAttribute
Self CONST_CANREQUESTAMMO 0 SetUnitAttribute
Self CONST_SUPPORTSDIGITALIS 0 SetUnitAttribute
"Awake" Trace

First

Here's some hints about how the mechanics work.

Spoiler

Towers start at 0% health. When they reach 100% they begin emitting creeper or spores, depending on their designation. See the image or the popup text for the designation.
[close]

Spoiler

Pairs of towers are "connected" by a link that allows one tower to resurrect its partner. Pairs are defined by color, which you can see if you mouse over it.
[close]

Spoiler

Killing a tower results in it being resurrected back by it's linked partner, but at 0% health. It will then proceed to grow back to full health over time.
[close]

Spoiler

A linked partner cannot resurrect its dead mate if it's health is below 33.3%. Once it reaches 33.3%, it will resurrect, however.
[close]

Spoiler

To effectively kill a pair, you have to kill them both before either one can reach 33.3% in health.
[close]

First

Here are a few tips that came to me while developing the map:

Spoiler

Establish a foothold using the power pack that's near the center of the map. Build a few reactors using the powerpack energy. Continue to build reactors to support Bertha's later.
[close]

Spoiler

Spores will be the first real problem. Build some beam towers, maybe 4 to start, but around 8 will be needed. The spore alert bar is not working in this map (too lazy to adopt existing good code). So, keep any eye out for spore timers (mouse over the spore towers for launch countdowns).
[close]

Spoiler

Build a forge early to capitalize on the two aether packs. Once you get the 500 aether, research energy efficiency (the opening phase is energy lean) and at least one firing rate (to kill spores more easily)
[close]

Spoiler

Look for a linked pair that are nearby and close to each other. Go for those first. Once you get a pair killed and cleared, build Berthas on the PZ. Use one on autotarget mode for strategic bombing of the deep creeper. Use on on manual target mode for tactical bombing.
[close]

Spoiler

A few terps will help with the annoying, broken terrain.
[close]



burguertime

Two things:

Spoiler
Bug: if you nullify a pair in the same frame (or veeeery close) they do not leave a power zone behind.
[close]

Spoiler
Score comparison on this map is impossible, since the randomness of placement and strengths could make hell or heaven.
[close]
Don't make a slog just because. Be like Master Mapmaker SPIFFEN:
Quote from: themaskedcrusader on October 05, 2010, 05:09:33 PM
(...)Difficulty is subjective. (...)
SPIFFEN chooses to rate each map as trivial because they believe that the difficulty of the map depends on the capability of the player.
BAD RATING: MEASUREMENT OF MAP HARDNESS.
Quote from: DumbCreeperGamer"Ugh, me no finish map, map too hard, ME RATE ONE.
oOga OoGa to you too.

First

QuoteBurguertime's good points (from above)

Agree on both. I got stuck on one or two race conditions that made the crpl code a bit messy. At the frame level, it's hard to determine how the script will behave between towers, so the issue you pointed out is yet unsolved. There is a better way, I am sure, I'm just too lazy (and already thinking on a new map idea) to fix it now.

As far as the score, you have a good point. I didn't think about that when designing the random start. Not sure how players feel about a random start (any thoughts out there?) A determined start is a bit like a game of solitaire without shuffling the cards. But on the other hand, pinning tactics down by trial and error is harder/more frustrating when the pieces are moving around. For myself, I might restart until I thought the board looked good - either easy or challenging. (Which gets me wondering if there's a way to select normal/heroic modes before the start, then set the board accordingly....)

- First

planetfall

Brilliant idea, but poor execution.

Basically the same as what Burguertime said. My first two attempts were pretty bad because there was an emitter on the left-center plateau. Third time I got a spore tower there and was able to beat it, but at first I was like "how is this at all possible?"

If you reused this script on a map where the enemies were fixed, I would absolutely love the mechanic. Reminded me of capping emitters in game 1. But as it stands it might be possible for someone relatively new to the game to get an absolute monster of a level, then say "this map is bugged/stupid/w/e".

Quote from: First on February 25, 2014, 04:06:51 AM
(Which gets me wondering if there's a way to select normal/heroic modes before the start, then set the board accordingly....)

Hmm... that + my above comment makes me wonder if it's possible to detect storyline shield keys in CS maps. If so it could be possible to create a map that adapts to a player's skill level based on how far they are in the story. On the other hand someone could reset the story to make such a map easier...

Or you could use this.
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.

burguertime

DON'T TAKE ME WRONG.

YOUR MAP WAS SURPRISINGLY REFRESHING AND FUN TO PLAY.

I really don't comment on crap maps, just skip them and hide from list forever.

Your idea was awesome, the randomness is great, and I really don't care about scoring.

For the ones having a tough time with the towers,

Spoiler
Re-roll the nodes by nullifying them. Their stats when reborn will be random. Even if you can't get the pair, changing a intensity 70 interval 0.5 emitter to a intensity 60 interval 1.7 will be a timesaver.
[close]
Don't make a slog just because. Be like Master Mapmaker SPIFFEN:
Quote from: themaskedcrusader on October 05, 2010, 05:09:33 PM
(...)Difficulty is subjective. (...)
SPIFFEN chooses to rate each map as trivial because they believe that the difficulty of the map depends on the capability of the player.
BAD RATING: MEASUREMENT OF MAP HARDNESS.
Quote from: DumbCreeperGamer"Ugh, me no finish map, map too hard, ME RATE ONE.
oOga OoGa to you too.

Helper

#9
Dad-gummed-blanket-blank-it!

:)

Make sure you get your timing right on taking out the pairs. I had to play Ping-Pong for about 5 minutes before getting the job done.
[EDIT] NOT Done finished yet, but having a ball!

burguertime

Quote from: Helper on February 26, 2014, 10:19:53 AM
Dad-gummed-blanket-blank-it!

:)

Make sure you get your timing right on taking out the pairs. I had to play Ping-Pong for about 5 minutes before getting the job done.
Done finished yet, but having a ball!

Spoiler
Build the nullifier next to the spore tower, and set it to DISABLED (red shade, not the cancel sign) once its energy level is at 44. Mostly the other six packets are already in the network, and it will reach fifty and STAY PUT. Build its brother, and then do the same thing.

Pause game, select both, activate them and unpause the game. Both will die in the SAME FRAME, triggering the no-PZ bug I talked above.
[close]
Don't make a slog just because. Be like Master Mapmaker SPIFFEN:
Quote from: themaskedcrusader on October 05, 2010, 05:09:33 PM
(...)Difficulty is subjective. (...)
SPIFFEN chooses to rate each map as trivial because they believe that the difficulty of the map depends on the capability of the player.
BAD RATING: MEASUREMENT OF MAP HARDNESS.
Quote from: DumbCreeperGamer"Ugh, me no finish map, map too hard, ME RATE ONE.
oOga OoGa to you too.

teknotiss

Quote from: burguertime on February 26, 2014, 07:44:21 PM
Build the nullifier next to the spore tower, and set it to DISABLED

or use the Disarm function?
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

Jamz

I feel like this post of mine is gonna be useless since it's already been said but yeah, the starting randomness put me off. Idea seems amazing but really didn't like that the map was different on a different run.

Karsten75

This map has been removed from the playlist by request of the author.

I am not removing this thread since the content may be useful to others.