forked from Mirrors/openclonk
216 lines
4.4 KiB
C
216 lines
4.4 KiB
C
/**
|
|
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$";
|