From c01cae990ee4f8343cf1b8084a3a7f68a1ad300a Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Sun, 7 Jan 2018 20:59:05 +0100 Subject: [PATCH] HotIce: Add Eci Toh and Miami Ice themes Thanks to K-Pone and KKenny! --- planet/Arena.ocf/HotIce.ocs/Map.c | 35 ++++-- .../HotIce.ocs/Material.ocg/BlackIce.ocm | 21 ++++ .../HotIce.ocs/Material.ocg/BlackWater.ocm | 14 +++ .../HotIce.ocs/Material.ocg/Rock.ocm | 20 +++ .../HotIce.ocs/Material.ocg/TEXMAP.TXT | 4 +- .../HotIce.ocs/Material.ocg/black.png | Bin 0 -> 69 bytes planet/Arena.ocf/HotIce.ocs/ParameterDefs.txt | 28 +++++ planet/Arena.ocf/HotIce.ocs/Script.c | 45 +++++++ planet/Arena.ocf/HotIce.ocs/SkyMiami.png | Bin 0 -> 439 bytes planet/Arena.ocf/HotIce.ocs/StringTblDE.txt | 14 +++ planet/Arena.ocf/HotIce.ocs/StringTblUS.txt | 14 +++ .../HotIce.ocs/System.ocg/MiamiBoomPack.c | 43 +++++++ .../HotIce.ocs/System.ocg/MiamiCoconut.c | 37 ++++++ .../HotIce.ocs/System.ocg/MiamiEffects.c | 116 ++++++++++++++++++ .../HotIce.ocs/System.ocg/MiamiIronBomb.c | 22 ++++ .../HotIce.ocs/System.ocg/MiamiWindBag.c | 33 +++++ 16 files changed, 436 insertions(+), 10 deletions(-) create mode 100644 planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackIce.ocm create mode 100644 planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackWater.ocm create mode 100644 planet/Arena.ocf/HotIce.ocs/Material.ocg/Rock.ocm create mode 100644 planet/Arena.ocf/HotIce.ocs/Material.ocg/black.png create mode 100644 planet/Arena.ocf/HotIce.ocs/SkyMiami.png create mode 100644 planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiBoomPack.c create mode 100644 planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiCoconut.c create mode 100644 planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiEffects.c create mode 100644 planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiIronBomb.c create mode 100644 planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiWindBag.c diff --git a/planet/Arena.ocf/HotIce.ocs/Map.c b/planet/Arena.ocf/HotIce.ocs/Map.c index 686fc5d6b..aae9375b4 100644 --- a/planet/Arena.ocf/HotIce.ocs/Map.c +++ b/planet/Arena.ocf/HotIce.ocs/Map.c @@ -5,15 +5,21 @@ @authors Sven2 */ +static g_theme; + // Called be the engine: draw the complete map here. public func InitializeMap(proplist map) { + InitTheme(); + // Map type 0: One big island; more small islands above // Map type 1: Only many small islands var t = SCENPAR_MapType; var w = map.Wdt, h=map.Hgt; g_map_width = w; + if (g_theme.BackgroundMat) + map->Draw(g_theme.BackgroundMat, nil, [0,0,w,h]); // Bottom lava lake map->Draw("^DuroLava", nil, [0,h*4/5,w,h/5]); @@ -21,15 +27,28 @@ public func InitializeMap(proplist map) if (t == 1) DrawSmallIslandsMap(map); // Alternate texctures - var icealt_tex = { Algo=MAPALGO_RndChecker, Wdt=2, Hgt=3 }; + var icealt_tex = { Algo=MAPALGO_RndChecker, Wdt=2, Hgt=3, Ratio=g_theme.AltMatRatio }; icealt_tex = { Algo=MAPALGO_Turbulence, Op=icealt_tex }; - icealt_tex = { Algo=MAPALGO_And, Op=[Duplicate("Ice"), icealt_tex]}; - map->Draw("^Ice-ice", icealt_tex); + icealt_tex = { Algo=MAPALGO_And, Op=[Duplicate(RegexMatch(g_theme.MatNames[1], "\\w+", Regex_FirstOnly)[0][0]), icealt_tex]}; + map->Draw(g_theme.MatNames[0], icealt_tex); // Return true to tell the engine a map has been successfully created. return true; } +func InitTheme() +{ + var theme = SCENPAR_Theme; + if (theme == 0) // Random Ice + theme = 1 + Random(3); + if (theme == 1) // Hot Ice + return g_theme = HotIce; + if (theme == 2) // Miami Ice + return g_theme = MiamiIce; + if (theme == 3) // Eci Toh + return g_theme = EciToh; +} + func SpawnPositionCount() { return Max(Max(GetStartupPlayerCount(), GetPlayerCount()), 2); @@ -42,16 +61,16 @@ func DrawBigIslandMap(proplist map) // Big var island = { Algo=MAPALGO_Polygon, X=[0,w,w*6/8,w*2/8], Y=[h*4/10,h*4/10,h*7/10,h*7/10] }; island = { Algo=MAPALGO_Turbulence, Op=island, Amplitude=[0, 8] }; - map->Draw("^Ice-ice2", island, [w/10,h*13/20,w*8/10,h*3/20]); + map->Draw(g_theme.MatNames[1], island, [w/10,h*13/20,w*8/10,h*3/20]); // Make sure one row of inner island is drawn because it's used for player spawns - map->Draw("^Ice-ice2", nil, [w*3/10,h*13/20,w*4/10+1,1]); + map->Draw(g_theme.MatNames[1], nil, [w*3/10,h*13/20,w*4/10+1,1]); // Smaller floating var n_islands = 12; while(n_islands--) { var x = w*1/10 + Random(w*8/10); var y = h*2/10 + Random(h*3/10); - map->Draw("^Ice-ice2", nil, [x,y,1,1]); + map->Draw(g_theme.MatNames[1], nil, [x,y,1,1]); } // Player spawns simply in middle of big island var plrcnt = SpawnPositionCount(); @@ -77,7 +96,7 @@ func DrawSmallIslandsMap(proplist map) szy = 1; if (y > h/2) szy += Random(2); // lower islands sometimes taller if (Abs(x-w/2) < w/10) szx += Random(3); // central islands sometimes wider - map->Draw("^Ice-ice2", nil, [x-szx,y,1+2*szx,szy]); + map->Draw(g_theme.MatNames[1], nil, [x-szx,y,1+2*szx,szy]); } // Balloon spawn: do nothing further if (SCENPAR_SpawnType == 1) @@ -90,7 +109,7 @@ func DrawSmallIslandsMap(proplist map) var x = w*2/10 + i * (w*6/10) / (spawn_island_count - 1); var y = Max(1, h/10) + Abs(x-w/2) * 3*h/10/w; if (SCENPAR_Weapons) y += 4; // Grenade launcher mode needs lower starting islands to prevent camping - map->Draw("^Ice-ice2", nil, [x,y,1,1]); + map->Draw(g_theme.MatNames[1], nil, [x,y,1,1]); g_player_spawn_positions[i] = [x, y-1]; } return true; diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackIce.ocm b/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackIce.ocm new file mode 100644 index 000000000..8a4731bce --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackIce.ocm @@ -0,0 +1,21 @@ +[Material] +Name=BlackIce +Shape=TopFlat +Density=60 +Friction=15 +DigFree=1 +BlastFree=1 +Blast2Object=BlackIce +Dig2Object=BlackIce +Dig2ObjectRatio=200 +Blast2ObjectRatio=220 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +TempConvStrength=3 +AboveTempConvert=10 +AboveTempConvertDir=1 +AboveTempConvertTo=BlackWater +Placement=21 +TextureOverlay=black +Soil=1 diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackWater.ocm b/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackWater.ocm new file mode 100644 index 000000000..1e7f8e3f9 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/BlackWater.ocm @@ -0,0 +1,14 @@ +[Material] +Name=BlackWater +Density=25 +Instable=1 +MaxAirSpeed=25 +MaxSlide=10000 +WindDrift=30 +Corrode=100 +Extinguisher=1 +TempConvStrength=3 +BelowTempConvert=-10 +BelowTempConvertTo=BlackIce +Placement=10 +TextureOverlay=black diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/Rock.ocm b/planet/Arena.ocf/HotIce.ocs/Material.ocg/Rock.ocm new file mode 100644 index 000000000..1ebcea97c --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/Rock.ocm @@ -0,0 +1,20 @@ +[Material] +Name=Rock +Shape=TopFlat +Density=60 +Friction=15 +DigFree=0 +BlastFree=1 +Blast2Object=Rock +Dig2Object=Rock +Dig2ObjectRatio=200 +Blast2ObjectRatio=220 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +TempConvStrength=4 +AboveTempConvert=10 +AboveTempConvertDir=1 +AboveTempConvertTo=DuroLava +Placement=21 +TextureOverlay=rock \ No newline at end of file diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT b/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT index da559c6c1..c80634885 100644 --- a/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT @@ -13,7 +13,7 @@ OverloadTextures 22=Acid-acid 23=Lava-lava_red 24=DuroLava-lava_red -25=Water-water +25=BlackWater-black #26=Oil-Smooth 27=Acid-acid 28=Lava-lava_red @@ -59,7 +59,7 @@ OverloadTextures 66=Ice-ice 67=Ice-ice2 68=Ice-ice2 - +69=BlackIce-black 70=Snow-snow1 71=Snow-snow1 72=Snow-snow1 diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/black.png b/planet/Arena.ocf/HotIce.ocs/Material.ocg/black.png new file mode 100644 index 0000000000000000000000000000000000000000..cf671d132881ed90f439205faa0b9831b9ca996c GIT binary patch literal 69 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2ryJf1F&Asp9}6A}`DJQfBCreateCountdown(3); + SetSky(g_theme.Sky); + g_theme->InitializeRound(); + return true; } @@ -461,3 +465,44 @@ func IsFirestoneSpot(int x, int y) // Very thorough ice surrounding check so they don't explode right away or when the first layer of ice melts return GBackSolid(x,y-1) && GBackSolid(x,y+4) && GBackSolid(x-2,y) && GBackSolid(x+2,y); } + +// ============= Themes ============= +static const HotIce = new Global { + InitializeRound = func() { }, + MatNames = ["^Ice-ice", "^Ice-ice2"], + AltMatRatio = 50, + BackgroundMat = nil, + Sky = "Default", +}; + +static const EciToh = new HotIce { + MatNames = ["Coal", "Rock-rock"], + AltMatRatio = 8, + BackgroundMat = "Tunnel", +}; + +static const MiamiIce = new HotIce { + MatNames = ["^BlackIce-black", "^BlackIce-black"], + Sky = "SkyMiami", + + InitializeRound = func() + { + // Colors + Scenario->CreateEffect(MiamiObjects, 1, 1); + + Tree_Coconut->Place(RandomX(7, 13)); + }, + + MiamiObjects = new Effect { + Timer = func(int time) + { + for (var o in FindObjects(Find_NoContainer())) + { + if (o->GetID() == Tree_Coconut) + continue; + o->SetClrModulation(HSL(time, 255, 100)); + } + }, + }, + +}; diff --git a/planet/Arena.ocf/HotIce.ocs/SkyMiami.png b/planet/Arena.ocf/HotIce.ocs/SkyMiami.png new file mode 100644 index 0000000000000000000000000000000000000000..bba521fa289b87acbf8312d57fbbb6b53660d970 GIT binary patch literal 439 zcmV;o0Z9IdP) z0s^4lRRrkofp_URzQ3dE-Tdp_=t#<&`3_gak7wh}`PY13|D-$dH~5Knh>!Vj;N|Yi zI8%J#kLNdkR(Q|b;fLQ+`Ig{O%m-NL8Jw6oD*M-QEB^&u$K^Tj&hMn3`S(q|JO7sb zkR;#e&)z?$caVRauXGNn(n8nqT)jl-qniDb_oLE_|I03Zim&z?!#*i>hyQV(UU+mI z+`VBz2y}%@@GD$)@AG?W9Pt7kYTg!nTVI7|#xwD_(B0{mXW}0p#Ebmncq;9e)R%mV z?{@|t?RmoA#i#N2b^S5FOYZ?c`azgFU*wb3_qF^U^zT3Pvw1n5-(>&9cst#b@992R h?T459Fx`*$`3Ex)L@Pg#r1t;-002ovPDHLkV1oTT)=vNc literal 0 HcmV?d00001 diff --git a/planet/Arena.ocf/HotIce.ocs/StringTblDE.txt b/planet/Arena.ocf/HotIce.ocs/StringTblDE.txt index 2fbaa6ea1..eb04b2160 100644 --- a/planet/Arena.ocf/HotIce.ocs/StringTblDE.txt +++ b/planet/Arena.ocf/HotIce.ocs/StringTblDE.txt @@ -1,21 +1,35 @@ +Theme=Thema +DescTheme=Genug Eis gesehen? +HotIce=Heißes Eis +DescHotIce=Das Übliche: Eis und Lava +RandomIce=Random Eis +DescRandomIce=Zufälliges Thema jede Runde +MiamiIce=Miami Eis +DescMiamiIce=Augenkrebs +EciToh=Eci Toh +DescEciToh=Was mag der Name nur bedeuten?! + MapType=Karte DescMapType=Definiert die Landschaftsform. MapTypeBigIsland=Große Insel DescMapTypeBigIsland=Eine zentrale Hauptinsel mit einigen Eisflecken in der Luft. MapTypeSpots=Kleine inseln DescMapTypeSpots=Viele kleine Eisflecken in der Luft. + Weapons=Waffen DescWeapons=Setzt fest welche Angriffsmittel den Spielern zur Verfügung stehen. WeaponsClassic=Klassisch DescWeaponsClassic=Bögen, Speere, Keulen und einige Feuersteine WeaponsExplosive=Explosiv DescWeaponsExplosive=Nur Granatwerfer mit Endlosmunition + SpawnType=Startpunkte DescSpawn=Legt fest, wo die Clonks der Spieler starten. ClassicSpawn=Klassisch DescClassicSpawn=Die Clonks starten auf den Eisinseln. BalloonSpawn=Ballons DescBalloonSpawn=Die Clonks fallen mit Ballons vom Himmel. + Rounds=Rundenzahl DescRounds=Mehrere Runden spielen Stalemate=Unentschieden! diff --git a/planet/Arena.ocf/HotIce.ocs/StringTblUS.txt b/planet/Arena.ocf/HotIce.ocs/StringTblUS.txt index 6871e53d1..7f371cbed 100644 --- a/planet/Arena.ocf/HotIce.ocs/StringTblUS.txt +++ b/planet/Arena.ocf/HotIce.ocs/StringTblUS.txt @@ -1,21 +1,35 @@ +Theme=Theme +DescTheme=In case you don't like ice. +HotIce=Hot Ice +DescHotIce=The standard setup: ice and lava +RandomIce=Random Ice +DescRandomIce=Random theme every round +MiamiIce=Miami Ice +DescMiamiIce=Cool Ice +EciToh=Eci Toh +DescEciToh=Battle on rocky islands! + MapType=Map DescMapType=Defines the shape of the landscape. MapTypeBigIsland=Big island DescMapTypeBigIsland=One central main island with small spots of ice in the air above. MapTypeSpots=Small islands DescMapTypeSpots=Many small spots of ice in the air. + Weapons=Weapons DescWeapons=Defines which weapons are available for players. WeaponsClassic=Classic DescWeaponsClassic=Bows, spears and clubs available in chests. WeaponsExplosive=Explosive DescWeaponsExplosive=Only grenade lauchers and wind bags available. + SpawnType=Spawn points DescSpawn=Defines where the starting positions will be. ClassicSpawn=Classic DescClassicSpawn=All clonks start on the ice islands. BalloonSpawn=Balloons DescBalloonSpawn=The clonks will drop with balloons from the sky. + Rounds=Number of rounds DescRounds=Play for multiple rounds. Stalemate=Stalemate! diff --git a/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiBoomPack.c b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiBoomPack.c new file mode 100644 index 000000000..8b9f52246 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiBoomPack.c @@ -0,0 +1,43 @@ +#appendto Boompack + +protected func FxFlightTimer(object pTarget, effect, int iEffectTime) +{ + if (g_theme != MiamiIce) return inherited(pTarget, effect, iEffectTime, ...); + + // clonk does sense the danger and with great presence of mind jumps of the rocket + if(fuel<20 && rider) + { + JumpOff(rider,30); + } + + if(!Random(105)) Sound("Fire::Cracker"); + + if(fuel<=0) + { + DoFireworks(); + return; + } + + var ignition = iEffectTime % 9; + + if(!ignition) + { + var angle = GetR()+RandomX(-dirdev,dirdev); + SetXDir(3*GetXDir()/4+Sin(angle,24)); + SetYDir(3*GetYDir()/4-Cos(angle,24)); + SetR(angle); + } + + var x = -Sin(GetR(), 10); + var y = +Cos(GetR(), 10); + + var xdir = GetXDir() / 2; + var ydir = GetYDir() / 2; + + if(!effect.clr) + effect.clr = HSL(Random(255), 255, 100); + + CreateParticle("FireDense", x, y, PV_Random(xdir - 4, xdir + 4), PV_Random(ydir - 4, ydir + 4), PV_Random(16, 38), Particles_Colored(Particles_Thrust(), effect.clr), 5); + + fuel--; +} diff --git a/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiCoconut.c b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiCoconut.c new file mode 100644 index 000000000..7320c8f4e --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiCoconut.c @@ -0,0 +1,37 @@ +#appendto Tree_Coconut + +public func Construction() +{ + if (g_theme == MiamiIce) + SetClrModulation(RGB()); + return _inherited(); +} + +public func BurstIntoAshes() +{ + if (g_theme != MiamiIce) return inherited(...); + + var particles = + { + Prototype = Particles_Dust(), + R = 50, G = 50, B = 50, + Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(2, 10), 1000, 0), + }; + + var r = GetR(); + var size = GetCon() * 110 / 100; + + for(var cnt = 0; cnt < 10; ++cnt) + { + var distance = Random(size/2); + var x = Sin(r, distance); + var y = -Cos(r, distance); + + for(var mirror = -1; mirror <= 1; mirror += 2) + { + CreateParticle("Dust", x * mirror, y * mirror, PV_Random(-3, 3), PV_Random(-3, -3), PV_Random(18, 1 * 36), particles, 2); + CastPXS("BlackIce", 5, 30, x * mirror, y * mirror); + } + } + RemoveObject(); +} diff --git a/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiEffects.c b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiEffects.c new file mode 100644 index 000000000..b3c383398 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiEffects.c @@ -0,0 +1,116 @@ +/* + Contains functions for (visual) effects that require particles or definitions from Objects.ocd to be loaded. +*/ + +/* +Creates a visual explosion effect at a position. +smoothness (in percent) determines how round the effect will look like +*/ +global func ExplosionEffect(int level, int x, int y, int smoothness, bool silent, int damage_level) +{ + if (g_theme != MiamiIce) return inherited(level, x, y, smoothness, silent, damage_level, ...); + + // Zero-size explosion doesn't affect anything + if (level <= 0) return; + + if(!silent) //Does object use it's own explosion sound effect? + { + // Select sound according to level: from 1 to 3, add the * to allow alternatives. + var grade = BoundBy(level / 10 - 1, 1, 3); + if(GBackLiquid(x, y)) + SoundAt(Format("Fire::BlastLiquid%d*",grade), x, y); + else + SoundAt(Format("Fire::Blast%d*", grade), x, y); + } + + // possibly init particle definitions? + if (!ExplosionParticles_Blast) + ExplosionParticles_Init(); + + smoothness = smoothness ?? 0; + var level_pow = level ** 2; + var level_pow_fraction = Max(level_pow / 25, 5 * level); + var wilderness_level = level * (100 - smoothness) / 100; + var smoothness_level = level * smoothness / 100; + + var smoke_size = PV_KeyFrames(0, 180, level, 1000, level * 2); + var blast_size = PV_KeyFrames(0, 0, 0, 260, level * 2, 1000, level); + var blast_smooth_size = PV_KeyFrames(0, 0, 0, 250, PV_Random(level, level * 2), 1000, level); + var star_size = PV_KeyFrames(0, 0, 0, 500, level * 2, 1000, 0); + var shockwave_size = PV_Linear(0, level * 4); + + var clr = HSL(Random(255), 255, 100); + + CreateParticle("SmokeDirty", PV_Random(x - 10,x + 10), PV_Random(y - 10, y + 10), 0, PV_Random(-2, 0), PV_Random(50, 100), {Prototype = Particles_Colored(ExplosionParticles_Smoke, clr), Size = smoke_size}, Max(2, wilderness_level / 10)); + CreateParticle("SmokeDirty", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(20, 40), {Prototype = Particles_Colored(ExplosionParticles_BlastSmoothBackground, clr), Size = blast_smooth_size}, smoothness_level / 5); + CreateParticle("SmokeDirty", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(20, 40), {Prototype = Particles_Colored(ExplosionParticles_BlastSmooth, clr), Size = blast_smooth_size}, smoothness_level / 5); + CreateParticle("Dust", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), 0, 0, PV_Random(18, 25), {Prototype = Particles_Colored(ExplosionParticles_Blast, clr), Size = blast_size}, smoothness_level / 5); + CreateParticle("StarFlash", PV_Random(x - 6, x + 6), PV_Random(y - 6, y + 6), PV_Random(-wilderness_level/4, wilderness_level/4), PV_Random(-wilderness_level/4, wilderness_level/4), PV_Random(10, 12), {Prototype = Particles_Colored(ExplosionParticles_Star, clr), Size = star_size}, wilderness_level / 3); + CreateParticle("Shockwave", x, y, 0, 0, 15, {Prototype = Particles_Colored(ExplosionParticles_Shockwave, clr), Size = shockwave_size}, nil); + + // cast either some sparks on land or bubbles under water + if(GBackLiquid(x, y) && Global.CastBubbles) + { + Global->CastBubbles(level * 7 / 10, level, x, y); + } + else + { + CreateParticle("Magic", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-level_pow_fraction, level_pow_fraction), PV_Random(-level_pow_fraction, level_pow_fraction), PV_Random(25, 70), Particles_Colored(ExplosionParticles_Glimmer, clr), level); + } + + // very wild explosion? Smoke trails! + var smoke_trail_count = wilderness_level / 10; + var angle = Random(360); + var failsafe = 0; // against infinite loops + while (smoke_trail_count > 0 && (++failsafe < smoke_trail_count * 10)) + { + angle += RandomX(40, 80); + var smokex = Sin(angle, RandomX(level / 4, level / 2)); + var smokey = -Cos(angle, RandomX(level / 4, level / 2)); + if (GBackSolid(x + smokex, y + smokey)) + continue; + var lvl = 2 * wilderness_level; + CreateSmokeTrail(lvl, angle, x + smokex, y + smokey, clr); + smoke_trail_count--; + } + + // Temporary light effect + if (level > 5) + Global->CreateLight(x, y, level, Fx_Light.LGT_Blast); + + return; +} + +global func FxSmokeTrailStart(object target, proplist e, int temp, int color) +{ + if (g_theme != MiamiIce) return inherited(target, e, temp, color, ...); + + if (temp) + return; + + e.color = color ?? RGBa(255, 128, 0, 200); + + var c = SplitRGBaValue(color); + var alpha = (e.color >> 24) & 0xff; + e.particles_smoke = + { + R = c.R, + G = c.G, + B = c.B, + Alpha = PV_KeyFrames(0, 0, alpha/4, 200, alpha, 1000, 0), + Rotation = PV_Random(-45,45), + ForceX = PV_Wind(20), + ForceY = PV_Gravity(-10), + }; + + e.particles_blast = + { + R = PV_Linear((e.color >> 16) & 0xff, 0), + G = PV_Linear((e.color >> 8) & 0xff, 0), + B = PV_Linear((e.color >> 0) & 0xff, 0), + Alpha = PV_KeyFrames(0, 0, alpha, 500, 3*alpha/4, 1000, 0), + Rotation = PV_Direction(), + BlitMode = GFX_BLIT_Additive, + Stretch = PV_Speed(1500, 1000) + }; +} diff --git a/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiIronBomb.c b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiIronBomb.c new file mode 100644 index 000000000..8f6be415b --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiIronBomb.c @@ -0,0 +1,22 @@ +#appendto IronBomb + +public func FxFuseBurnTimer(object target, effect fx, int time) +{ + if (g_theme != MiamiIce) return inherited(target, fx, time, ...); + + if(!fx.clr) + fx.clr = HSL(Random(255), 255, 100); + + // Emit some smoke from the fuse hole. + var i = 3; + var x = +Sin(GetR(), i); + var y = -Cos(GetR(), i); + CreateParticle("Smoke", x, y, x, y, PV_Random(18, 36), Particles_Colored(Particles_Smoke(), fx.clr), 2); + // Explode if time is up. + if (time >= FuseTime()) + { + DoExplode(); + return FX_Execute_Kill; + } + return FX_OK; +} diff --git a/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiWindBag.c b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiWindBag.c new file mode 100644 index 000000000..08859492f --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/System.ocg/MiamiWindBag.c @@ -0,0 +1,33 @@ +#appendto WindBag + +public func FxIntBurstWindStart(object target, proplist effect, int temp, object clonk, int x, int y) +{ + if (g_theme != MiamiIce) return inherited(target, effect, temp, clonk, x, y, ...); + + if (temp) + return FX_OK; + effect.Interval = 1; + effect.clonk = clonk; + effect.x = clonk->GetX(); + effect.y = clonk->GetY(); + effect.angle = Angle(0, 0, x, y); + // Sound effect. + Sound("Objects::Windbag::Gust"); + // Particle effect. + + var clr = HSL(Random(255), 255, 100); + + for (var dr = 12; dr < 32; dr++) + { + var r = RandomX(-20, 20); + var sx = Sin(effect.angle + r, dr / 2); + var sy = -Cos(effect.angle + r, dr / 2); + var vx = Sin(effect.angle + r, 2 * fill_amount / 3 + 12); + var vy = -Cos(effect.angle + r, 2 * fill_amount / 3 + 12); + if (!GBackSolid(sx, sy)) + CreateParticle("Air", sx, sy, vx, vy, 36, Particles_Colored(Particles_Air(), clr)); + } + // Make a timer call for the instant movement effect. + FxIntBurstWindTimer(target, effect, 0); + return FX_OK; +}