1 |
#include "Flatline.h" |
2 |
#include "Oni_Character.h" |
3 |
#include "Flatline_Client.h" |
4 |
#include "Flatline_Server.h" |
5 |
#include "Flatline_Events.h" |
6 |
#include "Daodan_Utility.h" |
7 |
#include <Windows.h> |
8 |
//#include <sys/time.h> |
9 |
#include <time.h> |
10 |
#include <float.h> |
11 |
#define isnan(x) ((x) != (x)) |
12 |
uint32_t last1 = 0; uint32_t last2 = 0; |
13 |
player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}}; |
14 |
player_info * PlayerList[MAX_CONNECTIONS] = {0}; |
15 |
multiplayer_status MultiplayerStatus; |
16 |
unsigned int lastPingTime; |
17 |
|
18 |
const char * Rejection_Messages[][255] = { |
19 |
{"Server is full"}, |
20 |
{"-2"}, |
21 |
{"-3"}, |
22 |
{"-4"}, |
23 |
{"-5"}, |
24 |
}; |
25 |
|
26 |
#define BETTER_SYNC |
27 |
|
28 |
bool FLrServer_PacketCallback(char* data, int datalen, int from) |
29 |
{ |
30 |
int i, j; |
31 |
bool found_player = 0; |
32 |
flatline_packet * packet = (flatline_packet*)data; |
33 |
static int recieved = 0; |
34 |
sockaddr_in sender; |
35 |
sender.sin_family = AF_INET; |
36 |
sender.sin_port = htons(27777); |
37 |
sender.sin_addr = *((struct in_addr*)(int*)&from); |
38 |
|
39 |
|
40 |
//packet->data[datalen] = '\0'; |
41 |
|
42 |
//DDrConsole_PrintF("Packet \r%d recieved from %i", ++recieved, from); |
43 |
|
44 |
|
45 |
|
46 |
//if data[0] != CONNECT_SEND, search in playerlist for ip address |
47 |
|
48 |
|
49 |
|
50 |
|
51 |
switch(packet->id) { |
52 |
flatline_packet connect_recv; |
53 |
player_info * playah; |
54 |
//rewrite this when we get TCP support. |
55 |
//rewrite this before we get TCP support* |
56 |
//the way of seeing if there is room for players sucks. |
57 |
case CONNECT_SEND: |
58 |
; |
59 |
|
60 |
connect_recv.id = CONNECT_REPLY; |
61 |
|
62 |
//if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message |
63 |
sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr); |
64 |
playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0); |
65 |
DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) ); |
66 |
if(!((int)playah > -5 && (int)playah <= 0)) { |
67 |
flatline_packet new_char = {0}; |
68 |
CharacterObject* Char; |
69 |
connect_recv.connect_reply.goodtogo = 1; |
70 |
connect_recv.connect_reply.player_slot = playah->list_slot; |
71 |
DDrConsole_PrintF("Slot: %i", playah->list_slot); |
72 |
|
73 |
//sending this several times to make sure it gets through. Really need to make up some form of packet tracking. |
74 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER); |
75 |
/* NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER); |
76 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER); |
77 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER); |
78 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER); |
79 |
Sleep(100); |
80 |
*/ |
81 |
new_char.id = NEW_PLAYER; |
82 |
Char = &new_char.new_player.Character; |
83 |
memset(Char, 0, sizeof(CharacterObject)); |
84 |
Char->Header.Type = 'CHAR'; |
85 |
Char->OSD.Options = chr_dontaim; |
86 |
for(j = 0; j < max_connections; j++) { |
87 |
if(PlayerList[j] != 0) { |
88 |
new_char.new_player.Playernumber = j; |
89 |
sprintf(Char->OSD.Name,"%s",PlayerList[j]->name); |
90 |
|
91 |
sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC)); |
92 |
DDrConsole_PrintF("Class %s", Char->OSD.Class ); |
93 |
|
94 |
sprintf(Char->OSD.Class, "konoko_generic"); |
95 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER ); |
96 |
} |
97 |
|
98 |
} |
99 |
} |
100 |
else { |
101 |
//fix the error messages... |
102 |
DDrConsole_PrintF("Server is full. :("); |
103 |
connect_recv.connect_reply.goodtogo = 0; |
104 |
sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr); |
105 |
memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full.")); |
106 |
NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full.")); |
107 |
|
108 |
} |
109 |
|
110 |
|
111 |
break; |
112 |
case CONNECT_REPLY: |
113 |
break; //do nothing...a server shouldn't recieve this type of packet. |
114 |
case MESSAGE: |
115 |
for(i = 0; i < MAX_PLAYERS; i++) { |
116 |
//DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip))); |
117 |
if(Players[i].ip == sender.sin_addr.S_un.S_addr) { |
118 |
found_player = 1; |
119 |
break; |
120 |
} |
121 |
} |
122 |
if(found_player == 0) return true; |
123 |
else { |
124 |
char message_buffer[512] = {0}; |
125 |
flatline_packet message; |
126 |
int message_size; |
127 |
data[datalen] = 0; |
128 |
|
129 |
DDrConsole_PrintF("%s: %s", Players[i].name, packet->data); |
130 |
sprintf(message_buffer, "%s: %s", Players[i].name, packet->data); |
131 |
|
132 |
message.id = MESSAGE; |
133 |
message_size = sprintf(message.data, "%s", message_buffer); |
134 |
COrMessage_Print(message_buffer, "chat", 0); |
135 |
UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER); |
136 |
break; |
137 |
} |
138 |
case CHANGE_NAME: |
139 |
; //wtf, needed or i get an error. |
140 |
// DDrConsole_PrintF("Changing Name to: %s", packet->data); |
141 |
for(i = 0; i < MAX_PLAYERS; i++) { |
142 |
if(PlayerList[i] && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) { |
143 |
found_player = 1; |
144 |
break; |
145 |
} |
146 |
} |
147 |
if(found_player == 0) break; |
148 |
else { |
149 |
bool name_exists = 0; |
150 |
for(j = 0; j < MAX_PLAYERS; j++) { |
151 |
if(PlayerList[j] && !strcmp(packet->data, PlayerList[j]->name)) { |
152 |
name_exists = 1; |
153 |
break; |
154 |
} |
155 |
} |
156 |
if(!name_exists) { |
157 |
FLsUpdateName( i, packet->data ); |
158 |
} |
159 |
break; |
160 |
} |
161 |
case PLAYER_INPUT: |
162 |
|
163 |
for(i = 0; i < max_connections; i++) { |
164 |
if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) { |
165 |
found_player = 1; |
166 |
break; |
167 |
} |
168 |
} |
169 |
|
170 |
if(found_player == 0) break; |
171 |
else { |
172 |
input_struct * packet_input = &packet->input_struct; |
173 |
|
174 |
|
175 |
PlayerList[i]->InputFromClient.Actions1 = packet_input->Actions1; |
176 |
PlayerList[i]->InputFromClient.Actions2 = packet_input->Actions2; |
177 |
PlayerList[i]->InputFromClient.MouseDeltaX = packet_input->MouseDeltaX; |
178 |
PlayerList[i]->InputFromClient.MouseDeltaY = packet_input->MouseDeltaY; |
179 |
PlayerList[i]->LastInputTime = packet_input->Time; |
180 |
|
181 |
break; |
182 |
} |
183 |
case PK_PONG: |
184 |
for(i = 0; i < max_connections; i++) { |
185 |
if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) { |
186 |
found_player = 1; |
187 |
break; |
188 |
} |
189 |
} |
190 |
|
191 |
if(found_player == 0) break; |
192 |
if(packet->ping != lastPingTime) |
193 |
{ |
194 |
PlayerList[i]->Ping = 999; |
195 |
} |
196 |
else |
197 |
{ |
198 |
PlayerList[i]->Ping = GetTickCount() - packet->ping; |
199 |
} |
200 |
break; |
201 |
default: |
202 |
DDrConsole_PrintF("Warning, recieved badly formed packet!"); |
203 |
break; |
204 |
} |
205 |
return true; |
206 |
} |
207 |
|
208 |
bool FLrServer_Run() |
209 |
{ |
210 |
// Get the local hostname |
211 |
char szHostName[255]; |
212 |
struct hostent *host_entry; |
213 |
gethostname(szHostName, 255); |
214 |
|
215 |
host_entry=gethostbyname(szHostName); |
216 |
DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list)); |
217 |
return NetUDPServer_Listen(27777, FLrServer_PacketCallback); |
218 |
} |
219 |
|
220 |
short TRrAnimation_GetType(char* anim) |
221 |
{ |
222 |
return *(short*)(anim + 0x15A); |
223 |
} |
224 |
|
225 |
void ONrCharacter_SetAnimationInternal(Character* Char, ActiveCharacter* AChar, |
226 |
short inFromState, short inNextAnimType, const void *TRAM) |
227 |
{ |
228 |
ONCC *ONCC = Char->ONCC; |
229 |
void *TRAC = ONCC->TRAC; |
230 |
short index = Char->Number; |
231 |
short animType; |
232 |
|
233 |
if (TRAM == 0) return; |
234 |
|
235 |
animType = TRrAnimation_GetType(TRAM); |
236 |
|
237 |
AChar->Animation = TRAM; |
238 |
AChar->Frame = 0; |
239 |
AChar->AnimationFromState = inFromState; |
240 |
AChar->AnimationType = animType; |
241 |
|
242 |
AChar->NextAnimationType= inNextAnimType; |
243 |
AChar->AnimationToState = TRrAnimation_GetTo(TRAM); |
244 |
|
245 |
return; |
246 |
} |
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
//wtf, this needs cleaned up... |
254 |
player_info *FLr_FindEmptySlot() { |
255 |
int j; |
256 |
for(j = 0; j < MAX_PLAYERS; j++) { |
257 |
if (Players[j].ip == 0) { |
258 |
return &Players[j]; |
259 |
} |
260 |
} |
261 |
return 0; |
262 |
} |
263 |
|
264 |
extern uint16_t max_connections; |
265 |
uint16_t FLr_FindEmptyListSlot() { |
266 |
int j; |
267 |
for(j = 0; j < max_connections; j++) { |
268 |
if (PlayerList[j] == 0) { |
269 |
return j; |
270 |
} |
271 |
} |
272 |
return -1; |
273 |
} |
274 |
typedef struct |
275 |
{ |
276 |
uint16_t x; |
277 |
uint16_t y; |
278 |
|
279 |
} IMtPoint2D; |
280 |
static flatline_packet cache_input = {0}; |
281 |
|
282 |
|
283 |
void * ONICALL FLrInput_Update_Keys(void) |
284 |
{ |
285 |
uint32_t i; |
286 |
flatline_packet all_input = {0}; |
287 |
int16_t InputIndex = 0; |
288 |
|
289 |
if(client_connected) |
290 |
{ |
291 |
int sent_bytes; |
292 |
flatline_packet input_packet = {0}; |
293 |
|
294 |
FLrClient_GetPackets(); |
295 |
|
296 |
input_packet.id = PLAYER_INPUT; |
297 |
input_packet.input_struct.Time = ONgGameState->GameTime; |
298 |
input_packet.input_struct.Actions1 = ONgGameState->Input.Current.Actions1; |
299 |
input_packet.input_struct.Actions2 = ONgGameState->Input.Current.Actions2; |
300 |
input_packet.input_struct.MouseDeltaX = ONgGameState->Input.MouseDeltaX; |
301 |
input_packet.input_struct.MouseDeltaY = ONgGameState->Input.MouseDeltaY; |
302 |
|
303 |
sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER); |
304 |
|
305 |
//return ONgGameState; |
306 |
} |
307 |
|
308 |
|
309 |
if(!(server_started || client_connected)) return ONgGameState; |
310 |
|
311 |
|
312 |
if(server_started) |
313 |
{ |
314 |
if(ONgGameState->GameTime % 120 == 0) |
315 |
{ |
316 |
FLsPingAll(); |
317 |
} |
318 |
|
319 |
if(PlayerList[0]) |
320 |
{ |
321 |
PlayerList[0]->InputFromClient.Actions1 = ONgGameState->Input.Current.Actions1; |
322 |
PlayerList[0]->InputFromClient.Actions2 = ONgGameState->Input.Current.Actions2; |
323 |
PlayerList[0]->InputFromClient.MouseDeltaX = ONgGameState->Input.MouseDeltaX; |
324 |
PlayerList[0]->InputFromClient.MouseDeltaY = ONgGameState->Input.MouseDeltaY; |
325 |
} |
326 |
FLsSendPlayerData(); |
327 |
} |
328 |
for(i = 0; i < max_connections; i++) { |
329 |
ActiveCharacter * Active_Player; |
330 |
Character* Player; |
331 |
GameInput * Active_Input; |
332 |
if(PlayerList[i] == 0) continue; |
333 |
|
334 |
|
335 |
|
336 |
Player = PlayerList[i]->Chr; |
337 |
Active_Player = ONrGetActiveCharacter( PlayerList[i]->Chr); |
338 |
|
339 |
if(!Player) |
340 |
{ |
341 |
DDrConsole_Print("Warning, missing Character!"); |
342 |
continue; |
343 |
} |
344 |
|
345 |
|
346 |
|
347 |
//Set the health properly first. |
348 |
if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Health) ) |
349 |
{ |
350 |
PlayerList[i]->Chr->MaxHealth = PlayerList[i]->Health.MaxHealth; |
351 |
ONrCharacter_SetHitPoints( PlayerList[i]->Chr, PlayerList[i]->Health.Health); |
352 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Health ); |
353 |
} |
354 |
//If the player is dead |
355 |
if( PlayerList[i]->Chr->Health == 0 ) |
356 |
|
357 |
{ |
358 |
const short TicksToRespawn = 3 * 60; |
359 |
|
360 |
//Permanently kill off dumb AI |
361 |
if(PlayerList[i]->flags & PF_SCRIPTEDAI) |
362 |
{ |
363 |
FLrPlayerDisconnect( i ); |
364 |
continue; |
365 |
} |
366 |
|
367 |
//Just to know if we have started counting off the respawn |
368 |
if(PlayerList[i]->state != STATE_DEAD) |
369 |
{ |
370 |
PlayerList[i]->state = STATE_DEAD; |
371 |
PlayerList[i]->DeathTime = ONgGameState->GameTime; |
372 |
if(i == client_slot) |
373 |
{ |
374 |
ONrGameState_Timer_Start( "", TicksToRespawn ); |
375 |
} |
376 |
|
377 |
if(server_started) |
378 |
{ |
379 |
FLsPublic_Event( EV_KILLED, &i ); |
380 |
} |
381 |
|
382 |
} |
383 |
|
384 |
//Server respawning |
385 |
if(server_started) |
386 |
{ |
387 |
int Actions; |
388 |
if(i == 0) |
389 |
{ |
390 |
Actions = ONgGameState->Input.Current.Actions1; |
391 |
} |
392 |
else |
393 |
{ |
394 |
Actions = PlayerList[i]->InputFromClient.Actions1; |
395 |
} |
396 |
|
397 |
if(ONgGameState->GameTime - PlayerList[i]->DeathTime > TicksToRespawn && |
398 |
(Actions & (Action_Punch | Action_Kick)) ) |
399 |
{ |
400 |
FLrPlayerRespawn( i ); |
401 |
|
402 |
FLsPublic_Event( EV_RESPAWN, &i ); |
403 |
} |
404 |
else |
405 |
{ |
406 |
continue; |
407 |
} |
408 |
} |
409 |
else //clients?! |
410 |
{ |
411 |
continue; |
412 |
} |
413 |
} |
414 |
|
415 |
PlayerList[i]->state = STATE_ALIVE; |
416 |
|
417 |
if( DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Facing ) ) |
418 |
{ |
419 |
PlayerList[i]->Chr->Facing = PlayerList[i]->Facings.Facing; |
420 |
PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->Facings.DesiredFacing; |
421 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Facing ); |
422 |
} |
423 |
|
424 |
if(Active_Player == 0) continue; |
425 |
|
426 |
|
427 |
if(client_connected) { |
428 |
Active_Player->PlayingFilm.Flags = 1; |
429 |
} |
430 |
|
431 |
|
432 |
if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Position) ) |
433 |
{ |
434 |
Active_Player->PhyContext->Position = PlayerList[i]->Position; |
435 |
|
436 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Position ); |
437 |
} |
438 |
|
439 |
|
440 |
|
441 |
|
442 |
if (!(Player->Flags & ONcCharacterFlag_BeingThrown) && |
443 |
DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) && (PlayerList[i]->Animation)) |
444 |
{ |
445 |
// get a pointer to the animation |
446 |
|
447 |
|
448 |
if (PlayerList[i]->Animation != Active_Player->Animation) |
449 |
{ |
450 |
|
451 |
/////////////////////////////////// |
452 |
//TODO: Check age of animation |
453 |
/////////////////////////////////// |
454 |
DDrConsole_PrintF("Changing animation from %s to %s", |
455 |
TMrInstance_GetInstanceName( Active_Player->Animation ), |
456 |
TMrInstance_GetInstanceName( PlayerList[i]->Animation ) ); |
457 |
// set the characters animation |
458 |
/*ONrCharacter_SetAnimationInternal(Player, |
459 |
Active_Player, |
460 |
Active_Player->AnimationToState, |
461 |
0, |
462 |
PlayerList[i]->Animation);*/ |
463 |
//ONrCharacter_NewAnimationHook(Player, Active_Player); |
464 |
ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(PlayerList[i]->Animation), PlayerList[i]->Animation, 1); |
465 |
//ONrCharacter_NewAnimationHook(Player, Active_Player); |
466 |
} |
467 |
|
468 |
|
469 |
} |
470 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Animation ); |
471 |
|
472 |
//Don't update the frame if we are waiting to change the animation |
473 |
if(DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_FramePing) && PlayerList[i]->Frame != -1 |
474 |
//&& !DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) |
475 |
) |
476 |
{ |
477 |
if( abs(PlayerList[i]->Frame - Active_Player->Frame) > 2 ) |
478 |
{ |
479 |
short AnimationLength; |
480 |
AnimationLength = TRrAnimation_GetDuration(Active_Player->Animation); |
481 |
if (PlayerList[i]->Frame >= AnimationLength) |
482 |
{ |
483 |
Active_Player->Frame = AnimationLength - 1; |
484 |
//Active_Player->Frame = 0; |
485 |
} |
486 |
else |
487 |
{ |
488 |
Active_Player->Frame = PlayerList[i]->Frame; |
489 |
} |
490 |
} |
491 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_FramePing ); |
492 |
} |
493 |
|
494 |
//Increment frame in case we were waiting |
495 |
PlayerList[i]->Frame++; |
496 |
|
497 |
if (DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Throws) |
498 |
&& PlayerList[i]->ThrowData.throwName[0] != 0) |
499 |
{ |
500 |
if(PlayerList[PlayerList[i]->ThrowData.throwing]) |
501 |
{ |
502 |
short throwTarget = PlayerList[PlayerList[i]->ThrowData.throwing]->spawnnumber; |
503 |
if ((throwTarget != Active_Player->throwing) && |
504 |
(PlayerList[i]->ThrowData.throwFrame < 10)) |
505 |
{ |
506 |
void *throw_animation; |
507 |
ActiveCharacter* Target; |
508 |
// get the animation |
509 |
|
510 |
TMrInstance_GetDataPtr( |
511 |
'TRAM', |
512 |
PlayerList[i]->ThrowData.throwName, |
513 |
&throw_animation); |
514 |
//if (error) return; |
515 |
|
516 |
// set the throw target |
517 |
Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[throwTarget]; |
518 |
Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter); |
519 |
if ((Target->Animation != throw_animation) && |
520 |
// (OldAnimation != Animation) && |
521 |
!(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown)) |
522 |
{ |
523 |
// set the throw variables |
524 |
Active_Player->targetThrow = throw_animation; |
525 |
Active_Player->throwing = throwTarget; |
526 |
|
527 |
// run the throw |
528 |
ONrCharacter_NewAnimationHook(Player, Active_Player); |
529 |
|
530 |
if (Active_Player->ThrowTargetCharacter) |
531 |
{ |
532 |
Target->Frame += 2; |
533 |
DDrConsole_PrintF("Thrown by player %hi", Player->Number ); |
534 |
DDrStartupMessage("Thrown by player %hi", Player->Number ); |
535 |
Target->thrownBy = Player->Number & 0x00ff; |
536 |
} |
537 |
} |
538 |
} |
539 |
} |
540 |
else |
541 |
{ |
542 |
DDrConsole_PrintF("Warning, tried to throw nonexistant player %hi", |
543 |
PlayerList[i]->ThrowData.throwing ); |
544 |
} |
545 |
} |
546 |
|
547 |
//Always discard old throw data, even if it isnt applied |
548 |
PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Throws ); |
549 |
|
550 |
Active_Input = &(Active_Player->Input); |
551 |
|
552 |
if( (server_started && i !=0) || !server_started ) |
553 |
{ |
554 |
Active_Input->Stop.Actions1 = ~PlayerList[i]->Input.Actions1 & Active_Input->Current.Actions1; |
555 |
Active_Input->Stop.Actions2 = ~PlayerList[i]->Input.Actions2 & Active_Input->Current.Actions2; |
556 |
Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Input.Actions1; |
557 |
Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Input.Actions2; |
558 |
|
559 |
Active_Input->Current.Actions1 = PlayerList[i]->Input.Actions1; |
560 |
Active_Input->Current.Actions2 = PlayerList[i]->Input.Actions2; |
561 |
Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1; |
562 |
Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2; |
563 |
Active_Input->MouseDeltaX = PlayerList[i]->Input.MouseDeltaX; |
564 |
Active_Input->MouseDeltaY = PlayerList[i]->Input.MouseDeltaY; |
565 |
} |
566 |
|
567 |
//Check for character switching requests |
568 |
if(server_started && PlayerList[i]->Chr->Health != 0 && PlayerList[i]->InputFromClient.Actions1 & Action_Block && PlayerList[i]->ShapeshiftCooldown < ONgGameState->GameTime) |
569 |
{ |
570 |
int error; |
571 |
|
572 |
|
573 |
|
574 |
ONCC *newClass; |
575 |
short numClasses = (short)TMrInstance_GetTagCount('ONCC'); |
576 |
/* |
577 |
if(Active_Player->Input.Start.Actions1 & Action_Block) |
578 |
{ |
579 |
//This might not be getting hit. Find out why, eh? |
580 |
PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 15; |
581 |
} |
582 |
else |
583 |
{ |
584 |
PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 5; |
585 |
} |
586 |
*/ |
587 |
if (PlayerList[i]->InputFromClient.Actions1 & Action_Crouch) { |
588 |
Player->ONCCnumber += numClasses - 1; |
589 |
} |
590 |
else { |
591 |
Player->ONCCnumber += 1; |
592 |
} |
593 |
|
594 |
if (numClasses > 0) { |
595 |
Player->ONCCnumber = Player->ONCCnumber % numClasses; |
596 |
|
597 |
error = TMrInstance_GetDataPtr_ByNumber('ONCC', Player->ONCCnumber, &newClass); |
598 |
|
599 |
if ((newClass != NULL) && (!error)) { |
600 |
ONrCharacter_SetCharacterClass(Player, newClass); |
601 |
} |
602 |
} |
603 |
|
604 |
} |
605 |
|
606 |
|
607 |
} |
608 |
|
609 |
MultiplayerStatus.PleaseUpdateAllPlayers = 0; |
610 |
return ONgGameState; |
611 |
} |
612 |
|
613 |
void FLrPlayerDisconnect( int Player ) |
614 |
{ |
615 |
if(server_started) |
616 |
{ |
617 |
//FLsPublic_Event(EV_DISCONNECT, &Player ); |
618 |
MultiplayerStatus.PleaseUpdateAllPlayers = 1; |
619 |
} |
620 |
//Kill off the character in another function, please |
621 |
//ONrCharacter_SetHitPoints( PlayerList[Player]->Chr, 0); |
622 |
|
623 |
memset(PlayerList[Player], 0, sizeof(player_info)); |
624 |
PlayerList[Player] = 0; |
625 |
|
626 |
|
627 |
|
628 |
return; |
629 |
} |
630 |
|
631 |
void FLrPlayerRespawn( int Player ) |
632 |
{ |
633 |
PlayerList[Player]->state = STATE_ALIVE; |
634 |
ONrCorpse_Create(PlayerList[Player]->Chr); |
635 |
ONrCharacter_SetHitPoints( PlayerList[Player]->Chr, PlayerList[Player]->Chr->MaxHealth ); |
636 |
} |
637 |
|
638 |
|
639 |
void* ScoreboardInstance = 0; |
640 |
void FLrRun_Scores() |
641 |
{ |
642 |
if(client_connected || server_started) |
643 |
{ |
644 |
if(!ScoreboardInstance){ |
645 |
void* TSFFTahoma; |
646 |
TMrInstance_GetDataPtr( 'TSFF', "Tahoma", &TSFFTahoma); |
647 |
TSrContext_New( TSFFTahoma, 7, 1, 1, 0, &ScoreboardInstance); |
648 |
} |
649 |
if(ScoreboardInstance){ |
650 |
const int white = 0x00FFFFFF; |
651 |
const int green = 0x0000FF00; |
652 |
const int red = 0x00FF0000; |
653 |
int i; |
654 |
char DrawString[255]; |
655 |
const int LineHeight = 15; |
656 |
IMtPoint2D DrawLocation = {20, 20}; |
657 |
TSrContext_SetShade(ScoreboardInstance, white); |
658 |
TSrContext_DrawText(ScoreboardInstance, "Oni Flatline build " __DATE__ " " __TIME__, 255, 0, &DrawLocation); |
659 |
DrawLocation.y += LineHeight; |
660 |
TSrContext_DrawText(ScoreboardInstance, "Name", 255, 0, &DrawLocation); |
661 |
DrawLocation.x += 150; |
662 |
TSrContext_DrawText(ScoreboardInstance, "Score", 255, 0, &DrawLocation); |
663 |
DrawLocation.x += 50; |
664 |
TSrContext_DrawText(ScoreboardInstance, "Ping", 255, 0, &DrawLocation); |
665 |
for(i = 0; i <MAX_PLAYERS; i++) |
666 |
{ |
667 |
if(PlayerList[i] == 0 || PlayerList[i]->Chr == 0) continue; |
668 |
|
669 |
DrawLocation.x = 20; |
670 |
DrawLocation.y += LineHeight; |
671 |
|
672 |
if(PlayerList[i]->Chr && PlayerList[i]->Chr->Health == 0) |
673 |
{ |
674 |
TSrContext_SetShade(ScoreboardInstance, red); |
675 |
} |
676 |
else if (i == client_slot) |
677 |
{ |
678 |
TSrContext_SetShade(ScoreboardInstance, green); |
679 |
} |
680 |
TSrContext_DrawText(ScoreboardInstance, PlayerList[i]->name, 255, 0, &DrawLocation); |
681 |
TSrContext_SetShade(ScoreboardInstance, white); |
682 |
DrawLocation.x += 150; |
683 |
sprintf(DrawString, "%i", PlayerList[i]->Chr->Damage); |
684 |
TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation); |
685 |
DrawLocation.x += 50; |
686 |
sprintf(DrawString, "%i", PlayerList[i]->Ping); |
687 |
TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation); |
688 |
} |
689 |
} |
690 |
} |
691 |
} |
692 |
|
693 |
bool FlatlineInitialize() |
694 |
{ |
695 |
|
696 |
memset( Players, 0, sizeof( player_info ) * MAX_PLAYERS ); |
697 |
memset( PlayerList, 0, 4 * MAX_PLAYERS ); |
698 |
memset( &MultiplayerStatus, 0, sizeof( multiplayer_status )); |
699 |
return 1; |
700 |
} |