openclonk/planet/Tutorials.ocf/PlayGround.ocs/Script.c

210 lines
4.7 KiB
C

/**
Playground
Author: Maikel
Reward for completing the tutorials, a small playground where the player can test all ingame objects.
TODO:
* Multiple map options.
* Options for animals, vegetation.
*/
protected func Initialize()
{
// Tutorial goal.
var goal = CreateObject(Goal_Tutorial);
goal.Name = "$MsgGoalName$";
goal.Description = "$MsgGoalDescription$";
// Add an effect to track the easter egg for all players.
AddEffect("EasterEgg", nil, 100, 36);
// Initialize different scenario parts.
InitVegetation(3);
InitAnimals(SCENPAR_Animals);
return;
}
private func InitVegetation(int type)
{
// No vegetation.
if (type <= 1)
return;
var wdt = LandscapeWidth();
var hgt = LandscapeHeight();
// Place surface vegetation.
Tree_Coniferous->Place(10);
Tree_Coniferous2->Place(10);
return;
}
private func InitAnimals(int type)
{
// No animals.
if (type <= 1)
return;
var wdt = LandscapeWidth();
var hgt = LandscapeHeight();
// Sky animals.
if (FindLocation(Loc_Sky()))
{
var amount = BoundBy(wdt * hgt - GetTotalMaterialCount() / 20000, 4, 40);
Butterfly->Place(amount);
Mosquito->Place(amount / 2, 10);
if (type >= 3)
{
Zaphive->Place(amount / 2);
}
}
// Land animals.
if (FindLocation(Loc_Sky(), Loc_Wall(CNAT_Bottom)))
{
var amount = BoundBy(wdt / 200, 4, 40);
if (type >= 3)
{
Chippie_Egg->Place(amount / 2);
}
}
// Underwater animals.
if (FindLocation(Loc_Material("Water")))
{
var amount = BoundBy(GetMaterialCount(Material("Water")) / 1500, 4, 40);
Fish->Place(amount);
if (type >= 3)
{
Piranha->Place(amount / 2);
}
}
return;
}
/*-- Player Handling --*/
protected func InitializePlayer(int plr)
{
// Position player's clonk.
var clonk = GetCrew(plr, 0);
clonk->SetPosition(624, 526);
var effect = AddEffect("ClonkRestore", clonk, 100, 10);
effect.to_x = 624;
effect.to_y = 526;
// Standard player zoom for tutorials, set max zoom roughly up to scenario boundaries.
SetPlayerViewLock(plr, true);
SetPlayerZoomByViewRange(plr, 400, nil, PLRZOOM_Direct);
SetPlayerZoomByViewRange(plr, 1200, nil, PLRZOOM_LimitMax);
// Give the player all construction plans.
var index = 0, def;
while (def = GetDefinition(index++))
SetPlrKnowledge(plr, def);
// Create tutorial guide, add messages, show first.
var guide = CreateObject(TutorialGuide, 0, 0 , plr);
var con_spawnmenu = GetPlayerControlAssignment(plr, CON_SpawnMenu, true, true);
guide->AddGuideMessage(Format("$MsgPlaygroundWelcome$", con_spawnmenu));
guide->ShowGuideMessage();
AddEffect("RemoveGuide", clonk, 100, 36 * 10);
// Achievement: Playground is completed by just playing it.
GainScenarioAchievement("TutorialCompleted", 3);
return;
}
global func FxRemoveGuideTimer(object target, proplist effect, int time)
{
return -1;
}
global func FxRemoveGuideStop(object target, proplist effect, int reason, bool temporary)
{
if (temporary)
return;
var guide = FindObject(Find_ID(TutorialGuide));
if (guide)
{
guide->HideGuide();
guide->RemoveObject();
}
}
/*-- Easter Egg --*/
global func FxEasterEggTimer(object target, proplist effect, int time)
{
// Check whether the landscape has been completely destroyed.
if (GetBlastableMaterialCount() < 1000)
{
GainScenarioAchievement("TutorialEasterEgg");
return FX_Execute_Kill;
}
return FX_OK;
}
global func GetBlastableMaterialCount()
{
var total = 0;
for (var index = 0; index < 256; index++)
{
// Only for solids.
if (GetMaterialVal("Density", "Material", index) < 50)
continue;
if (!GetMaterialVal("BlastFree", "Material", index) || !GetMaterialVal("DigFree", "Material", index))
continue;
var mat_cnt = GetMaterialCount(index);
if (mat_cnt != -1)
total += mat_cnt;
}
return total;
}
global func GetTotalMaterialCount()
{ var total = 0;
for (var index = 0; index < 256; index++)
{
var mat_cnt = GetMaterialCount(index);
if (mat_cnt != -1)
total += mat_cnt;
}
return total;
}
/*-- Clonk Restoring --*/
global func FxClonkRestoreTimer(object target, proplist effect, int time)
{
return 1;
}
// Relaunches the clonk, from death or removal.
global func FxClonkRestoreStop(object target, effect, int reason, bool temporary)
{
if (reason == 3 || reason == 4)
{
var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER);
var x = BoundBy(target->GetX(), 0, LandscapeWidth());
var y = BoundBy(target->GetY(), 0, LandscapeHeight());
restorer->SetPosition(x, y);
var to_x = effect.to_x;
var to_y = effect.to_y;
// Respawn new clonk.
var plr = target->GetOwner();
var clonk = CreateObject(Clonk, 0, 0, plr);
clonk->GrabObjectInfo(target);
SetCursor(plr, clonk);
clonk->DoEnergy(100000);
restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");
}
return 1;
}