ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/Daodan/MSVC/Flatline.c
Revision: 587
Committed: Mon Feb 7 05:34:47 2011 UTC (14 years, 8 months ago) by gumby
Content type: text/x-csrc
File size: 16912 byte(s)
Log Message:

File Contents

# Content
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))
12 uint32_t last1 = 0; uint32_t last2 = 0;
13 player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
14 player_info * PlayerList[MAX_CONNECTIONS] = {0};
15 multiplayer_status MultiplayerStatus;
16 unsigned int lastPingTime;
17
18 const char * Rejection_Messages[][255] = {
19 {"Server is full"},
20 {"-2"},
21 {"-3"},
22 {"-4"},
23 {"-5"},
24 };
25
26 #define BETTER_SYNC
27
28
29 bool FLrServer_Run()
30 {
31 // Get the local hostname
32 char szHostName[255];
33 struct hostent *host_entry;
34 gethostname(szHostName, 255);
35
36 host_entry=gethostbyname(szHostName);
37 DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
38 return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
39 }
40
41 short TRrAnimation_GetType(char* anim)
42 {
43 return *(short*)(anim + 0x15A);
44 }
45
46 void ONrCharacter_SetAnimationInternal(Character* Char, ActiveCharacter* AChar,
47 short inFromState, short inNextAnimType, const void *TRAM)
48 {
49 ONCC *ONCC = Char->ONCC;
50 void *TRAC = ONCC->TRAC;
51 short index = Char->Number;
52 short animType;
53
54 if (TRAM == 0) return;
55
56 animType = TRrAnimation_GetType(TRAM);
57
58 AChar->Animation = TRAM;
59 AChar->Frame = 0;
60 AChar->AnimationFromState = inFromState;
61 AChar->AnimationType = animType;
62
63 AChar->NextAnimationType= inNextAnimType;
64 AChar->AnimationToState = TRrAnimation_GetTo(TRAM);
65
66 return;
67 }
68
69
70
71
72
73
74 //wtf, this needs cleaned up...
75 player_info *FLr_FindEmptySlot() {
76 int j;
77 for(j = 0; j < MAX_PLAYERS; j++) {
78 if (Players[j].ip == 0) {
79 return &Players[j];
80 }
81 }
82 return 0;
83 }
84
85 extern uint16_t max_connections;
86 uint16_t FLr_FindEmptyListSlot() {
87 int j;
88 for(j = 0; j < max_connections; j++) {
89 if (PlayerList[j] == 0) {
90 return j;
91 }
92 }
93 return -1;
94 }
95 typedef struct
96 {
97 uint16_t x;
98 uint16_t y;
99
100 } IMtPoint2D;
101 static flatline_packet cache_input = {0};
102
103
104 void * ONICALL FLrInput_Update_Keys(void)
105 {
106 uint32_t i;
107 flatline_packet all_input = {0};
108 int16_t InputIndex = 0;
109
110 if(client_connected)
111 {
112 int sent_bytes;
113 flatline_packet input_packet = {0};
114
115 FLrClient_GetPackets();
116
117 input_packet.id = PLAYER_INPUT;
118 // input_packet.input_struct.Time = ONgGameState->GameTime;
119 input_packet.input_struct.Actions1 = ONgGameState->Input.Current.Actions1;
120 input_packet.input_struct.Actions2 = ONgGameState->Input.Current.Actions2;
121 input_packet.input_struct.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
122 input_packet.input_struct.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
123 input_packet.input_struct.DesiredFacing = ONgGameState->PlayerCharacter->DesiredFacing;
124
125 sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
126
127 //return ONgGameState;
128 }
129
130
131 if(!(server_started || client_connected)) return ONgGameState;
132
133
134
135 for(i = 0; i < max_connections; i++) {
136 ActiveCharacter * Active_Player;
137 Character* Player;
138 GameInput * Active_Input;
139 if(PlayerList[i] == 0) continue;
140
141
142
143 Player = PlayerList[i]->Chr;
144 Active_Player = ONrGetActiveCharacter( PlayerList[i]->Chr);
145
146 if(!Player)
147 {
148 DDrConsole_Print("Warning, missing Character!");
149 continue;
150 }
151
152 if( server_started && i != 0 )
153 {
154 PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->FacingFromClient;
155 }
156
157
158
159 //Set the health properly first.
160 //Always overridden by the server because of the chance of random damage and such
161 if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Health) )
162 {
163 PlayerList[i]->Chr->MaxHealth = PlayerList[i]->Health.MaxHealth;
164 ONrCharacter_SetHitPoints( PlayerList[i]->Chr, PlayerList[i]->Health.Health);
165 //PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Health );
166 }
167
168 //If the player is dead
169 if( PlayerList[i]->Chr->Health == 0 )
170
171 {
172 const short TicksToRespawn = 3 * 60;
173
174 //Permanently kill off dumb AI
175 if(PlayerList[i]->flags & PF_SCRIPTEDAI)
176 {
177 FLrPlayerDisconnect( i );
178 continue;
179 }
180
181 //Just to know if we have started counting off the respawn
182 if(PlayerList[i]->state != STATE_DEAD)
183 {
184 PlayerList[i]->state = STATE_DEAD;
185 PlayerList[i]->DeathTime = ONgGameState->GameTime;
186 if(i == client_slot)
187 {
188 ONrGameState_Timer_Start( "", TicksToRespawn );
189 }
190
191 if(server_started)
192 {
193 FLsPublic_Event( EV_KILLED, &i );
194 }
195
196 }
197
198 //Server respawning
199 if(server_started)
200 {
201 int Actions;
202 if(i == 0)
203 {
204 Actions = ONgGameState->Input.Current.Actions1;
205 }
206 else
207 {
208 Actions = PlayerList[i]->InputFromClient.Actions1;
209 }
210
211 if(ONgGameState->GameTime - PlayerList[i]->DeathTime > TicksToRespawn &&
212 (Actions & (Action_Punch | Action_Kick)) )
213 {
214 FLrPlayerRespawn( i );
215
216 FLsPublic_Event( EV_RESPAWN, &i );
217 }
218 else
219 {
220 continue;
221 }
222 }
223 else //clients?!
224 {
225 continue;
226 }
227 }
228
229 PlayerList[i]->state = STATE_ALIVE;
230
231 if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Class ) )
232 {
233 if(PlayerList[i]->Class)
234 {
235 ONrCharacter_SetCharacterClass( PlayerList[i]->Chr, PlayerList[i]->Class );
236 }
237 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Class );
238 }
239
240 if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Facing ) )
241 {
242 PlayerList[i]->Chr->Facing = PlayerList[i]->Facings.Facing;
243 if(i != client_slot)
244 {
245 PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->Facings.DesiredFacing;
246 }
247 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Facing );
248 }
249
250 if(Active_Player == 0) continue;
251
252
253
254 // Active_Player->PlayingFilm.Flags = 1;
255
256 Active_Input = &(Active_Player->Input);
257
258
259 if( (server_started && i !=0) || !server_started )
260 {
261 Active_Input->Stop.Actions1 = ~PlayerList[i]->Input.Actions1 & Active_Input->Current.Actions1;
262 Active_Input->Stop.Actions2 = ~PlayerList[i]->Input.Actions2 & Active_Input->Current.Actions2;
263 Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Input.Actions1;
264 Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Input.Actions2;
265
266 Active_Input->Current.Actions1 = PlayerList[i]->Input.Actions1;
267 Active_Input->Current.Actions2 = PlayerList[i]->Input.Actions2;
268 Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
269 Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
270 if(client_connected && i == client_slot)
271 {
272 Active_Input->MouseDeltaX = ONgGameState->Input.MouseDeltaX;
273 Active_Input->MouseDeltaY = ONgGameState->Input.MouseDeltaY;
274 }
275 else
276 {
277 Active_Input->MouseDeltaX = PlayerList[i]->Input.MouseDeltaX;
278 Active_Input->MouseDeltaY = PlayerList[i]->Input.MouseDeltaY;
279 }
280 }
281
282 {
283 void* ConsoleAnimation = 0;
284 TMrInstance_GetDataPtr( 'TRAM', "KONOKOwatch_idle", &ConsoleAnimation);
285
286 if(!Active_Player->IsInAir && Active_Input->Current.Actions1 & (Action_Console | Action_PauseScreen)
287 && !(PlayerList[i]->Chr->Flags & ONcCharacterFlag_BeingThrown)
288 && Active_Player->ThrowTargetCharacter != -1)
289 {
290 if(ConsoleAnimation && ConsoleAnimation != Active_Player->Animation)
291 {
292 ONrCharacter_SetAnimationExternal(PlayerList[i]->Chr, Active_Player->AnimationFromState, ConsoleAnimation, 10);
293 Player->Flags |= 0x00200000;
294 Active_Player->ForcedAnimationFrames = -1;// TRrAnimation_GetDuration(ConsoleAnimation);
295 }
296 }
297 else if(Active_Input->Stopped.Actions1 & (Action_Console | Action_PauseScreen) )
298 {
299 Active_Player->ForcedAnimationFrames = 0;
300 }
301
302 }
303
304 //Check for character switching requests
305 if(server_started && PlayerList[i]->Chr->Health != 0
306 && PlayerList[i]->InputFromClient.Actions1 & Action_Block)
307 {
308 if( PlayerList[i]->ShapeshiftCooldown < ONgGameState->GameTime)
309 {
310 int error;
311
312
313
314 ONCC *newClass;
315 short numClasses = (short)TMrInstance_GetTagCount('ONCC');
316 /*
317 if(Active_Player->Input.Start.Actions1 & Action_Block)
318 {
319 //This might not be getting hit. Find out why, eh?
320 PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 15;
321 }
322 else
323 {
324 PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 5;
325 }
326 */
327
328 PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 15;
329
330 if (PlayerList[i]->InputFromClient.Actions1 & Action_Crouch) {
331 Player->ONCCnumber += numClasses - 1;
332 }
333 else {
334 Player->ONCCnumber += 1;
335 }
336
337 if (numClasses > 0) {
338 Player->ONCCnumber = Player->ONCCnumber % numClasses;
339
340 error = TMrInstance_GetDataPtr_ByNumber('ONCC', Player->ONCCnumber, &newClass);
341
342 if ((newClass != NULL) && (!error)) {
343 ONrCharacter_SetCharacterClass(Player, newClass);
344 }
345 }
346
347 }
348 }
349 else
350 {
351 PlayerList[i]->ShapeshiftCooldown = 0;
352 }
353 if(client_connected) {
354
355 if( DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Position) )
356 {
357 //Active_Player->PhyContext->Position = PlayerList[i]->Position;
358
359 Active_Player->PhyContext->Position.X =
360 (PlayerList[i]->Position.X + Active_Player->PhyContext->Position.X) / 2;
361
362 Active_Player->PhyContext->Position.Y =
363 (PlayerList[i]->Position.Y + Active_Player->PhyContext->Position.Y) / 2;
364
365 Active_Player->PhyContext->Position.Z =
366 (PlayerList[i]->Position.Z + Active_Player->PhyContext->Position.Z) / 2;
367
368 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Position );
369 }
370
371
372
373
374 if (!(Player->Flags & ONcCharacterFlag_BeingThrown) &&
375 DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) && (PlayerList[i]->Animation))
376 {
377 // get a pointer to the animation
378
379
380 if (PlayerList[i]->Animation != Active_Player->Animation)
381 {
382
383 ///////////////////////////////////
384 //TODO: Check age of animation
385 ///////////////////////////////////
386 // set the characters animation
387 /*ONrCharacter_SetAnimationInternal(Player,
388 Active_Player,
389 Active_Player->AnimationToState,
390 0,
391 PlayerList[i]->Animation);*/
392 //ONrCharacter_NewAnimationHook(Player, Active_Player);
393 ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(PlayerList[i]->Animation), PlayerList[i]->Animation, 1);
394 //ONrCharacter_NewAnimationHook(Player, Active_Player);
395 }
396
397
398 }
399 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Animation );
400
401 //Disabled Frame syncing for now. In most cases it won't be useful.
402 if(0 && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_FramePing) && PlayerList[i]->Frame != -1
403 //&& !DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation)
404 )
405 {
406 if( abs(PlayerList[i]->Frame - Active_Player->Frame) > 2 )
407 {
408 short AnimationLength;
409 AnimationLength = TRrAnimation_GetDuration(Active_Player->Animation);
410 if (PlayerList[i]->Frame >= AnimationLength)
411 {
412 Active_Player->Frame = AnimationLength - 1;
413 //Active_Player->Frame = 0;
414 }
415 else
416 {
417 Active_Player->Frame = PlayerList[i]->Frame;
418 }
419 }
420
421 }
422 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_FramePing );
423
424 //Increment frame in case we were waiting
425 PlayerList[i]->Frame++;
426
427 if (DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Throws)
428 && PlayerList[i]->ThrowData.throwName[0] != 0)
429 {
430 if(PlayerList[PlayerList[i]->ThrowData.throwing])
431 {
432 short throwTarget = PlayerList[PlayerList[i]->ThrowData.throwing]->spawnnumber;
433 /*if ((throwTarget != Active_Player->throwing) &&
434 (PlayerList[i]->ThrowData.throwFrame < 10))*/
435 {
436 void *throw_animation;
437 ActiveCharacter* Target;
438 // get the animation
439
440 TMrInstance_GetDataPtr(
441 'TRAM',
442 PlayerList[i]->ThrowData.throwName,
443 &throw_animation);
444 //if (error) return;
445
446 // set the throw target
447 Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[throwTarget];
448 Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
449 //if (/*(Target->Animation != throw_animation) &&*/
450 // (OldAnimation != Animation) &&
451 // !(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
452 // Target->thrownBy == -
453 {
454 // set the throw variables
455 Active_Player->targetThrow = throw_animation;
456 Active_Player->throwing = throwTarget;
457
458 // run the throw
459 ONrCharacter_NewAnimationHook(Player, Active_Player);
460
461 //if (Active_Player->ThrowTargetCharacter)
462 {
463 // Target->Frame += 2;
464 //DDrConsole_PrintF("Thrown by player %hi", Player->Number );
465 //DDrStartupMessage("Thrown by player %hi", Player->Number );
466 Target->thrownBy = Player->Number & 0x00ff;
467 }
468 }
469 }
470 }
471 else
472 {
473 DDrConsole_PrintF("Warning, tried to throw nonexistant player %hi",
474 PlayerList[i]->ThrowData.throwing );
475 }
476 }
477
478 //Always discard old throw data, even if it isnt applied
479 PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Throws );
480 }
481
482
483 }
484
485 if(server_started)
486 {
487 if(ONgGameState->GameTime % 120 == 0)
488 {
489 FLsPingAll();
490 }
491
492 if(PlayerList[0])
493 {
494 PlayerList[0]->InputFromClient.Actions1 = ONgGameState->Input.Current.Actions1;
495 PlayerList[0]->InputFromClient.Actions2 = ONgGameState->Input.Current.Actions2;
496 PlayerList[0]->InputFromClient.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
497 PlayerList[0]->InputFromClient.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
498 }
499 FLsSendPlayerData();
500 }
501 MultiplayerStatus.PleaseUpdateAllPlayers = 0;
502 return ONgGameState;
503 }
504
505 void FLrPlayerDisconnect( int Player )
506 {
507 if(server_started)
508 {
509 //FLsPublic_Event(EV_DISCONNECT, &Player );
510 MultiplayerStatus.PleaseUpdateAllPlayers = 1;
511 }
512 //Kill off the character in another function, please
513 //ONrCharacter_SetHitPoints( PlayerList[Player]->Chr, 0);
514
515 memset(PlayerList[Player], 0, sizeof(player_info));
516 PlayerList[Player] = 0;
517
518
519
520 return;
521 }
522
523 void FLrPlayerRespawn( int Player )
524 {
525 PlayerList[Player]->state = STATE_ALIVE;
526 ONrCorpse_Create(PlayerList[Player]->Chr);
527 ONrCharacter_SetHitPoints( PlayerList[Player]->Chr, PlayerList[Player]->Chr->MaxHealth );
528 }
529
530
531 void* ScoreboardInstance = 0;
532 void FLrRun_Scores()
533 {
534 if(client_connected || server_started)
535 {
536 if(!ScoreboardInstance){
537 void* TSFFTahoma;
538 TMrInstance_GetDataPtr( 'TSFF', "Tahoma", &TSFFTahoma);
539 TSrContext_New( TSFFTahoma, 7, 1, 1, 0, &ScoreboardInstance);
540 }
541 if(ScoreboardInstance){
542 const int white = 0x00FFFFFF;
543 const int green = 0x0000FF00;
544 const int red = 0x00FF0000;
545 const int blue = 0x000000FF;
546 int i;
547 char DrawString[255];
548 const int LineHeight = 15;
549 IMtPoint2D DrawLocation = {25, 20};
550 TSrContext_SetShade(ScoreboardInstance, white);
551 TSrContext_DrawText(ScoreboardInstance, "Oni Flatline build " __DATE__ " " __TIME__, 255, 0, &DrawLocation);
552 TSrContext_SetShade(ScoreboardInstance, white);
553 DrawLocation.y += LineHeight;
554 DrawLocation.x = 25;
555 TSrContext_DrawText(ScoreboardInstance, "Name", 255, 0, &DrawLocation);
556 DrawLocation.x += 150;
557 TSrContext_DrawText(ScoreboardInstance, "Score", 255, 0, &DrawLocation);
558 DrawLocation.x += 50;
559 TSrContext_DrawText(ScoreboardInstance, "Ping", 255, 0, &DrawLocation);
560 for(i = 0; i <MAX_PLAYERS; i++)
561 {
562 if(PlayerList[i] == 0 || PlayerList[i]->Chr == 0) continue;
563
564 DrawLocation.x = 10;
565 DrawLocation.y += LineHeight;
566
567 sprintf(DrawString, "%i.", i );
568 TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation);
569 DrawLocation.x += 15;
570
571 if(PlayerList[i]->Chr && PlayerList[i]->Chr->Health == 0)
572 {
573 TSrContext_SetShade(ScoreboardInstance, red);
574 }
575 else if (i == client_slot)
576 {
577 TSrContext_SetShade(ScoreboardInstance, green);
578 }
579 TSrContext_DrawText(ScoreboardInstance, PlayerList[i]->name, 255, 0, &DrawLocation);
580 TSrContext_SetShade(ScoreboardInstance, white);
581 DrawLocation.x += 150;
582 sprintf(DrawString, "%i", PlayerList[i]->Chr->Damage);
583 TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation);
584 DrawLocation.x += 50;
585 sprintf(DrawString, "%i", PlayerList[i]->Ping);
586 TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation);
587 }
588 }
589 }
590 }
591
592 bool FlatlineInitialize()
593 {
594 memset( Players, 0, sizeof( player_info ) * MAX_PLAYERS );
595 memset( PlayerList, 0, 4 * MAX_PLAYERS );
596 memset( &MultiplayerStatus, 0, sizeof( multiplayer_status ));
597 return 1;
598 }