Add Flintbrawl by Zapper

master
Lukas Werling 2019-01-26 18:01:07 +01:00
parent ee35d256aa
commit 918c4139e8
29 changed files with 719 additions and 1 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -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

View File

@ -0,0 +1,2 @@
Name=Flummy
Description=Springt rum.

View File

@ -0,0 +1,2 @@
Name=Bouncy
Description=Bounces around.

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -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

View File

@ -0,0 +1,2 @@
Name=Chippyflint
Description=Spawnt Chippies.

View File

@ -0,0 +1,2 @@
Name=Chippy Flint
Description=Spawns chippies.

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -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

View File

@ -0,0 +1,2 @@
Name=Treibsandflint
Description=Fällt durch Erde.

View File

@ -0,0 +1,2 @@
Name=Quicksand Bomb
Description=Falls through earth.

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
#appendto Chippie_Egg
public func GetLifeTime()
{
return 10000;
}

View File

@ -0,0 +1,2 @@
[Teams]
TeamDistribution=Free

View File

@ -0,0 +1,2 @@
DE:Flintgemenge
US:Flint Brawl

View File

@ -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