Add MeltingCastle team melee

liquid_container
Sven Eberhardt 2016-02-07 17:20:46 -05:00
parent 1ebdc31182
commit c9d3cd7417
20 changed files with 485 additions and 0 deletions

View File

@ -0,0 +1,5 @@
Schmelzendes Schloss
Teamwork-Melee in luftiger Hoehe. Es gibt endlos Respawn an der Flagge - bis der Gegner sie in den Abgrund geschleudert hat.
Ziel: Gegnerische Flagge in den Abgrund sprengen. Danach: Last Team Standing (Bleibe als Letzter am Leben und gewinne)

View File

@ -0,0 +1,5 @@
Melting Castle
Teamwork-Melee high in the skies. Infinite respawn at the flagpole, until the opposing team (or melting ice) has dropped it down.
Goal: Blast opponent flag into the abyss. Afterwards, be the last team to have a clonk alive.

View File

@ -0,0 +1,17 @@
[DefCore]
id=IceWallKit
Version=8,0
Category=C4D_Object
Width=12
Height=4
Offset=-6,-2
Vertices=3
VertexX=-5,5,0
VertexY=0,0,0
VertexCNAT=1,2,16
VertexFriction=30,30,30
Value=8
Mass=12
Components=Ice=2
Rotate=1
Picture=0,20,64,64

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -0,0 +1,68 @@
/* Wall kit */
// Modified to draw Ice + not allowed too close to flag
#include WallKit
public func ControlUseStop(object clonk, int x, int y, ...)
{
StopPreview(clonk);
if (!IsIceBridgeAllowed(clonk, x, y))
{
clonk->PlaySoundDoubt();
clonk->Message("$NoWall$");
return true;
}
else
{
return inherited(clonk, x, y, ...);
}
}
private func IsIceBridgeAllowed(object clonk, int x, int y)
{
var c = Offset2BridgeCoords(clonk, x, y);
// Must not intersect a flag
// Search from clonk context because that's the coordinate space returned by Offset2BridgeCoords
var flag = clonk->FindObject(Find_ID(Goal_Flag), clonk->Find_AtRect(Min(c.x1, c.x2)-5, Min(c.y1, c.y2)-5, Abs(c.x1 - c.x2)+11, Abs(c.y1 - c.y2)+11));
return !flag;
}
private func SetPreview(object clonk, int x, int y, ...)
{
if (!preview) AddTimer(this.UpdateIcePreviewColor, 3);
this.ice_last_clonk = clonk;
this.ice_last_x = x;
this.ice_last_y = y;
var r = inherited(clonk, x, y, ...);
UpdateIcePreviewColor();
return r;
}
private func UpdateIcePreviewColor()
{
if (preview)
{
var ok = IsIceBridgeAllowed(this.ice_last_clonk, this.ice_last_x, this.ice_last_y);
if (ok)
preview->SetColor(0xff80ffff);
else
preview->SetColor(0xffff0000);
}
return true;
}
private func StopPreview(object clonk, ...)
{
RemoveTimer(this.UpdateIcePreviewColor);
return inherited(clonk, ...);
}
/* Status */
local Collectible = 1;
local Name = "$Name$";
local Description = "$Description$";
local BridgeLength = 15;
local BridgeThickness = 5;
local BridgeMaterial = "Ice-ice";

View File

@ -0,0 +1,3 @@
NoWall=Zu dicht an der Flagge.
Name=Eisbausatz
Description=Mit dem Eisbausatz koennen temporaere Eiswaende errichtet werden. Halte [Benutzen] gedrückt, um eine Vorschau für die Brücke zu erhalten. Lasse los, um die Brücke am gewünschten Ort zu errichten. Kann nicht in unmittelbarer Naehe der Flage genutzt werden.

View File

@ -0,0 +1,3 @@
NoWall=Too close to the flag.
Name=Ice wall kit
Description=You can create ice walls with the ice wall kit. Hold down the [Use] key to see a preview in the direction you are pointing. Let go to build there. Cannot be used close to the flag.

View File

@ -0,0 +1,20 @@
/*
Melting Castle
Team melee to melt each others castles
@authors Sven2
*/
// Only half of the actual map is present in the map file and Objects.c.
// Create a mirror for the missing half here.
public func InitializeMap(proplist map)
{
// Not when editing
if (EDIT_MAP) return true;
// Mirror map
var old_map = Duplicate();
Resize(this.Wdt*2, this.Hgt);
Blit(old_map);
Blit({Algo=MAPALGO_Scale, OffX=old_map.Wdt, X=-100, Op=old_map});
return true;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,20 @@
[Material]
Name=Ice
Shape=TopFlat
Density=60
Friction=15
DigFree=1
BlastFree=1
Blast2Object=Ice
Dig2Object=Ice
Dig2ObjectRatio=200
Blast2ObjectRatio=220
MaxAirSpeed=100
MaxSlide=1
Corrode=60
TempConvStrength=2
AboveTempConvert=10
AboveTempConvertDir=1
AboveTempConvertTo=Water
Placement=21
TextureOverlay=ice

View File

@ -0,0 +1,52 @@
# Automatically generated texture map
# Contains material-texture-combinations added at runtime
# Import materials from global file as well
OverloadMaterials
# Import textures from global file as well
OverloadTextures
10=Tunnel-tunnel
11=Tunnel-tunnel
12=Tunnel-brickback
13=BrickSoft-brick
19=DuroLava-lava_red
20=Water-water
22=Acid-acid
23=Lava-lava_red
24=DuroLava-lava_red
25=Water-water
27=Acid-acid
28=Lava-lava_red
29=Earth-earth
30=Earth-earth_root
31=Earth-earth_spongy
32=Earth-earth
33=Ashes-ashes
36=Ore-ore
37=Ore-ore
38=Ore-ore
40=Granite-granite
41=Granite-granite
42=Granite-rock
45=Gold-gold
50=Rock-rock
51=Rock-rock
52=Rock-rock
53=Firestone-firestone
54=Coal-coal
55=Sand-sand
56=Sand-sand
65=Ice-ice
66=Ice-ice
67=Ice-ice2
68=Ice-ice2
70=Snow-snow1
71=Snow-snow1
72=Snow-snow1
73=Brick-brick
1=Amethyst-amethyst
2=Everrock-everrock
3=HalfVehicle-none
4=Ruby-ruby
5=SandDry-sand
6=Vehicle-none

View File

@ -0,0 +1,47 @@
/* Automatically created objects file */
func InitializeObjects()
{
CreateObject(Rule_KillLogs, 50, 50);
CreateObject(Rule_Gravestones, 50, 50);
CreateObject(Goal_Melee, 50, 50);
ItemSpawn->Create(Firestone,407,389);
ItemSpawn->Create(Firestone,423,389);
ItemSpawn->Create(PowderKeg,669,261);
ItemSpawn->Create(Bread,407,258);
ItemSpawn->Create(IronBomb,441,389);
var Chest001 = CreateObjectAbove(Chest, 1047, 359);
CreateObjectAbove(Idol, 313, 254);
var WoodenBridge001 = CreateObjectAbove(WoodenBridge, 1126, 372);
WoodenBridge001->SetCategory(C4D_StaticBack);
var WoodenBridge002 = CreateObjectAbove(WoodenBridge, 513, 282);
WoodenBridge002->SetCategory(C4D_StaticBack);
CreateObjectAbove(Goal_Flag, 507, 180);
CreateObjectAbove(Catapult, 728, 431);
CreateObjectAbove(Catapult, 627, 269);
var Cannon001 = CreateObjectAbove(Cannon, 692, 253);
Cannon001->SetRDir(3);
CreateObjectAbove(Cannon, 511, 179);
CreateObjectAbove(Airship, 369, 269);
Chest001->CreateContents(Boompack);
Chest001->CreateContents(IronBomb, 2);
Chest001->CreateContents(Bread);
Chest001->CreateContents(BombArrow);
Chest001->CreateContents(Bow);
return true;
}

View File

@ -0,0 +1,27 @@
[Head]
Icon=21
Title=MeltingCastle
Version=8
MaxPlayer=20
MinPlayer=2
NoInitialize=true
[Game]
Mode=Melee
[Player1]
[Player2]
[Player3]
[Player4]
[Landscape]
BottomOpen=1
MapWidth=64,0,64,10000
MapHeight=40,0,40,10000
MapZoom=18,0,0,18
[Weather]
Climate=0,10,0,100

View File

@ -0,0 +1,193 @@
/* Melting Castle */
static g_respawn_flags, g_had_intro_msg;
static const EDIT_MAP = false; // Set to true to edit map and Objects.c; avoids map resize and object duplication
func Initialize()
{
if (EDIT_MAP) return true;
// Mirror map objects by moving them to the other side, then re-running object initialization
for (var o in FindObjects(Find_NoContainer(), Find_Not(Find_Category(C4D_Goal | C4D_Rule))))
{
var oid = o->GetID();
if (oid == Ambience) continue; // Can't filter by C4D_Environment, because we do want waterfalls and item spawns
o->SetPosition(LandscapeWidth() - o->GetX(), o->GetY());
// Catapults and cannons should point left on the right island
if (oid == Catapult)
o->TurnLeft();
else if (oid == Cannon)
o->TurnCannon(DIR_Left, true);
}
ScenarioObjects->InitializeObjects();
// Some adjustments to the bridges
for (var bridge in FindObjects(Find_ID(WoodenBridge)))
{
bridge->SetClrModulation(0xff00ffff);
bridge->SetHalfVehicleSolidMask(true);
bridge->SetCategory(C4D_Vehicle);
bridge->SetVertex(,,-37); // prevent self-stuck
}
// Item spawns by team
for (var item_spawn in FindObjects(Find_ID(ItemSpawn)))
{
item_spawn->SetTeam(1 + (item_spawn->GetX() > LandscapeWidth()/2));
}
// Remember flags for respawn
g_respawn_flags = CreateArray(3);
for (var flag in FindObjects(Find_ID(Goal_Flag)))
{
flag->DisablePickup(); // Not using CTF goal
flag.Destruction = Scenario.OnFlagDestruction;
flag.team = 1;
flag.Plane = 274; // cannot be moved by airship
if (flag->GetX() > LandscapeWidth()/2) ++flag.team;
g_respawn_flags[flag.team] = flag;
}
// Weapon drops timer
ScheduleCall(nil, Scenario.DoBalloonDrop, 36*8, 99999);
return true;
}
local weapon_list = [ // id, vertex, offx, offy, deployy
[Firestone, 0, -3, -6, -18],
[IronBomb, 0, 0, -6, -10],
[IceWallKit, 2, 0, -5, -10],
[DynamiteBox, 0, 3, -5, -10],
[BombArrow, 2, 0, -8, -10],
[Boompack, 0, 0, 0, 0],
[GrenadeLauncher, 3, 0, -4, -10]
];
func DoBalloonDrop()
{
// Random weapon
var wp = Scenario.weapon_list[Random(GetLength(Scenario.weapon_list))];
var x = LandscapeWidth()/4 + Random(LandscapeWidth()/2);
var y = 0;
var balloon = CreateObject(BalloonDeployed, x, y);
if (!balloon) return;
balloon->SetInflated();
var cargo = CreateObject(wp[0]);
if (!cargo) return;
balloon->SetCargo(cargo, wp[1], wp[2], wp[3], wp[4]);
if (wp[0] == GrenadeLauncher) cargo->CreateContents(IronBomb);
return balloon;
}
func OnFlagDestruction()
{
// Callback from flag after it dropped
Log("$FlagDownMsg$", ["$TeamLeft$", "$TeamRight$"][this.team-1]);
return true;
}
func InitializePlayer(int plr)
{
// Everything freely visible (to allow aiming with the cannon)
SetFoW(false, plr);
SetPlayerZoomByViewRange(plr,LandscapeWidth(),LandscapeHeight(),PLRZOOM_LimitMax);
SetPlayerViewLock(plr, false);
// Acquire base
var team = GetPlayerTeam(plr);
var flag = g_respawn_flags[team];
if (flag && flag->GetOwner() == NO_OWNER) AcquireBase(plr, team);
// Intro message. Delayed to be visible to all players.
if (!g_had_intro_msg)
{
g_had_intro_msg = true;
ScheduleCall(nil, Scenario.IntroMsg, 10, 1);
}
// Initial launch
RelaunchPlayer(plr);
return true;
}
func IntroMsg()
{
var speaker = FindObject(Find_ID(Goal_Flag));
if (speaker)
{
var c = speaker->GetColor();
var n = speaker->GetName();
speaker->SetColor(0xffffff);
speaker->SetName("$IntroName$");
Dialogue->MessageBoxAll("$IntroMsg$", speaker, true);
speaker->SetName(n);
speaker->SetColor(c);
}
return true;
}
func LaunchPlayer(int plr)
{
// Position at flag
var flagpole = g_respawn_flags[GetPlayerTeam(plr)];
if (!flagpole) return EliminatePlayer(plr); // Flag lost and clonk died? Game over!
var crew = GetCrew(plr), start_x = flagpole->GetX(), start_y = flagpole->GetY();
crew->SetPosition(start_x, start_y);
// Make sure clonk can move
DigFreeRect(start_x-6,start_y-10,13,18,true);
// Crew setup
crew.MaxEnergy = 100000;
crew->DoEnergy(1000);
crew->CreateContents(WindBag);
return true;
}
func RelaunchPlayer(int plr)
{
// Find flag for respawn
var flagpole = g_respawn_flags[GetPlayerTeam(plr)];
if (!flagpole) return EliminatePlayer(plr); // Flag lost and clonk died? Game over!
// Player positioning.
var start_x = flagpole->GetX(), start_y = flagpole->GetY();
// Relaunch: New clonk
var crew = GetCrew(plr);
var is_relaunch = (!crew || !crew->GetAlive());
if (is_relaunch)
{
crew = CreateObject(Clonk, 10,10, plr);
if (!crew) return false; // wat?
crew->MakeCrewMember(plr);
SetCursor(plr, crew, false);
}
// Relaunch near current flag pos (will be adjusted on actual relaunch)
crew->SetPosition(start_x, start_y);
var relaunch = CreateObjectAbove(RelaunchContainer, start_x, start_y, plr);
if (relaunch)
{
relaunch->StartRelaunch(crew);
relaunch->SetRelaunchTime(8, is_relaunch);
}
return true;
}
// GameCall from RelaunchContainer.
func OnClonkLeftRelaunch(object clonk)
{
if (clonk) return LaunchPlayer(clonk->GetOwner());
}
func RelaunchWeaponList() { return [Bow, Sword, Club, Javelin, Musket, Firestone, IceWallKit]; }
func AcquireBase(int plr, int team)
{
// Change ownership of some stuff in the base to the first player of a team joining
// Note that this may be called late into the game in case all players of one team join late into the game
var base_x0 = 0;
if (team == 2) base_x0 = LandscapeWidth()/2;
var base_ids = [Catapult, Cannon, Goal_Flag, Chest];
for (var obj in FindObjects(Find_InRect(base_x0, 100, LandscapeWidth()/2, LandscapeHeight()-100), Find_NoContainer(), Find_Owner(NO_OWNER)))
{
var idobj = obj->GetID();
if (GetIndexOf(base_ids, idobj))
{
obj->SetOwner(plr);
if (idobj == Goal_Flag) obj->SetClrModulation(0xff000000 | GetPlayerColor(plr));
}
}
return true;
}

View File

@ -0,0 +1,5 @@
TeamLeft=Rot (links)
TeamRight=Gruen (rechts)
FlagDownMsg=Team %s hat die Flagge verloren - sie werden nicht mehr wiederbelebt!
IntroMsg=Sprengt die gegnerische Flagge in die Lava und eliminiert dann die Gegner!
IntroName=Schmelzendes Schloss

View File

@ -0,0 +1,5 @@
TeamLeft=Red (left)
TeamRight=Green (right)
FlagDownMsg=Team %s lost their flag - they will no longer respawn!
IntroMsg=Blast the enemy flag down into the lava to stop them from respawning and then eliminate your opponents!
IntroName=Melting Castle

View File

@ -0,0 +1,13 @@
[Teams]
LastTeamID=2
TeamColors=true
[Team]
id=1
Name=$TeamLeft$
Color=16711680
[Team]
id=2
Name=$TeamRight$
Color=65280

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,2 @@
DE:Schmelzendes Schloss
US:Melting Castle