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

Last change on this file since 954 was 881, checked in by alloc, 11 years ago

Daodan: Some flatline cleanups

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