source: Daodan/MSVC/Flatline.c@ 579

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