forked from Mirrors/openclonk
186 lines
5.1 KiB
C
186 lines
5.1 KiB
C
/** Tutorial Guide
|
|
* The tutorial guide can be clicked by the player, it supplies the player with information and hints.
|
|
* The following callbacks are made to the scenario script:
|
|
* - \c OnGuideMessageShown(int plr, int index) when a message is shown
|
|
* - \c OnGuideMessageRemoved(int plr, int index) when a message is removed, all events
|
|
* @author Maikel
|
|
*/
|
|
|
|
|
|
local messages; // A container to hold all messages.
|
|
local index; // Progress in reading messages.
|
|
|
|
protected func Initialize()
|
|
{
|
|
// parallaxity
|
|
this["Parallaxity"] = [0, 0];
|
|
// visibility
|
|
this["Visibility"] = VIS_Owner;
|
|
messages = [];
|
|
index = 0;
|
|
return;
|
|
}
|
|
|
|
/* Creates the tutorial guide in the upper part of the HUD, returns the guide as a pointer.
|
|
* @param plr The player for which the guide should be created.
|
|
* @return the guide object.
|
|
*/
|
|
global func CreateTutorialGuide(int plr)
|
|
{
|
|
var guide = CreateObject(TutorialGuide, 0, 0 , plr);
|
|
guide->SetPosition(- 128 - 32 - TutorialGuide->GetDefWidth() / 2, 8 + TutorialGuide->GetDefHeight() / 2);
|
|
return guide;
|
|
}
|
|
|
|
// Get-Setters for the message index.
|
|
public func GetGuideIndex() { return index; }
|
|
public func SetGuideIndex(int to_index)
|
|
{
|
|
index = BoundBy(to_index, 0, GetLength(messages));
|
|
return;
|
|
}
|
|
|
|
/* Adds a message to the guide. The internal index is set to this message meaning that this message will
|
|
* be shown if the player clicks the guide.
|
|
* @param msg Message that should be added to the message stack.
|
|
*/
|
|
public func AddGuideMessage(string msg)
|
|
{
|
|
// Automatically set index to current.
|
|
index = GetLength(messages);
|
|
// Add message to list.
|
|
messages[index] = msg;
|
|
// Make visible that there is a new message.
|
|
AddEffect("NotifyPlayer", this, 100, 0, this);
|
|
return;
|
|
}
|
|
|
|
/* Shows a guide message to the player, also resets the internal index to that point.
|
|
* @param show_index The message corresponding to this index will be shown.
|
|
*/
|
|
public func ShowGuideMessage(int show_index)
|
|
{
|
|
index = Max(0, show_index);
|
|
if (!messages[index])
|
|
return;
|
|
if (GetEffect("MessageShown", this))
|
|
RemoveEffect("MessageShown", this);
|
|
if (GetEffect("NotifyPlayer", this))
|
|
RemoveEffect("NotifyPlayer", this);
|
|
GuideMessage(index);
|
|
if (GetLength(messages) > index+1)
|
|
index++;
|
|
return;
|
|
}
|
|
|
|
// Removes the current guide message.
|
|
public func ClearGuideMessage()
|
|
{
|
|
if (GetEffect("MessageShown", this))
|
|
RemoveEffect("MessageShown", this);
|
|
CustomMessage("", nil, GetOwner(), nil, nil, nil, nil, nil, MSG_HCenter);
|
|
return;
|
|
}
|
|
|
|
// Callback: the player has clicked on the guide.
|
|
public func MouseSelection(int plr)
|
|
{
|
|
if (plr != GetOwner())
|
|
return;
|
|
if (GetEffect("NotifyPlayer", this))
|
|
RemoveEffect("NotifyPlayer", this);
|
|
// Clear guide message if the latest is already shown.
|
|
var effect = GetEffect("MessageShown", this, nil, 0);
|
|
if (effect)
|
|
{
|
|
if (effect.show_index == index)
|
|
return ClearGuideMessage();
|
|
else
|
|
RemoveEffect("MessageShown", this);
|
|
}
|
|
// Show guide message if there is a new one, and increase index if possible.
|
|
if (!messages[index])
|
|
return;
|
|
GuideMessage(index);
|
|
if (GetLength(messages) > index+1)
|
|
index++;
|
|
return;
|
|
}
|
|
|
|
// Shows a message at the right place in message box.
|
|
private func GuideMessage(int show_index)
|
|
{
|
|
if (GetOwner() == NO_OWNER)
|
|
return false;
|
|
var message = messages[show_index];
|
|
if (!message)
|
|
return false;
|
|
// Message as regular one, don't stop the player.
|
|
CustomMessage(message, nil, GetOwner(), 0, 16 + TutorialGuide->GetDefHeight(), 0xffffff, GUI_MenuDeco, this, MSG_HCenter);
|
|
var effect = AddEffect("MessageShown", this, 100, 2 * GetLength(message), this);
|
|
effect.show_index = show_index;
|
|
// Messages with @ in front are shown infinetely long.
|
|
if(GetChar(message, 0) == GetChar("@", 0))
|
|
effect.var1 = true;
|
|
return true;
|
|
}
|
|
|
|
// Effect exists as long as the message is shown.
|
|
// Message index is stored in EffectVar 0.
|
|
// For messages with @ in front, EffectVar 1 is true.
|
|
protected func FxMessageShownStart(object target, effect, int temporary)
|
|
{
|
|
if (temporary == 0)
|
|
GameCall("OnGuideMessageShown", target->GetOwner(), index);
|
|
return 1;
|
|
}
|
|
|
|
protected func FxMessageShownTimer(object target, effect, int time)
|
|
{
|
|
// Delete effect if time has passed, i.e. message has disappeared.
|
|
// But only if it is not a message of infinite length, with @ in front.
|
|
if (time && !effect.var1)
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
protected func FxMessageShownStop(object target, effect, int reason, bool temporary)
|
|
{
|
|
if (!temporary)
|
|
GameCall("OnGuideMessageRemoved", target->GetOwner(), index);
|
|
return 1;
|
|
}
|
|
|
|
// Effect to display the player notification for some time.
|
|
protected func FxNotifyPlayerStart(object target, effect, int temporary)
|
|
{
|
|
// Display notifier.
|
|
SetGraphics("SpeakBubble", GetID(), 1, GFXOV_MODE_Base);
|
|
SetObjDrawTransform(500, 0, -24000, 0, 500, -2000, 1);
|
|
return 1;
|
|
}
|
|
|
|
protected func FxNotifyPlayerTimer(object target, effect, int time)
|
|
{
|
|
// Delete effect if time has passed.
|
|
if (time)
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
protected func FxNotifyPlayerStop(object target, effect, int reason, bool temporary)
|
|
{
|
|
// Remove notifier.
|
|
SetGraphics(nil, nil, 1);
|
|
return 1;
|
|
}
|
|
|
|
protected func FxNotifyPlayerEffect(string new_name)
|
|
{
|
|
if (new_name == "NotifyPlayer")
|
|
return -1;
|
|
}
|
|
|
|
local Name = "$Name$";
|
|
|