source: Daodan/MSVC/Flatline.c@ 585

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

Getting there. Throws still rarely crash and classes aren't synced.

File size: 19.9 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 "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))
12uint32_t last1 = 0; uint32_t last2 = 0;
13player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
14player_info * PlayerList[MAX_CONNECTIONS] = {0};
15multiplayer_status MultiplayerStatus;
16unsigned int lastPingTime;
17
18const char * Rejection_Messages[][255] = {
19 {"Server is full"},
20 {"-2"},
21 {"-3"},
22 {"-4"},
23 {"-5"},
24};
25
26#define BETTER_SYNC
27
28bool 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
208bool 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
220short TRrAnimation_GetType(char* anim)
221{
222 return *(short*)(anim + 0x15A);
223}
224
225void 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...
254player_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
264extern uint16_t max_connections;
265uint16_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}
274typedef struct
275{
276 uint16_t x;
277 uint16_t y;
278
279} IMtPoint2D;
280static flatline_packet cache_input = {0};
281
282
283void * 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
613void 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
631void 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
639void* ScoreboardInstance = 0;
640void 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
693bool 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}
Note: See TracBrowser for help on using the repository browser.