Add MtBrame.ocs, a cooperative scenario for BeyondTheRocks

floating-point
Armin Burgmeier 2012-04-08 19:56:14 +02:00
parent db4ad404b1
commit a0b13ad238
23 changed files with 5057 additions and 0 deletions

View File

@ -0,0 +1,9 @@
[DefCore]
id=Dialogue
Version=5,2,0,1
Category=C4D_StaticBack
Width=8
Height=20
Offset=-4,-10

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,215 @@
/**
Dialogue
Attach to a non player charachter to provide a message interface.
*/
local dlg_target;
local dlg_name;
local dlg_info;
local dlg_progress;
local dlg_status;
static const DLG_Status_Active = 0;
static const DLG_Status_Stop = 1;
static const DLG_Status_Remove = 2;
/*-- Dialogue creation --*/
// Sets a new dialogue for a npc.
global func SetDialogue(string name)
{
if (!this)
return;
var dialogue = CreateObject(Dialogue);
dialogue->InitDialogue(name, this);
dialogue->SetObjectLayer(nil);
return dialogue;
}
// Removes the existing dialogue of an object.
global func RemoveDialogue()
{
if (!this)
return;
var dialogue = FindObject(Find_ID(Dialogue), Find_ActionTarget(this));
if (dialogue)
dialogue->RemoveObject();
return;
}
/*-- Dialogue properties --*/
protected func Initialize()
{
// Dialogue progress to one.
dlg_progress = 1;
dlg_status = DLG_Status_Active;
return;
}
public func InitDialogue(string name, object target)
{
dlg_target = target;
dlg_name = name;
// Attach dialogue object to target.
SetAction("Dialogue", target);
// Update dialogue to target.
UpdateDialogue();
return;
}
private func UpdateDialogue()
{
// Adapt size to target and its direction.
var wdt = dlg_target->GetID()->GetDefWidth();
var hgt = dlg_target->GetID()->GetDefHeight();
var dir = dlg_target->GetDir();
SetShape(-wdt/2 + 2*(dir-1)*wdt, -hgt/2, 3*wdt, hgt);
// Transfer target name.
//SetName(Format("$MsgSpeak$", dlg_target->GetName()));
return;
}
public func SetDialogueInfo()
{
return;
}
public func SetDialogueProgress(int progress)
{
dlg_progress = Max(1, progress);
return;
}
public func SetDialogueStatus(int status)
{
dlg_status = status;
return;
}
/*-- Interaction --*/
// Players can talk to NPC via the interaction bar.
public func IsInteractable() { return true; }
// Adapt appearance in the interaction bar.
public func GetInteractionMetaInfo(object clonk)
{
if (InDialogue(clonk))
return { Description = Format("$MsgSpeak$", dlg_target->GetName()) , IconName = nil, IconID = Clonk, Selected = true };
return { Description = Format("$MsgSpeak$", dlg_target->GetName()) , IconName = nil, IconID = Clonk, Selected = false };
}
// Called on player interaction.
public func Interact(object clonk)
{
// Currently in a dialogue: abort that dialogue.
if (InDialogue(clonk))
clonk->CloseMenu();
// No conversation context: abort.
if (!dlg_name)
return true;
// Stop dialogue?
if (dlg_status == DLG_Status_Stop)
{
clonk->CloseMenu();
dlg_status = DLG_Status_Active;
return true;
}
// Remove dialogue?
if (dlg_status == DLG_Status_Remove)
{
clonk->CloseMenu();
RemoveObject();
return true;
}
// Start conversation context.
// Update dialogue progress first.
var progress = dlg_progress;
dlg_progress++;
// Then call relevant functions.
Call(Format("Dlg_%s_%d", dlg_name, progress), clonk);
return true;
}
private func InDialogue(object clonk)
{
return clonk->GetMenu() == Dialogue;
}
public func MessageBoxAll(string message, object talker)
{
for(var i = 0; i < GetPlayerCount(); ++i)
MessageBox(message, GetCursor(GetPlayerByIndex(i)), talker);
}
private func MessageBox(string message, object clonk, object talker)
{
// Use current NPC as talker if unspecified.
if (!talker)
talker = dlg_target;
// Use a menu for this dialogue.
clonk->CreateMenu(Dialogue, this, C4MN_Extra_None, nil, nil, C4MN_Style_Dialog, false, Dialogue);
// Add NPC portrait.
//var portrait = Format("%i", talker->GetID()); //, Dialogue, talker->GetColor(), "1");
clonk->AddMenuItem("", "", Dialogue, nil, nil, nil, C4MN_Add_ImgObject, talker); //TextSpec);
// Add NPC message.
var msg = Format("<c %x>%s:</c> %s", talker->GetColor(), talker->GetName(), message);
clonk->AddMenuItem(msg, "", nil, nil, nil, nil, C4MN_Add_ForceNoDesc);
// Add answers.
//for (var i = 0; i < GetLength(message.Answers); i++)
//{
// var ans = message.Answers[i][0];
// var call_back = message.Answers[i][1];
// target->AddMenuItem(ans, call_back, nil, nil, target, nil, C4MN_Add_ForceNoDesc);
//}
// Set menu decoration.
clonk->SetMenuDecoration(GUI_MenuDeco);
// Set text progress to NPC name.
var name = dlg_target->GetName();
var n_length;
while (GetChar(name, n_length))
n_length++;
clonk->SetMenuTextProgress(n_length + 1);
return;
}
local ActMap = {
Dialogue = {
Prototype = Action,
Name = "Dialogue",
Procedure = DFA_ATTACH,
Delay = 0,
NextAction = "Dialogue",
}
};
local Name = "$Name$";

View File

@ -0,0 +1,2 @@
Name=Dialogue
MsgSpeak=%s ansprechen

View File

@ -0,0 +1,2 @@
Name=Dialogue
MsgSpeak=Speak to %s

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
[DefCore]
id=Goal_GetBack
Version=5,2,0,1
Category=C4D_StaticBack|C4D_Goal
Picture=0,0,128,128

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,50 @@
/*--
Get back goal
Author: ck
All players have to get back to the hut
--*/
#include Library_Goal
protected func Initialize()
{
return inherited(...);
}
public func IsFulfilled()
{
var cabin = FindObject(Find_ID(WoodenCabin));
if (!cabin)
return false;
if (!GetPlayerCount() || GetEffect("IntIntro"))
return false;
for(var i = 0; i < GetPlayerCount(); ++i)
{
var plr = GetPlayerByIndex(i), obj;
for(var j = 0; obj = GetCrew(plr, j); ++j)
if(ObjectDistance(obj, cabin) > 80)
return false;
}
return true;
}
public func Activate(int byplr)
{
if (IsFulfilled())
MessageWindow("$MsgGoalFulfilled$", byplr);
else
MessageWindow("$MsgGoalUnFulfilled$", byplr);
return;
}
public func GetShortDescription(int plr)
{
return "{{WoodenCabin}}"; // TODO
}
/*-- Proplist --*/
local Name = "$Name$";

View File

@ -0,0 +1,3 @@
Name=Finde den Weg zurück
MsgGoalFulfilled=Ihr habt den Weg zurück gefunden.
MsgGoalUnFulfilled=Ihr seid noch nicht zuhause.

View File

@ -0,0 +1,3 @@
Name=Find your way back home
MsgGoalFulfilled=You have made your way back home.
MsgGoalUnFulfilled=You are not at home yet.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,38 @@
[Head]
Icon=23
Title=MtBrame
Version=5,2,90,21
Difficulty=50
MaxPlayer=3
NoInitialize=true
[Game]
Rules=Rule_TeamAccount=1
[Player1]
Crew=Clonk=1
Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1
[Player2]
Crew=Clonk=1
Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1
[Player3]
Crew=Clonk=1
Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1
[Player4]
Crew=Clonk=1
Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1
[Landscape]
Sky=Clouds2
MapWidth=200,0,64,10000
MapHeight=175,0,40,10000
NoScan=true
NewStyleLandscape=2
[Weather]
Climate=30,10,0,100
YearSpeed=0,0,0,100
Wind=0,100,-100,100

View File

@ -0,0 +1,49 @@
/**
Mt. Brame
Find a way back to your hut, defeating the dangers of Mt. Brame
@authors ck
*/
static g_is_initialized;
func DoInit(int first_player)
{
// Set time of day to morning and create some clouds and celestials.
Cloud->Place(20);
CreateObject(Environment_Celestial);
var time = CreateObject(Environment_Time);
time->SetTime(400);
time->SetCycleSpeed(4);
// Workshop owner
var workshop = FindObject(Find_ID(ToolsWorkshop));
if (workshop) workshop->SetOwner(first_player);
// Goal
CreateObject(Goal_GetBack);
return true;
}
func InitializePlayer(int plr)
{
var crew;
// Scenario init
if (!g_is_initialized) g_is_initialized = DoInit(plr);
// Start intro if not yet started
IntroStart();
// Add player to intro if recently started
if(!IntroAddPlayer(plr))
{
// Too late for entry? Just start in the valley
var index = 0;
for(var index = 0; crew = GetCrew(plr, index); ++index)
{
var x = 260*8/10 + Random(50);
var y = 1350*8/10;
crew->SetPosition(x , y);
}
}
}

View File

@ -0,0 +1,187 @@
static g_intro_initialized;
global func IntroStart()
{
if(!g_intro_initialized && !GetEffect("IntIntro"))
{
AddEffect("IntIntro", nil, 1, 2, nil, nil);
g_intro_initialized = true;
}
}
global func IntroAddPlayer(int plr)
{
var effect = GetEffect("IntIntro");
if(!effect) return false;
if(effect.Time > 30) return false;
var crew;
for(var index = 0; crew = GetCrew(plr, index); ++index)
{
var skin = crew->GetCrewExtraData("Skin");
if (skin == nil) skin = GetPlrClonkSkin(plr);
var container = effect.Cabin->CreateContents(Clonk);
container->SetOwner(plr);
if(skin != nil) container->SetSkin(skin);
container->SetName(crew->GetName());
container->SetAction("Walk");
crew->Enter(container);
SetPlrView(plr, crew);
SetPlayerViewLock(plr, true);
SetPlayerZoomByViewRange(plr, 320, 240);
container->SetCommand("None", container);
crew->SetCommand("None", crew);
effect.Players[GetLength(effect.Players)] = crew;
}
return true;
}
global func IntroCreateBoompack(int x, int y, int fuel)
{
var boompack = CreateObject(Boompack, x, y, NO_OWNER);
boompack->SetFuel(fuel);
boompack->SetDirectionDeviation(8); // make sure direction of boompack is roughly kept
boompack->SetControllable(false);
return boompack;
}
global func FxIntIntroStart(object target, proplist effect)
{
effect.Cabin = FindObject(Find_ID(WoodenCabin));
if(!effect.Cabin) return -1;
effect.Sister = CreateObject(Clonk, 174, 532, NO_OWNER);
effect.Sister->MakeInvincible();
effect.Sister->MakeNonFlammable();
effect.Sister->SetSkin(1);
effect.Sister->SetName("$NameSister$");
effect.Sister->SetColor(RGB(213, 68, 172));
effect.Sister->SetObjectLayer(effect.Sister);
effect.Sister->SetDir(DIR_Right);
effect.Dialog = effect.Sister->SetDialogue("Sister");
effect.Rock = effect.Sister->CreateContents(Rock);
effect.Rock->SetObjectLayer(0);
effect.Players = [];
}
global func FxIntIntroTimer(object target, proplist effect, int time)
{
if(effect.Time == 40)
{
effect.Sister->SetCommand("MoveTo", effect.Sister, effect.Cabin->GetX() + 65 - effect.Sister->GetX(), effect.Cabin->GetY() + 10 - effect.Sister->GetY());
}
if(effect.Time == 110)
effect.Dialog->MessageBoxAll("$MsgIntro1$", effect.Sister);
if(effect.Time == 150)
{
for(var crew in effect.Players)
{
crew = crew->Contained();
crew->SetCommand("Exit", crew);
crew->AppendCommand("MoveTo", crew, effect.Cabin->GetX() + RandomX(10,40) - crew->GetX(), effect.Cabin->GetY() - crew->GetY());
}
}
if(effect.Time == 200)
effect.Dialog->MessageBoxAll("$MsgIntro2$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0));
if(effect.Time == 270)
{
effect.Dialog->MessageBoxAll("$MsgIntro3$", effect.Sister);
}
if(effect.Time == 350)
{
effect.Sister->SetCommand("MoveTo", effect.Sister, 214 - effect.Sister->GetX(), 540 - effect.Sister->GetY());
}
if(effect.Time == 370)
{
for(var crew in effect.Players)
{
crew = crew->Contained();
crew->SetCommand("MoveTo", crew, 245 - crew->GetX(), 555 - crew->GetY());
}
}
if(effect.Time == 500)
{
effect.Sister->SetCommand("MoveTo", effect.Sister, 214 - effect.Sister->GetX(), 540 - effect.Sister->GetY());
for(var crew in effect.Players)
crew->Contained()->SetDir(DIR_Left);
effect.Dialog->MessageBoxAll("$MsgIntro4$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0));
}
if(effect.Time == 520)
effect.Sister->SetDir(DIR_Right);
if(effect.Time == 550)
{
effect.Sister->ObjectCommand("Throw", effect.Rock, 500, 100);
for(var i = 0; i < GetPlayerCount(); ++i)
SetPlrView(GetPlayerByIndex(i), effect.Sister);
}
if(effect.Time == 570)
{
effect.Dialog->MessageBoxAll("$MsgIntro5$", effect.Sister);
}
if(effect.Time == 620)
{
effect.Dialog->MessageBoxAll("$MsgIntro6$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0));
}
if(effect.Time == 700)
{
effect.Dialog->MessageBoxAll("$MsgIntro7$", effect.Sister);
}
if(effect.Time == 800)
{
effect.Dialog->MessageBoxAll("$MsgIntro8$", effect.Sister);
}
if(effect.Time == 860)
{
effect.Sister->SetCommand("Enter", effect.Cabin);
}
if(effect.Time == 920)
{
for(var i = 0; i < GetPlayerCount(); ++i)
GetCursor(GetPlayerByIndex(i))->CloseMenu();
}
if(effect.Time == 950)
{
for(var crew in effect.Players)
{
SetPlrView(crew->GetOwner(), crew);
SetPlayerViewLock(crew->GetOwner(), true);
var container = crew->Contained();
crew->Exit(0, 10);
container->RemoveObject();
}
for(var i = 0; i < GetPlayerCount(); ++i)
GetCursor(GetPlayerByIndex(i))->CloseMenu();
}
if(effect.Time >= 1000)
{
// just to be sure...
effect.Sister->Enter(effect.Cabin);
return -1;
}
}

View File

@ -0,0 +1,3 @@
#appendto ToolsWorkshop
private func PowerNeed() { return 0; }

View File

@ -0,0 +1,12 @@
# Intro
NameSister=Ruth
# Intro
MsgIntro1=Hey ihr Schlafmützen, schaut mal was ich gefunden habe!
MsgIntro2=...was? Wo denn?
MsgIntro3=Dort unten, am Hang!
MsgIntro4=Und was soll hier sein..?
MsgIntro5=Hihi...!
MsgIntro6=Waaaaaah!
MsgIntro7=Hm, war vielleicht doch ein bisschen tief?
MsgIntro8=Egal, die werden schon rausfinden...

View File

@ -0,0 +1,11 @@
NameSister=Ruth
# Intro
MsgIntro1=Hey sleepyheads! Check out what I have found!
MsgIntro2=...what? And where?
MsgIntro3=Down there, at the hillside!
MsgIntro4=And what's supposed to be here..?
MsgIntro5=Hihi...!
MsgIntro6=Waaaaaah!
MsgIntro7=Hm, maybe it was a bit deep in the end?
MsgIntro8=Whatever, they will find their way...

View File

@ -0,0 +1,5 @@
[Teams]
Active=false
Custom=false
AllowHostilityChange=true
AutoGenerateTeams=true

View File

@ -0,0 +1,2 @@
DE:Mount Brame
US:Mount Brame