forked from Mirrors/openclonk
Aerobatics: new game mode and small improvements
parent
03c0933d6f
commit
6a3eaa2716
|
@ -24,15 +24,29 @@ public func InitializeMap(proplist map)
|
|||
var map_wdt = 140 + nr_checkpoints * 6;
|
||||
var map_hgt = map_wdt / 2;
|
||||
if (SCENPAR_GameMode == 2)
|
||||
map_wdt *= 2;
|
||||
{
|
||||
map_wdt = 60 + nr_checkpoints * 28;
|
||||
map_hgt = 72 + nr_checkpoints * 2;
|
||||
}
|
||||
map->Resize(map_wdt, map_hgt);
|
||||
|
||||
// Draw the start platform
|
||||
DrawStartFinishIsland(map, map.Wdt / 5, map.Hgt / 2 - 2);
|
||||
PushBack(checkpoint_locations, [map.Wdt / 5, map.Hgt / 2 - 2]);
|
||||
// Determine start and finish locations.
|
||||
var start_x = map.Wdt / 5;
|
||||
var finish_x = 4 * map.Wdt / 5;
|
||||
var middle_x = map.Wdt / 2;
|
||||
var island_y = map.Hgt / 2 - 2;
|
||||
if (SCENPAR_GameMode == 2)
|
||||
{
|
||||
start_x = 10;
|
||||
finish_x = map.Wdt - 10;
|
||||
}
|
||||
|
||||
// Draw the start platform.
|
||||
DrawStartFinishIsland(map, start_x, island_y);
|
||||
PushBack(checkpoint_locations, [start_x, island_y]);
|
||||
|
||||
// Find the checkpoint locations: substract the finish from the number of checkpoints.
|
||||
var checkpoint_islands = FindCheckPointLocations(map, nr_checkpoints - 1);
|
||||
var checkpoint_islands = FindCheckPointLocations(map, nr_checkpoints - 1, SCENPAR_GameMode, start_x, finish_x, middle_x, island_y);
|
||||
// Store the locations in the list and draw the islands.
|
||||
for (var index = 0; index < GetLength(checkpoint_islands); index++)
|
||||
{
|
||||
|
@ -42,15 +56,15 @@ public func InitializeMap(proplist map)
|
|||
}
|
||||
|
||||
// Draw the finish platform.
|
||||
DrawStartFinishIsland(map, 4 * map.Wdt / 5, map.Hgt / 2 - 2);
|
||||
PushBack(checkpoint_locations, [4 * map.Wdt / 5, map.Hgt / 2 - 2]);
|
||||
DrawStartFinishIsland(map, finish_x, island_y);
|
||||
PushBack(checkpoint_locations, [finish_x, island_y]);
|
||||
|
||||
// Draw a platform for the inventor's lab.
|
||||
DrawStartFinishIsland(map, map.Wdt / 2, map.Hgt / 2 - 2);
|
||||
inventorslab_location = [map.Wdt / 2, map.Hgt / 2 - 2];
|
||||
DrawStartFinishIsland(map, middle_x, island_y);
|
||||
inventorslab_location = [middle_x, island_y];
|
||||
|
||||
// Draw other smaller islands.
|
||||
DrawSmallIslands(map, checkpoint_locations);
|
||||
DrawSmallIslands(map, checkpoint_locations, start_x, finish_x, middle_x, island_y);
|
||||
|
||||
// Return true to tell the engine a map has been successfully created.
|
||||
return true;
|
||||
|
@ -65,27 +79,34 @@ public func DrawStartFinishIsland(proplist map, int x, int y)
|
|||
Draw("Earth", island);
|
||||
DrawMaterial("Firestone", island, 2, 10);
|
||||
DrawMaterial("Rock", island, 2, 25);
|
||||
var brick = {Algo = MAPALGO_Rect, X = x - 5, Y = y, Wdt = 11, Hgt = 4};
|
||||
var brick = {Algo = MAPALGO_Rect, X = x - 5, Y = y, Wdt = 11, Hgt = 2};
|
||||
Draw("Brick", brick);
|
||||
return;
|
||||
}
|
||||
|
||||
public func FindCheckPointLocations(proplist map, int nr_checkpoints)
|
||||
public func FindCheckPointLocations(proplist map, int nr_checkpoints, int game_mode, int start_x, int finish_x, int middle_x, int island_y)
|
||||
{
|
||||
// Prepare a mask out of the map.
|
||||
var mask = map->CreateLayer();
|
||||
mask->Draw("Rock");
|
||||
// Remove the start, finish and middle island from the mask.
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = map.Wdt / 5, Y = map.Hgt / 2, Wdt = 38, Hgt = 38});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = 4 * map.Wdt / 5, Y = map.Hgt / 2, Wdt = 38, Hgt = 38});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = map.Wdt / 2, Y = map.Hgt / 2, Wdt = 38, Hgt = 38});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = start_x, Y = island_y, Wdt = 38, Hgt = 38});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = finish_x, Y = island_y, Wdt = 38, Hgt = 38});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = middle_x, Y = island_y, Wdt = 38, Hgt = 38});
|
||||
// Remove the middle area between start and finish from the mask.
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Rect, X = map.Wdt / 5, Y = map.Hgt / 2 - 16, Wdt = 3 * map.Wdt / 5, Hgt = 16});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Rect, X = start_x, Y = island_y - 16, Wdt = finish_x - start_x, Hgt = 16});
|
||||
// Array for the checkpoint islands.
|
||||
var checkpoint_islands = [];
|
||||
// Add checkpoint islands at random locations around the map.
|
||||
var border = 10;
|
||||
var cp_dist = 28;
|
||||
var cp_dist_x = 28;
|
||||
var cp_dist_y = 28;
|
||||
// For the horizontal game mode the distance is larger.
|
||||
if (game_mode == 2)
|
||||
{
|
||||
cp_dist_x = 42;
|
||||
cp_dist_y = 30;
|
||||
}
|
||||
for (var i = 0; i < nr_checkpoints; i++)
|
||||
{
|
||||
var cp_island = {};
|
||||
|
@ -94,9 +115,24 @@ public func FindCheckPointLocations(proplist map, int nr_checkpoints)
|
|||
Log("WARNING: Map script could not find a suitable checkpoint location, there will be one checkpoint less in this round.");
|
||||
continue;
|
||||
}
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = cp_island.X, Y = cp_island.Y, Wdt = cp_dist, Hgt = cp_dist});
|
||||
mask->Draw("Tunnel", {Algo = MAPALGO_Ellipsis, X = cp_island.X, Y = cp_island.Y, Wdt = cp_dist_x, Hgt = cp_dist_y});
|
||||
PushBack(checkpoint_islands, cp_island);
|
||||
}
|
||||
// Sort the checkpoints horizontally if the game mode is such.
|
||||
if (game_mode == 2)
|
||||
{
|
||||
for (var i = 1; i < GetLength(checkpoint_islands); i++)
|
||||
{
|
||||
var store = checkpoint_islands[i];
|
||||
var j = i - 1;
|
||||
while (j >= 0 && checkpoint_islands[j].X > store.X)
|
||||
{
|
||||
checkpoint_islands[j + 1] = checkpoint_islands[j];
|
||||
j--;
|
||||
}
|
||||
checkpoint_islands[j + 1] = store;
|
||||
}
|
||||
}
|
||||
return checkpoint_islands;
|
||||
}
|
||||
|
||||
|
@ -122,7 +158,7 @@ public func DrawCheckpointIsland(proplist map, int x, int y, bool enclosed)
|
|||
return;
|
||||
}
|
||||
|
||||
public func DrawSmallIslands(proplist map, array checkpoints)
|
||||
public func DrawSmallIslands(proplist map, array checkpoints, int start_x, int finish_x, int middle_x, int island_y)
|
||||
{
|
||||
// Prepare a mask out of the checkpoint positions.
|
||||
var mask = {Algo = MAPALGO_Rect, X = 0, Y = 0, Wdt = 0, Hgt = 0};
|
||||
|
@ -131,14 +167,16 @@ public func DrawSmallIslands(proplist map, array checkpoints)
|
|||
// Remove checkpoints and middle area from mask.
|
||||
for (var cp in checkpoints)
|
||||
mask = {Algo = MAPALGO_Or, Op = [mask, {Algo = MAPALGO_Ellipsis, X = cp[0], Y = cp[1], Wdt = island_border, Hgt = island_border}]};
|
||||
mask = {Algo = MAPALGO_Or, Op = [mask, {Algo = MAPALGO_Rect, X = map.Wdt / 5, Y = map.Hgt / 2 - 16, Wdt = 3 * map.Wdt / 5, Hgt = 16}]};
|
||||
mask = {Algo = MAPALGO_Or, Op = [mask, {Algo = MAPALGO_Rect, X = start_x, Y = island_y - 16, Wdt = finish_x - start_x, Hgt = 16}]};
|
||||
mask = {Algo = MAPALGO_Not, Op = mask};
|
||||
mask = {Algo = MAPALGO_And, Op = [mask, {Algo = MAPALGO_Rect, X = map_border, Y = map_border, Wdt = map.Wdt - 2 * map_border, Hgt = map.Hgt - 2 * map_border}]};
|
||||
|
||||
// Construct the island masks.
|
||||
var islands = {Algo = MAPALGO_RndChecker, Seed = Random(65536), Ratio = 4, Wdt = 4, Hgt = 3};
|
||||
islands = {Algo = MAPALGO_And, Op = [islands, mask]};
|
||||
islands = {Algo = MAPALGO_Or, Op = [islands, {Algo = MAPALGO_Turbulence, Seed = Random(65536), Amplitude = 6, Scale = 6, Op = islands}]};
|
||||
|
||||
// Draw earth and some materials.
|
||||
Draw("Earth", islands);
|
||||
DrawMaterial("Firestone", islands, 2, 10);
|
||||
DrawMaterial("Rock", islands, 2, 25);
|
||||
|
|
|
@ -42,6 +42,6 @@ Default=1
|
|||
Name=$ScenParGameModeZigZag$
|
||||
Value=1
|
||||
|
||||
#[Option]
|
||||
#Name=$ScenParGameModeHorizontal$
|
||||
#Value=2
|
||||
[Option]
|
||||
Name=$ScenParGameModeHorizontal$
|
||||
Value=2
|
||||
|
|
|
@ -37,13 +37,14 @@ protected func Initialize()
|
|||
if (index == GetLength(checkpoint_locations) - 1)
|
||||
{
|
||||
goal->SetFinishpoint(x, y);
|
||||
ItemSpawn->Create(Balloon, x + 30, y);
|
||||
if (SCENPAR_GameMode == 1)
|
||||
ItemSpawn->Create(Balloon, x + 30, y);
|
||||
continue;
|
||||
}
|
||||
var mode = PARKOUR_CP_Check | PARKOUR_CP_Ordered | PARKOUR_CP_Respawn | PARKOUR_CP_Bonus;
|
||||
goal->AddCheckpoint(x - 10, y, mode);
|
||||
var spawn_items = [Dynamite, Loam, DynamiteBox, IronBomb, Javelin];
|
||||
ItemSpawn->Create(spawn_items[Random(Min(index, GetLength(spawn_items)))], x + 20, y);
|
||||
var spawn_id = GetItemSpawnType(index, y);
|
||||
ItemSpawn->Create(spawn_id, x + 20, y);
|
||||
}
|
||||
|
||||
// Rules.
|
||||
|
@ -57,16 +58,39 @@ protected func Initialize()
|
|||
InitAnimals(amount);
|
||||
|
||||
// Start the intro sequence.
|
||||
StartSequence("Intro", 0);
|
||||
StartSequence("Intro", 0, checkpoint_locations[0], checkpoint_locations[-1]);
|
||||
return;
|
||||
}
|
||||
|
||||
private func GetItemSpawnType(int cp_number, int height)
|
||||
{
|
||||
// For normal checkpoints the item type depends on the height and is random.
|
||||
var spawn_items = [Dynamite, Loam];
|
||||
if (cp_number >= 3)
|
||||
{
|
||||
if (height < LandscapeHeight() / 2)
|
||||
var spawn_items = [Dynamite, Loam, DynamiteBox];
|
||||
else
|
||||
var spawn_items = [Dynamite, Loam, Loam, Boompack];
|
||||
}
|
||||
return RandomElement(spawn_items);
|
||||
}
|
||||
|
||||
private func InitMaterials(int amount)
|
||||
{
|
||||
// In material objects.
|
||||
PlaceObjects(Dynamite, 4 * amount, "Earth");
|
||||
PlaceObjects(Loam, 4 * amount, "Earth");
|
||||
PlaceObjects(Metal, 2 * amount, "Earth");
|
||||
|
||||
// Additional item spawns.
|
||||
if (SCENPAR_GameMode == 2)
|
||||
{
|
||||
// There is no balloon in the horizontal mode at the finish so place one randomly in the first part of the map.
|
||||
var pos = FindLocation(Loc_Sky(), Loc_Space(30), Loc_InRect(LandscapeWidth() / 6, 150, LandscapeWidth() / 6, LandscapeHeight() - 300));
|
||||
if (pos)
|
||||
ItemSpawn->Create(Balloon, pos.x, pos.y);
|
||||
|
||||
}
|
||||
// Place chests on several of the sky islands.
|
||||
for (var count = 0; count < amount / 2; count++)
|
||||
{
|
||||
|
@ -76,6 +100,7 @@ private func InitMaterials(int amount)
|
|||
var chest = CreateObjectAbove(Chest, pos.x, pos.y);
|
||||
chest->CreateContents(Dynamite, 4);
|
||||
chest->CreateContents(Club);
|
||||
chest->CreateContents(Javelin);
|
||||
chest->CreateContents(Musket)->CreateContents(LeadShot);
|
||||
chest->CreateContents(Bow)->CreateContents(Arrow);
|
||||
chest->CreateContents(Bread, 2);
|
||||
|
@ -108,14 +133,6 @@ private func InitMaterials(int amount)
|
|||
cannon->CreateContents(PowderKeg, 1);
|
||||
}
|
||||
}
|
||||
// Place some ropeladders.
|
||||
for (var count = 0; count < 2; count++)
|
||||
{
|
||||
var pos = FindLocation(Loc_Sky(), Loc_Wall(CNAT_Top));
|
||||
if (!pos)
|
||||
continue;
|
||||
CreateObject(Ropeladder, pos.x, pos.y)->Unroll(-1, COMD_Up);
|
||||
}
|
||||
// An inventor's lab on its island.
|
||||
var map_zoom = GetScenarioVal("MapZoom", "Landscape");
|
||||
var lab = CreateObjectAbove(InventorsLab, inventorslab_location[0] * map_zoom, inventorslab_location[1] * map_zoom);
|
||||
|
@ -184,6 +201,7 @@ protected func InitializePlayer(int plr)
|
|||
// Give the player knowledge for items in the inventor's lab.
|
||||
SetPlrKnowledge(plr, WindBag);
|
||||
SetPlrKnowledge(plr, WallKit);
|
||||
SetPlrKnowledge(plr, Balloon);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
#appendto Sequence
|
||||
|
||||
public func Intro_Start()
|
||||
public func Intro_Start(array start, array finish)
|
||||
{
|
||||
this.airship = CreateObjectAbove(Airship, LandscapeWidth() / 4 + 40, LandscapeHeight() / 2 - 40);
|
||||
this.host = CreateObjectAbove(Clonk, LandscapeWidth() / 4 + 40, LandscapeHeight() / 2 - 50);
|
||||
var map_zoom = GetScenarioVal("MapZoom", "Landscape");
|
||||
var start_x = start[0] * map_zoom + 40;
|
||||
var start_y = start[1] * map_zoom - 20;
|
||||
this.finish_x = finish[0] * map_zoom;
|
||||
this.airship = CreateObjectAbove(Airship, start_x, start_y);
|
||||
this.host = CreateObjectAbove(Clonk, start_x, start_y - 10);
|
||||
this.host->SetAlternativeSkin("Mime");
|
||||
this.host->SetName("Mr. Aerobat");
|
||||
this.host->SetDir(DIR_Left);
|
||||
|
@ -31,7 +35,7 @@ public func Intro_1()
|
|||
|
||||
public func Intro_2()
|
||||
{
|
||||
AddEffect("IntroControlAirship", nil, 100, 5, nil, this->GetID(), this.airship, this.host);
|
||||
AddEffect("IntroControlAirship", nil, 100, 5, nil, this->GetID(), this.airship, this.host, this.finish_x);
|
||||
return ScheduleNext(12);
|
||||
}
|
||||
|
||||
|
@ -54,7 +58,7 @@ public func Intro_Stop()
|
|||
return true;
|
||||
}
|
||||
|
||||
public func FxIntroControlAirshipStart(object target, proplist effect, int temp, object airship, object host)
|
||||
public func FxIntroControlAirshipStart(object target, proplist effect, int temp, object airship, object host, int finish_x)
|
||||
{
|
||||
if (temp)
|
||||
return FX_OK;
|
||||
|
@ -62,13 +66,14 @@ public func FxIntroControlAirshipStart(object target, proplist effect, int temp,
|
|||
effect.host = host;
|
||||
effect.host->SetCommand("Grab", effect.airship);
|
||||
effect.airship->ControlRight(effect.host);
|
||||
effect.finish_x = finish_x;
|
||||
effect.state = 1;
|
||||
return FX_OK;
|
||||
}
|
||||
|
||||
public func FxIntroControlAirshipTimer(object target, proplist effect, int time)
|
||||
{
|
||||
if (effect.state == 1 && effect.host->GetX() > 4 * LandscapeWidth() / 5 - 30)
|
||||
if (effect.state == 1 && effect.host->GetX() > effect.finish_x - 30)
|
||||
{
|
||||
effect.airship->ControlStop(effect.host);
|
||||
effect.airship->ControlDown(effect.host);
|
||||
|
|
Loading…
Reference in New Issue