source: Daodan/src/flatline/Flatline.c@ 878

Last change on this file since 878 was 878, checked in by alloc, 12 years ago

Daodan: Flatline fix

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