forked from Mirrors/openclonk
add keypad to decoration objects
This can control lots of things and triggers on entering the correct code.console-destruction
parent
8a09fcc1b1
commit
32f5b1cb25
|
@ -0,0 +1,8 @@
|
|||
[DefCore]
|
||||
id=Keypad
|
||||
Version=8,0
|
||||
Category=C4D_StaticBack
|
||||
Picture=0,0,112,144
|
||||
Width=14
|
||||
Height=18
|
||||
Offset=-7,-9
|
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,366 @@
|
|||
/**
|
||||
Keypad
|
||||
allows to enter digit codes to trigger an event.
|
||||
|
||||
@author Maikel
|
||||
*/
|
||||
|
||||
// Background colors for hovering and bars and description.
|
||||
static const KEYPADMENU_BackgroundColor = 0x77000000;
|
||||
static const KEYPADMENU_HoverColor = 0x99888888;
|
||||
static const KEYPADMENU_BarColor = 0x99888888;
|
||||
|
||||
local code, correct_code;
|
||||
local target_door;
|
||||
local correct_code_action, wrong_code_action;
|
||||
local menu, menu_id, menu_target, menu_controller;
|
||||
|
||||
|
||||
/*-- Script Interface --*/
|
||||
|
||||
public func SetKeypadCode(string to_code)
|
||||
{
|
||||
// Check if code contains any non-digits.
|
||||
var non_digits = RegexMatch(to_code, "[^0-9]+");
|
||||
if (!DeepEqual(non_digits, []))
|
||||
{
|
||||
Log("$WarningKeypadCode$", to_code);
|
||||
return;
|
||||
}
|
||||
// If code is valid, set it.
|
||||
correct_code = to_code;
|
||||
return;
|
||||
}
|
||||
|
||||
public func SetStoneDoor(object door)
|
||||
{
|
||||
target_door = door;
|
||||
return true;
|
||||
}
|
||||
|
||||
public func OpenDoor(object clonk)
|
||||
{
|
||||
SetPlrView(clonk->GetController(), target_door);
|
||||
var y_off = target_door->~GetFloorOffset();
|
||||
Global->CreateLight(target_door->GetX(), target_door->GetY() + y_off, 30, Fx_Light.LGT_Temp, clonk->GetController(), 30, 50);
|
||||
target_door->OpenDoor();
|
||||
return;
|
||||
}
|
||||
|
||||
public func OnCorrectCodeEntered(object clonk)
|
||||
{
|
||||
// Open door if specified.
|
||||
if (target_door)
|
||||
OpenDoor(clonk);
|
||||
// Perform user action last; it may delete the door/clonk/etc.
|
||||
UserAction->EvaluateAction(correct_code_action, this, clonk);
|
||||
return;
|
||||
}
|
||||
|
||||
public func OnWrongCodeEntered(object clonk)
|
||||
{
|
||||
// Perform user action last; it may delete the door/clonk/etc.
|
||||
UserAction->EvaluateAction(wrong_code_action, this, clonk);
|
||||
return;
|
||||
}
|
||||
|
||||
public func SetCodeActions(new_correct_action, new_wrong_action)
|
||||
{
|
||||
correct_code_action = new_correct_action;
|
||||
wrong_code_action = new_wrong_action;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Saving --*/
|
||||
|
||||
public func SaveScenarioObject(proplist props)
|
||||
{
|
||||
if (!_inherited(props, ...)) return false;
|
||||
if (correct_code) props->AddCall("Code", this, "SetKeypadCode", Format("%v", correct_code));
|
||||
if (target_door) props->AddCall("Target", this, "SetStoneDoor", target_door);
|
||||
if (correct_code_action || wrong_code_action) props->AddCall("Action", this, "SetCodeActions", correct_code_action, wrong_code_action);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*-- Editor --*/
|
||||
|
||||
public func Definition(proplist def)
|
||||
{
|
||||
if (!def.EditorProps)
|
||||
def.EditorProps = {};
|
||||
def.EditorProps.correct_code = { Name = "$KeypadCode$", Type = "string", Set="SetKeypadCode", EditorHelp = "$HelpKeypadCode$" };
|
||||
def.EditorProps.target_door = { Name = "$KeypadTarget$", Type = "object", Filter = "IsSwitchTarget", EditorHelp = "$HelpKeypadTarget$" };
|
||||
def.EditorProps.correct_code_action = new UserAction.Prop { Name = "$OnCorrectCodeAction$", EditorHelp = "$HelpOnCorrectCodeAction$" };
|
||||
def.EditorProps.wrong_code_action = new UserAction.Prop { Name = "$OnWrongCodeAction$", EditorHelp = "$HelpOnWrongCodeAction$" };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Interaction --*/
|
||||
|
||||
public func IsInteractable(object clonk)
|
||||
{
|
||||
return clonk->GetProcedure() == "WALK" && (!clonk->GetMenu() || clonk->GetMenu().ID != menu_id);
|
||||
}
|
||||
|
||||
public func Interact(object clonk)
|
||||
{
|
||||
code = "";
|
||||
OpenKeypadMenu(clonk);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*-- Menu --*/
|
||||
|
||||
public func OpenKeypadMenu(object clonk)
|
||||
{
|
||||
// Only one clonk at a time can handle the keypad.
|
||||
if (menu_controller)
|
||||
return;
|
||||
|
||||
// If the menu is already open, don't open another instance.
|
||||
if (clonk->GetMenu() && clonk->GetMenu().ID == menu_id)
|
||||
return;
|
||||
|
||||
// This object functions as menu target and for visibility.
|
||||
menu_target = CreateContents(Dummy);
|
||||
menu_target.Visibility = VIS_Owner;
|
||||
menu_target->SetOwner(clonk->GetOwner());
|
||||
menu_controller = clonk;
|
||||
|
||||
// Make the room/credits menu.
|
||||
menu =
|
||||
{
|
||||
Target = menu_target,
|
||||
Left = "50%-6em",
|
||||
Right = "50%+6em",
|
||||
Top = "50%-10em",
|
||||
Bottom = "50%+8em",
|
||||
Decoration = GUI_MenuDeco,
|
||||
BackgroundColor = {Std = KEYPADMENU_BackgroundColor},
|
||||
};
|
||||
menu.code =
|
||||
{
|
||||
Target = this,
|
||||
ID = 2,
|
||||
Bottom = "1.5em",
|
||||
text =
|
||||
{
|
||||
Target = this,
|
||||
ID = 21,
|
||||
Right = "4em",
|
||||
Style = GUI_TextVCenter,
|
||||
Text = "$MsgEnterCode$"
|
||||
},
|
||||
value =
|
||||
{
|
||||
Target = this,
|
||||
ID = 22,
|
||||
Left = "4em",
|
||||
Right = "100%-0.05em",
|
||||
Style = GUI_TextVCenter | GUI_TextRight,
|
||||
Text = nil
|
||||
}
|
||||
};
|
||||
menu.bar =
|
||||
{
|
||||
Target = this,
|
||||
ID = 3,
|
||||
Top = "1.5em",
|
||||
Bottom = "2em",
|
||||
BackgroundColor = {Std = ROOMMENU_BarColor},
|
||||
};
|
||||
menu.keys =
|
||||
{
|
||||
Target = this,
|
||||
ID = 4,
|
||||
Top = "2em",
|
||||
};
|
||||
menu.keys.key1 = MakePadButton(0, 0, Icon_Number, "1", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 1));
|
||||
menu.keys.key2 = MakePadButton(1, 0, Icon_Number, "2", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 2));
|
||||
menu.keys.key3 = MakePadButton(2, 0, Icon_Number, "3", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 3));
|
||||
menu.keys.key4 = MakePadButton(0, 1, Icon_Number, "4", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 4));
|
||||
menu.keys.key5 = MakePadButton(1, 1, Icon_Number, "5", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 5));
|
||||
menu.keys.key6 = MakePadButton(2, 1, Icon_Number, "6", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 6));
|
||||
menu.keys.key7 = MakePadButton(0, 2, Icon_Number, "7", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 7));
|
||||
menu.keys.key8 = MakePadButton(1, 2, Icon_Number, "8", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 8));
|
||||
menu.keys.key9 = MakePadButton(2, 2, Icon_Number, "9", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 9));
|
||||
menu.keys.key0 = MakePadButton(1, 3, Icon_Number, "0", "$TooltipDigit$", GuiAction_Call(this, "UpdateMenuCode", 0));
|
||||
menu.keys.enter = MakePadButton(2, 3, Icon_Ok, nil, "$TooltipCheck$", GuiAction_Call(this, "EnterKeypadCode", nil));
|
||||
|
||||
menu.keys.clearlast = MakePadButton(0, 0, Icon_Number, "Hash", "$TooltipClearLast$", GuiAction_Call(this, "UpdateMenuCode", nil));
|
||||
menu.keys.clearlast.Left = "0em"; menu.keys.clearlast.Right = "2em"; menu.keys.clearlast.Top = "12em"; menu.keys.clearlast.Bottom = "14em";
|
||||
menu.keys.clearlast.image = {Left = "50%", Top = "50%", Symbol = Icon_Arrow, GraphicsName = "Left"};
|
||||
|
||||
menu.keys.clearcode = MakePadButton(0, 0, Icon_Number, "Hash", "$TooltipClearCode$", GuiAction_Call(this, "ClearMenuCode", nil));
|
||||
menu.keys.clearcode.Left = "2em"; menu.keys.clearcode.Right = "4em"; menu.keys.clearcode.Top = "12em"; menu.keys.clearcode.Bottom = "14em";
|
||||
menu.keys.clearcode.image = {Left = "50%", Top = "50%", Symbol = Icon_Cancel};
|
||||
|
||||
menu.keys.resetcode = MakePadButton(0, 0, Icon_Number, "Hash", "$TooltipResetCode$", GuiAction_Call(this, "ResetKeypadCode", nil));
|
||||
menu.keys.resetcode.Left = "2em"; menu.keys.resetcode.Right = "4em"; menu.keys.resetcode.Top = "14em"; menu.keys.resetcode.Bottom = "16em";
|
||||
menu.keys.resetcode.image = {Left = "50%", Top = "50%", Symbol = Icon_Swap};
|
||||
|
||||
menu.keys.close = MakePadButton(0, 0, Icon_Cancel, nil, "$TooltipClose$", GuiAction_Call(this, "CloseKeypadMenu", nil));
|
||||
menu.keys.close.Left = "0em"; menu.keys.close.Right = "2em"; menu.keys.close.Top = "14em"; menu.keys.close.Bottom = "16em";
|
||||
|
||||
// Open the menu and store the menu ID.
|
||||
menu_id = GuiOpen(menu);
|
||||
// Notify the clonk and set the menu.
|
||||
clonk->SetMenu(this);
|
||||
return;
|
||||
}
|
||||
|
||||
public func MakePadButton(int x, int y, id symbol, string graphics_name, string tooltip, on_click)
|
||||
{
|
||||
return {
|
||||
Left = Format("%dem", 4 * x),
|
||||
Right = Format("%dem", 4 * (x + 1)),
|
||||
Top = Format("%dem", 4 * y),
|
||||
Bottom = Format("%dem", 4 * (y + 1)),
|
||||
Symbol = symbol,
|
||||
GraphicsName = graphics_name,
|
||||
BackgroundColor = {Std = 0, Hover = KEYPADMENU_HoverColor},
|
||||
OnMouseIn = GuiAction_SetTag("Hover"),
|
||||
OnMouseOut = GuiAction_SetTag("Std"),
|
||||
OnClick = on_click,
|
||||
Tooltip = tooltip
|
||||
};
|
||||
}
|
||||
|
||||
public func UpdateMenuCode(int digit_pressed)
|
||||
{
|
||||
if (digit_pressed == nil)
|
||||
{
|
||||
if (GetType(code) == C4V_String)
|
||||
code = TakeString(code, 0, GetLength(code) - 1);
|
||||
Sound("UI::Click?");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code == nil)
|
||||
code = Format("%d", digit_pressed);
|
||||
else
|
||||
code = Format("%s%d", code, digit_pressed);
|
||||
Sound("UI::Tick");
|
||||
}
|
||||
menu.code.value.Text = code;
|
||||
GuiUpdate(menu.code.value, menu_id, menu.code.value.ID, this);
|
||||
return;
|
||||
}
|
||||
|
||||
public func ClearMenuCode()
|
||||
{
|
||||
code = nil;
|
||||
Sound("UI::Click?");
|
||||
menu.code.value.Text = code;
|
||||
GuiUpdate(menu.code.value, menu_id, menu.code.value.ID, this);
|
||||
return;
|
||||
}
|
||||
|
||||
public func EnterKeypadCode()
|
||||
{
|
||||
if (menu_controller.code_reset_state == "reset")
|
||||
{
|
||||
correct_code = code;
|
||||
code = nil;
|
||||
menu.code.value.Text = "$MsgCodeReset$";
|
||||
menu_controller.code_reset_state = nil;
|
||||
Sound("UI::Confirmed");
|
||||
menu.code.text.Text = "$MsgEnterCode$";
|
||||
GuiUpdate(menu.code.text, menu_id, menu.code.text.ID, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (correct_code == nil)
|
||||
{
|
||||
code = nil;
|
||||
menu.code.value.Text = "$MsgNoCode$";
|
||||
Sound("UI::Error");
|
||||
}
|
||||
else if (correct_code == code)
|
||||
{
|
||||
code = nil;
|
||||
Sound("UI::Confirmed");
|
||||
if (menu_controller.code_reset_state == "confirm")
|
||||
{
|
||||
menu.code.value.Text = "$MsgCodeConfirmed$";
|
||||
menu_controller.code_reset_state = "reset";
|
||||
menu.code.text.Text = "$MsgEnterNewCode$";
|
||||
GuiUpdate(menu.code.text, menu_id, menu.code.text.ID, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.code.value.Text = "$MsgCorrectCode$";
|
||||
// Execute the correct code trigger.
|
||||
OnCorrectCodeEntered(menu_controller);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
code = nil;
|
||||
menu.code.value.Text = "$MsgWrongCode$";
|
||||
Sound("UI::Error");
|
||||
// Execute the wrong code trigger.
|
||||
OnWrongCodeEntered(menu_controller);
|
||||
}
|
||||
}
|
||||
GuiUpdate(menu.code.value, menu_id, menu.code.value.ID, this);
|
||||
return;
|
||||
}
|
||||
|
||||
public func ResetKeypadCode()
|
||||
{
|
||||
// Only allow resetting the code if the clonk (menu_target) has entered the correct code before.
|
||||
if (correct_code == nil)
|
||||
{
|
||||
menu_controller.code_reset_state = "reset";
|
||||
menu.code.text.Text = "$MsgEnterNewCode$";
|
||||
GuiUpdate(menu.code.text, menu_id, menu.code.text.ID, this);
|
||||
}
|
||||
else if (menu_controller.code_reset_state != "reset" && menu_controller.code_reset_state != "confirm")
|
||||
{
|
||||
menu_controller.code_reset_state = "confirm";
|
||||
menu.code.text.Text = "$MsgConfirmCode$";
|
||||
GuiUpdate(menu.code.text, menu_id, menu.code.text.ID, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_controller.code_reset_state = nil;
|
||||
menu.code.text.Text = "$MsgEnterCode$";
|
||||
GuiUpdate(menu.code.text, menu_id, menu.code.text.ID, this);
|
||||
}
|
||||
Sound("UI::Tick");
|
||||
return;
|
||||
}
|
||||
|
||||
public func CloseKeypadMenu()
|
||||
{
|
||||
// Close the menu and inform the controller.
|
||||
Sound("UI::Close");
|
||||
GuiClose(menu_id, nil, this);
|
||||
menu_target->RemoveObject();
|
||||
menu_target = nil;
|
||||
menu_id = nil;
|
||||
if (menu_controller)
|
||||
{
|
||||
menu_controller.code_reset_state = nil;
|
||||
menu_controller->MenuClosed();
|
||||
}
|
||||
menu_controller = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
public func Close()
|
||||
{
|
||||
CloseKeypadMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Properties --*/
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
|
@ -0,0 +1,28 @@
|
|||
Name=Ziffernblock
|
||||
Description=Richtiger Kennzahl eingeben um ein Ereignis aus zu lösen.
|
||||
|
||||
MsgEnterCode=Kennzahl eingeben:
|
||||
MsgEnterNewCode=Neue Kennzahl:
|
||||
MsgConfirmCode=Kennzahl bestätigen:
|
||||
MsgNoCode=<c ffff00>Ziffernblock hat kein Kennzahl!</c>
|
||||
MsgCorrectCode=<c 00ff00>Richtiger Kennzahl!</c>
|
||||
MsgWrongCode=<c ff0000>Falscher Kennzahl!</c>
|
||||
MsgCodeReset=<c 00ff00>Kennzahl wurde zurück gesetzt!</c>
|
||||
MsgCodeConfirmed=<c 00ff00>Kennzahl bestätigt, jetzt zurücksetzen.</c>
|
||||
|
||||
TooltipDigit=Gebe Nummer ein.
|
||||
TooltipCheck=Kontrolliere die eingebene Kennzahl.
|
||||
TooltipClose=Schließe das Ziffernblock.
|
||||
TooltipClearLast=Entferne die letzte Nummer.
|
||||
TooltipClearCode=Eingegebene Kennzahl löschen.
|
||||
TooltipResetCode=Die Kennzahl des Ziffernblocks zurücksetzen.
|
||||
|
||||
KeypadCode=Kennzahl
|
||||
KeypadTarget=Ziel
|
||||
OnCorrectCodeAction=Aktion 'richtige Kennzahl'
|
||||
OnWrongCodeAction=Aktion 'falsche Kennzahl'
|
||||
HelpKeypadCode=Gib den Kennzahl ein der vom Spieler eingetippt werden muss (darf nur Zahlen enthalten).
|
||||
HelpKeypadTarget=Tür die geöffnet wird wenn den richtigen Kennzahl eingegeben wird.
|
||||
HelpOnCorrectCodeAction=Aktion die ausgeführt wird wenn die richtige Kennzahl eingegeben wird.
|
||||
HelpOnWrongCodeAction=Aktion die ausgeführt wird wenn eine falsche Kennzahl eingegeben wird.
|
||||
WarningKeypadCode=WARNUNG: Kennzahl vom Ziffernblock (%s) enthält Charaktere die nicht Zahlen sind, Kennzahl wird nicht gesetzt.
|
|
@ -0,0 +1,28 @@
|
|||
Name=Keypad
|
||||
Description=Enter the correct code to trigger an event.
|
||||
|
||||
MsgEnterCode=Enter code:
|
||||
MsgEnterNewCode=New code:
|
||||
MsgConfirmCode=Confirm code:
|
||||
MsgNoCode=<c ffff00>Keypad has no code!</c>
|
||||
MsgCorrectCode=<c 00ff00>Correct code!</c>
|
||||
MsgWrongCode=<c ff0000>Wrong code!</c>
|
||||
MsgCodeReset=<c 00ff00>Code has been reset!</c>
|
||||
MsgCodeConfirmed=<c 00ff00>Code confirmed, reset now.</c>
|
||||
|
||||
TooltipDigit=Enter digit.
|
||||
TooltipCheck=Check the entered code.
|
||||
TooltipClose=Close the keypad.
|
||||
TooltipClearLast=Delete the last digit.
|
||||
TooltipClearCode=Clear the entered code.
|
||||
TooltipResetCode=Reset the keypad code.
|
||||
|
||||
KeypadCode=Code
|
||||
KeypadTarget=Target
|
||||
OnCorrectCodeAction=Action 'correct code'
|
||||
OnWrongCodeAction=Action 'wrong code'
|
||||
HelpKeypadCode=Enter the keypad code the player must type in (must be digits only).
|
||||
HelpKeypadTarget=Target door that will be opened when the correct has been entered.
|
||||
HelpOnCorrectCodeAction=Action to be executed when the correct code has been entered.
|
||||
HelpOnWrongCodeAction=Action to be executed when a wrong code has been entered.
|
||||
WarningKeypadCode=WARNING: keypad code (%s) contains some non-digit characters, code will not be set.
|
Loading…
Reference in New Issue