-
Notifications
You must be signed in to change notification settings - Fork 172
/
commsScriptInterface.cpp
146 lines (129 loc) · 5.67 KB
/
commsScriptInterface.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "commsScriptInterface.h"
#include "spaceObjects/cpuShip.h"
#include "spaceObjects/playerSpaceship.h"
static CommsScriptInterface* comms_script_interface = NULL;
static int setCommsMessage(lua_State* L)
{
if (!comms_script_interface)
return 0;
comms_script_interface->setCommsMessage(luaL_checkstring(L, 1));
return 0;
}
static int addCommsReply(lua_State* L)
{
if (!comms_script_interface)
return 0;
ScriptSimpleCallback callback;
int idx = 2;
convert<ScriptSimpleCallback>::param(L, idx, callback);
comms_script_interface->addCommsReply(luaL_checkstring(L, 1), callback);
return 0;
}
static int commsSwitchToGM(lua_State* L)
{
if (!comms_script_interface)
return 0;
comms_script_interface->switchToGM();
return 0;
}
/// void setCommsMessage(string message)
/// Sets the content of an accepted hail, or in a comms reply.
/// If no message is set, attempting to open comms results in "no reply", or a dialogue with the message "?" in a reply.
/// Use this only in replies (addCommsReply()), comms scripts (SpaceObject:setCommsScript()), or comms functions (SpaceObject:setCommsFunction()).
/// When used in the callback function of addCommsReply(), this clears all existing replies.
/// Example:
/// -- Send a greeting upon hail if the player is friendly with the comms target
/// function friendlyComms()
/// if comms_source:isFriendly(comms_target) then
/// setCommsMessage("Hello, friend!")
/// else
/// setCommsMessage("Who are you?")
/// end
/// end
/// -- When some_ship is hailed, run friendlyComms() with some_ship as the comms_target and the player as the comms_source
/// some_ship:setCommsFunction(friendlyComms)
REGISTER_SCRIPT_FUNCTION(setCommsMessage);
/// void addCommsReply(string message, ScriptSimpleCallback callback)
/// Adds a selectable reply option to a communications dialogue as a button with the given text.
/// When clicked, the button calls the given function.
/// Use this only after comms messages (setCommsMessage() in comms scripts (SpaceObject:setCommsScript()), or comms functions (SpaceObject:setCommsFunction()).
/// Comms scripts pass global variables `comms_target` and `comms_source`. See SpaceObject:setCommsScript().
/// Comms functions pass only `comms_source`. See SpaceObject:setCommsFunction().
/// Instead of using these globals, the callback function can take two parameters.
/// To present multiple options in one comms message, call addCommsReply() for each option.
/// To create a dialogue tree, run setCommsMessage() inside the addCommsReply() callback, then add new comms replies.
/// Example:
/// if comms_source:isFriendly(comms_target) then
/// setCommsMessage("Hello, friend!")
/// addCommsReply("Can you send a supply drop?", function(comms_source, comms_target) ... end) -- runs the given function when selected
/// ...
/// Deprecated: In a comms script, `player` can also be used for `comms_source`.
REGISTER_SCRIPT_FUNCTION(addCommsReply);
/// void commsSwitchToGM()
/// Switches a PlayerSpaceship communications dialogue from a comms script/function to interactive chat with the GM.
/// When triggered, this opens a comms chat window on both the player crew's screen and GM console.
/// Use this in a communication callback function, such as addCommsReply() or SpaceObject:setCommsFunction().
/// Example:
/// if comms_source:isFriendly(comms_target) then
/// setCommsMessage("Hello, friend!")
/// addCommsReply("I want to speak to your manager!", function() commsSwitchToGM() end) -- launches a GM chat when selected
/// ...
REGISTER_SCRIPT_FUNCTION(commsSwitchToGM);
bool CommsScriptInterface::openCommChannel(P<PlayerSpaceship> ship, P<SpaceObject> target)
{
string script_name = target->comms_script_name;
comms_script_interface = this;
reply_callbacks.clear();
this->ship = ship;
this->target = target;
if (scriptObject)
scriptObject->destroy();
scriptObject = nullptr;
has_message = false;
if (script_name != "")
{
scriptObject = new ScriptObject();
// consider "player" deprecated, but keep it for a long time
scriptObject->registerObject(ship, "player");
scriptObject->registerObject(ship, "comms_source");
scriptObject->registerObject(target, "comms_target");
scriptObject->run(script_name);
}else if (target->comms_script_callback.isSet())
{
target->comms_script_callback.getScriptObject()->registerObject(ship, "comms_source");
target->comms_script_callback.getScriptObject()->registerObject(target, "comms_target");
target->comms_script_callback.call<void>(ship, target);
}
comms_script_interface = nullptr;
return has_message;
}
void CommsScriptInterface::commChannelMessage(int32_t message_id)
{
comms_script_interface = this;
if (message_id >= 0 && message_id < int(reply_callbacks.size()) && ship && target)
{
ScriptSimpleCallback callback = reply_callbacks[message_id];
if (!scriptObject)
{
target->comms_script_callback.getScriptObject()->registerObject(ship, "comms_source");
target->comms_script_callback.getScriptObject()->registerObject(target, "comms_target");
}
reply_callbacks.clear();
callback.call<void>(ship, target);
}
comms_script_interface = nullptr;
}
void CommsScriptInterface::setCommsMessage(string message)
{
has_message = true;
ship->setCommsMessage(message);
}
void CommsScriptInterface::addCommsReply(string message, ScriptSimpleCallback callback)
{
comms_script_interface->ship->addCommsReply(reply_callbacks.size(), message);
reply_callbacks.push_back(callback);
}
void CommsScriptInterface::switchToGM()
{
ship->switchCommsToGM();
}