diff --git a/planet/Arena.ocf/FlintBrawl.ocs/DescDE.txt b/planet/Arena.ocf/FlintBrawl.ocs/DescDE.txt new file mode 100644 index 000000000..90157deea --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/DescDE.txt @@ -0,0 +1,10 @@ + Flintgemenge + +Ein Kampf ohne klassische Waffen: In diesem Szenario bewirft man sich stattdessen mit einer großen Auswahl an Flints. + +Ziel: Last Man Standing mit mehreren Runden (Bleibe als Letzter am Leben und gewinne die meisten Runden) + +- Der Windbeutel eignet sich nicht nur für große Sprünge, sondern erlaubt es auch, geworfenen Flints einen extra Schub zu geben. +- Die Kanone ist bereits mit Schießpulver geladen und schussbereit. +- Vorsicht, es regnet Chippiemeteoriten und der Boden ist offen. +- Je länger eine Runde dauert, umso stärkere Flints erscheinen im Untergrund. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/DescUS.txt b/planet/Arena.ocf/FlintBrawl.ocs/DescUS.txt new file mode 100644 index 000000000..1646d5e82 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/DescUS.txt @@ -0,0 +1,10 @@ + Flint Brawl + +Fight without the usual weapons: In this scenario, everyone throws flints instead. + +Goal: Last Man Standing with multiple rounds (Be the one to stay alive longest and win most rounds) + +- The wind bag isn't only for getting to the high ground, but can also give an extra push to flying flints. +- The cannon is loaded with gunpowder and ready to shoot. +- Be careful, it's raining chippies and you can fall out of the bottom. +- The longer the round, the stronger the flints that spawn underground. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/DefCore.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/DefCore.txt new file mode 100644 index 000000000..b427208e6 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=Bouncy +Version=6,0 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 +Value=5 +Mass=10 +Projectile=1 +Fragile=1 \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Graphics.8.png b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Graphics.8.png new file mode 100644 index 000000000..44529e1ea Binary files /dev/null and b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Graphics.8.png differ diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Script.c b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Script.c new file mode 100644 index 000000000..118e2db62 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/Script.c @@ -0,0 +1,73 @@ +/*--- Flint ---*/ + +local counter = 0; + +public func IsGrenadeLauncherAmmo() { return true; } + +protected func Construction() +{ + return true; +} + +func HitEffect() +{ + var smoke = + { + Alpha = PV_Linear(255, 0), + Size = 15, + DampingX = 900, DampingY = 900, + R = 100, G = 100, B = 100, + Phase = PV_Random(0, 15) + }; + CreateParticle("Smoke", 0, 0, PV_Random(-5,5), PV_Random(-5,5), 20, smoke, 25); +} + +func Hit(int xdir, int ydir) +{ + if (counter < 2 + Random(10)) + { + Bounce(xdir, ydir); + Sound("Hits::Materials::Glass::GlassHit[34]", {pitch = 100 + 10 * counter}); + counter++; + HitEffect(); + return; + } + + // Cast lots of shrapnel. + var shrapnel_count = 40; + var offset = GetSurfaceVector(0, 0); + for (var cnt = 0; cnt < shrapnel_count; cnt++) + { + var shrapnel = CreateObject(Shrapnel, offset[0], offset[1]); + shrapnel->SetVelocity(Random(359), RandomX(100, 140)); + shrapnel->SetRDir(-30 + Random(61)); + shrapnel->Launch(GetController()); + CreateObjectAbove(BulletTrail)->Set(shrapnel, 2, 30); + } + Sound("Hits::Materials::Glass::GlassShatter", {volume = 20}); + Fireworks(RGB(150, 115, 200)); + RemoveObject(); +} + +func Bounce(int xdir, int ydir) +{ + var angle = Angle(0, 0, xdir, ydir); + + var surface = GetSurfaceVector(0, 0); + var surface_angle = Angle(0, 0, surface[0], surface[1]); + var angle_diff = GetTurnDirection(angle - 180, surface_angle); + var new_angle = surface_angle + angle_diff + RandomX(-10, 10); + + var speed = Distance(0, 0, xdir, ydir); + speed = 4 * speed / 4; + SetXDir(Sin(new_angle, speed), 100); + SetYDir(-Cos(new_angle, speed), 100); +} + + +public func HasExplosionOnImpact() { return true; } + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 530; // cause it's explosive, players should see it in a pile of stuff diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblDE.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblDE.txt new file mode 100644 index 000000000..599eb0de5 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Flummy +Description=Springt rum. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblUS.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblUS.txt new file mode 100644 index 000000000..8e0ea5e2c --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/Bouncy.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Bouncy +Description=Bounces around. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/DefCore.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/DefCore.txt new file mode 100644 index 000000000..e497fcc20 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=ChippyFlint +Version=6,0 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=4 +VertexX=-5,5, 0, 0 +VertexY=0,0, -5, 5, +VertexFriction=20 +Value=5 +Mass=10 +Projectile=1 +Fragile=1 \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Graphics.8.png b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Graphics.8.png new file mode 100644 index 000000000..182fe07a1 Binary files /dev/null and b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Graphics.8.png differ diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Script.c b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Script.c new file mode 100644 index 000000000..e980a3596 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/Script.c @@ -0,0 +1,49 @@ +/*--- Flint ---*/ + +public func IsGrenadeLauncherAmmo() { return true; } + +protected func Construction() +{ + return true; +} + +func Hit() +{ + ScheduleCall(this, this.Fuse, 1, 1); + return true; +} + +func Fuse() +{ + Sound("Fire::Spark*"); + CreateParticle("Fire", 0, 0, PV_Random(-5, 5), PV_Random(-15, 5), PV_Random(10, 40), Particles_Glimmer(), 5); + return true; +} + +func Hit2() +{ + for (var i = 0; i < 10; ++i) + { + var egg = CreateObject(Chippie_Egg, 0, 0, GetController()); + egg.age = -5000; + egg->SetVelocity(Random(360), RandomX(20, 40)); + } + + var particles = + { + Prototype = Particles_Material(RGB(100, 255, 50)), + DampingX = 800, DampingY = 800, + ForceY = -GetGravity() / 10, + }; + CreateParticle("SmokeDirty", PV_Random(-5, 5), PV_Random(-5, 5), + PV_Random(-10, 10), PV_Random(-10, 10), + PV_Random(10, 20), particles, 60); + RemoveObject(); +} + +public func HasExplosionOnImpact() { return true; } + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 530; // cause it's explosive, players should see it in a pile of stuff \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblDE.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblDE.txt new file mode 100644 index 000000000..ec21d1d79 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Chippyflint +Description=Spawnt Chippies. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblUS.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblUS.txt new file mode 100644 index 000000000..c26919e10 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/ChippyFlint.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Chippy Flint +Description=Spawns chippies. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/DefCore.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/DefCore.txt new file mode 100644 index 000000000..2a3a049af --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=QuickSandBomb +Version=6,0 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 +Value=5 +Mass=10 +Projectile=1 +Fragile=1 \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Graphics.8.png b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Graphics.8.png new file mode 100644 index 000000000..2a4a9eebd Binary files /dev/null and b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Graphics.8.png differ diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Script.c b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Script.c new file mode 100644 index 000000000..1107451f8 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/Script.c @@ -0,0 +1,47 @@ +/*--- Flint ---*/ + +local fused_fx; + +public func IsGrenadeLauncherAmmo() { return true; } + +protected func Construction() +{ + return true; +} + +func HitEffect() +{ + var smoke = + { + Alpha = PV_Linear(255, 0), + Size = 15, + DampingX = 900, DampingY = 900, + R = 100, G = 100, B = 100, + Phase = PV_Random(0, 15) + }; + CreateParticle("Smoke", 0, 0, PV_Random(-5,5), PV_Random(-5,5), 20, smoke, 25); +} + +local FusedEffect = new Effect +{ + Timer = func() + { + this.Target->Explode(30); + } +}; + +func Hit(int xdir, int ydir) +{ + if (!fused_fx) + fused_fx = CreateEffect(FusedEffect, 1, 30); + ShakeFree(GetX(), GetY(), 10); + SetSpeed(xdir, ydir, 100); + Sound("Environment::Disasters::EarthquakeEnd"); +} + +public func HasExplosionOnImpact() { return true; } + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 530; // cause it's explosive, players should see it in a pile of stuff \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblDE.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblDE.txt new file mode 100644 index 000000000..ac7732589 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Treibsandflint +Description=Fällt durch Erde. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblUS.txt b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblUS.txt new file mode 100644 index 000000000..0af22bea2 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Flints.ocd/QuickSandBomb.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Quicksand Bomb +Description=Falls through earth. diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Map.c b/planet/Arena.ocf/FlintBrawl.ocs/Map.c new file mode 100644 index 000000000..2382afeff --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Map.c @@ -0,0 +1,183 @@ +/** + Flint Brawl + + @author Zapper +*/ + +#include Library_Map + + +// Called be the engine: draw the complete map here. +protected func InitializeMap(proplist map) +{ + // Retrieve the settings according to the MapSize setting. + var map_size = [50, 25]; + + // Set the map size. + map->Resize(map_size[0], map_size[1]); + + // Draw the main surface: a rectangle with some turbulence on top makes. + var rect = {X = 0, Y = 4 * map.Hgt / 10, Wdt = map.Wdt, Hgt = 6 * map.Hgt / 10}; + var surface = {Algo = MAPALGO_Rect, X = rect.X, Y = rect.Y, Wdt = rect.Wdt, Hgt = 8 * rect.Hgt / 6}; + surface = {Algo = MAPALGO_Turbulence, Iterations = 4, Amplitude = [0, 12], Seed = Random(65536), Op = surface}; + Draw("Earth", surface); + + // Draw materials inside the main surface. + DrawMaterials(rect, surface); + + for (var i = 0; i < 3; ++i) + DrawCave(RandomX(5, map_size[0] - 10), RandomX(5, map_size[1] - 10), 10, 5); + + // Return true to tell the engine a map has been successfully created. + return true; +} + +// Draws materials on the given surface. +public func DrawMaterials(proplist rect, proplist surface) +{ + var mask; + var x = rect.X; + var y = rect.Y; + var wdt = rect.Wdt; + var hgt = rect.Hgt; + + // A bit of different types of earth all around the surface. + mask = {Algo = MAPALGO_Rect, X = x, Y = y, Wdt = wdt, Hgt = hgt}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Earth-earth", mask, 4, 12); + DrawMaterial("Earth-earth_root", mask, 2, 16); + DrawMaterial("Earth-earth_spongy", mask, 2, 16); + DrawMaterial("Earth-earth", mask, 4, 12); + + // Coal and surface in the first layer. + mask = {Algo = MAPALGO_Rect, X = x, Y = y, Wdt = wdt, Hgt = hgt}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Firestone", mask, 4, 5); + DrawMaterial("Firestone", mask); + + // Some small lakes as well in a second layer . + mask = {Algo = MAPALGO_Rect, X = x, Y = y + 1 * hgt / 4, Wdt = wdt, Hgt = hgt / 4}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Firestone", mask, 4, 5); + DrawMaterial("Water", mask, 4, 10); + DrawMaterial("Ashes", mask, 4, 10); + + // The top border consists of top soil and dry earth and a bit of sand. + var border = {Algo = MAPALGO_Border, Top = 4, Op = surface}; + Draw("Earth", border); + var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = 30, Wdt = 2, Hgt = 2}; + var rnd_border = {Algo = MAPALGO_And, Op = [border, rnd_checker]}; + Draw("Ashes", rnd_border); + Draw("Earth-earth_root", rnd_border); + return; +} + +public func DrawCave(int x, int y, int wdt, int hgt) +{ + var cave_layer = CreateLayer("Gold", wdt, hgt); + var dug_out = cave_layer->DigOutCave(); + + cave_layer = {Algo = MAPALGO_Filter, Op = cave_layer, Filter="~Gold"}; + cave_layer = {Algo = MAPALGO_Scale, X = 200, Y = 150, Op = cave_layer, OffX = cave_layer.Wdt/2, OffY = cave_layer.Hgt/2}; + cave_layer = {Algo = MAPALGO_Offset, Op=cave_layer, OffX = x, OffY = y}; + + Blit(cave_layer); + //cave_layer = {Algo = MAPALGO_Border, Op = cave_layer, Left=2, Right=2, Top=2, Bottom=2}; + //Draw("Tunnel", cave_layer); + return dug_out; +} + +public func DigOutCave() +{ + var center_x = this.Wdt / 2; + var center_y = this.Hgt / 2; + var runners = [[center_x, center_y]]; + var runner_count = 1; + + var dug_out = 0; + var possible_x_dirs = [-1, 1, -1, 1, 0, 0]; + var possible_y_dirs = [0, 0, 0, 0, -1, 1]; + var possible_dir_count = 6; + var tunnel = GetMaterialTextureIndex("Tunnel"); + var iterations = 5 * Max(this.Wdt, this.Hgt); + for (var i = 0; i < iterations; ++i) + { + for (var r = 0; r < GetLength(runners); ++r) + { + var runner = runners[r]; + if (!runner) continue; + + // Get direction. + var x_dir = 0, y_dir = 0; + var r_dir = 0; + if (!Random(9)) r_dir = r % possible_dir_count; + else r_dir = Random(possible_dir_count); + x_dir = possible_x_dirs[r_dir]; + y_dir = possible_y_dirs[r_dir]; + + var x = runner[0] + x_dir; + var y = runner[1] + y_dir; + var solid = GetPixel(x, y) != tunnel; + var out_of_bounds = (x < 0) || (x > this.Wdt) || (y < 0) || (y > this.Hgt); + var destroy = out_of_bounds; + + runners[r] = [x, y]; + + if (solid) + { + ++dug_out; + this->SetPixel(x, y, tunnel); + if (!Random(1 + 1 * runner_count) && (runner_count < 4)) + { + var pos = -1; + for (var c = 0; c < GetLength(runners); ++c) + { + if (runners[c]) continue; + pos = c; + break; + } + if (pos == -1) PushBack(runners, [x, y]); + else runners[pos] = [x, y]; + + runner_count += 1; + } + } + else + { + destroy = destroy || !Random(10); + } + + if (destroy) + { + if (runner_count <= 1) + { + runners[r] = [center_x, center_y]; + } + else + { + runners[r] = nil; + runner_count -= 1; + } + } + } + } + + // Now perform a smoothing step. Just do it in place, meh. + for (var smooth = 0; smooth < 1; ++smooth) + { + for (var x = 1; x < this.Wdt - 1; ++x) + for (var y = 1; y < this.Hgt - 1; ++y) + { + var free_count = 0; + if (GetPixel(x - 1, y) == tunnel) ++free_count; + if (GetPixel(x + 1, y) == tunnel) ++free_count; + if (GetPixel(x, y - 1) == tunnel) ++free_count; + if (GetPixel(x, y + 1) == tunnel) ++free_count; + + if (free_count >= 3) SetPixel(x, y, tunnel); + } + } + return dug_out; +} diff --git a/planet/Arena.ocf/FlintBrawl.ocs/ParameterDefs.txt b/planet/Arena.ocf/FlintBrawl.ocs/ParameterDefs.txt new file mode 100644 index 000000000..5a910c251 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/ParameterDefs.txt @@ -0,0 +1,63 @@ +[ParameterDef] +Name=$Rounds$ +Description=$DescRounds$ +ID=Rounds +Default=4 + + [Options] + + [Option] + Name=1 + Value=1 + + [Option] + Name=2 + Value=2 + + [Option] + Name=3 + Value=3 + + [Option] + Name=5 + Value=5 + + [Option] + Name=7 + Value=7 + + [Option] + Name=11 + Value=11 + +[ParameterDef] +Name=Items +Description=$DescItems$ +ID=ItemAmount +Default=1 + + [Options] + + [Option] + Name=$ItemsNormal$ + Value=1 + + [Option] + Name=$ItemsMany$ + Value=3 + +[ParameterDef] +Name=$TeamsTogether$ +Description=$DescTeamsTogether$ +ID=TeamsTogether +Default=1 + + [Options] + + [Option] + Name=$Yes$ + Value=1 + + [Option] + Name=$No$ + Value=0 diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Scenario.txt b/planet/Arena.ocf/FlintBrawl.ocs/Scenario.txt new file mode 100644 index 000000000..1cd04889c --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Scenario.txt @@ -0,0 +1,24 @@ +[Head] +Title=Flint Brawl +Version=9,0 +MinPlayer=2 +MaxPlayer=20 +Icon=40 + +[Game] +Mode=Melee +Goals=Goal_MultiRoundMelee=1; +Rules=Rule_KillLogs=1;Rule_Gravestones=1; + +[Landscape] +MapWidth=64 +MapHeight=40 +TopOpen=1 +BottomOpen=1 +LeftOpen=10000 +RightOpen=10000 +AutoScanSideOpen=0 +MapZoom=18,0,0,18 + +[Weather] +Climate=0 diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Script.c b/planet/Arena.ocf/FlintBrawl.ocs/Script.c new file mode 100644 index 000000000..3a663ba14 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Script.c @@ -0,0 +1,172 @@ +/* Flint Brawl */ + +local team_spawn_positions = nil; +local spawn_item_particles; +func Initialize() +{ + spawn_item_particles = + { + Size = PV_Linear(2, 0), + Alpha = PV_KeyFrames(0, 0, 0, 300, 255, 1000, 0), + Rotation = PV_Random(0, 360), + R = 255, G = 200, B = 50, + Stretch = PV_Random(10000, 15000), + BlitMode = GFX_BLIT_Additive + }; + +} + +local SpawnItem = new Effect +{ + Timer = func(int time) + { + if (Random(time / 38)) + { + CreateParticle("StarSpark", this.x + RandomX(-2, 2), this.y + RandomX(-2, 2), 0, 0, PV_Random(1, 7), Scenario.spawn_item_particles, 10); + } + + if (time > 38 * 4) + { + var obj = CreateObject(this.ID, this.x, this.y, NO_OWNER); + obj->SetR(Random(360)); + return FX_Execute_Kill; + } + return FX_OK; + } +}; + +local SpawnEffect = new Effect +{ + Timer = func(int time) + { + var location = FindLocation(Loc_Material("Earth")); + if (!location) return FX_OK; + var fx = Scenario->CreateEffect(Scenario.SpawnItem, 1, 2); + fx.x = location.x; + fx.y = location.y; + + var items = [Dynamite, Firestone, Bouncy, QuickSandBomb, IronBomb]; + + if (!Random(4) && ((FrameCounter() - this.round_start_time) > 38 * 60)) + items = [Lantern, ChippyFlint, Boompack, SmokeBomb, GrenadeLauncher]; + var item = items[Random(GetLength(items))]; + fx.ID = item; + } +}; + +func GetTeamSpawnPosition(int team_id) +{ + if ((team_id >= GetLength(team_spawn_positions)) || (team_spawn_positions[team_id] == nil)) + { + var location = FindLocation(Loc_Wall(CNAT_Bottom), Loc_Space(25, CNAT_Top)); + team_spawn_positions[team_id] = location; + if (location) + Fireworks(GetTeamColor(team_id), location.x, location.y - 20); + } + + return team_spawn_positions[team_id]; +} + +func InitializeRound() +{ + team_spawn_positions = []; // reset team spawns. + + var i, pos; + var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight(); + // Materials: Firestones + for (i=0; i<30; ++i) + { + var pos = FindLocation(Loc_InRect(0,ls_hgt/2,ls_wdt,ls_hgt/3), Loc_Solid()); + if (pos && IsFirestoneSpot(pos.x,pos.y)) + CreateObjectAbove(Firestone,pos.x,pos.y-1); + } + // Some firestones and bombs in lower half. For ap type 1, more firestones in lower than upper half. + var items = [Firestone,IronBomb, Dynamite, Loam, PowderKeg]; + var item_count = GetLength(items); + for (i=0; i<30; ++i) + { + var pos = FindLocation(Loc_InRect(0,0,ls_wdt,ls_hgt), Loc_Solid()); + if (pos && IsFirestoneSpot(pos.x,pos.y)) + { + var item_idx = Random(item_count); + if (Random(3)) item_idx = Random(item_idx); + CreateObjectAbove(items[item_idx],pos.x,pos.y-1); + } + } + + var trees = []; + for (var ID in [Tree_Coniferous, Tree_Coniferous2, Tree_Coniferous3, Tree_Coniferous4]) + for (var tree in ID->Place(Random(3))) PushBack(trees, tree); + + + for (var tree in trees) + { + tree->CreateObjectInTreetop(Zaphive); + } + Mushroom->Place(10); + Stalactite->Place(5, Shape->Rectangle(0, 0, ls_wdt, ls_hgt/2)); + LargeCaveMushroom->Place(2); + Bat->Place(2); + + var location = FindLocation(Loc_Tunnel(), Loc_Wall(CNAT_Bottom), Loc_Space(20, CNAT_Top)); + if (location) + { + var obj = CreateObjectAbove(Cannon, location.x, location.y, NO_OWNER); + obj->CreateContents(PowderKeg); + } + + if (!FindObject(Find_ID(Time))) + CreateObject(Time); + Time->SetTime(24 * 60); + Meteor->SetChance(10, Chippie_Egg, 10); + + var spawn_fx = CreateEffect(this.SpawnEffect, 1, (38 * 3) / SCENPAR_ItemAmount); + spawn_fx.round_start_time = FrameCounter(); + return true; +} + +func InitPlayerRound(int plr, object crew) +{ + // everything visible + SetFoW(false, plr); + // Player positioning. + var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight(); + var start_pos = nil; + if (SCENPAR_TeamsTogether == 1) + { + start_pos = GetTeamSpawnPosition(GetPlayerTeam(plr)); + } + if (start_pos == nil) + { + // Start positions not defined or exhausted: Spawn in lower area for both maps becuase starting high is an an advantage. + start_pos = FindLocation(Loc_InRect(ls_wdt/5,ls_hgt/2,ls_wdt*3/5,ls_hgt/3), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot)); + if (!start_pos) start_pos = FindLocation(Loc_InRect(ls_wdt/10,0,ls_wdt*8/10,ls_hgt*4/5), Loc_Wall(CNAT_Bottom), Loc_Func(Scenario.IsStartSpot)); + if (!start_pos) start_pos = {x=Random(ls_wdt*6/10)+ls_wdt*2/10, y=ls_hgt*58/100}; + } + + crew->SetPosition(start_pos.x, start_pos.y-10); + + // initial material + crew->CreateContents(WindBag); + crew->CreateContents(Shovel); + + crew.MaxEnergy = 50000; + crew->DoEnergy(1000); +} + +// Horizontal Loc_Space doesn't work with Loc_Wall because it checks inside the ground. +func IsStartSpot(int x, int y) +{ + // Don't spawn just at the border of an island. + if (!GBackSolid(x-3,y+2)) return false; + if (!GBackSolid(x+3,y+2)) return false; + if (GBackSemiSolid(x, y)) return false; + // Spawn with some space. + return PathFree(x-5, y, x+5, y) && PathFree(x, y-21, x, y-1); +} + +func IsFirestoneSpot(int x, int y) +{ + // Very thorough material 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); +} diff --git a/planet/Arena.ocf/FlintBrawl.ocs/StringTblDE.txt b/planet/Arena.ocf/FlintBrawl.ocs/StringTblDE.txt new file mode 100644 index 000000000..4ac48d087 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/StringTblDE.txt @@ -0,0 +1,10 @@ +DescItems=Anzahl der neuen Items. +ItemsNormal=Normal +ItemsMany=Viele +TeamsTogether=Teams vereint +DescTeamsTogether=Die Spieler eines Teams starten zusammen. +Yes=Ja +No=Nein + +Rounds=Rundenzahl +DescRounds=Mehrere Runden spielen diff --git a/planet/Arena.ocf/FlintBrawl.ocs/StringTblUS.txt b/planet/Arena.ocf/FlintBrawl.ocs/StringTblUS.txt new file mode 100644 index 000000000..5f29025c6 --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/StringTblUS.txt @@ -0,0 +1,10 @@ +DescItems=Amount of items to spawn. +ItemsNormal=Normal +ItemsMany=Many +TeamsTogether=Teams together +DescTeamsTogether=The players of a team start together. +Yes=Yes +No=No + +Rounds=Number of rounds +DescRounds=Play for multiple rounds diff --git a/planet/Arena.ocf/FlintBrawl.ocs/System.ocg/Chippie_Egg.c b/planet/Arena.ocf/FlintBrawl.ocs/System.ocg/Chippie_Egg.c new file mode 100644 index 000000000..b7c6c9eba --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/System.ocg/Chippie_Egg.c @@ -0,0 +1,6 @@ +#appendto Chippie_Egg + +public func GetLifeTime() +{ + return 10000; +} diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Teams.txt b/planet/Arena.ocf/FlintBrawl.ocs/Teams.txt new file mode 100644 index 000000000..808ec034d --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Teams.txt @@ -0,0 +1,2 @@ +[Teams] +TeamDistribution=Free \ No newline at end of file diff --git a/planet/Arena.ocf/FlintBrawl.ocs/Title.txt b/planet/Arena.ocf/FlintBrawl.ocs/Title.txt new file mode 100644 index 000000000..8771af1da --- /dev/null +++ b/planet/Arena.ocf/FlintBrawl.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Flintgemenge +US:Flint Brawl diff --git a/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit3.ogg b/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit3.ogg new file mode 100644 index 000000000..f0e566d31 Binary files /dev/null and b/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit3.ogg differ diff --git a/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit4.ogg b/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit4.ogg new file mode 100644 index 000000000..f697d4881 Binary files /dev/null and b/planet/Sound.ocg/Hits.ocg/Materials.ocg/Glass.ocg/GlassHit4.ogg differ diff --git a/planet/Sound.ocg/authors.txt b/planet/Sound.ocg/authors.txt index 62ffcde7e..4494c7171 100644 --- a/planet/Sound.ocg/authors.txt +++ b/planet/Sound.ocg/authors.txt @@ -19,7 +19,7 @@ ala - Fire/Spark1&2&3, Objects/Weapons/Musket/Click1&2&3, Clonk/Acti Chirp, Flutter1&2&3, Noise1&2&3 Animals/Mooq: Die1-5, DieFat, Hurt1-2, Munch1-4, Snort1-3, Snorting1-2, Spit1-2 -K-Pone - Objects/Pickaxe/ClangHard1 Fire/Blast3alt Fire/BlastLiquid3alt +K-Pone - Objects/Pickaxe/ClangHard1 Fire/Blast3alt Fire/BlastLiquid3alt GlassHit3-4 Ringwaul - Monster/Growl1-3, Monster/Die, Wipf/Snuff1-2, Wipf/Aroof, Wipf/Whine, Chest/Open, Chest/Close Winbag/Charge, Winbag/ChargeStop, Winbag/Gust, Pickaxe/Clang1-3