source: Daodan/MSVC/Flatline.c@ 584

Last change on this file since 584 was 584, checked in by gumby, 14 years ago

Almost working rework

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