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