Merge pull request GH#37 from Fulgen301/Rule_Relaunch

alut-include-path
Nicolas Hake 2017-04-12 17:45:51 +02:00
commit 23f6c74c4b
69 changed files with 643 additions and 675 deletions

View File

@ -10,6 +10,9 @@ protected func Initialize()
{
// Environment
CreateObject(Rule_ObjectFade)->DoFadeTime(10 * 36);
GetRelaunchRule()->SetLastWeaponUse(false);
var time=CreateObject(Time);
time->SetTime();
time->SetCycleSpeed();
@ -151,16 +154,6 @@ protected func InitializePlayer(int plr)
return;
}
// Gamecall from CTF goal, on respawning.
protected func OnPlayerRelaunch(int plr)
{
var clonk = GetCrew(plr);
var relaunch = CreateObjectAbove(RelaunchContainer, clonk->GetX(), clonk->GetY(), clonk->GetOwner());
relaunch->StartRelaunch(clonk);
relaunch->SetRelaunchTime(8, true);
return;
}
func RelaunchWeaponList() { return [Blunderbuss, Sword, Javelin, FrostboltScroll, Shovel]; }
/*-- Chest filler effects --*/

View File

@ -18,10 +18,15 @@ protected func Initialize()
goal->SetFlagBase(2, LandscapeWidth() - 120, 502);
// Rules
CreateObject(Rule_Restart);
GetRelaunchRule()
->SetDefaultRelaunchCount(nil)
->EnablePlayerRestart();
CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetDefaultRelaunchCount(nil);
GetRelaunchRule()->SetRespawnDelay(8);
GetRelaunchRule()->SetLastWeaponUse(false);
var lwidth = LandscapeWidth();
@ -100,16 +105,6 @@ protected func InitializePlayer(int plr)
return;
}
// Gamecall from CTF goal, on respawning.
protected func OnPlayerRelaunch(int plr)
{
var clonk = GetCrew(plr);
var relaunch = CreateObjectAbove(RelaunchContainer, clonk->GetX(), clonk->GetY(), clonk->GetOwner());
relaunch->StartRelaunch(clonk);
relaunch->SetRelaunchTime(8, true);
return;
}
// Game call from RelaunchContainer when a Clonk has left the respawn.
public func OnClonkLeftRelaunch(object clonk)
{

View File

@ -47,7 +47,9 @@ func Initialize()
g_goal = CreateObject(Goal_BeRich);
CreateObject(Rule_BuyAtFlagpole);
CreateObject(Rule_BaseRespawn);
GetRelaunchRule()
->SetBaseRespawn(true)
->SetLastClonkRespawn(true);
CreateObject(Rule_KillLogs);
CreateObject(Rule_TeamAccount);

View File

@ -4,8 +4,7 @@ func InitializeObjects()
{
CreateObject(Rule_KillLogs, 50, 50);
CreateObject(Rule_Gravestones, 50, 50);
CreateObject(Rule_Restart, 50, 50);
CreateObject(Goal_Melee, 50, 50);
ItemSpawn->Create(Firestone,407,389);

View File

@ -7,6 +7,10 @@ static const EDIT_MAP = false; // Set to true to edit map and Objects.c; avoids
func Initialize()
{
if (EDIT_MAP) return true;
GetRelaunchRule()->SetRelaunchCount(nil);
GetRelaunchRule()->SetRespawnDelay(8);
GetRelaunchRule()->SetLastWeaponUse(false);
GetRelaunchRule()->EnablePlayerRestart();
// 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))))
{
@ -105,7 +109,6 @@ func InitializePlayer(int plr)
ScheduleCall(nil, Scenario.IntroMsg, 10, 1);
}
// Initial launch
RelaunchPlayer(plr);
return true;
}
@ -125,56 +128,38 @@ func IntroMsg()
return true;
}
func LaunchPlayer(int plr)
func LaunchPlayer(object pClonk, 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);
DigFreeRect(pClonk->GetX()-6,pClonk->GetY()-10,13,18,true);
// Crew setup
crew.MaxEnergy = 100000;
crew->DoEnergy(1000);
crew->CreateContents(WindBag);
pClonk.MaxEnergy = 100000;
pClonk->DoEnergy(1000);
pClonk->CreateContents(WindBag);
return true;
}
func RelaunchPlayer(int plr)
public func OnPlayerRelaunch(iPlr)
{
if(!g_respawn_flags[GetPlayerTeam(plr)]) return EliminatePlayer(plr);
}
public func RelaunchPosition(int iPlr, int iTeam)
{
if(!g_respawn_flags[iTeam]) return;
return [g_respawn_flags[iTeam]->GetX(), g_respawn_flags[iTeam]->GetY()];
}
public func OnClonkLeftRelaunch(object pClonk, 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);
}
// Reset available items in spawns
for (var item_spawn in FindObjects(Find_ID(ItemSpawn))) item_spawn->Reset(plr);
// 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());
return LaunchPlayer(plr);
}
func RelaunchWeaponList() { return [Bow, Sword, Club, Javelin, Blunderbuss, Firestone, IceWallKit]; }

View File

@ -18,6 +18,7 @@ protected func Initialize()
CreateObject(Rule_ObjectFade)->DoFadeTime(7 * 36);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetLastWeaponUse(false);
//make lava collapse
CreateObjectAbove(Firestone,625,480);
@ -147,31 +148,9 @@ global func CreateChestContents(id obj_id)
return;
}
protected func InitializePlayer(int plr)
public func RelaunchPosition()
{
return JoinPlayer(plr);
}
// GameCall from RelaunchContainer.
protected func RelaunchPlayer(int plr)
{
var clonk = CreateObjectAbove(Clonk, 0, 0, plr);
clonk->MakeCrewMember(plr);
SetCursor(plr, clonk);
JoinPlayer(plr);
return;
}
protected func JoinPlayer(int plr)
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var position = [[420,200],[300,440],[130,176],[140,368],[700,192],[670,336],[750,440],[440,392],[45,256]];
var r=Random(GetLength(position));
var x = position[r][0], y = position[r][1];
var relaunch = CreateObjectAbove(RelaunchContainer, x, y, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
return;
return [[420,200],[300,440],[130,176],[140,368],[700,192],[670,336],[750,440],[440,392],[45,256]];
}
func RelaunchWeaponList() { return [Bow, Shield, Sword, Javelin, Blunderbuss, Club]; }

View File

@ -14,6 +14,7 @@ protected func Initialize()
CreateObject(Goal_LastManStanding);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetLastWeaponUse(false);
//Enviroment.
Cloud->Place(25);
@ -339,27 +340,19 @@ global func CreateChestContents(id obj_id)
// GameCall from RelaunchContainer.
func OnClonkLeftRelaunch(object clonk)
{
var pos = GetRandomSpawn();
clonk->SetPosition(pos[0],pos[1]);
CreateParticle("Air", pos[0],pos[1], PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), Overcast_air_particles, 25);
return;
}
global func GetRandomSpawn()
public func RelaunchPosition()
{
var spawns = [[432,270],[136,382],[200,134],[864,190],[856,382],[840,518],[408,86],[536,470]];
var rand = Random(GetLength(spawns));
return spawns[rand];
return [[432,270],[136,382],[200,134],[864,190],[856,382],[840,518],[408,86],[536,470]];
}
// Gamecall from LastManStanding goal, on respawning.
protected func OnPlayerRelaunch(int plr)
global func GetRandomSpawn()
{
var clonk = GetCrew(plr);
var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
return;
return Scenario->RelaunchPosition();
}
func KillsToRelaunch() { return 0; }

View File

@ -12,6 +12,7 @@ protected func Initialize()
CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetLastWeaponUse(false);
// Chests with weapons.
var chest = CreateObjectAbove(Chest, 108, 248);
@ -82,16 +83,6 @@ protected func InitializePlayer(int plr)
return;
}
// Gamecall from LastManStanding goal, on respawning.
protected func OnPlayerRelaunch(int plr)
{
var clonk = GetCrew(plr);
var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
return;
}
// Refill/fill chests.
global func FxIntFillChestsStart(object target, proplist effect, int temporary, object chest)
{
@ -135,5 +126,10 @@ public func OnClonkLeftRelaunch(object clonk)
return;
}
public func RelaunchPosition()
{
return [LandscapeWidth() / 2, LandscapeHeight() / 2];
}
public func KillsToRelaunch() { return 0; }
public func RelaunchWeaponList() { return [Bow, Shield, Sword, Firestone, Dynamite, Javelin, Blunderbuss]; }

View File

@ -13,6 +13,7 @@ protected func Initialize()
CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetLastWeaponUse(false);
// Mood.
SetSkyAdjust(RGBa(255, 255, 255, 127), RGB(255, 200, 150));
@ -37,15 +38,6 @@ protected func Initialize()
return;
}
// Gamecall from LastManStanding goal, on respawning.
protected func OnPlayerRelaunch(int plr)
{
var clonk = GetCrew(plr);
var relaunch = CreateObjectAbove(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
return;
}
global func FxRainTimer(object pTarget, effect, int timer)
{

View File

@ -13,6 +13,9 @@ protected func Initialize()
CreateObject(Goal_LastManStanding);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()
->SetRespawnDelay(3)
->SetLastWeaponUse(false);
// Enviroment.
CreateObject(Rule_ObjectFade)->DoFadeTime(10 * 36);
@ -73,25 +76,21 @@ private func PlaceGras()
return;
}
protected func OnPlayerRelaunch(int plr)
public func RelaunchPosition()
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var x = RandomX(75,500);
var y=100;
while(!GBackSolid(x,y)) y+=1;
y-=30;
var relaunch = CreateObjectAbove(RelaunchContainer, x, y, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
relaunch->SetRelaunchTime(3);
clonk->CreateContents(TeleGlove);
return;
return [x, y];
}
public func OnClonkLeftRelaunch(object clonk)
{
clonk->CreateParticle("Fire", 0, 0, PV_Random(-20, 20), PV_Random(-40, 5), PV_Random(20, 90), Particles_Glimmer(), 30);
clonk->SetYDir(-5);
clonk->CreateContents(TeleGlove);
return;
}
@ -104,5 +103,4 @@ public func OnClonkDeath(object clonk)
}
// Settings for LMS and DM.
public func RelaunchCount() { return 5; }
public func WinKillCount() { return 5; }

View File

@ -18,6 +18,7 @@ protected func Initialize()
AddEffect("BlessTheKing",goal,100,1,nil);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
GetRelaunchRule()->SetLastWeaponUse(false);
//Enviroment.
//SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220));
@ -247,29 +248,11 @@ protected func InitializePlayer(int plr)
{
// This scenario does not have shadows.
SetFoW(false, plr);
return JoinPlayer(plr);
}
// GameCall from RelaunchContainer.
protected func RelaunchPlayer(int plr)
public func RelaunchPosition()
{
var clonk = CreateObjectAbove(Clonk, 0, 0, plr);
clonk->MakeCrewMember(plr);
SetCursor(plr, clonk);
JoinPlayer(plr);
return;
}
protected func JoinPlayer(int plr)
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var position = [[180,150],[310,320],[600,290],[650,180],[790,110],[440,190]];
var r=Random(GetLength(position));
var x = position[r][0], y = position[r][1];
var relaunch = CreateObjectAbove(RelaunchContainer, x, y + 49, clonk->GetOwner());
relaunch->StartRelaunch(clonk);
return;
return [[180,150],[310,320],[600,290],[650,180],[790,110],[440,190]];
}
func KillsToRelaunch() { return 0; }

View File

@ -46,7 +46,7 @@ func InitializePlayer(int plr, int iX, int iY, object pBase, int iTeam)
{
g_relaunchs = [];
g_scores = [];
Scoreboard->Init([{key = "relaunchs", title = Rule_Restart, sorted = true, desc = true, default = "", priority = 75},
Scoreboard->Init([{key = "relaunchs", title = Rule_Relaunch, sorted = true, desc = true, default = "", priority = 75},
{key = "score", title = Nugget, sorted = true, desc = true, default = "0", priority = 100}]);
}
for (var stonedoor in FindObjects(Find_ID(StoneDoor), Find_Owner(NO_OWNER))) stonedoor->SetOwner(plr);

View File

@ -15,7 +15,7 @@ protected func Initialize()
// Rules.
CreateObject(Rule_BuyAtFlagpole);
CreateObject(Rule_BaseRespawn);
GetRelaunchRule()->SetBaseRespawn(true);
CreateObject(Rule_TeamAccount);
CreateObject(Rule_NoFriendlyFire);
CreateObject(Rule_Gravestones)->SetFadeOut(3 * 36);

View File

@ -45,7 +45,7 @@ func InitializePlayer(int plr, int iX, int iY, object pBase, int iTeam)
{
g_relaunchs = [];
g_scores = [];
Scoreboard->Init([{key = "relaunchs", title = Rule_Restart, sorted = true, desc = true, default = "", priority = 75},
Scoreboard->Init([{key = "relaunchs", title = Rule_Relaunch, sorted = true, desc = true, default = "", priority = 75},
{key = "score", title = Nugget, sorted = true, desc = true, default = "0", priority = 100}]);
}
g_relaunchs[plr] = MAX_RELAUNCH;

View File

@ -9,14 +9,8 @@ func InitializeObjects()
var BoilingLava001 = CreateObject(BoilingLava);
BoilingLava001->SetIntensity(25);
var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
Rule_BaseRespawn001->SetInventoryTransfer(true);
Rule_BaseRespawn001->SetFreeCrew(true);
CreateObject(Rule_TeamAccount);
CreateObject(Rule_Restart);
CreateObjectAbove(Tree_Coniferous, 380, 877);
var Tree_Coniferous2001 = CreateObjectAbove(Tree_Coniferous2, 562, 563);

View File

@ -53,6 +53,12 @@ func DoInit(int first_player)
// Start intro if not yet started
StartSequence("Intro", 0, GetCrew(first_player));
GetRelaunchRule()
->SetInventoryTransfer(true)
->SetLastClonkRespawn(true)
->SetFreeCrew(true)
->EnablePlayerRestart();
return true;
}

View File

@ -11,9 +11,6 @@ func InitializeObjects()
var Grass003 = CreateObjectAbove(Grass, 228, 1180);
Grass003->SetClrModulation(0xffa08060);
var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
Rule_BaseRespawn001->SetInventoryTransfer(true);
Rule_BaseRespawn001->SetFreeCrew(true);
var Tree_Coniferous_Burned001 = CreateObject(Tree_Coniferous_Burned, 17, 1097);
Tree_Coniferous_Burned001->SetR(10);
@ -543,7 +540,5 @@ func InitializeObjects()
CreateObject(Rule_Gravestones);
CreateObject(Rule_Restart);
return true;
}

View File

@ -11,7 +11,7 @@ Definition1=Objects.ocd
Definition2=Decoration.ocd
[Game]
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1;
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;
[Player1]
Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;InventorsLab=1;Sawmill=1;BombArrow=1;FireArrow=1;GrenadeLauncher=1;Torch=1;WoodenBridge=1;Basement=1;

View File

@ -11,6 +11,12 @@ static npc_pyrit;
private func DoInit(int first_player)
{
GetRelaunchRule()
->SetBaseRespawn(true)
->SetInventoryTransfer(true)
->SetFreeCrew(true)
->EnablePlayerRestart()
->SetLastClonkRespawn(true);
// Message when first player enters shroom area
ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff);
// Scorching village

View File

@ -11,7 +11,7 @@ Definition2=Decoration.ocd\Misc.ocd\Hat.ocd
Definition3=Decoration.ocd\Clonk.ocd\AltSkins.ocd
[Game]
Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1;Rule_BaseRespawn=1;Rule_Restart=1;
Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1;
Goals=Goal_BuildCrystalCommunicator=1;
ValueOverloads=Ruby=10;Amethyst=10

View File

@ -33,12 +33,13 @@ protected func PostIntroInitialize()
}
// Rules
var respawn_rule = FindObject(Find_ID(Rule_BaseRespawn));
if (respawn_rule)
{
respawn_rule->SetInventoryTransfer(true);
respawn_rule->SetFreeCrew(true);
}
GetRelaunchRule()
->SetDefaultRelaunches()
->SetInventoryTransfer(true)
->SetFreeCrew(true)
->EnablePlayerRestart()
->SetBaseRespawn(true)
->SetLastClonkRespawn(true);
// Initialize different parts of the scenario.
InitializeAmbience();

View File

@ -7,17 +7,11 @@ func InitializeObjects()
var Time001 = CreateObject(Time);
Time001->SetTime(600);
Time001->SetCycleSpeed(20);
var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
Rule_BaseRespawn001->SetInventoryTransfer(true);
Rule_BaseRespawn001->SetFreeCrew(true);
CreateObject(Rule_NoPowerNeed);
CreateObject(Rule_TeamAccount);
CreateObject(Rule_Restart);
CreateObjectAbove(EnvPack_Scarecrow, 1218, 440);
CreateObjectAbove(EnvPack_Guidepost, 835, 369);

View File

@ -10,7 +10,7 @@ Definition2=Decoration.ocd
[Game]
Goals=Goal_Raid=1
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1;
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;
[Player1]
Knowledge=Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;GoldBar=1;Metal=1;Pipe=1;WallKit=1;WindGenerator=1;

View File

@ -26,6 +26,12 @@ static g_is_initialized, // intro started
func Initialize()
{
GetRelaunchRule()
->SetBaseRespawn(true)
->SetFairCrew(true)
->InventoryTransfer(true)
->EnablePlayerRestart()
->SetLastClonkRespawn(true);
npc_newton->SetAlternativeSkin("MaleBlackHair");
npc_pyrit->SetAlternativeSkin("MaleBrownHair");
npc_woody->SetAlternativeSkin("Youngster");

View File

@ -32,16 +32,10 @@ func InitializeObjects()
Column001->SetMeshMaterial("AncientColumn", 0);
Column001.Plane = 50;
var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
Rule_BaseRespawn001->SetInventoryTransfer(true);
Rule_BaseRespawn001->SetFreeCrew(true);
CreateObject(Rule_TeamAccount);
CreateObject(Rule_NoPowerNeed);
CreateObject(Rule_Restart);
var LargeCaveMushroom001 = CreateObjectAbove(LargeCaveMushroom, 1308, 1038);
LargeCaveMushroom001->SetClrModulation(0xffe4effc);
var LargeCaveMushroom002 = CreateObjectAbove(LargeCaveMushroom, 1345, 1028);

View File

@ -10,7 +10,7 @@ MissionAccess=S2Sea
Definition2=Decoration.ocd
[Game]
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;Rule_BaseRespawn=1;
Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1;
[Player1]
Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1;Catapult=1;WallKit=1;WoodenBridge=1;Basement=1;

View File

@ -15,6 +15,12 @@ static npc_pyrit;
func DoInit(int first_player)
{
GetRelaunchRule()
->SetBaseRespawn(true)
->SetLastClonkRespawn(true)
->SetInventoryTransfer(true)
->SetFreeCrew(true)
->EnablePlayerRestart();
ClearFreeRect(530,1135, 50,2);
if (g_last_stone_door) g_last_stone_door->DoDamage(170 - g_last_stone_door->GetDamage());
if (g_golden_idol)

View File

@ -18,6 +18,8 @@ func ScoreboardTeamID(int team)
protected func Initialize()
{
score_list = [];
GetRelaunchRule()->SetRespawnDelay(0);
GetRelaunchRule()->SetDefaultRelaunches(nil);
// init scoreboard
Scoreboard->Init(
@ -75,38 +77,18 @@ private func EliminateOthers(int win_team)
protected func InitializePlayer(int plr, int x, int y, object base, int team)
{
// Join new clonk.
JoinPlayer(plr);
GetRelaunchRule()->DoRelaunch(iPlr, nil, RelaunchPosition(team), true);
// make scoreboard entry for team
Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team));
// Broadcast to scenario.
GameCall("OnPlayerRelaunch", plr, false);
return _inherited(plr, x, y, base, team, ...);
}
protected func RelaunchPlayer(int plr)
public func RelaunchPosition(int iTeam)
{
// New clonk.
var clonk = CreateObjectAbove(Clonk, 0, 0, plr);
clonk->MakeCrewMember(plr);
SetCursor(plr, clonk);
// Join new clonk.
JoinPlayer(plr);
// Broadcast to scenario.
GameCall("OnPlayerRelaunch", plr, true);
return _inherited(plr, ...);
}
private func JoinPlayer(int plr)
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var team = GetPlayerTeam(plr);
var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team));
if (base)
clonk->SetPosition(base->GetX(), base->GetY() - 10);
return;
if (base) return [base->GetX(), base->GetY() - 10];
return nil;
}
protected func RemovePlayer(int plr)

View File

@ -23,66 +23,19 @@ func Initialize()
}
maxkills = GameCall("WinKillCount");
if(maxkills == nil || maxkills < 1) maxkills = 4;
GetRelaunchRule()->SetDefaultRelaunches(nil);
return _inherited(...);
}
protected func InitializePlayer(int plr)
{
// Join plr.
JoinPlayer(plr);
// Scenario script callback.
GameCall("OnPlayerRelaunch", plr, false);
return _inherited(plr, ...);
}
protected func RelaunchPlayer(int plr, int killer)
{
_inherited(plr, killer, ...);
var clonk = CreateObjectAbove(Clonk, 0, 0, plr);
clonk->MakeCrewMember(plr);
SetCursor(plr, clonk);
JoinPlayer(plr);
// Scenario script callback.
GameCall("OnPlayerRelaunch", plr, true);
// Show scoreboard for a while
DoScoreboardShow(1, plr + 1);
Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * ShowBoardTime);
NotifyHUD();
return;
}
protected func JoinPlayer(int plr)
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var pos = FindRelaunchPos(plr);
clonk->SetPosition(pos[0], pos[1]);
return;
}
private func FindRelaunchPos(int plr)
{
var tx, ty; // Test position.
for (var i = 0; i < 500; i++)
{
tx = Random(LandscapeWidth());
ty = Random(LandscapeHeight());
if (GBackSemiSolid(AbsX(tx), AbsY(ty)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10)))
continue;
// Succes.
return [tx, ty];
}
return nil;
}
public func IsFulfilled()
{
// Check whether someone has reached the limit.
@ -94,7 +47,7 @@ public func IsFulfilled()
// Otherwise just check if there are no enemies
return Goal_Melee->IsFulfilled();
// Eliminate all players, that are not in a team with one of the winners
for (var i = 0; i < GetPlayerCount(); i++)
for (var i = 0; i < GetPlayerCount(); i++)
{
var plr = GetPlayerByIndex(i);
if (winner == plr)
@ -117,7 +70,7 @@ public func GetDescription(int plr)
{
var score = GetRelativeScore(plr);
if (score.kills > 0)
return Format("$MsgAhead$", score.kills, GetPlayerName(score.best));
return Format("$MsgAhead$", score.kills, GetPlayerName(score.best));
else if (score.kills < 0)
return Format("$MsgBehind$", -score.kills, GetPlayerName(score.best));
else if (score.best == plr)
@ -136,7 +89,7 @@ public func Activate(int byplr)
else
{
var score = GetRelativeScore(byplr);
if(score.kills > 0) MessageWindow(Format("$MsgAhead$", score.kills, GetPlayerName(score.best)), byplr);
if(score.kills > 0) MessageWindow(Format("$MsgAhead$", score.kills, GetPlayerName(score.best)), byplr);
else if(score.kills < 0) MessageWindow(Format("$MsgBehind$", -score.kills,GetPlayerName(score.best)), byplr);
else if(score.best == byplr) MessageWindow(Format("$MsgYouAreBest$", score.kills), byplr);
else MessageWindow(Format("$MsgEqual$", GetPlayerName(score.best)), byplr);

View File

@ -4,8 +4,6 @@
Premade goal for simple melees with relaunches.
Callbacks made to scenario script:
* OnPlayerRelaunch(int plr) made when the player is relaunched and at game start plr init.
* RelaunchCount() should return the number of relaunches.
* KillsToRelaunch() should return how many kills will earn the player an extra relaunch.
--*/
@ -19,7 +17,6 @@
#include Scoreboard_Relaunch
// Some rule default values
local DefaultRelaunchCount = 5; // Number of relaunches.
local DefaultKillsToRelaunch = 4; // Number of kills one needs to make before gaining a relaunch.
local ShowBoardTime = 5; // Duration in seconds the scoreboard will be shown to a player on an event.
@ -33,14 +30,6 @@ protected func Initialize()
/*-- Scenario callbacks --*/
private func RelaunchCount()
{
var relaunch_cnt = GameCall("RelaunchCount");
if (relaunch_cnt != nil)
return relaunch_cnt;
return DefaultRelaunchCount;
}
private func KillsToRelaunch()
{
var kills_to_relaunch = GameCall("KillsToRelaunch");
@ -53,21 +42,12 @@ private func KillsToRelaunch()
protected func InitializePlayer(int plr)
{
// First process relaunches, etc.
_inherited(plr, ...);
// Join plr.
JoinPlayer(plr);
// Scenario script callback.
GameCall("OnPlayerRelaunch", plr, false);
return;
}
protected func RelaunchPlayer(int plr, int killer)
{
_inherited(plr, killer, ...);
if (GetRelaunchCount(plr) < 0)
return EliminatePlayer(plr);
// the kill logs rule cares about logging the respawn
// ..
@ -82,50 +62,11 @@ protected func RelaunchPlayer(int plr, int killer)
Log("$MsgRelaunchGained$", GetPlayerName(killer));
}
var clonk = CreateObjectAbove(Clonk, 0, 0, plr);
clonk->MakeCrewMember(plr);
SetCursor(plr, clonk);
JoinPlayer(plr);
// Scenario script callback.
GameCall("OnPlayerRelaunch", plr, true);
// Show scoreboard for a while.
DoScoreboardShow(1, plr + 1);
Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * ShowBoardTime);
return;
}
protected func JoinPlayer(int plr)
{
var clonk = GetCrew(plr);
clonk->DoEnergy(100000);
var pos = FindRelaunchPos(plr);
clonk->SetPosition(pos[0], pos[1]);
return;
}
private func FindRelaunchPos(int plr)
{
var tx, ty; // Test position.
for (var i = 0; i < 500; i++)
{
tx = Random(LandscapeWidth());
ty = Random(LandscapeHeight());
if (GBackSemiSolid(AbsX(tx), AbsY(ty)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10)))
continue;
// Succes.
return [tx, ty];
}
return nil;
}
protected func RemovePlayer(int plr)
{
return _inherited(plr, ...);

View File

@ -56,8 +56,7 @@ protected func Initialize(...)
private func EnsureRestartRule()
{
if (!ObjectCount(Find_ID(Rule_Restart)))
CreateObject(Rule_Restart, Min(64, LandscapeWidth()-GetX()-32), 0, NO_OWNER);
GetRelaunchRule()->EnablePlayerRestart();
return true;
}
@ -440,7 +439,7 @@ protected func OnClonkDeath(object clonk, int killed_by)
JoinPlayer(plr);
// Transfer contents if active.
if (transfer_contents)
Rule_BaseRespawn->TransferInventory(clonk, new_clonk);
GetRelaunchRule()->TransferInventory(clonk, new_clonk);
// Scenario script callback.
GameCall("OnPlayerRespawn", plr, FindRespawnCP(plr));
// Log message.
@ -498,10 +497,7 @@ public func SaveScenarioObject(props)
{
if (!inherited(props, ...))
return false;
// Force dependency on restart rule.
var restart_rule = FindObject(Find_ID(Rule_Restart));
if (restart_rule)
restart_rule->MakeScenarioSaveName();
props->AddCall("Goal", this, "EnsureRestartRule");
if (no_respawn_handling)
props->AddCall("Goal", this, "DisableRespawnHandling");
if (transfer_contents)

View File

@ -228,6 +228,11 @@ public func GetCarryTransform()
return Trans_Rotate(90, 1, 0, 0);
}
public func OnRelaunchCreation()
{
CreateContents(LeadBullet);
}
public func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(1500, 0, -1500), Trans_Rotate(170, 0, 1, 0), Trans_Rotate(30, 0, 0, 1)), def);

View File

@ -232,6 +232,12 @@ public func GetCarrySpecial(clonk)
if(fAiming) return "pos_hand2";
}
public func OnRelaunchCreation()
{
CreateContents(Arrow);
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-4000,-2000,4000),Trans_Rotate(180,0,1,0),Trans_Rotate(-45,0,0,1));

View File

@ -247,6 +247,12 @@ public func GetCarryTransform(object clonk, bool idle, bool nohand, bool second_
return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1));
}
public func OnRelaunchCreation()
{
CreateContents(IronBomb);
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));

View File

@ -10,24 +10,14 @@
* RemovePlayer(int plr);
--*/
local score_relaunch_list; // Here the relaunch count of all players is stored, access through plrid.
// Overload this.
public func RelaunchCount()
{
return 5;
}
/*-- Callbacks --*/
protected func Initialize()
{
// Make sure it is a list.
score_relaunch_list = [];
// init scoreboard
// init scoreboard, uses the condition of Scoreboard_Deaths too
Scoreboard->Init(
if(UnlimitedRelaunches()) return;
Scoreboard->Init(
[{key = "relaunches", title = Scoreboard_Relaunch, sorted = true, desc = true, default = "", priority = 75, conditional = Scoreboard_Death.ScoreboardCondition}]
);
return _inherited(...);
@ -35,20 +25,16 @@ protected func Initialize()
protected func InitializePlayer(int plr)
{
var plrid = GetPlayerID(plr);
// create scoreboard entry
score_relaunch_list[plrid] = RelaunchCount();
if(UnlimitedRelaunches()) return;
Scoreboard->NewPlayerEntry(plr);
Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]);
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr));
return _inherited(plr, ...);
}
protected func RelaunchPlayer(int plr, int killer)
{
var plrid = GetPlayerID(plr);
// Modify scoreboard relaunch count entry for this player.
score_relaunch_list[plrid]--;
Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]);
if(UnlimitedRelaunches()) return;
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchCount(plr));
return _inherited(plr, killer, ...);
}
@ -59,26 +45,6 @@ protected func RemovePlayer(int plr)
/*-- Misc --*/
public func SetRelaunchCount(int plr, int value)
{
var plrid = GetPlayerID(plr);
score_relaunch_list[plrid] = value;
Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]);
return;
}
public func GetRelaunchCount(int plr)
{
var plrid = GetPlayerID(plr);
return score_relaunch_list[plrid];
}
public func DoRelaunchCount(int plr, int value)
{
var plrid = GetPlayerID(plr);
score_relaunch_list[plrid] += value;
Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]);
return;
}
local Name = "Scoreboard Relaunches";

View File

@ -1,185 +1,7 @@
/**
Base Respawn
If neutral flagpoles are available, respawn there (for free). Otherwise, respawn
at the nearest base if sufficient clonks and clunkers are available.
TODO: make more general for all kinds of available crew members.
@author Maikel, Sven2
*/
/* Converts itself to the Rule_Relaunch rule. */
// Determines whether the inventory of the crew member is transfered upon respawn.
local inventory_transfer = false;
// Determines whether a crew member needs to be bought.
local free_crew = false;
// Delay between clonk death and respawn (in seconds)
local respawn_delay = 2;
protected func Initialize()
protected func Construction()
{
ScheduleCall(this, this.CheckDescription, 1, 1);
return true;
}
private func CheckDescription()
{
// If neutral flagpoles exist, update name and description.
if (ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral")))
{
SetName("$Name2$");
this.Description = "$Description2$";
}
return true;
}
public func SetInventoryTransfer(bool transfer)
{
inventory_transfer = transfer;
return true;
}
public func GetInventoryTransfer()
{
return inventory_transfer;
}
public func SetFreeCrew(bool free)
{
free_crew = free;
return true;
}
public func GetFreeCrew()
{
return free_crew;
}
protected func OnClonkDeath(object clonk)
{
var plr = clonk->GetOwner();
// Skip eliminated players, NO_OWNER, etc.
if (!GetPlayerName(plr))
return true;
// Only respawn a clonk if it is the last crew member.
if (GetCrewCount(plr) >= 1)
return true;
// Get the bases at which the clonk can possibly respawn.
var bases = GetBases(clonk), crew;
for (var base in bases)
{
if (!base)
continue;
// If free crew just create a clonk at the base.
if (free_crew)
{
crew = CreateObjectAbove(Clonk, base->GetX() - GetX(), base->GetY() + base->GetDefHeight() / 2 - GetY(), plr);
crew->MakeCrewMember(plr);
SetCursor(plr, crew);
// Transfer inventory if turned on.
if (inventory_transfer) TransferInventory(clonk, crew);
break;
}
// Try to buy a crew member at the base.
var pay_plr = base->GetOwner();
// Payment in neutral bases by clonk owner.
if (pay_plr == NO_OWNER)
pay_plr = plr;
crew = base->~DoBuy(Clonk, plr, pay_plr, clonk);
if (crew)
{
crew->Exit(0, base->GetDefHeight() / 2);
SetCursor(plr, crew);
// Transfer inventory if turned on.
if (inventory_transfer) TransferInventory(clonk, crew);
break;
}
}
// Respawn delay (+Weapon choice if desired by scenario)
if (crew && respawn_delay)
{
crew->SetCrewEnabled(false); // will be re-set by relauncher
var relaunch = CreateObject(RelaunchContainer, crew->GetX() - GetX(), crew->GetY() - GetY(), plr);
relaunch->SetRelaunchTime(respawn_delay, false);
relaunch->StartRelaunch(crew);
// But keep view on old corpse because the death might be exciting!
// And sometimes you want to know why you died (just like in real-life!)
var light = CreateLight(clonk->GetX() - GetX(), clonk->GetY() - GetY(), 100, Fx_Light.LGT_Temp, plr, 20, respawn_delay*36);
SetCursor(plr, nil);
SetPlrView(plr, light);
}
return true;
}
private func TransferInventory(object from, object to)
{
// Drop some items that cannot be transferred (such as connected pipes and dynamite igniters)
var i = from->ContentsCount(), contents;
while (i--)
if (contents = from->Contents(i))
if (contents->~IsDroppedOnDeath(from))
{
contents->Exit();
}
else
{
// The new clonk doesn't burn. To be consistent, also extinguish contents
contents->Extinguish();
}
return to->GrabContents(from);
}
private func GetBases(object clonk)
{
var plr = clonk->GetOwner();
// Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions.
var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance());
// If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk.
if (GetLength(bases) <= 0)
bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance());
return bases;
}
protected func Activate(int byplr)
{
MessageWindow(this.Description, byplr);
return true;
}
/*-- Scenario saving --*/
public func SaveScenarioObject(props, ...)
{
if (!inherited(props, ...))
return false;
// Custom properties
props->Remove("Name"); // updated by initialization
props->Remove("Description"); // updated by initialization
if (inventory_transfer)
props->AddCall("InvenctoryTransfer", this, "SetInventoryTransfer", inventory_transfer);
if (free_crew)
props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew);
return true;
}
/* Editor */
public func Definition(def)
{
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" };
def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" };
}
/*-- Proplist --*/
local Name = "$Name$";
local Description = "$Description$";
local Visibility = VIS_Editor;
local EditorPlacementLimit = 1; // Rules are to be placed only once
GetRelaunchRule()->SetBaseRespawn(true);
return RemoveObject();
}

View File

@ -1,8 +0,0 @@
Name=Basis Neustart
Name2=Neustart am Flaggenmast
Description=Du wirst in der nächstliegenden Basis wiederbelebt, wenn ausreichend Clonks und Clunker vorhanden sind.
Description2=Du wirst am nächstliegenden Flaggenmast wiederbelebt.
InventoryTransfer=Inventar behalten
InventoryTransferHelp=Ob das Inventar sterbender Clonks beim Respawn zum neuen Clonk teleportiert werden soll.
FreeCrew=Kostenloser Respawn
FreeCrewHelp=Ob man die Clonks umsonst bekommt.

View File

@ -1,8 +0,0 @@
Name=Base Respawn
Name2=Respawn at flagpole
Description=You respawn at the nearest base if sufficient clonks and clunkers are available.
Description2=You respawn at the nearest respawn flagpole.
InventoryTransfer=Keep inventory
InventoryTransferHelp=Whether the inventory of dying clonks is beamed to the newly respawned clonk.
FreeCrew=Free respawn
FreeCrewHelp=Whether respawning clonks are free. If not set, respawn happens only if the player has sufficient gold and clonks available for sale.

View File

@ -42,16 +42,7 @@ func OnClonkDeathEx(object clonk, int plr, int killed_by)
log=Format(Translate(Format("Teamkill%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by));
else log=Format(Translate(Format("KilledByPlayer%d", which_one)), GetTaggedPlayerName(plr), name, GetTaggedPlayerName(killed_by));
// okay, why is GetRelaunchCount not a global function..?
// and why are the relaunches not stored in a static variable or a singleton that can be accessed somehow..
var relaunches=nil;
for(var goal in FindObjects(Find_Or(Find_Category(C4D_Goal), Find_Category(C4D_Rule))))
{
relaunches = goal->~GetRelaunchCount(plr);
if(relaunches != nil) break;
}
if(relaunches == nil) relaunches=GameCall("GetRelaunchCount", plr);
var relaunches = GetRelaunchCount(plr);
if(relaunches != nil)
{
var msg="";

View File

@ -0,0 +1,7 @@
[DefCore]
id=Rule_Relaunch
Version=8,0
Category=C4D_StaticBack | C4D_Rule
Width=32
Height=32
Offset=-16,-16

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -3,34 +3,20 @@
Author: Maikel
This container holds the clonk after relaunches.
* The time the clonk is held can be specified with SetRelaunchTime(int time);
* The time the clonk is held can be specified by calling GetRelaunchRule()->SetRespawnDelay(int time).
* After that time the clonk is released and OnClonkLeftRelaunch(object clonk) is called in the scenario script.
* Optionally the clonk can choose a weapon if GetRelaunchWeaponList in the scenario script returns a valid id-array.
--*/
local time;
local menu;
local hold;
local has_selected;
local crew;
protected func Initialize()
{
time = 36 * 10;
return;
}
// Sets the GetRelaunchRule().RelaunchTime, in seconds, the clonk is held in the container.
// Sets the time, in seconds, the clonk is held in the container.
public func SetRelaunchTime(int to_time, bool to_hold)
{
time = to_time * 36;
hold = to_hold;
return;
}
// Returns the time, in seconds the clonk is held.
public func GetRelaunchTime() { return time / 36; }
// Returns the GetRelaunchRule().RelaunchTime, in seconds the clonk is held.
public func GetRelaunchTime() { return GetRelaunchRule().RelaunchTime / 36; }
// Retrieve weapon list from scenario.
private func WeaponList() { return GameCall("RelaunchWeaponList"); }
@ -47,7 +33,6 @@ public func StartRelaunch(object clonk)
clonk->Enter(this);
ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk);
AddEffect("IntTimeLimit", this, 100, 36, this);
return true;
}
@ -62,11 +47,17 @@ private func OpenWeaponMenu(object clonk)
{
menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner());
menu->SetPermanent();
menu->SetTitle(Format("$MsgWeapon$", time / 36));
clonk->SetMenu(menu, true);
menu->SetTitle(Format("$MsgWeapon$", GetRelaunchRule().RelaunchTime / 36));
clonk->SetMenu(menu, true);
if(GetType(GetRelaunchRule().LastUsedPlayerWeapons) != C4V_Array) GetRelaunchRule().LastUsedPlayerWeapons = [];
for (var weapon in weapons)
menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon);
{
if(GetRelaunchRule().LastUsedPlayerWeapons[clonk->GetOwner()] != weapon)
{
menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon);
}
}
menu->Open();
}
@ -81,7 +72,7 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime)
RemoveObject();
return -1;
}
if (fxtime >= time)
if (fxtime >= GetRelaunchRule().RelaunchTime)
{
if (!has_selected && WeaponList())
GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]);
@ -89,22 +80,23 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime)
return -1;
}
if (menu)
menu->SetTitle(Format("$MsgWeapon$", (time - fxtime) / 36));
menu->SetTitle(Format("$MsgWeapon$", (GetRelaunchRule().RelaunchTime - fxtime) / 36));
else
PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (time - fxtime) / 36));
PlayerMessage(clonk->GetOwner(), Format("$MsgRelaunch$", (GetRelaunchRule().RelaunchTime - fxtime) / 36));
return 1;
}
public func OnWeaponSelected(id weapon)
{
if(!crew) return;
GiveWeapon(weapon);
if(GetRelaunchRule().DisableLastWeapon) GetRelaunchRule().LastUsedPlayerWeapons[crew->GetOwner()] = weapon;
has_selected = true;
// Close menu manually, to prevent selecting more weapons.
if (menu)
menu->Close();
if (!hold)
if (!GetRelaunchRule().Hold)
RelaunchClonk();
return true;
}
@ -120,7 +112,7 @@ private func RelaunchClonk()
SetPlrView(clonk->GetOwner(), clonk);
}
clonk->Exit();
GameCall("OnClonkLeftRelaunch", clonk);
GameCall("OnClonkLeftRelaunch", clonk, clonk->GetOwner());
if (menu)
menu->Close();
PlayerMessage(clonk->GetOwner(), "");
@ -131,12 +123,9 @@ private func RelaunchClonk()
private func GiveWeapon(id weapon_id)
{
var newobj = CreateObjectAbove(weapon_id);
if (weapon_id == Bow)
newobj->CreateContents(Arrow);
if (weapon_id == Blunderbuss)
newobj->CreateContents(LeadBullet);
newobj->~OnRelaunchCreation(crew);
crew->Collect(newobj);
return;
return true;
}
public func SaveScenarioObject() { return false; }

View File

@ -0,0 +1,418 @@
/**
Relaunch Rule
This rule enables and handles relaunches.
@author Maikel, Sven2, Fulgen
*/
// Determines whether the inventory of the crew member is transfered upon respawn.
local inventory_transfer = false;
// Determines whether a crew member needs to be bought.
local free_crew = true;
//Determines whether the clonk will be respawned at the base
local respawn_at_base = false;
//Determines whether only the last clonk gets respawned
local RespawnLastClonk = false;
local DefaultRelaunchCount = nil;
local aRelaunches = [];
local ClonkType = Clonk;
local DisableLastWeapon = false;
local LastUsedPlayerWeapons = [];
local RelaunchTime = 36 * 10;
local Hold = false;
local RestartPlayer = false;
public func Activate(int plr)
{
if(!RestartPlayer) return MessageWindow(this.Description, plr);
// Notify scenario.
if (!GameCall("OnPlayerRestart", plr))
return;
// Remove the player's clonk, including contents.
var clonk = GetCrew(plr);
if (clonk && clonk->GetCrewEnabled())
{
clonk->Kill(clonk, true);
clonk->RemoveObject();
}
}
protected func Initialize()
{
ScheduleCall(this, this.CheckDescription, 1, 1);
if(GetScenarioVal("Mode", "Game") == "Melee") DefaultRelaunchCount = 5;
return true;
}
private func CheckDescription()
{
// If neutral flagpoles exist, update name and description.
if(respawn_at_base)
{
if(ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral")))
{
SetName("$Name2$");
this.Description = "$Description2$";
}
else
{
SetName("$Name3$");
this.Description = "$Description3$";
}
}
else
{
SetName("$Name$");
this.Description = "$Description$";
}
return true;
}
public func SetInventoryTransfer(bool transfer)
{
inventory_transfer = transfer;
return true;
}
public func GetInventoryTransfer()
{
return inventory_transfer;
}
public func SetFreeCrew(bool free)
{
free_crew = free;
return true;
}
public func GetFreeCrew()
{
return free_crew;
}
public func SetRespawnDelay(int iDelay)
{
RelaunchTime = iDelay * 36;
return this;
}
public func GetRespawnDelay()
{
return RelaunchTime / 36;
}
public func SetHolding(bool fHold)
{
Hold = fHold;
return this;
}
public func GetHolding()
{
return Hold;
}
public func SetLastWeaponUse(bool fUse)
{
this.DisableLastWeapon = !fUse;
return this;
}
public func GetLastWeaponUse()
{
return DisableLastWeapon;
}
public func SetBaseRespawn(bool fSet)
{
respawn_at_base = fSet;
return this;
}
public func GetBaseRespawn()
{
return respawn_at_base;
}
public func SetDefaultRelaunches(int iRelaunches)
{
DefaultRelaunchCount = iRelaunches;
}
public func SetLastClonkRespawn(bool b)
{
RespawnLastClonk = b;
return this;
}
public func EnablePlayerRestart()
{
RestartPlayer = true;
return this;
}
public func DisablePlayerRestart()
{
RestartPlayer = false;
return this;
}
public func GetLastClonkRespawn()
{
return RespawnLastClonk;
}
public func InitializePlayer(int iPlr)
{
_inherited(iPlr, ...);
// Scenario script callback.
aRelaunches[iPlr] = DefaultRelaunchCount;
GameCallEx("OnPlayerRelaunch", iPlr, false);
return DoRelaunch(iPlr, nil, nil, true);
}
/*public func OnClonkDeath(int plr, object pClonk, int iKiller)
{
return RelaunchPlayer(plr, iKiller, pClonk);
}*/
public func RelaunchPlayer(int plr, int killer, object pClonk)
{
if(plr == nil || plr == NO_OWNER) return Log("NO PlAYER: %d", plr);
if(DefaultRelaunchCount != nil)
{
aRelaunches[plr]--;
if(aRelaunches[plr] < 0)
{
EliminatePlayer(plr);
return;
}
}
GameCall("OnPlayerRelaunch", plr, true);
return DoRelaunch(plr, pClonk, nil);
}
private func RespawnAtBase(int iPlr, object pClonk)
{
for(var base in GetBases(pClonk))
{
if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2];
}
}
private func TransferInventory(object from, object to)
{
if(!from || !to) return;
// Drop some items that cannot be transferred (such as connected pipes and dynamite igniters)
var i = from->ContentsCount(), contents;
while (i--)
if (contents = from->Contents(i))
if (contents->~IsDroppedOnDeath(from))
{
contents->Exit();
}
else
{
// The new clonk doesn't burn. To be consistent, also extinguish contents
contents->Extinguish();
}
return to->GrabContents(from);
}
private func GetBases(object clonk)
{
var plr = clonk->GetOwner();
// Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions.
var bases = clonk->FindObjects(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance());
// If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk.
if (GetLength(bases) <= 0)
bases = clonk->FindObjects(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance());
return bases;
}
public func DoRelaunch(int iPlr, object pClonk, array position, bool fNoCreation)
{
if(!GetPlayerName(iPlr)) return;
if(RespawnLastClonk && GetCrewCount(iPlr) >= 1) return;
if(respawn_at_base) position = RespawnAtBase(iPlr, pClonk);
position = (position ?? GameCallEx("RelaunchPosition", iPlr, GetPlayerTeam(iPlr))) ?? FindRelaunchPos(iPlr);
var spawn;
// position array either has the form [x, y] or [[x, y], [x, y], ...]
if(GetType(position) == C4V_Array)
{
if(GetType(position[0]) == C4V_Array)
{
spawn = position[Random(GetLength(position))];
}
else spawn = position;
}
var clonk;
if(!fNoCreation)
{
if(free_crew)
{
clonk = CreateObjectAbove(ClonkType, spawn[0], spawn[1],iPlr);
if(!clonk) return;
clonk->MakeCrewMember(iPlr);
}
else
{
// Try to buy a crew member at the base.
var pay_plr = base->GetOwner();
// Payment in neutral bases by clonk owner.
if (pay_plr == NO_OWNER)
pay_plr = plr;
clonk = base->~DoBuy(ClonkType, plr, pay_plr, pClonk);
if (clonk)
{
clonk->Exit();
}
}
}
else
{
clonk = GetCrew(iPlr);
if(!clonk) return;
}
if (inventory_transfer) TransferInventory(pClonk, clonk);
clonk->SetPosition(spawn[0], spawn[1], iPlr)
if(!GetCursor(iPlr) || GetCursor(iPlr) == pClonk) SetCursor(iPlr, clonk);
clonk->DoEnergy(clonk.Energy || 100000);
if(RelaunchTime)
{
clonk->CreateObject(RelaunchContainer,nil,nil,iPlr)->StartRelaunch(clonk);
}
return true;
}
protected func FindRelaunchPos(int plr)
{
var tx, ty; // Test position.
for (var i = 0; i < 500; i++)
{
tx = Random(LandscapeWidth());
ty = Random(LandscapeHeight());
if (GBackSemiSolid(AbsX(tx), AbsY(ty)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10)))
continue;
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10)))
continue;
// Succes.
return [tx, ty];
}
return nil;
}
/*-- Scenario saving --*/
public func SaveScenarioObject(props, ...)
{
if (!inherited(props, ...))
return false;
// Custom properties
props->Remove("Name"); // updated by initialization
props->Remove("Description"); // updated by initialization
if (inventory_transfer)
props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer);
if (free_crew)
props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew);
if(respawn_at_base)
props->AddCall("BaseRespawn", this, "SetBaseRespawn", respawn_at_base);
return true;
}
/*-- Globals --*/
global func SetRelaunchCount(int plr, int value)
{
if(UnlimitedRelaunches()) return;
GetRelaunchRule().aRelaunches[plr] = value;
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]);
return value;
}
global func GetRelaunchCount(int plr)
{
return GetRelaunchRule().aRelaunches[plr];
}
global func DoRelaunchCount(int plr, int value)
{
if(UnlimitedRelaunches()) return;
GetRelaunchRule().aRelaunches[plr] += value;
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().aRelaunches[plr]);
return;
}
global func UnlimitedRelaunches()
{
return GetRelaunchRule().DefaultRelaunchCount == nil;
}
global func GetRelaunchRule()
{
return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch);
}
/* Editor */
public func Definition(def)
{
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" };
def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" };
def.EditorProps.respawn_at_base = {
Name = "$RespawnAtBase$",
EditorHelp = "$RespawnAtBaseHelp$",
Type = "bool",
Set = "SetBaseRespawn"
};
def.EditorProps.hold = {
Name = "$Holding$",
EditorHelp = "$HoldingHelp$",
Type = "bool",
Set = "SetHolding"
};
def.EditorProps.respawn_delay = {
Name = "$RespawnDelay$",
EditorHelp = "$RespawnDelayHelp$",
Type = "int",
Set = "SetRespawnDelay"
};
def.EditorProps.relaunch_count = {
Name = "$RelaunchCount$",
EditorHelp = "$RelaunchCountHelp$",
Type = "int",
Set = "SetDefaultRelaunches"
};
}
/*-- Proplist --*/
local Name = "$Name$";
local Description = "$Description$";
local Visibility = VIS_Editor;
local EditorPlacementLimit = 1; // Rules are to be placed only once

View File

@ -0,0 +1,18 @@
Name=Relaunches
Name2=Neustart am Flaggenmast
Name3=Neustart in der Basis
Description=Du wirst an einem vorgegebenen Ort in der Landschaft wiederbelebt.
Description2=Du wirst am nächstliegenden Flaggenmast wiederbelebt.
Description3=Du wirst in der nächstliegenden Basis wiederbelebt, wenn ausreichend Clonks und Clunker vorhanden sind.
InventoryTransfer=Inventar behalten
InventoryTransferHelp=Ob das Inventar sterbender Clonks beim Respawn zum neuen Clonk teleportiert werden soll.
FreeCrew=Kostenloser Respawn
FreeCrewHelp=Ob man die Clonks umsonst bekommt.
RespawnAtBase=Respawn bei der Basis
RespawnAtBaseHelp=Ob man bei der Basis spawnt.
Holding=Clonk bleibt im Container
HoldingHelp=Ob der Clonk nach Auswahl einer Waffe im Container bleibt.
RespawnDelay=Respawnzeit
RespawnDelayHelp=Zeit, die vom Tod bis zum Respawn vergeht.
RelaunchCount=Anzahl der Relaunches
RelaunchCountHelp=Anzahl der Relaunches, die man erhält. Auf -1 setzen, um unbegrenzte Relaunches zu ermöglichen.

View File

@ -0,0 +1,18 @@
Name=Relaunches
Name2=Respawn at flagpole
Name3=Base respawn
Description=You respawn at a fixed point in the map.
Description2=You respawn at the nearest respawn flagpole.
Description3=You respawn at the nearest base if sufficient clonks and clunkers are available.
InventoryTransfer=Keep inventory
InventoryTransferHelp=Whether the inventory of dying clonks is beamed to the newly respawned clonk.
FreeCrew=Free respawn
FreeCrewHelp=Whether respawning clonks are free. If not set, respawn happens only if the player has sufficient gold and clonks available for sale.
RespawnAtBase=Respawn bei der Basis
RespawnAtBaseHelp=Ob man bei der Basis spawnt.
Holding=Clonks stay in the container
HoldingHelp=Whether respawning clonks stay in the container until the respawn time ends.
RespawnDelay=Respawn delay
RespawnDelayHelp=Time from death to respawning.
RelaunchCount=Relaunch count
RelaunchCountHelp=Amount of relaunches. Set it to -1 to enable infinite relaunches.

View File

@ -1,7 +0,0 @@
[DefCore]
id=Rule_Restart
Version=8,0
Category=C4D_StaticBack|C4D_Rule
Width=32
Height=32
Offset=-16,-16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,39 +0,0 @@
/*-- Restart --*/
local remove_contents;
protected func Initialize()
{
// Contents are removed
remove_contents = true;
return;
}
public func Activate(int plr)
{
// Notify scenario.
if (GameCall("OnPlayerRestart", plr))
return;
// Remove the player's clonk, including contents.
var clonk = GetCrew(plr);
if (clonk && clonk->GetCrewEnabled())
{
// Remove contents only if the Base Respawn Rule isn't there otherwise it will handle inventory
if (!ObjectCount(Find_ID(Rule_BaseRespawn)) && remove_contents)
while (clonk->Contents())
clonk->Contents()->RemoveObject();
clonk->Kill(clonk, true);
clonk->RemoveObject();
}
}
public func SetRemoveContents(bool do_removal)
{
remove_contents = do_removal;
return;
}
local Name = "$Name$";
local Description = "$Description$";
local Visibility = VIS_Editor;
local EditorPlacementLimit = 1; // Rules are to be placed only once

View File

@ -1,2 +0,0 @@
Name=Neu starten
Description=Diese Spielregel erlaubt dem Spieler nochmal von vorne zu beginnen.

View File

@ -1,2 +0,0 @@
Name=Restart
Description=This rule allows the player to start again.

View File

@ -45,10 +45,9 @@ protected func Initialize()
// Rules: no power and restart with keeping inventory.
CreateObject(Rule_NoPowerNeed);
var restart = FindObject(Find_ID(Rule_Restart));
if (!restart)
restart = CreateObject(Rule_Restart);
restart->SetRemoveContents(false);
GetRelaunchRule()
->EnablePlayerRestart()
->SetInventoryTransfer(true);
// Initialize parts of the scenario.
var amount = BoundBy(SCENPAR_NrCheckPoints, 6, 20);

View File

@ -503,7 +503,6 @@ func InitializeObjects()
var Torch018 = CreateObjectAbove(Torch, 1005, 1164);
Torch018->AttachToWall(true);
var Rule_Restart001 = CreateObject(Rule_Restart);
g_goal = CreateObject(Goal_Parkour);

View File

@ -2,6 +2,8 @@
private func Initialize()
{
GetRelaunchRule()
->EnablePlayerRestart();
// Create dynamite below the first lava basin
DrawMaterialQuad("Tunnel",1378,1327-5,1860,1327-5,1860,1330,1387,1330,1);

View File

@ -62,7 +62,6 @@ protected func Initialize()
// Create Disasters.
//Earthquake->SetChance(2); - this is so random...not fair without relaunches
ScheduleCall(nil, Global.RemoveAll, 3, nil, Find_ID(Rule_Restart));
return;
}

View File

@ -42,7 +42,6 @@ protected func Initialize()
};
CreateEffect(fx_volcano, 1, 40);
ScheduleCall(nil, Global.RemoveAll, 3, nil, Find_ID(Rule_Restart));
// Bottom is open, so put some stable lava here to prevent remaining lava from just flowing out of the map
DrawMaterialQuad("StableLava",0,h0,w,h0,w,h,0,h);
return;

View File

@ -11,10 +11,6 @@ func InitializeObjects()
var Grass003 = CreateObjectAbove(Grass, 228, 1180);
Grass003->SetClrModulation(0xffa08060);
var Rule_BaseRespawn001 = CreateObject(Rule_BaseRespawn);
Rule_BaseRespawn001->SetInventoryTransfer(true);
Rule_BaseRespawn001->SetFreeCrew(true);
var Tree_Coniferous_Burned001 = CreateObject(Tree_Coniferous_Burned, 17, 1097);
Tree_Coniferous_Burned001->SetR(10);
var Tree_Coniferous_Burned002 = CreateObject(Tree_Coniferous_Burned, 43, 1246);

View File

@ -28,6 +28,11 @@ func DoInit(int first_player)
enemy->DoEnergy(10000);
enemy->AddEnergyBar();
}
GetRelaunchRule()
->SetBaseRespawn(true)
->SetInventoryTransfer(true)
->SetFreeCrew(true);
return true;
}

View File

@ -513,7 +513,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -485,7 +485,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -637,7 +637,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -535,7 +535,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -376,7 +376,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -414,7 +414,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");

View File

@ -368,7 +368,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
// Add an interaction to call the airship.

View File

@ -477,7 +477,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
Rule_BaseRespawn->TransferInventory(target, clonk);
Rule_Relaunch->TransferInventory(target, clonk);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");