1 #include <i18n.h>
2 #include "playerInfo.h"
3 #include "screens/mainScreen.h"
4 #include "screens/crewStationScreen.h"
5 
6 #include "screens/crew6/helmsScreen.h"
7 #include "screens/crew6/weaponsScreen.h"
8 #include "screens/crew6/engineeringScreen.h"
9 #include "screens/crew6/scienceScreen.h"
10 #include "screens/crew6/relayScreen.h"
11 
12 #include "screens/crew4/tacticalScreen.h"
13 #include "screens/crew4/engineeringAdvancedScreen.h"
14 #include "screens/crew4/operationsScreen.h"
15 
16 #include "screens/crew1/singlePilotScreen.h"
17 
18 #include "screens/extra/damcon.h"
19 #include "screens/extra/powerManagement.h"
20 #include "screens/extra/databaseScreen.h"
21 #include "screens/extra/commsScreen.h"
22 #include "screens/extra/shipLogScreen.h"
23 
24 #include "screenComponents/mainScreenControls.h"
25 #include "screenComponents/selfDestructEntry.h"
26 
27 static const int16_t CMD_UPDATE_CREW_POSITION = 0x0001;
28 static const int16_t CMD_UPDATE_SHIP_ID = 0x0002;
29 static const int16_t CMD_UPDATE_MAIN_SCREEN = 0x0003;
30 static const int16_t CMD_UPDATE_MAIN_SCREEN_CONTROL = 0x0004;
31 static const int16_t CMD_UPDATE_NAME = 0x0005;
32 
33 P<PlayerInfo> my_player_info;
34 P<PlayerSpaceship> my_spaceship;
35 PVector<PlayerInfo> player_info_list;
36 
37 REGISTER_MULTIPLAYER_CLASS(PlayerInfo, "PlayerInfo");
PlayerInfo()38 PlayerInfo::PlayerInfo()
39 : MultiplayerObject("PlayerInfo")
40 {
41     ship_id = -1;
42     client_id = -1;
43     main_screen_control = false;
44     registerMemberReplication(&client_id);
45 
46     for(int n=0; n<max_crew_positions; n++)
47     {
48         crew_position[n] = false;
49         registerMemberReplication(&crew_position[n]);
50     }
51     registerMemberReplication(&ship_id);
52     registerMemberReplication(&name);
53     registerMemberReplication(&main_screen);
54     registerMemberReplication(&main_screen_control);
55 
56     player_info_list.push_back(this);
57 }
58 
isOnlyMainScreen()59 bool PlayerInfo::isOnlyMainScreen()
60 {
61     if (!main_screen)
62         return false;
63     for(int n=0; n<max_crew_positions; n++)
64         if (crew_position[n])
65             return false;
66     return true;
67 }
68 
commandSetCrewPosition(ECrewPosition position,bool active)69 void PlayerInfo::commandSetCrewPosition(ECrewPosition position, bool active)
70 {
71     sf::Packet packet;
72     packet << CMD_UPDATE_CREW_POSITION << int32_t(position) << active;
73     sendClientCommand(packet);
74 
75     crew_position[position] = active;
76 }
77 
commandSetShipId(int32_t id)78 void PlayerInfo::commandSetShipId(int32_t id)
79 {
80     sf::Packet packet;
81     packet << CMD_UPDATE_SHIP_ID << id;
82     sendClientCommand(packet);
83 }
84 
commandSetMainScreen(bool enabled)85 void PlayerInfo::commandSetMainScreen(bool enabled)
86 {
87     sf::Packet packet;
88     packet << CMD_UPDATE_MAIN_SCREEN << enabled;
89     sendClientCommand(packet);
90 
91     main_screen = enabled;
92 }
93 
commandSetMainScreenControl(bool control)94 void PlayerInfo::commandSetMainScreenControl(bool control)
95 {
96     sf::Packet packet;
97     packet << CMD_UPDATE_MAIN_SCREEN_CONTROL << control;
98     sendClientCommand(packet);
99 
100     main_screen_control = control;
101 }
102 
commandSetName(const string & name)103 void PlayerInfo::commandSetName(const string& name)
104 {
105     sf::Packet packet;
106     packet << CMD_UPDATE_NAME << name;
107     sendClientCommand(packet);
108 
109     this->name = name;
110 }
111 
onReceiveClientCommand(int32_t client_id,sf::Packet & packet)112 void PlayerInfo::onReceiveClientCommand(int32_t client_id, sf::Packet& packet)
113 {
114     if (client_id != this->client_id) return;
115     int16_t command;
116     packet >> command;
117     switch(command)
118     {
119     case CMD_UPDATE_CREW_POSITION:
120         {
121             int32_t position;
122             bool active;
123             packet >> position >> active;
124             crew_position[position] = active;
125         }
126         break;
127     case CMD_UPDATE_SHIP_ID:
128         packet >> ship_id;
129         break;
130     case CMD_UPDATE_MAIN_SCREEN:
131         packet >> main_screen;
132         break;
133     case CMD_UPDATE_MAIN_SCREEN_CONTROL:
134         packet >> main_screen_control;
135         break;
136     case CMD_UPDATE_NAME:
137         packet >> name;
138         break;
139     }
140 }
141 
spawnUI()142 void PlayerInfo::spawnUI()
143 {
144     if (my_player_info->isOnlyMainScreen())
145     {
146         new ScreenMainScreen();
147     }
148     else {
149 
150         CrewStationScreen* screen = new CrewStationScreen{ main_screen };
151         auto container = screen->getTabContainer();
152 
153         //Crew 6/5
154         if (crew_position[helmsOfficer])
155             screen->addStationTab(new HelmsScreen(container), helmsOfficer, getCrewPositionName(helmsOfficer), getCrewPositionIcon(helmsOfficer));
156         if (crew_position[weaponsOfficer])
157             screen->addStationTab(new WeaponsScreen(container), weaponsOfficer, getCrewPositionName(weaponsOfficer), getCrewPositionIcon(weaponsOfficer));
158         if (crew_position[engineering])
159             screen->addStationTab(new EngineeringScreen(container), engineering, getCrewPositionName(engineering), getCrewPositionIcon(engineering));
160         if (crew_position[scienceOfficer])
161             screen->addStationTab(new ScienceScreen(container), scienceOfficer, getCrewPositionName(scienceOfficer), getCrewPositionIcon(scienceOfficer));
162         if (crew_position[relayOfficer])
163             screen->addStationTab(new RelayScreen(container, true), relayOfficer, getCrewPositionName(relayOfficer), getCrewPositionIcon(relayOfficer));
164 
165         //Crew 4/3
166         if (crew_position[tacticalOfficer])
167             screen->addStationTab(new TacticalScreen(container), tacticalOfficer, getCrewPositionName(tacticalOfficer), getCrewPositionIcon(tacticalOfficer));
168         if (crew_position[engineeringAdvanced])
169             screen->addStationTab(new EngineeringAdvancedScreen(container), engineeringAdvanced, getCrewPositionName(engineeringAdvanced), getCrewPositionIcon(engineeringAdvanced));
170         if (crew_position[operationsOfficer])
171             screen->addStationTab(new OperationScreen(container), operationsOfficer, getCrewPositionName(operationsOfficer), getCrewPositionIcon(operationsOfficer));
172 
173         //Crew 1
174         if (crew_position[singlePilot])
175             screen->addStationTab(new SinglePilotScreen(container), singlePilot, getCrewPositionName(singlePilot), getCrewPositionIcon(singlePilot));
176 
177         //Extra
178         if (crew_position[damageControl])
179             screen->addStationTab(new DamageControlScreen(container), damageControl, getCrewPositionName(damageControl), getCrewPositionIcon(damageControl));
180         if (crew_position[powerManagement])
181             screen->addStationTab(new PowerManagementScreen(container), powerManagement, getCrewPositionName(powerManagement), getCrewPositionIcon(powerManagement));
182         if (crew_position[databaseView])
183             screen->addStationTab(new DatabaseScreen(container), databaseView, getCrewPositionName(databaseView), getCrewPositionIcon(databaseView));
184         if (crew_position[altRelay])
185             screen->addStationTab(new RelayScreen(container, false), altRelay, getCrewPositionName(altRelay), getCrewPositionIcon(altRelay));
186         if (crew_position[commsOnly])
187             screen->addStationTab(new CommsScreen(container), commsOnly, getCrewPositionName(commsOnly), getCrewPositionIcon(commsOnly));
188         if (crew_position[shipLog])
189             screen->addStationTab(new ShipLogScreen(container), shipLog, getCrewPositionName(shipLog), getCrewPositionIcon(shipLog));
190 
191         GuiSelfDestructEntry* sde = new GuiSelfDestructEntry(container, "SELF_DESTRUCT_ENTRY");
192         for(int n=0; n<max_crew_positions; n++)
193             if (crew_position[n])
194                 sde->enablePosition(ECrewPosition(n));
195         if (crew_position[tacticalOfficer])
196         {
197             sde->enablePosition(weaponsOfficer);
198             sde->enablePosition(helmsOfficer);
199         }
200         if (crew_position[engineeringAdvanced])
201         {
202             sde->enablePosition(engineering);
203         }
204         if (crew_position[operationsOfficer])
205         {
206             sde->enablePosition(scienceOfficer);
207             sde->enablePosition(relayOfficer);
208         }
209 
210         if (main_screen_control)
211             new GuiMainScreenControls(container);
212 
213         screen->finishCreation();
214     }
215 }
216 
getCrewPositionName(ECrewPosition position)217 string getCrewPositionName(ECrewPosition position)
218 {
219     switch(position)
220     {
221     case helmsOfficer: return tr("station","Helms");
222     case weaponsOfficer: return tr("station","Weapons");
223     case engineering: return tr("station","Engineering");
224     case scienceOfficer: return tr("station","Science");
225     case relayOfficer: return tr("station","Relay");
226     case tacticalOfficer: return tr("station","Tactical");
227     case engineeringAdvanced: return tr("station","Engineering+");
228     case operationsOfficer: return tr("station","Operations");
229     case singlePilot: return tr("station","Single Pilot");
230     case damageControl: return tr("station","Damage Control");
231     case powerManagement: return tr("station","Power Management");
232     case databaseView: return tr("station","Database");
233     case altRelay: return tr("station","Strategic Map");
234     case commsOnly: return tr("station","Comms");
235     case shipLog: return tr("station","Ship's Log");
236     default: return "ErrUnk: " + string(position);
237     }
238 }
239 
getCrewPositionIcon(ECrewPosition position)240 string getCrewPositionIcon(ECrewPosition position)
241 {
242     switch(position)
243     {
244     case helmsOfficer: return "gui/icons/station-helm";
245     case weaponsOfficer: return "gui/icons/station-weapons";
246     case engineering: return "gui/icons/station-engineering";
247     case scienceOfficer: return "gui/icons/station-science";
248     case relayOfficer: return "gui/icons/station-relay";
249     case tacticalOfficer: return "";
250     case engineeringAdvanced: return "";
251     case operationsOfficer: return "";
252     case singlePilot: return "";
253     case damageControl: return "";
254     case powerManagement: return "";
255     case databaseView: return "";
256     case altRelay: return "";
257     case commsOnly: return "";
258     case shipLog: return "";
259     default: return "ErrUnk: " + string(position);
260     }
261 }
262 
263 /* Define script conversion function for the ECrewPosition enum. */
param(lua_State * L,int & idx,ECrewPosition & cp)264 template<> void convert<ECrewPosition>::param(lua_State* L, int& idx, ECrewPosition& cp)
265 {
266     string str = string(luaL_checkstring(L, idx++)).lower();
267 
268     //6/5 player crew
269     if (str == "helms" || str == "helmsofficer")
270         cp = helmsOfficer;
271     else if (str == "weapons" || str == "weaponsofficer")
272         cp = weaponsOfficer;
273     else if (str == "engineering" || str == "engineeringsofficer")
274         cp = engineering;
275     else if (str == "science" || str == "scienceofficer")
276         cp = scienceOfficer;
277     else if (str == "relay" || str == "relayofficer")
278         cp = relayOfficer;
279 
280     //4/3 player crew
281     else if (str == "tactical" || str == "tacticalofficer")
282         cp = tacticalOfficer;    //helms+weapons-shields
283     else if (str == "engineering+" || str == "engineering+officer" || str == "engineeringadvanced" || str == "engineeringadvancedofficer")
284         cp = engineeringAdvanced;//engineering+shields
285     else if (str == "operations" || str == "operationsofficer")
286         cp = operationsOfficer; //science+comms
287 
288     //1 player crew
289     else if (str == "single" || str == "singlepilot")
290         cp = singlePilot;
291 
292     //extras
293     else if (str == "damagecontrol")
294         cp = damageControl;
295     else if (str == "powermanagement")
296         cp = powerManagement;
297     else if (str == "database" || str == "databaseview")
298         cp = databaseView;
299     else if (str == "altrelay")
300         cp = altRelay;
301     else if (str == "commsonly")
302         cp = commsOnly;
303     else if (str == "shiplog")
304         cp = shipLog;
305     else
306         luaL_error(L, "Unknown value for crew position: %s", str.c_str());
307 }
308