add tutorial 3

shapetextures
Maikel de Vries 2015-10-11 12:11:10 +02:00
parent dd5f7d2ebe
commit fd4e7c120e
17 changed files with 1087 additions and 0 deletions

View File

@ -0,0 +1,21 @@
{\rtf1\ansi\deff0\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Arial;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fswiss\fprq0\fcharset1 Arial;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f7\fnil\fprq2\fcharset0 Arial;}{\f8\fnil\fprq0\fcharset1 Mangal;}}
{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Normal;}
{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af8\afs28\alang1081\loch\f5\fs28\lang1043 Heading;}
{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Text body;}
{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 List;}
{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\ai\loch\f4\fs24\lang1043 Caption;}
{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Index;}
}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720
\viewscale100
{\*\pgdsctbl
{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}}
\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af8\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033\loch\f3
Carry & Construct}
\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar\cf1\b\kerning1\langfe2052\dbch\af8\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033\loch\f3
\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar\rtlch \ltrch\loch
\par }

View File

@ -0,0 +1,21 @@
{\rtf1\ansi\deff0\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Arial;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fswiss\fprq0\fcharset1 Arial;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f7\fnil\fprq2\fcharset0 Arial;}{\f8\fnil\fprq0\fcharset1 Mangal;}}
{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Normal;}
{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af8\afs28\alang1081\loch\f5\fs28\lang1043 Heading;}
{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Text body;}
{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 List;}
{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\ai\loch\f4\fs24\lang1043 Caption;}
{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043 Index;}
}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720
\viewscale100
{\*\pgdsctbl
{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}}
\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af8\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033\loch\f3
Carry & Construct}
\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar\cf1\b\kerning1\langfe2052\dbch\af8\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033\loch\f3
\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af7\langfe2052\dbch\af8\afs24\alang1081\loch\f4\fs24\lang1043\nowidctlpar\rtlch \ltrch\loch
\par }

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,23 @@
[Head]
Icon=4
Title=Tutorial03
Version=5,4,0,0
MaxPlayer=1
Difficulty=3
[Definitions]
Definition1=Objects.ocd
Definition2=Decoration.ocd
[Player1]
Crew=Clonk=1
[Landscape]
Sky=Clouds1
SkyScrollMode=2
[Weather]
Climate=0,0,0,100
StartSeason=0,0,0,100
YearSpeed=0,0,0,100
Wind=1,100,-100,100

View File

@ -0,0 +1,606 @@
/**
Tutorial 03:
Author: Maikel
Construct sawmill and flagpole: explains contents menu, dynamite, chopping, foundry and construction site.
Following controls and concepts are explained:
* Contents menu: foundry and chest
* Production menu: foundry
* Using items: dynamite, hammer, axe
*/
static guide; // guide object.
protected func Initialize()
{
// Tutorial goal.
var goal = CreateObject(Goal_Tutorial);
goal.Name = "$MsgGoalName$";
goal.Description = "$MsgGoalDescription$";
// Place objects in different sections.
InitVillageEntrance();
InitVillageMain();
InitOreMine();
InitVillageUnderground();
InitVegetation();
InitAnimals();
InitAI();
// Dialogue options -> repeat round.
SetNextMission("Tutorials.ocf\\Tutorial03.ocs", "$MsgRepeatRound$", "$MsgRepeatRoundDesc$");
return;
}
// Gamecall from goals, set next mission.
protected func OnGoalsFulfilled()
{
// Achievement: Tutorial completed.
GainScenarioAchievement("TutorialCompleted", 3);
// Dialogue options -> next round.
SetNextMission("Tutorials.ocf\\Tutorial04.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$");
// Normal scenario ending by goal library.
return false;
}
private func InitVillageEntrance()
{
// Create a signpost.
CreateObjectAbove(EnvPack_Guidepost, 56, 384);
// Create a small forest.
CreateObjectAbove(Tree_Coniferous, 128, 384);
CreateObjectAbove(Tree_Coniferous, 148, 384);
CreateObjectAbove(Tree_Coniferous2, 156, 390);
CreateObjectAbove(Tree_Coniferous3, 176, 390);
CreateObjectAbove(Tree_Coniferous, 188, 384);
// Wind generator and sawmill construction site for wood production.
CreateObjectAbove(WindGenerator, 224, 384);
var site = CreateObjectAbove(ConstructionSite, 264, 386);
site.MeshTransformation = Trans_Mul(Trans_Rotate(RandomX(-30, 30), 0, 1, 0), Trans_Rotate(RandomX(-10, 10), 1, 0, 0));
site->Set(Sawmill);
site->CreateContents(Wood, 1);
site->CreateContents(Rock, 1);
// A hole where the axe is hidden.
CreateObjectAbove(Axe, 159, 474);
// A wooden cabin ruin on fire.
var cabin = CreateObjectAbove(Ruin_WoodenCabin, 370, 352);
for (var x = -20; x <= 20; x += 10)
CreateObjectAbove(Flame, cabin->GetX() + x, cabin->GetY());
cabin->AddScorch(-30, 15, 45, 32, 1200);
cabin->AddScorch(15, 0, -45, 50, 1500);
var chest = CreateObjectAbove(Chest, 410, 352);
chest->CreateContents(Hammer);
return;
}
private func InitOreMine()
{
// A foundry halfway down.
var foundry = CreateObjectAbove(Foundry, 456, 488);
var lantern = foundry->CreateContents(Lantern);
lantern->TurnOn();
// A lorry with mining equipment.
var lorry = CreateObjectAbove(Lorry, 212, 640);
lorry->CreateContents(Dynamite, 3);
return;
}
private func InitVillageMain()
{
// Elevator, and grain production on the right.
var elevator = CreateObjectAbove(Elevator, 601, 392);
elevator->CreateShaft(264);
var mill = CreateObjectAbove(Ruin_Windmill, 816, 392);
mill->AddScorch(-15, 42, 90, 50, 1200);
CreateObjectAbove(Kitchen, 904, 376);
CreateObjectAbove(Loom, 560, 392);
Wheat->Place(40 + Random(10), Rectangle(704, 352, 80, 64));
Cotton->Place(3, Rectangle(654, 352, 40, 64));
CreateObjectAbove(StrawMan, 714, 391);
CreateObjectAbove(StrawMan, 762, 391);
// Stone door to protect the village.
var door = CreateObjectAbove(StoneDoor, 1004, 376);
var wheel = CreateObjectAbove(SpinWheel, 972, 376);
wheel->SetStoneDoor(door);
// A tree is blocking the path down in this round.
CreateObject(MovingBrick, 870, 396);
var tree = CreateObjectAbove(Tree_Coniferous, 890, 422);
tree->SetR(90);
tree.Plane = 450;
// Tools and armory down below.
CreateObjectAbove(ToolsWorkshop, 698, 504);
CreateObjectAbove(Armory, 772, 504);
CreateObjectAbove(Flagpole, 828, 496);
return;
}
private func InitVillageUnderground()
{
// A wooden cabin ruin.
var cabin = CreateObjectAbove(Ruin_WoodenCabin, 574, 568);
cabin->AddScorch(-20, 12, 45, 50, 1500);
cabin->AddScorch(15, 10, -45, 50, 1500);
// Chemical lab ruin and flagpole on the left of the elevator.
var lab = CreateObjectAbove(Ruin_ChemicalLab, 484, 664);
lab->AddScorch(-12, 18, 130, 80, 1300);
CreateObjectAbove(Flagpole, 528, 664);
// Steam engine for power supply below.
var engine = CreateObjectAbove(SteamEngine, 780, 752);
engine->CreateContents(Coal, 5);
// Lorry with materials down below, the materials are only added in tutorial 4.
CreateObjectAbove(Lorry, 954, 670);
return;
}
private func InitVegetation()
{
PlaceGrass(85);
PlaceObjects(Firestone, 25 + Random(5), "Earth");
PlaceObjects(Loam, 15 + Random(5), "Earth");
Branch->Place(20, nil, {underground = true});
return;
}
private func InitAnimals()
{
// The wipf as your friend, controlled by AI.
var wipf = CreateObjectAbove(Wipf, 64, 384);
wipf->SetMeshMaterial("WipfSkin");
wipf->SetObjectLayer(wipf);
wipf->EnableTutorialControl(true);
// Some wipfs near the grain field.
var wipfs = Wipf->Place(4, Rectangle(640, 352, 180, 40));
for (wipf in wipfs)
{
wipf->SetObjectLayer(wipf);
wipf->EnableTutorialControl(false);
}
// Some butterflies as atmosphere.
for (var i = 0; i < 25; i++)
PlaceAnimal(Butterfly);
return;
}
// Initializes the AI: which is all defined in System.ocg
private func InitAI()
{
// A lumberjack npc for explaining how to cut trees.
var npc_lumberjack = CreateObjectAbove(Clonk, 192, 384);
npc_lumberjack->SetColor(0xffff00);
npc_lumberjack->SetName("Sato");
npc_lumberjack->SetObjectLayer(npc_lumberjack);
npc_lumberjack->SetSkin(3);
npc_lumberjack->SetDir(DIR_Left);
npc_lumberjack->SetDialogue("Lumberjack", true);
// A fireman NPC who extinguishes a burning cabin.
var npc_fireman = CreateObjectAbove(Clonk, 200, 384);
npc_fireman->SetColor(0xff0000);
npc_fireman->SetName("Hubert");
var barrel = npc_fireman->CreateContents(Barrel);
barrel->SetFilled("Water", 300);
npc_fireman->SetObjectLayer(npc_fireman);
npc_fireman->SetSkin(2);
npc_fireman->SetDir(DIR_Left);
npc_fireman->SetDialogue("Fireman", true);
// A builder which tells you where to place the flagpole.
var npc_builder = CreateObjectAbove(Clonk, 504, 376);
npc_builder->SetColor(0x440088);
npc_builder->SetName("Kummerog");
npc_builder->CreateContents(Hammer);
npc_builder->SetObjectLayer(npc_builder);
npc_builder->SetDir(DIR_Left);
npc_builder->SetDialogue("Builder", true);
// A farmer near the grain field.
var npc_farmer = CreateObjectAbove(Clonk, 720, 392);
npc_farmer->SetColor(0x00ffff);
npc_farmer->SetName("Genhered");
npc_farmer->SetObjectLayer(npc_farmer);
npc_farmer->SetSkin(1);
npc_farmer->SetDir(DIR_Left);
npc_farmer->SetDialogue("Farmer", true);
// Lookout.
// Village head.
return;
}
/*-- Player Handling --*/
protected func InitializePlayer(int plr)
{
// Position player's clonk.
var clonk = GetCrew(plr);
clonk->SetPosition(48, 374);
clonk->CreateContents(Shovel);
var effect = AddEffect("ClonkRestore", clonk, 100, 10);
effect.to_x = 48;
effect.to_y = 374;
// Claim ownership of structures.
for (var structure in FindObjects(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole"))))
structure->SetOwner(plr);
// Add an effect to the clonk to track the goal.
AddEffect("TrackGoal", clonk, 100, 2);
// Standard player zoom for tutorials.
SetPlayerViewLock(plr, true);
SetPlayerZoomByViewRange(plr, 400, nil, PLRZOOM_Direct | PLRZOOM_Set);
// Take ownership of the sawmill construction site.
var site = FindObject(Find_ID(ConstructionSite));
site->SetOwner(plr);
// Knowledge for the flagpole construction.
SetPlrKnowledge(plr, Flagpole);
// Create tutorial guide, add messages, show first.
guide = CreateObject(TutorialGuide, 0, 0, plr);
var interact = GetPlayerControlAssignment(plr, CON_Interact, true, true);
guide->AddGuideMessage(Format("$MsgTutorialWipfville$", interact));
guide->ShowGuideMessage(0);
var effect = AddEffect("TutorialTalkedToLumberjack", nil, 100, 5);
effect.plr = plr;
return;
}
/*-- Intro, Tutorial Goal & Outro --*/
global func FxTrackGoalTimer(object target, proplist effect, int time)
{
if (FindObject(Find_ID(Sawmill)) && ObjectCount(Find_ID(Flagpole)) >= 3)
{
AddEffect("GoalOutro", target, 100, 5);
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxGoalOutroStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
// Show guide message congratulating.
guide->AddGuideMessage("$MsgTutorialCompleted$");
guide->ShowGuideMessage(13);
return FX_OK;
}
global func FxGoalOutroTimer(object target, proplist effect, int time)
{
if (time >= 54)
{
var goal = FindObject(Find_ID(Goal_Tutorial));
goal->Fulfill();
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxGoalOutroStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
}
/*-- Guide Messages --*/
public func OnHasTalkedToLumberjack()
{
RemoveEffect("TutorialTalkedToLumberjack");
RemoveEffect("TutorialTalkedToLumberjack2");
return;
}
global func FxTutorialTalkedToLumberjackTimer()
{
return FX_OK;
}
global func FxTutorialTalkedToLumberjackStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
guide->AddGuideMessage("$MsgTutorialFindRock$");
guide->ShowGuideMessage(1);
var new_effect = AddEffect("TutorialFoundLorry", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_OK;
}
global func FxTutorialFoundLorryTimer(object target, proplist effect)
{
if (FindObject(Find_OCF(OCF_CrewMember), Find_Owner(effect.plr), Find_InRect(168, 576, 104, 72)))
{
guide->AddGuideMessage("$MsgTutorialDynamiteLorry$");
guide->ShowGuideMessage(2);
var new_effect = AddEffect("TutorialObtainedDynamite", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialObtainedDynamiteTimer(object target, proplist effect)
{
var clonk = FindObject(Find_OCF(OCF_CrewMember), Find_Owner(effect.plr));
if (clonk && FindObject(Find_ID(Dynamite), Find_Container(clonk)))
{
guide->AddGuideMessage("$MsgTutorialBlastRock$");
guide->ShowGuideMessage(3);
var new_effect = AddEffect("TutorialBlastedRock", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialBlastedRockTimer(object target, proplist effect)
{
if (FindObject(Find_ID(Rock), Find_InRect(180, 592, 100, 64)))
{
guide->AddGuideMessage("$MsgTutorialPickUpRock$");
guide->ShowGuideMessage(4);
var new_effect = AddEffect("TutorialObtainedRock", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialObtainedRockTimer(object target, proplist effect)
{
var clonk = FindObject(Find_OCF(OCF_CrewMember), Find_Owner(effect.plr));
if (clonk && ObjectCount(Find_ID(Rock), Find_Container(clonk)) >= 3)
{
guide->AddGuideMessage("$MsgTutorialSawmill$");
guide->ShowGuideMessage(5);
var new_effect = AddEffect("TutorialSawmillFinished", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialSawmillFinishedTimer(object target, proplist effect)
{
if (FindObject(Find_ID(Sawmill)))
{
guide->AddGuideMessage("$MsgTutorialTalkToFireman$");
guide->ShowGuideMessage(6);
var new_effect = AddEffect("TutorialTalkedForFlagpole", nil, 100, 5);
new_effect.plr = effect.plr;
// Notify lumberjack the sawmill is done.
var dialogue_lumberjack = Dialogue->FindByName("Lumberjack");
if (dialogue_lumberjack)
dialogue_lumberjack->SetDialogueProgress(5, nil, true);
return FX_Execute_Kill;
}
return FX_OK;
}
public func OnHasTalkedToFireman()
{
var effect = GetEffect("TutorialTalkedForFlagpole");
if (effect)
effect.talked_to_fireman = true;
return;
}
public func OnHasTalkedToBuilder()
{
var effect = GetEffect("TutorialTalkedForFlagpole");
if (effect)
effect.talked_to_builder = true;
return;
}
global func FxTutorialTalkedForFlagpoleTimer(object target, proplist effect)
{
if (effect.talked_to_fireman && effect.talked_to_builder)
{
guide->AddGuideMessage("$MsgTutorialConstructFlagpole$");
guide->ShowGuideMessage(7);
var new_effect = AddEffect("TutorialPlacedFlagpole", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialPlacedFlagpoleTimer(object target, proplist effect)
{
if (FindObject(Find_ID(ConstructionSite), Find_AtRect(480, 356, 32, 20)))
{
guide->AddGuideMessage("$MsgTutorialFlagpoleMaterials$");
guide->ShowGuideMessage(8);
var new_effect = AddEffect("TutorialTalkedToLumberjack2", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialTalkedToLumberjack2Timer()
{
return FX_OK;
}
global func FxTutorialTalkedToLumberjack2Stop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
guide->AddGuideMessage("$MsgTutorialAxeChopping$");
guide->ShowGuideMessage(9);
var new_effect = AddEffect("TutorialWoodInSite", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_OK;
}
global func FxTutorialWoodInSiteTimer(object target, proplist effect)
{
var site = FindObject(Find_ID(ConstructionSite), Find_AtRect(480, 356, 32, 20));
if (site && ObjectCount(Find_ID(Wood), Find_Container(site)) >= 3)
{
guide->AddGuideMessage("$MsgTutorialOreMining$");
guide->ShowGuideMessage(10);
var new_effect = AddEffect("TutorialHasOreCoal", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialHasOreCoalTimer(object target, proplist effect)
{
var clonk = FindObject(Find_OCF(OCF_CrewMember), Find_Owner(effect.plr));
if (FindObject(Find_ID(Ore), Find_Container(clonk)) && FindObject(Find_ID(Coal), Find_Container(clonk)))
{
guide->AddGuideMessage("$MsgTutorialProduceMetal$");
guide->ShowGuideMessage(11);
var new_effect = AddEffect("TutorialMetalFinished", nil, 100, 5);
new_effect.plr = effect.plr;
return FX_Execute_Kill;
}
return FX_OK;
}
global func FxTutorialMetalFinishedTimer(object target, proplist effect)
{
if (FindObject(Find_ID(Metal)))
{
guide->AddGuideMessage("$MsgTutorialMetalToSite$");
guide->ShowGuideMessage(12);
return FX_Execute_Kill;
}
return FX_OK;
}
protected func OnGuideMessageShown(int plr, int index)
{
// Show the lumberjack.
if (index == 0)
TutArrowShowTarget(FindObject(Find_ID(Clonk), Find_Not(Find_Owner(plr)), Sort_Distance(192, 384)));
// Show the statue and the mine entrance.
if (index == 1)
{
TutArrowShowTarget(FindObject(Find_ID(ConstructionSite)));
TutArrowShowPos(428, 392, 225);
TutArrowShowPos(368, 516, 225);
}
// Show the lorry with dynamite.
if (index == 2)
TutArrowShowTarget(FindObject(Find_ID(Lorry), Sort_Distance(212, 632)));
// Show the rock to blast.
if (index == 3)
TutArrowShowPos(192, 596, 315);
// Show the closest chunks of rock.
if (index == 4)
{
var clonk = FindObject(Find_OCF(OCF_CrewMember), Find_Owner(plr));
var rock = FindObject(Find_ID(Rock), Sort_Distance(clonk->GetX(), clonk->GetY()));
TutArrowShowTarget(rock);
}
// Show the sawmill construction site.
if (index == 5)
TutArrowShowTarget(FindObject(Find_ID(ConstructionSite)));
// Show the fireman and builder.
if (index == 6)
{
TutArrowShowTarget(FindObject(Find_ID(Clonk), Find_Not(Find_Owner(plr)), Sort_Distance(304, 366)));
TutArrowShowTarget(FindObject(Find_ID(Clonk), Find_Not(Find_Owner(plr)), Sort_Distance(504, 376)));
}
// Show the chest for the hammer and the construction location.
if (index == 7)
{
TutArrowShowTarget(FindObject(Find_ID(Chest)));
TutArrowShowPos(496, 376, 135);
}
// Show the lumberjack.
if (index == 8)
TutArrowShowTarget(FindObject(Find_ID(Clonk), Find_Not(Find_Owner(plr)), Sort_Distance(192, 384)));
// Show way to the axe and show the axe and a tree.
if (index == 9)
{
TutArrowShowPos(292, 512, 315);
TutArrowShowPos(184, 320, 225);
TutArrowShowTarget(FindObject(Find_ID(Axe)));
}
// Show the ore and coal.
if (index == 10)
{
TutArrowShowPos(136, 636, 270);
TutArrowShowPos(306, 628, 90);
}
// Show the foundry.
if (index == 11)
{
TutArrowShowTarget(FindObject(Find_ID(Foundry)));
}
// Show the metal and the flagpole site.
if (index == 12)
{
TutArrowShowTarget(FindObject(Find_ID(Metal)));
TutArrowShowTarget(FindObject(Find_ID(ConstructionSite), Find_AtRect(480, 356, 32, 20)));
}
return;
}
protected func OnGuideMessageRemoved(int plr, int index)
{
TutArrowClear();
return;
}
/*-- Clonk restoring --*/
global func FxClonkRestoreTimer(object target, proplist effect, int time)
{
// Respawn clonk to new location if reached certain position.
return FX_OK;
}
// 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 FX_OK;
}

View File

@ -0,0 +1,25 @@
# Goal Description
MsgGoalName=Reconstruct Village
MsgGoalDescription=Help the villagers reconstruct their destroyed buildings.
# Dialogue options
MsgNextTutorial=&Next tutorial
MsgNextTutorialDesc=Start the next tutorial scenario.
MsgRepeatRound=&Repeat this round
MsgRepeatRoundDesc=Restart this scenario.
# Tutorial messages
MsgTutorialWipfville=This guidepost reads Wipfville, probably the reason why your wipf ran off. It seems that this little village has been under attack, maybe you can find out more by talking to that lumberjack over there. Stand in front of an NPC and press [%s] to start a conversation.
MsgTutorialFindRock=Okay, we need to find some rock to finish the construction of this sawmill over here. Let's have a look at the mines of this village, maybe we can find something there.
MsgTutorialDynamiteLorry=There is a lorry filled with dynamite. You can access the contents of many vehicles and buildings by pressing [E], which opens the interaction menu. You can interchange items between different containers by clicking them. Grab a stick of dynamite!
MsgTutorialBlastRock=Perfect, with dynamite you can blast the rock at the ceiling, rock is used as a construction material. Hang onto the rock material and select one of the dynamite sticks, press the left mouse button once to fuse it and press it another time in the direction of the rock to stick it into the wall. Then jump off and run!
MsgTutorialPickUpRock=Great, pick up three pieces of rock, so that you can finish the sawmill construction.
MsgTutorialSawmill=Go up to the sawmill construction site and put the three pieces of rock into construction site via the interaction menu (press [E] to open). If all building materials are put into a construction site the building will be constructed automatically.
MsgTutorialTalkToFireman=The villagers seem to need a little more help, talk to the fireman standing next to the burned hut and to the builder next to the mine entrance.
MsgTutorialConstructFlagpole=Get the hammer from the chest, then use it to open the construction menu. From the construction menu you can select a building you wish to construct, select the flagpole and place it at the indicated position.
MsgTutorialFlagpoleMaterials=Now that the construction site is placed we need some wood and metal. Talk to the lumberjack again to obtain some wood.
MsgTutorialAxeChopping=Find the axe in the mine and use it chop down a tree for wood, then put three pieces of wood into the construction site for the flagpole. Stand next to a tree and use the axe to start chopping, be sure to not stand exactly in front of it and keep holding down the mouse button. The fallen tree can either be pushed into the sawmill or chopped to wood manually.
MsgTutorialOreMining=Good, now only one piece of metal is needed to finish the flagpole. This can be produced at the foundry using ore and coal. Descend into the mine again and get on piece of ore by blasting the ore material and one piece of coal by digging the coal material.
MsgTutorialProduceMetal=With ore and coal you can smelt metal, which is used as construction material for many structures and items. Go to the foundry and use the interaction menu (press [E] to open) to transfer the coal and ore to the foundry. For production facilities like the foundry there is an additional section in the interaction menu, select metal production here and wait for it to finish.
MsgTutorialMetalToSite=The metal is finished, pick it up and put it into the flagpole construction site to finish the flagpole.
MsgTutorialCompleted=Well done! You have mastered the basics of construction, using rock, wood and metal. The villagers of Wipfville will be grateful. Let's proceed to the next tutorial.

View File

@ -0,0 +1,25 @@
# Goal Description
MsgGoalName=Reconstruct Village
MsgGoalDescription=Help the villagers reconstruct their destroyed buildings.
# Dialogue options
MsgNextTutorial=&Next tutorial
MsgNextTutorialDesc=Start the next tutorial scenario.
MsgRepeatRound=&Repeat this round
MsgRepeatRoundDesc=Restart this scenario.
# Tutorial messages
MsgTutorialWipfville=This guidepost reads Wipfville, probably the reason why your wipf ran off. It seems that this little village has been under attack, maybe you can find out more by talking to that lumberjack over there. Stand in front of an NPC and press [%s] to start a conversation.
MsgTutorialFindRock=Okay, we need to find some rock to finish the construction of this sawmill over here. Let's have a look at the mines of this village, maybe we can find something there.
MsgTutorialDynamiteLorry=There is a lorry filled with dynamite. You can access the contents of many vehicles and buildings by pressing [E], which opens the interaction menu. You can interchange items between different containers by clicking them. Grab a stick of dynamite!
MsgTutorialBlastRock=Perfect, with dynamite you can blast the rock at the ceiling, rock is used as a construction material. Hang onto the rock material and select one of the dynamite sticks, press the left mouse button once to fuse it and press it another time in the direction of the rock to stick it into the wall. Then jump off and run!
MsgTutorialPickUpRock=Great, pick up three pieces of rock, so that you can finish the sawmill construction.
MsgTutorialSawmill=Go up to the sawmill construction site and put the three pieces of rock into construction site via the interaction menu (press [E] to open). If all building materials are put into a construction site the building will be constructed automatically.
MsgTutorialTalkToFireman=The villagers seem to need a little more help, talk to the fireman standing next to the burned hut and to the builder next to the mine entrance.
MsgTutorialConstructFlagpole=Get the hammer from the chest, then use it to open the construction menu. From the construction menu you can select a building you wish to construct, select the flagpole and place it at the indicated position.
MsgTutorialFlagpoleMaterials=Now that the construction site is placed we need some wood and metal. Talk to the lumberjack again to obtain some wood.
MsgTutorialAxeChopping=Find the axe in the mine and use it chop down a tree for wood, then put three pieces of wood into the construction site for the flagpole. Stand next to a tree and use the axe to start chopping, be sure to not stand exactly in front of it and keep holding down the mouse button. The fallen tree can either be pushed into the sawmill or chopped to wood manually.
MsgTutorialOreMining=Good, now only one piece of metal is needed to finish the flagpole. This can be produced at the foundry using ore and coal. Descend into the mine again and get on piece of ore by blasting the ore material and one piece of coal by digging the coal material.
MsgTutorialProduceMetal=With ore and coal you can smelt metal, which is used as construction material for many structures and items. Go to the foundry and use the interaction menu (press [E] to open) to transfer the coal and ore to the foundry. For production facilities like the foundry there is an additional section in the interaction menu, select metal production here and wait for it to finish.
MsgTutorialMetalToSite=The metal is finished, pick it up and put it into the flagpole construction site to finish the flagpole.
MsgTutorialCompleted=Well done! You have mastered the basics of construction, using rock, wood and metal. The villagers of Wipfville will be grateful. Let's proceed to the next tutorial.

View File

@ -0,0 +1,46 @@
// A builder which tells you how to use the sawmill.
#appendto Dialogue
public func Dlg_Builder_Init(object clonk)
{
return true;
}
public func Dlg_Builder_1(object clonk)
{
MessageBox(Format("$DlgBuilderHello$", dlg_target->GetName()), clonk, dlg_target);
return true;
}
public func Dlg_Builder_2(object clonk)
{
MessageBox(Format("$DlgBuilderReply$", clonk->GetName()), clonk, clonk);
return true;
}
public func Dlg_Builder_3(object clonk)
{
MessageBox("$DlgBuilderFlagpole$", clonk, dlg_target);
return true;
}
public func Dlg_Builder_4(object clonk)
{
MessageBox("$DlgBuilderWhyHere$", clonk, clonk);
return true;
}
public func Dlg_Builder_5(object clonk)
{
MessageBox("$DlgBuilderConnect$", clonk, dlg_target);
StopDialogue();
SetDialogueProgress(1);
return true;
}
public func Dlg_Builder_Closed(object clonk)
{
GameCall("OnHasTalkedToBuilder", clonk);
return true;
}

View File

@ -0,0 +1,28 @@
// An npc next to the farming area.
#appendto Dialogue
public func Dlg_Farmer_Init(object clonk)
{
return true;
}
public func Dlg_Farmer_1(object clonk)
{
MessageBox("$DlgFarmerHello$", clonk, clonk);
return true;
}
public func Dlg_Farmer_2(object clonk)
{
MessageBox("$DlgFarmerYesSafe$", clonk, dlg_target);
return true;
}
public func Dlg_Farmer_3(object clonk)
{
MessageBox("$DlgFarmerRebuild$", clonk, clonk);
StopDialogue();
SetDialogueProgress(1);
return true;
}

View File

@ -0,0 +1,67 @@
// A fireman which puts out the fires around the village.
#appendto Dialogue
public func Dlg_Fireman_Init(object clonk)
{
clonk->Message("<c ff0000>Fire!</c> Out of my way!");
AddEffect("IntFireman", clonk, 100, 5, this);
return true;
}
public func Dlg_Fireman_1(object clonk)
{
MessageBox("$DlgFiremanLastFire$", clonk, dlg_target);
return true;
}
public func Dlg_Fireman_2(object clonk)
{
MessageBox("$DlgFiremanGoodJob$", clonk, clonk);
return true;
}
public func Dlg_Fireman_3(object clonk)
{
MessageBox("$DlgFiremanEvilGuys$", clonk, dlg_target);
return true;
}
public func Dlg_Fireman_4(object clonk)
{
MessageBox("$DlgFiremanFurryFriend$", clonk, clonk);
return true;
}
public func Dlg_Fireman_5(object clonk)
{
MessageBox("$DlgFiremanFlagpole$", clonk, dlg_target);
StopDialogue();
SetDialogueProgress(5);
return true;
}
public func Dlg_Fireman_Closed(object clonk)
{
GameCall("OnHasTalkedToFireman", clonk);
return true;
}
public func FxIntFiremanStart(object target, proplist effect)
{
return FX_OK;
}
public func FxIntFiremanTimer(object target, proplist effect, int time)
{
if (time == 20)
target->SetCommand("MoveTo", nil, 320, 348);
if (!target->GetCommand() && time > 50)
{
target->SetDir(DIR_Right);
target->Contents(0)->ControlUse(target, 10, -2);
return FX_Execute_Kill;
}
return FX_OK;
}

View File

@ -0,0 +1,66 @@
// A lumberjack which tells you how to use the sawmill.
#appendto Dialogue
public func Dlg_Lumberjack_Init(object clonk)
{
return true;
}
public func Dlg_Lumberjack_1(object clonk)
{
MessageBox(Format("$DlgLumberjackHello$", dlg_target->GetName()), clonk, dlg_target);
return true;
}
public func Dlg_Lumberjack_2(object clonk)
{
MessageBox(Format("$DlgLumberjackReply$", clonk->GetName()), clonk, clonk);
return true;
}
public func Dlg_Lumberjack_3(object clonk)
{
MessageBox("$DlgLumberjackSawmill$", clonk, dlg_target);
return true;
}
public func Dlg_Lumberjack_4(object clonk)
{
MessageBox("$DlgLumberjackRock$", clonk, clonk);
StopDialogue();
SetDialogueProgress(1);
return true;
}
public func Dlg_Lumberjack_5(object clonk)
{
MessageBox("$DlgLumberjackWellDone$", clonk, dlg_target);
return true;
}
public func Dlg_Lumberjack_6(object clonk)
{
MessageBox("$DlgLumberjackFavor$", clonk, clonk);
return true;
}
public func Dlg_Lumberjack_7(object clonk)
{
MessageBox("$DlgLumberjackMines$", clonk, dlg_target);
return true;
}
public func Dlg_Lumberjack_8(object clonk)
{
MessageBox("$DlgLumberjackLook$", clonk, clonk);
StopDialogue();
SetDialogueProgress(5);
return true;
}
public func Dlg_Lumberjack_Closed(object clonk)
{
GameCall("OnHasTalkedToLumberjack", clonk);
return true;
}

View File

@ -0,0 +1,28 @@
# Dialogue: Lumberjack
DlgLumberjackHello=Hello I am %s, the lumberjack of this small village.
DlgLumberjackReply=My name is %s, you seem sad.
DlgLumberjackSawmill=Yes, indeed. My sawmill got destroyed and I can't find any rock to rebuild it. Can you help me?
DlgLumberjackRock=Yes, I'll find you some rock.
DlgLumberjackWellDone=Thanks a lot, for constructing the sawmill. Can I do anything for you?
DlgLumberjackFavor=Actually you can, I need wood, do you happen to have an axe?
DlgLumberjackMines=No, I don't, but I have dropped my axe in the mines when I was hiding there during the attack.
DlgLumberjackLook=Ok, I'll have a look.
# Dialogue: Fireman
DlgFiremanLastFire=Phew that was the last fire!
DlgFiremanGoodJob=Good job, have you been under attack?
DlgFiremanEvilGuys=Yes our village has been, the evil guys took some of our wipfs.
DlgFiremanFurryFriend=That is bad, I hope they won't take my little furry friend! How can I help?
DlgFiremanFlagpole=We need to construct a new flag pole, to reconnect the power supply in our village.
# Dialogue: Builder
DlgBuilderHello=Hi there, My name is %s and I am a builder.
DlgBuilderReply=Then you have lots of work. Do you need a hand?
DlgBuilderFlagpole=Yes, can you construct a flagpole over here?
DlgBuilderWhyHere=Of course, but why over here?
DlgBuilderConnect=Because then the flagpole will provide a power connection between the wind generator and the elevator.
# Dialogue: Farmer
DlgFarmerHello=Hi, is my wipf safe here?
DlgFarmerYesSafe=Yes it is, I will look after it. Are you helping us rebuild?
DlgFarmerRebuild=I am!

View File

@ -0,0 +1,28 @@
# Dialogue: Lumberjack
DlgLumberjackHello=Hello I am %s, the lumberjack of this small village.
DlgLumberjackReply=My name is %s, you seem sad.
DlgLumberjackSawmill=Yes, indeed. My sawmill got destroyed and I can't find any rock to rebuild it. Can you help me?
DlgLumberjackRock=Yes, I'll find you some rock.
DlgLumberjackWellDone=Thanks a lot, for constructing the sawmill. Can I do anything for you?
DlgLumberjackFavor=Actually you can, I need wood, do you happen to have an axe?
DlgLumberjackMines=No, I don't, but I have dropped my axe in the mines when I was hiding there during the attack.
DlgLumberjackLook=Ok, I'll have a look.
# Dialogue: Fireman
DlgFiremanLastFire=Phew that was the last fire!
DlgFiremanGoodJob=Good job, have you been under attack?
DlgFiremanEvilGuys=Yes our village has been, the evil guys took some of our wipfs.
DlgFiremanFurryFriend=That is bad, I hope they won't take my little furry friend! How can I help?
DlgFiremanFlagpole=We need to construct a new flag pole, to reconnect the power supply in our village.
# Dialogue: Builder
DlgBuilderHello=Hi there, My name is %s and I am a builder.
DlgBuilderReply=Then you have lots of work. Do you need a hand?
DlgBuilderFlagpole=Yes, can you construct a flagpole over here?
DlgBuilderWhyHere=Of course, but why over here?
DlgBuilderConnect=Because then the flagpole will provide a power connection between the wind generator and the elevator.
# Dialogue: Farmer
DlgFarmerHello=Hi, is my wipf safe here?
DlgFarmerYesSafe=Yes it is, I will look after it. Are you helping us rebuild?
DlgFarmerRebuild=I am!

View File

@ -0,0 +1,101 @@
// Artificial intelligence for the wipf.
#appendto Wipf
public func EnableTutorialControl(bool friend)
{
RemoveEffect("IntActivity", this);
var effect = AddEffect("TutorialWipf", this, 1, 5, this);
if (!friend)
effect.sequence = "StayAtGrainField";
return;
}
public func DisableTutorialControl()
{
RemoveEffect("TutorialWipf", this);
AddEffect("IntActivity", this, 1, 10, this);
return;
}
protected func FxTutorialWipfStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
effect.sequence = "WaitABit";
this.Collectible = false;
return FX_OK;
}
protected func FxTutorialWipfTimer(object target, proplist effect, int time)
{
// Wait a bit to start walking.
if (effect.sequence == "WaitABit" && time >= 20)
{
SetAction("Walk");
SetCommand("MoveTo", nil, 700, 388);
effect.sequence = "WalkToGrainField";
}
// Walk to statue and wait there.
if (effect.sequence == "WalkToGrainField" && Inside(GetX(), 680, 720) && Inside(GetY(), 340, 420))
{
effect.sequence = "StayAtGrainField";
}
if (effect.sequence == "StayAtGrainField")
{
// Don't do anything if contained.
if (Contained())
return FX_OK;
if (IsWalking())
{
if (GetDir() == DIR_Left && GetX() < 648)
{
SetComDir(COMD_Right);
return FX_OK;
}
if (GetDir() == DIR_Right && GetX() > 840)
{
SetComDir(COMD_Left);
return FX_OK;
}
if (!Random(3))
{
SetComDir([COMD_Left, COMD_Right][Random(2)]);
return FX_OK;
}
// Stop walking from time to time.
if (!Random(3) && GetComDir() != COMD_Stop)
{
SetComDir(COMD_Stop);
return FX_OK;
}
// Start standing when com dir is stop and speed is zero.
if (GetComDir() == COMD_Stop && GetYDir() == 0)
{
SetAction("Stand");
return FX_OK;
}
return FX_OK;
}
if (IsStanding())
{
if (!Random(10))
{
SetAction("Walk");
SetComDir([COMD_Left, COMD_Right][Random(2)]);
return FX_OK;
}
return FX_OK;
}
}
return FX_OK;
}
protected func FxTutorialWipfStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
this.Collectible = true;
return FX_OK;
}

View File

@ -0,0 +1,2 @@
DE:Carry & Construct
US:Carry & Construct