Aerobatics: new game mode and small improvements

objectmenu
Maikel de Vries 2016-01-24 00:19:57 +01:00
parent 03c0933d6f
commit 6a3eaa2716
4 changed files with 103 additions and 42 deletions

View File

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

View File

@ -42,6 +42,6 @@ Default=1
Name=$ScenParGameModeZigZag$
Value=1
#[Option]
#Name=$ScenParGameModeHorizontal$
#Value=2
[Option]
Name=$ScenParGameModeHorizontal$
Value=2

View File

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

View File

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