source: Daodan/MSVC/Flatline.c @ 579

Last change on this file since 579 was 579, checked in by gumby, 12 years ago

Finally back up to pre data loss standards

File size: 28.4 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 <sys/time.h>
7#include <time.h>
8uint32_t last1 = 0; uint32_t last2 = 0;
9player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
10player_info * PlayerList[MAX_CONNECTIONS] = {0};
11const char * Rejection_Messages[][255] = {
12        {"Server is full"},
13        {"-2"},
14        {"-3"},
15        {"-4"},
16        {"-5"},
17};
18
19#define BETTER_SYNC
20
21void DoRareSync( short Player, sockaddr_in * sender )
22{
23        flatline_packet sync = {0};     
24
25        if (Player > max_connections || !PlayerList[ Player ] ) return;
26       
27                       
28//      DDrConsole_PrintF( "Sending sync data for player %i, new index %u", Player, PlayerList[ Player ]->rare_sync_index);
29        sender->sin_addr.S_un.S_addr = htonl(sender->sin_addr.S_un.S_addr);
30        sync.id = RARE_SYNC_DATA;
31        sprintf( sync.rare_sync_data.Class, TMrInstance_GetInstanceName( PlayerList[ Player ]->Chr->ONCC ) );
32        //using ->Inventory instead of ->Chr->Inventory to keep the index and Inventory in sync, just in case.
33        memcpy( &(sync.rare_sync_data.Inventory), &(PlayerList[ Player ]->Inventory), sizeof(Inventory) );
34        //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
35        sync.rare_sync_data.Inventory.Weapons[0] = NULL;
36        sync.rare_sync_data.Inventory.Weapons[1] = NULL;
37        sync.rare_sync_data.Inventory.Weapons[2] = NULL;
38        sync.rare_sync_data.PlayerNum = Player;
39        sync.rare_sync_data.index = PlayerList[ Player ]->rare_sync_index;
40        NetTCPServer_Send( sender, (char*)&sync, sizeof(rare_sync_data) + FLATLINE_HEADER );
41}
42
43bool FLrServer_PacketCallback(char* data, int datalen, int from)
44{
45        int i, j;
46        bool found_player = 0;
47        flatline_packet * packet = (flatline_packet*)data;
48        static int recieved = 0;
49        sockaddr_in sender;
50        sender.sin_family = AF_INET;
51        sender.sin_port = htons(27777);
52        sender.sin_addr = *((struct in_addr*)(int*)&from);
53       
54
55        //packet->data[datalen] = '\0';
56       
57        //DDrConsole_PrintF("Packet \r%d recieved from %i",  ++recieved, from);
58
59       
60       
61        //if data[0] != CONNECT_SEND, search in playerlist for ip address
62       
63
64
65       
66        switch(packet->id) {
67                flatline_packet connect_recv;
68                player_info * playah;
69                //rewrite this when we get TCP support.
70                //rewrite this before we get TCP support*
71                //the way of seeing if there is room for players sucks.
72                case CONNECT_SEND:
73                        ;
74                       
75                        connect_recv.id = CONNECT_REPLY;
76               
77                        //if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
78                        sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
79                        playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
80                        DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
81                        if(!((int)playah > -5 && (int)playah <= 0)) {
82                                flatline_packet new_char = {0};
83                                CharacterObject* Char;
84                                connect_recv.connect_reply.goodtogo = 1;
85                                connect_recv.connect_reply.player_slot = playah->list_slot;
86                                DDrConsole_PrintF("Slot: %i", playah->list_slot);
87
88                                //sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
89                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
90                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
91                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
92                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
93                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
94                                Sleep(100);
95
96                                new_char.id = NEW_PLAYER;
97                                Char = &new_char.new_player.Character;
98                                memset(Char, 0, sizeof(CharacterObject));
99                                Char->Header.Type = 'CHAR';
100                                Char->OSD.Options = chr_dontaim;
101                                for(j = 0; j < max_connections; j++) {
102                                        if(PlayerList[j] != 0) {
103                                                new_char.new_player.Playernumber = j;
104                                                sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
105
106                                                sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
107                                                DDrConsole_PrintF("Class %s", Char->OSD.Class );
108
109                                                sprintf(Char->OSD.Class, "konoko_generic");
110                                                NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
111                                        }
112
113                                }
114                        }
115                        else {
116                                //fix the error messages...
117                                DDrConsole_PrintF("Server is full. :(");
118                                connect_recv.connect_reply.goodtogo = 0;
119                                sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
120                                memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
121                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));   
122
123                        } 
124
125
126                        break;
127                case CONNECT_REPLY:
128                        break;  //do nothing...a server shouldn't recieve this type of packet.
129                case MESSAGE:
130                        for(i = 0; i < MAX_PLAYERS; i++) {
131                                //DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
132                                if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
133                                        found_player = 1;
134                                        break;
135                                }       
136                        }
137                        if(found_player == 0) return true;
138                        else {
139                                char message_buffer[512] = {0};
140                                flatline_packet message;
141                                int message_size;
142                                data[datalen] = 0;
143
144                                DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
145                                sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
146                               
147                                message.id = MESSAGE;
148                                message_size = sprintf(message.data, "%s", message_buffer);
149                                COrMessage_Print(message_buffer, "chat", 0);
150                                UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
151                                break;
152                        }
153                case CHANGE_NAME:
154                        ; //wtf, needed or i get an error.
155                        DDrConsole_PrintF("Changing Name to: %s", packet->data);
156                        for(i = 0; i < MAX_PLAYERS; i++) {
157                                if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
158                                        found_player = 1;
159                                        break;
160                                }       
161                        }
162                        if(found_player == 0) return true;
163                        else {
164                                bool name_exists = 0;
165                                for(j = 0; j < MAX_PLAYERS; j++) {
166                                        if(!strcmp(packet->data, Players[j].name)) {
167                                                name_exists = 1;
168                                                break;
169                                        }
170                                }
171                                if(!name_exists) {
172                                        char message_buffer[1024];
173                                        sprintf(message_buffer,"%s changed their name to %s", Players[i].name, packet->data);
174                                        COrMessage_Print(message_buffer, "name_change", 0);
175                                        memcpy(Players[i].name, packet->data, 256);
176
177                                }
178                                break;
179                        }
180                case PLAYER_INPUT:
181                       
182                        for(i = 0; i < max_connections; i++) {
183                                if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
184                                        found_player = 1;
185                                        break;
186                                }       
187                        }
188                       
189                        if(found_player == 0) return true;
190                        else {
191                                input_struct * packet_input = &packet->input_struct;
192
193
194                                PlayerList[i]->Actions1 = packet_input->Actions1;
195                                PlayerList[i]->Actions2 = packet_input->Actions2;
196                                PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
197                                PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
198                                PlayerList[i]->LastInputTime = packet_input->Time;
199
200                                break;
201                        }
202                case RARE_SYNC_DATA_REQUEST:
203                        DoRareSync( packet->sync_request , &sender);
204                        break;
205                default:
206                        DDrConsole_PrintF("Warning, recieved badly formed packet!");
207                        break;
208        }
209        return true;
210}
211
212bool FLrServer_Run()
213{
214        // Get the local hostname
215        char szHostName[255];
216                struct hostent *host_entry;
217        gethostname(szHostName, 255);
218
219        host_entry=gethostbyname(szHostName);
220        DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
221        return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
222}
223
224short TRrAnimation_GetType(char* anim)
225{
226        return *(short*)(anim + 0x15A);
227}
228
229void ONrCharacter_SetAnimationInternal(Character* Char, ActiveCharacter* AChar,
230                                                                           short inFromState, short inNextAnimType, const void *TRAM)
231{
232        ONCC            *ONCC   = Char->ONCC;
233        void            *TRAC   = ONCC->TRAC;
234        short   index = Char->Number;
235        short animType;
236
237        if (TRAM == 0) return;
238       
239        animType = TRrAnimation_GetType(TRAM);
240       
241        AChar->Animation = TRAM;
242        AChar->Frame = 0;
243        AChar->AnimationFromState = inFromState;
244        AChar->AnimationType = animType;
245       
246        AChar->NextAnimationType= inNextAnimType;
247        AChar->AnimationToState = TRrAnimation_GetTo(TRAM);
248
249        return;
250}
251
252
253        RGBA green = {0, 0xFF, 0, 0};
254        RGBA red = {0, 0, 0xFF, 0};
255        RGBA grey = {0x80,0x80,0x80,0x80};
256       
257//FLrClient_Run
258//Looping function that waits for packets from the server.
259
260int client_slot = 0;
261bool FLrClient_Run(flatline_packet* packet)
262{
263
264        char data[1400];
265        uint16_t len;
266        int j;
267        int sent_bytes;
268        client_connected = 0;
269       
270
271        //starts the connection
272        DDrConsole_PrintF("Connecting to server %s on socket %i",  inet_ntoa(address.sin_addr), client_sock);
273        sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
274        if(sent_bytes == SOCKET_ERROR) {
275                NetCatchError();
276        }
277        //loops once per second waiting for a reply.
278        for(j = 0; j < CONNECTION_TIMEOUT; j++) {
279                while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){             
280                        packet = (flatline_packet*)data;
281                        if(packet->id == CONNECT_REPLY) {
282                                if(packet->connect_reply.goodtogo){
283                                        client_connected = 1;
284
285                                        client_slot = ((connect_reply*)packet->data)->player_slot;
286
287                                        PlayerList[client_slot] = Players+client_slot;
288                                        PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter;
289
290                                        DDrConsole_PrintColored("Connection successful!",0,green, grey);
291                                       
292                                        //disable local input.
293                                        DDrPatch_NOOP(0x004FA929, 5 + 6 + 5);
294                                       
295                                        //DDrConsole_PrintF("Slot %i",  ((connect_reply*)packet)->player_slot);
296                                        break;
297                                }
298                                else {
299                                        DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message);
300                                        return false;
301                                        break;
302                                }
303                        }
304                }
305                if(client_connected) break;
306                DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j);
307                Sleep(1000);
308        }
309        //the client timed out without recieving an error message.
310        if(!client_connected) {
311                DDrConsole_PrintColored("Connection timed out.",0,red, grey);
312                return false;
313        }
314        else
315        {
316                ActiveCharacter * Active;
317                flatline_packet packet;
318//#define SPAM_INPUT
319#ifdef SPAM_INPUT
320                struct timeval lasttime;
321                struct timeval thistime;
322                gettimeofday(&lasttime, 0);
323#endif
324                while(1) {
325#ifdef SPAM_INPUT
326                        gettimeofday(&thistime, 0);
327                       
328                        //DDrConsole_PrintF("%i.%i | %i.%i | %i.%i",lasttime.tv_sec, lasttime.tv_usec, thistime.tv_sec, thistime.tv_usec,
329                        //      thistime.tv_sec - lasttime.tv_sec, thistime.tv_usec - lasttime.tv_usec);
330                        //checks to see if enough time has passed since the last input update (by default once every 10ms)
331                        if( 
332                                ((thistime.tv_sec > lasttime.tv_sec) && ((thistime.tv_usec + 1000000 - lasttime.tv_usec ) > update_rate * 1000) )
333                                || ((thistime.tv_sec == lasttime.tv_sec) && ((thistime.tv_usec - lasttime.tv_usec ) > update_rate * 1000))
334                        ) {
335                               
336                                flatline_packet input_packet;
337                                lasttime.tv_usec = ++thistime.tv_usec; //in case recieving packets takes less than 1 ms.
338
339                                input_packet.id = PLAYER_INPUT;
340                               
341                                if( ((GameState*)(ONgGameState))->Input.Current.Actions1 != last1 || ((GameState*)(ONgGameState))->Input.Current.Actions2 != last2) {
342                                        last1 =((GameState*)(ONgGameState))->Input.Current.Actions1;
343                                        last2 =((GameState*)(ONgGameState))->Input.Current.Actions2;
344                                }
345
346                                ((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
347                                ((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
348                                ((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
349                                ((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
350                                sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);                       
351                                //if(sent_bytes == SOCKET_ERROR)        NetCatchError();
352                        }
353#endif
354                        if(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, &packet, &len)) {
355                                //packet = (flatline_packet*)data;
356                                //DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id);
357                                switch(packet.id) {
358                case MESSAGE:
359                        COrMessage_Print(packet.data, "chat", 0);
360                        break;
361                case CONNECT_SEND:
362                        ;if(1) {
363                                flatline_packet connect_recv;
364                                memcpy(&connect_recv.connect_reply.message,"This isn't a server!", sizeof("This isn't a server!"));
365                                NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!"));                   
366                        }
367                case CONNECT_REPLY:
368                        break; //extra packet or something.
369                case NEW_PLAYER:
370                        ;if(1) { //haxhaxhax
371                        CharacterObject* Char = &(packet.new_player.Character);
372                        uint32_t chr_index = 0;
373                        Character* PC;
374                        DDrConsole_PrintF("%i |  %i", packet.new_player.Playernumber ,client_slot);
375                        //Char->OSD.Options = 0;
376                        if(packet.new_player.Playernumber == client_slot) {
377                                PlayerList[packet.new_player.Playernumber] = &Players[0];
378                                PC = (ONgGameState->PlayerCharacter);
379                                Players[0].Chr = PC;
380
381                        }
382                        else {
383                                ONrGameState_NewCharacter(Char, NULL, NULL, &chr_index);
384                                ONgGameState->CharacterStorage[chr_index].charType = 0;
385                                PlayerList[packet.new_player.Playernumber] = &Players[chr_index];
386                                Players[chr_index].Chr = &(ONgGameState->CharacterStorage[chr_index]);
387                                Players[chr_index].Chr->Flags &= 0xFFBFFFFF;
388                                Players[chr_index].spawnnumber = chr_index;
389                                DDrConsole_PrintF("Spawning player %s, class %s, slot  %i", ((new_player*)(packet.data))->Character.OSD.Name, ((new_player*)(packet.data))->Character.OSD.Class,chr_index) ;
390                        }
391                        //Players[((new_player*)(packet.data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet.data))->Character), NULL, NULL, 0);
392                        break;
393                                }
394                case PLAYER_DATA:
395                        if(1) { //haxhaxhax
396                        player_data* pd = &packet.player_data;
397                        uint16_t i = pd->PlayerNum;
398                        GameInput * Active_Input;
399                        pd = (void*)packet.data;
400                       
401                        //DDrConsole_PrintF("Got data for Player %i, %x", i, PlayerList[i]);
402                        if (i > max_connections) break;
403                        if( !PlayerList[i] ) break;
404                        //PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
405
406                        PlayerList[i]->Actions1 = pd->Inputs.Actions1;
407                        PlayerList[i]->Actions2 = pd->Inputs.Actions2;
408                        PlayerList[i]->MouseDeltaX = pd->Inputs.MouseDeltaX;
409                        PlayerList[i]->MouseDeltaY = pd->Inputs.MouseDeltaY;
410                        memcpy( &(PlayerList[i]->player_data), pd, sizeof(player_data) );
411
412                        if( !server_started && pd->rare_sync_index > PlayerList[i]->rare_sync_index )
413                        {
414                                        int sent_bytes;
415                                        flatline_packet sync_request = {0};
416                                        sync_request.id = RARE_SYNC_DATA_REQUEST;
417                                        sync_request.sync_request = i;
418                                        DDrConsole_PrintF( "Requesting sync data for player %i, old index %u", i, PlayerList[i]->rare_sync_index);
419                                        sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&sync_request, FLATLINE_HEADER + sizeof(int) );
420                        }
421
422
423
424       
425                        break;
426                        }
427                case RARE_SYNC_DATA:
428                        if(1) {
429                        sl_arg hax[2];
430                        int dontuse;
431                        uint16_t i = packet.rare_sync_data.PlayerNum;
432                                               
433                        if (i > max_connections) break;
434                        if( !PlayerList[i] ) break;
435
436                        //WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
437                        packet.rare_sync_data.Inventory.Weapons[0] = NULL;
438                        packet.rare_sync_data.Inventory.Weapons[1] = NULL;
439                        packet.rare_sync_data.Inventory.Weapons[2] = NULL;
440//                      TMrInstance_GetDataPtr( 'ONCC', packet.rare_sync_data.Class, PlayerList[ i ]->Chr->ONCC );
441                       
442                        //add the target character
443                        hax[0].type = sl_int32;
444                        hax[0].value_int32 = PlayerList[ packet.rare_sync_data.PlayerNum ]->spawnnumber;
445
446                        //add the new class
447                        //fix this later so we cant buffer overflow :O
448                        hax[1].type = sl_str32;
449                        hax[1].value_str32 = packet.rare_sync_data.Class;
450                       
451                        //we are directly calling a bsl function instead of using the normal method for two reasons
452                        //1. it has all the checking built in
453                        iSetCharacterClass( 0, 2, hax, &dontuse, &dontuse, hax );
454                        //DDrConsole_PrintF( "Recieved sync data for player %i, class %s, old index %u, new index %u", i, packet.rare_sync_data.Class, PlayerList[i]->rare_sync_index, packet.rare_sync_data.index);
455                        memcpy( &(PlayerList[ i ]->Chr->Inventory), &(packet.rare_sync_data.Inventory), sizeof(Inventory ));
456
457                        PlayerList[i]->rare_sync_index = packet.rare_sync_data.index;
458                        }
459                        break;
460                case FLATLINE_EVENT:
461                        FLcEventHandler( packet.flatline_event.event_index, packet.flatline_event.intArray );
462                        break;
463                default:
464                        DDrConsole_PrintF("Warning, recieved badly formed packet!");
465                        break;
466                                }
467                        }
468                        else {
469                                Sleep(1);
470                        }
471                }
472        }
473        return true;
474}
475
476//wtf, this needs cleaned up...
477player_info *FLr_FindEmptySlot() {
478        int j;
479        for(j = 0; j < MAX_PLAYERS; j++) {
480                if (Players[j].ip == 0) {
481                        return &Players[j];
482                }
483        }
484        return 0;
485}
486
487extern uint16_t max_connections;
488uint16_t FLr_FindEmptyListSlot() {
489        int j;
490        for(j = 0; j < max_connections; j++) {
491                if (PlayerList[j] == 0) {
492                        return j;
493                }
494        }
495        return -1;
496}
497        typedef struct
498        {
499                uint16_t x;
500                uint16_t y;
501               
502        } IMtPoint2D;
503static flatline_packet cache_input = {0};
504extern void* TSrTest;
505void * ONICALL FLrInput_Update_Keys(void) 
506{
507        uint16_t i;
508
509        ActiveCharacter * Active_Player = ONgGameState->ActiveCharacters;
510        Active_Player->PhyContext->Rotation;
511        Active_Player->PhyContext->Position;
512        ONgGameState->PlayerCharacter->Position;
513
514        if(client_connected) 
515        {
516                int sent_bytes;
517                flatline_packet input_packet = {0};
518                input_packet.id = PLAYER_INPUT;
519                input_packet.input_struct.Time = ONgGameState->GameTime;
520                input_packet.input_struct.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
521                input_packet.input_struct.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
522                input_packet.input_struct.MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
523                input_packet.input_struct.MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
524               
525                sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
526               
527                //return ONgGameState;
528        }
529
530
531        if(!(server_started || client_connected)) return ONgGameState;
532
533        for(i = 0; i < max_connections; i++) {
534                ActiveCharacter * Active_Player;
535                Character* Player;
536                GameInput * Active_Input;
537                if(PlayerList[i] == 0) continue;
538               
539               
540                Player = PlayerList[i]->Chr;
541                if( Player->Health == 0) 
542                {
543                        int Actions;
544                        const short TicksToRespawn = 3 * 60;
545                        if(PlayerList[i]->state != STATE_DEAD)
546                        {
547                                PlayerList[i]->state = STATE_DEAD;
548                                PlayerList[i]->DeathTime = ONgGameState->GameTime;
549                                if(i == client_slot)
550                                {
551                                        ONrGameState_Timer_Start( "", TicksToRespawn  );
552                                }
553                        }
554
555                        if(server_started & i == 0)
556                        {
557                                Actions =  ONgGameState->Input.Current.Actions1;
558                        }
559                        else
560                        {
561                                Actions = PlayerList[i]->Actions1;
562                        }
563
564                        if(PlayerList[i]->flags & PF_SCRIPTEDAI)
565                        {
566                                FLrPlayerDisconnect( i );
567                        }
568                        else if(ONgGameState->GameTime - PlayerList[i]->DeathTime < TicksToRespawn )
569                        {
570                                continue;
571                        }
572                        else if(Actions & (Action_Punch | Action_Kick))
573                        {
574                                FLrPlayerRespawn( i );
575                        }
576                        continue;
577                               
578                       
579                }
580
581                Active_Player = ONrGetActiveCharacter( PlayerList[i]->Chr);
582               
583                if(Active_Player == 0) continue;
584                Active_Input = &(Active_Player->Input);
585                if(server_started) {
586                        player_data * data;
587                        flatline_packet data_out = {0};
588
589                       
590
591                        data_out.id = PLAYER_DATA;
592                        data = (void*)&(data_out.data);
593                        data->PlayerNum = i;
594                        data->Health = PlayerList[i]->Chr->Health;
595                        data->MaxHealth = PlayerList[i]->Chr->MaxHealth;
596                        data->Position = PlayerList[i]->Chr->Position;
597                        data->Facing = PlayerList[i]->Chr->Facing;
598                        data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
599                        data->Position = Active_Player->PhyContext->Position;
600                        memcpy(data->Animation, TMrInstance_GetInstanceName(Active_Player->Animation), 31);
601                        data->Frame = Active_Player->Frame;
602                       
603                        if(Active_Player->targetThrow)
604                        {
605                                data->throw_data.throwing = Players[Active_Player->throwing].list_slot;
606                                memcpy(data->throw_data.throwName, TMrInstance_GetInstanceName(Active_Player->targetThrow), 31);
607                                data->throw_data.throwFrame = ONrGetActiveCharacter(Active_Player->targetThrow)->Frame;
608                        }
609                       
610                       
611                        if( PlayerList[i]->OldClass != PlayerList[i]->Chr->ONCC || memcmp( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) ) )
612                        {
613                                PlayerList[i]->OldClass = PlayerList[i]->Chr->ONCC;
614                                memcpy( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) );
615                                PlayerList[i]->rare_sync_index++;
616
617                        }
618                       
619                        data->rare_sync_index = PlayerList[i]->rare_sync_index;
620                       
621
622                        if(i == 0) {
623                                data->Inputs.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
624                                data->Inputs.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
625                                data->Inputs.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
626                                data->Inputs.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
627                        }
628                        else{
629                                data->Inputs.Actions1 = PlayerList[i]->Actions1;
630                                data->Inputs.Actions2 = PlayerList[i]->Actions2;
631                                data->Inputs.MouseDeltaX = PlayerList[i]->MouseDeltaX;
632                                data->Inputs.MouseDeltaY = PlayerList[i]->MouseDeltaY;
633                        }
634                        memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
635                       
636                        UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
637                }
638               
639                if( (server_started && i !=0)  || (!server_started/* && i != client_slot*/) ) 
640                {
641                        Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
642                        Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
643                        Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
644                        Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
645                       
646                        Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
647                        Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
648                        Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
649                        Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
650                        Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
651                        Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
652
653
654                        if( !server_started && PlayerList[i]->player_data.Health != 0) {
655                                void* OldAnimation;
656                                void* Animation;
657                                player_data* pd = &PlayerList[i]->player_data;
658                                Player->Health = PlayerList[i]->player_data.Health;
659                                PlayerList[i]->Chr->MaxHealth = PlayerList[i]->player_data.MaxHealth;
660
661                                PlayerList[i]->Chr->Facing = PlayerList[i]->player_data.Facing;
662                                PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->player_data.DesiredFacing;
663
664                                PlayerList[i]->Actions1 = PlayerList[i]->player_data.Inputs.Actions1;
665                                PlayerList[i]->Actions2 = PlayerList[i]->player_data.Inputs.Actions2;
666                                PlayerList[i]->MouseDeltaX = PlayerList[i]->player_data.Inputs.MouseDeltaX;
667                                PlayerList[i]->MouseDeltaY = PlayerList[i]->player_data.Inputs.MouseDeltaY;
668                                Active_Player->PhyContext->Position = PlayerList[i]->player_data.Position;
669                                OldAnimation = Active_Player->Animation;
670                               
671                                if (!(Player->Flags & ONcCharacterFlag_BeingThrown) &&
672                                        (pd->Animation != 0))
673                                {
674                                        // get a pointer to the animation
675                                       
676                                                TMrInstance_GetDataPtr(
677                                                'TRAM',
678                                                pd->Animation,
679                                                &Animation);
680                                                if (Animation != OldAnimation)
681                                        {
682                                                short   num_frames;
683                                                bool    updateAnimation = true;
684
685                                                // if the character is dead, make sure this animation is appropriate for death
686                                /*
687                                                if (Player->Flags & ONcCharacterFlag_Dead)
688                                                {
689                                                        short   curToState = TRrAnimation_GetTo(Active_Player->Animation);
690                                                        short   newToState = TRrAnimation_GetTo(animation);
691
692                                                        // if we are currently heading towards fallen and the new animation would not
693                                                        // then this is a better animation to run when we are dead
694                                                        if ((ONrAnimState_IsFallen(curToState)) &&
695                                                                (!ONrAnimState_IsFallen(newToState)))
696                                                        {
697                                                                updateAnimation = false;
698                                                        }
699                                                }
700                                                */
701                                                if ((updateAnimation) && (Active_Player->Animation == Animation))
702                                                {
703                                                        int             oldFrame = Active_Player->Frame;
704                                                        int             newFrame = pd->Frame;
705
706                                                        if (abs(oldFrame - newFrame) < 2)
707                                                        {
708                                                                updateAnimation = false;
709                                                        }
710                                                }
711
712                                                if (updateAnimation)
713                                                {
714                                                        // set the characters animation
715                                        /*      ONrCharacter_SetAnimationInternal(Player,
716                                                                Active_Player,
717                                                                Active_Player->AnimationToState,
718                                                                0,
719                                                                Animation);
720                                                ONrCharacter_NewAnimationHook(Player, Active_Player);*/
721                                                //Player->Flags |= 0x00000010;
722                                                        ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(Animation), Animation, 0);
723                                                }
724
725                                                num_frames = TRrAnimation_GetDuration(Active_Player->Animation);
726
727                                                if (pd->Frame == num_frames)
728                                                {
729                                                        Active_Player->Frame = num_frames - 1;
730                                                        //Active_Player->Frame = 0;
731                                                }
732                                                else
733                                                {
734                                                        Active_Player->Frame = pd->Frame;
735                                                }
736                                        }
737                                }
738
739                                if (PlayerList[i]->player_data.throw_data.throwName[0] != 0)
740                                {
741                                        pd->throw_data.throwing = PlayerList[pd->throw_data.throwing]->spawnnumber;
742                                        if ((pd->throw_data.throwing != Active_Player->throwing) &&
743                                                (pd->throw_data.throwFrame < 10))
744                                        {
745                                                void    *throw_animation;
746                                                ActiveCharacter* Target;
747                                                // get the animation
748
749                                                TMrInstance_GetDataPtr(
750                                                        'TRAM',
751                                                        pd->throw_data.throwName,
752                                                        &throw_animation);
753                                                //if (error) return;
754
755                                                // set the throw target
756                                                Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[pd->throw_data.throwing];
757                                                Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
758                                                if ((Target->Animation != throw_animation) &&
759                                                        (OldAnimation != Animation) &&
760                                                        !(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
761                                                {
762                                                        // set the throw variables
763                                                        Active_Player->targetThrow      = throw_animation;
764                                                        Active_Player->throwing         = pd->throw_data.throwing;
765
766                                                        // run the throw
767                                                        ONrCharacter_NewAnimationHook(Player, Active_Player);
768                                                       
769                                                        if (Active_Player->ThrowTargetCharacter)
770                                                        {
771                                                                Target->Frame += 2;
772                                                                Target->thrownBy = Player->Number;
773                                                        }
774                                                }
775                                        }
776                                }
777
778                        }
779                }
780        }
781
782        return ONgGameState;
783}
784
785void FLrPlayerDisconnect( int Player )
786{
787        if(server_started)
788        {
789                //FLsPublic_Event(EV_DISCONNECT, &Player );
790        }
791        //Kill off the character in another function, please
792        //ONrCharacter_SetHitPoints(  PlayerList[Player]->Chr, 0);
793       
794        memset(PlayerList[Player], 0, sizeof(player_info));
795        PlayerList[Player] = 0;
796       
797
798
799        return;
800}
801
802void FLrPlayerRespawn( int Player )
803{
804        PlayerList[Player]->state = STATE_ALIVE;
805        ONrCorpse_Create(PlayerList[Player]->Chr);
806        ONrCharacter_SetHitPoints(  PlayerList[Player]->Chr, PlayerList[Player]->Chr->MaxHealth );
807}
808
809
810void* ScoreboardInstance = 0;
811void FLrRun_Scores()
812{
813        if(client_connected || server_started)
814        {
815                if(!ScoreboardInstance){
816                        void* TSFFTahoma;
817                        TMrInstance_GetDataPtr( 'TSFF', "Tahoma", &TSFFTahoma);
818                        TSrContext_New( TSFFTahoma, 7, 1, 1,  0, &ScoreboardInstance);
819                }
820                if(ScoreboardInstance){
821                        const int white =       0x00FFFFFF;
822                        const int green =       0x0000FF00;
823                        const int red =         0x00FF0000;
824                        int i;
825                        char DrawString[255];
826                        const int LineHeight = 15;
827                        IMtPoint2D DrawLocation = {20, 20};
828                        TSrContext_SetShade(ScoreboardInstance, white);
829                        TSrContext_DrawText(ScoreboardInstance, "Oni Flatline build " __DATE__ " " __TIME__, 255, 0, &DrawLocation);
830                        DrawLocation.y += LineHeight;
831                        TSrContext_DrawText(ScoreboardInstance, "Name", 255, 0, &DrawLocation);
832                        DrawLocation.x += 150;
833                        TSrContext_DrawText(ScoreboardInstance, "Score", 255, 0, &DrawLocation);
834                        for(i = 0; i <MAX_PLAYERS; i++)
835                        {
836                                if(PlayerList[i] == 0) continue;
837
838                                DrawLocation.x = 20;
839                                DrawLocation.y += LineHeight;
840                               
841                                if(PlayerList[i]->Chr->Health == 0) 
842                                {
843                                        TSrContext_SetShade(ScoreboardInstance, red);
844                                }
845                                else if (i == client_slot)
846                                {
847                                        TSrContext_SetShade(ScoreboardInstance, green);
848                                }
849                                TSrContext_DrawText(ScoreboardInstance, PlayerList[i]->Chr->Name, 255, 0, &DrawLocation);
850                                TSrContext_SetShade(ScoreboardInstance, white);
851                                DrawLocation.x += 150;
852                                sprintf(DrawString, "%i", PlayerList[i]->Chr->Damage);
853                                TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation);
854
855                        }
856                }
857        }
858}
Note: See TracBrowser for help on using the repository browser.