source: Daodan/MSVC/Flatline.c @ 585

Last change on this file since 585 was 585, checked in by gumby, 11 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.