1 #include "servership.h"
2 #include "servergame.h"
3 #include "serverdata.h"
4 #include "serversound.h"
5 #include "netconfig.h"
6 #include "sizes.h"
7 
8 
ServerShip(struct Point Pos,struct Point Vel,struct Point Rot,int Type,float Size,float Mass,int playernum,char * playername,int bot)9 ServerShip::ServerShip(struct Point Pos, struct Point Vel, struct Point Rot, int Type, float Size, float Mass, int playernum, char *playername, int bot) : ServerObject(Pos, Vel, Rot, Type, Size, Mass, playernum) {
10   Bot=bot;
11   InitPlayer();
12   strcpy(PlayerName, playername);
13   if (!Bot) {
14     Connections[PlayerNum].Connected=1;
15     NumConnectedPlayers++;
16   }
17 
18   printf("Adding Player %d\n", PlayerNum);
19 }
20 
21 
~ServerShip()22 ServerShip::~ServerShip()
23 {
24   if (!Bot) {
25     NumConnectedPlayers--;
26     Connections[PlayerNum].Connected=0;
27   }
28 
29   printf("Deleting Player %d\n", PlayerNum);
30 }
31 
32 
InitPlayer()33 void ServerShip::InitPlayer()
34 {
35   int i;
36 
37   for (i=0; i<MAX_SOUNDS; i++) {
38     Sounds[PlayerNum][i].type=-1;
39   }
40 
41   CreateRandomPosition(&Position);
42 
43   InitMatrix(InvRotationMatrix);
44 
45   InitMatrix(RotationMatrix);
46 
47   Acceleration.x=0.0;
48   Acceleration.y=0.0;
49   Acceleration.z=0.0;
50 
51   xAcceleration=0.0;
52   yAcceleration=0.0;
53   if (Bot) {
54     zAcceleration=3.0*BotRatio;
55     NextBotFireTime=0;
56     BotShieldOnTime=0;
57     Shield=(int)(BotRatio*(float)StartShield);
58     Armor=(int)(BotRatio*(float)StartArmor);
59   } else {
60     zAcceleration=0.0;
61     Shield=StartShield;
62     Armor=StartArmor;
63   }
64   Warps=StartWarps;
65   WarpTime=0;
66   Nukes=StartNukes;
67 
68   Action.shield=0;
69   Action.shooting=0;
70 
71   ShakeTime=0;
72   ShotPos=1.0;
73   Score=0;
74 
75   if (ServerGameType==DEATHMATCH) {
76     Lives=-1;
77   } else {
78     Lives=StartLives;
79   }
80 
81   AliveTime=-1;
82 }
83 
84 
UpdateRotation()85 void ServerShip::UpdateRotation()
86 {
87   float Multiplier=RotationSpeed;
88 
89   if (WarpTime) {
90     return;
91   }
92 
93   if (Bot) {
94     Multiplier*=BotRatio;
95   }
96 
97   if (AliveTime==-1) {
98     xRotateMatrix(Multiplier*Rotation.x, RotationMatrix, 2);
99     yRotateMatrix(Multiplier*Rotation.y, RotationMatrix, 2);
100     zRotateMatrix(Multiplier*Rotation.z, RotationMatrix, 2);
101 
102     xRotateMatrix(-Multiplier*Rotation.x, InvRotationMatrix, 1);
103     yRotateMatrix(-Multiplier*Rotation.y, InvRotationMatrix, 1);
104     zRotateMatrix(-Multiplier*Rotation.z, InvRotationMatrix, 1);
105 
106     CalcAcceleration();
107   }
108 }
109 
110 
UpdateVelocity()111 void ServerShip::UpdateVelocity()
112 {
113   float Distance;
114 
115   if (WarpTime) {
116     return;
117   }
118 
119   if (AliveTime==-1) {
120     Velocity.x+=Acceleration.x;
121     Velocity.y+=Acceleration.y;
122     Velocity.z+=Acceleration.z;
123 
124     Velocity.x*=DecelerationConstant;
125     Velocity.y*=DecelerationConstant;
126     Velocity.z*=DecelerationConstant;
127   }
128 }
129 
130 
Accelerate(int type,float Accelerate)131 void ServerShip::Accelerate(int type, float Accelerate)
132 {
133   if (type==1) {
134     xAcceleration=Accelerate*AccelerationConstant;
135   } else if (type==2) {
136     yAcceleration=Accelerate*AccelerationConstant;
137   } else if (type==3) {
138     zAcceleration=Accelerate*AccelerationConstant;
139   }
140 
141   CalcAcceleration();
142 }
143 
144 
CalcAcceleration()145 void ServerShip::CalcAcceleration()
146 {
147   Acceleration.x=-0.001*xAcceleration*RotationMatrix[0][0];
148   Acceleration.y=-0.001*xAcceleration*RotationMatrix[0][1];
149   Acceleration.z=-0.001*xAcceleration*RotationMatrix[0][2];
150   Acceleration.x-=0.001*yAcceleration*RotationMatrix[1][0];
151   Acceleration.y-=0.001*yAcceleration*RotationMatrix[1][1];
152   Acceleration.z-=0.001*yAcceleration*RotationMatrix[1][2];
153   Acceleration.x-=0.001*zAcceleration*RotationMatrix[2][0];
154   Acceleration.y-=0.001*zAcceleration*RotationMatrix[2][1];
155   Acceleration.z-=0.001*zAcceleration*RotationMatrix[2][2];
156 }
157 
158 
die()159 void ServerShip::die()
160 {
161   AliveTime=250;
162   ShakeTime=0;
163   WarpTime=0;
164 
165   Position.x+=1.0*RotationMatrix[2][0];
166   Position.y+=1.0*RotationMatrix[2][1];
167   Position.z+=1.0*RotationMatrix[2][2];
168 
169   Velocity.x=0.0;
170   Velocity.y=0.0;
171   Velocity.z=0.0;
172 
173   Shield=0;
174   Action.shooting=0;
175   Action.shield=0;
176 }
177 
178 
live()179 void ServerShip::live()
180 {
181   AliveTime=-1;
182 
183   CreateRandomPosition(&Position);
184 
185   InitMatrix(InvRotationMatrix);
186   InitMatrix(RotationMatrix);
187 
188   Velocity.x=0.0;
189   Velocity.y=0.0;
190   Velocity.z=0.0;
191 
192   Acceleration.x=0.0;
193   Acceleration.y=0.0;
194   Acceleration.z=0.0;
195 
196   xAcceleration=0.0;
197   yAcceleration=0.0;
198   if (Bot) {
199     zAcceleration=3.0*BotRatio;
200     Shield=(int)(BotRatio*(float)StartShield);
201     Armor=(int)(BotRatio*(float)StartArmor);
202   } else {
203     zAcceleration=0.0;
204     Shield=StartShield;
205     Armor=StartArmor;
206   }
207 
208   Warps=StartWarps;
209   Nukes=StartNukes;
210 
211   Action.shooting=0;
212   Action.shield=0;
213 }
214 
215 
FireShot()216 void ServerShip::FireShot()
217 {
218   struct Point shotVelocity, shotPosition, shotRotation;
219   int i, j;
220 
221   if (AliveTime==-1) {
222     AddSound(PlayerNum, &Position, ShotSound);
223     shotVelocity.x=Velocity.x-ShotSpeed*RotationMatrix[2][0];
224     shotVelocity.y=Velocity.y-ShotSpeed*RotationMatrix[2][1];
225     shotVelocity.z=Velocity.z-ShotSpeed*RotationMatrix[2][2];
226 
227     shotPosition.x=Position.x+0.047*ShotPos*RotationMatrix[0][0]+
228                    0.022*RotationMatrix[1][0]-0.06*RotationMatrix[2][0];
229     shotPosition.y=Position.y+0.047*ShotPos*RotationMatrix[0][1]+
230                    0.022*RotationMatrix[1][1]-0.06*RotationMatrix[2][1];
231     shotPosition.z=Position.z+0.047*ShotPos*RotationMatrix[0][2]+
232                    0.022*RotationMatrix[1][2]-0.06*RotationMatrix[2][2];
233     ShotPos*=-1.0;
234 
235     shotRotation.x=0.0;
236     shotRotation.y=0.0;
237     shotRotation.z=0.0;
238 
239     for (i=0; i<MAX_OBJECTS; i++) {
240       if (ServerObjects[i]==NULL) {
241         ServerObjects[i]=new ServerObject(shotPosition, shotVelocity,
242                                           shotRotation, SHOT_TYPE, 0.01,
243                                           0.05, PlayerNum);
244         memcpy(ServerObjects[i]->RotationMatrix, InvRotationMatrix,
245                sizeof(float [3][3]));
246         break;
247       }
248     }
249   }
250 }
251 
252 
FireNuke()253 void ServerShip::FireNuke()
254 {
255   struct Point nukeVelocity, nukePosition, nukeRotation;
256   int i, j;
257 
258   if (AliveTime==-1 && !WarpTime && Nukes) {
259     AddSound(PlayerNum, &Position, FireNukeSound);
260     for (i=0; i<MAX_PLAYERS; i++) {
261       if (i!=PlayerNum) {
262         AddSound(i, &Position, NukeAlertSound);
263       }
264     }
265 
266     nukeVelocity.x=Velocity.x-NukeSpeed*RotationMatrix[2][0];
267     nukeVelocity.y=Velocity.y-NukeSpeed*RotationMatrix[2][1];
268     nukeVelocity.z=Velocity.z-NukeSpeed*RotationMatrix[2][2];
269 
270     nukePosition.x=Position.x-0.1*RotationMatrix[1][0]-0.06*RotationMatrix[2][0];
271     nukePosition.y=Position.y-0.1*RotationMatrix[1][1]-0.06*RotationMatrix[2][1];
272     nukePosition.z=Position.z-0.1*RotationMatrix[1][2]-0.06*RotationMatrix[2][2];
273 
274     nukeRotation.x=0.0;
275     nukeRotation.y=0.0;
276     nukeRotation.z=0.0;
277 
278     for (i=0; i<MAX_OBJECTS; i++) {
279       if (ServerObjects[i]==NULL) {
280         ServerObjects[i]=new ServerObject(nukePosition, nukeVelocity,
281                                           nukeRotation, NUKE_TYPE, 0.1,
282                                           0.05, PlayerNum);
283         memcpy(ServerObjects[i]->RotationMatrix, InvRotationMatrix,
284                sizeof(float [3][3]));
285         Nukes--;
286         break;
287       }
288     }
289   }
290 }
291 
292 
DoUpdates()293 void ServerShip::DoUpdates()
294 {
295   if (Bot) {
296     CalcBotRotation();
297 
298     NextBotFireTime++;
299     if (NextBotFireTime >= (int)((float)BotFireTime*(1.0/BotRatio))) {
300       NextBotFireTime=0;
301       FireShot();
302     }
303 
304     if (BotNukeOdds) {
305       if (!(rand()%BotNukeOdds)) {
306         FireNuke();
307       }
308     }
309 
310     if (BotShieldOnTime) {
311       BotShieldOnTime--;
312       if (!BotShieldOnTime) {
313         Action.shield=0;
314       }
315     }
316   }
317 
318   UpdatePosition();
319   UpdateRotation();
320   UpdateVelocity();
321 
322   if (WarpTime) {
323     WarpTime--;
324     if (!WarpTime) {
325       Velocity.x=0.0;
326       Velocity.y=0.0;
327       Velocity.z=0.0;
328     }
329   } else {
330     if (Action.shield && Shield && AliveTime==-1) {
331       Shield--;
332     }
333 
334     if (ShakeTime) {
335       ShakeTime--;
336     }
337 
338     if (Action.shooting) {
339       FireShot();
340       Action.shooting=0;
341     }
342   }
343 
344   if (AliveTime > 0) {
345     AliveTime--;
346     if (AliveTime==0) {
347       if (ServerGameType!=DEATHMATCH && !Bot) {
348         Lives--;
349         if (Lives) {
350           live();
351         }
352       } else {
353         live();
354       }
355     }
356   }
357 }
358 
359 
TakeDamage(int DamageAmount)360 int ServerShip::TakeDamage(int DamageAmount)
361 {
362   if (DamageAmount > 0) {
363     Armor-=DamageAmount;
364     if (Armor <= 0) {
365       Armor=0;
366       AddSoundAll(&Position, ShipHitSound);
367       CreateExplosion(PlayerNum, 1);
368       die();
369       return(1);
370     } else {
371       if (!Bot) {
372         AddSound(PlayerNum, &Position, CrunchSound);
373         ShakeTime+=30;
374         if (ShakeTime > 100) {
375           ShakeTime=100;
376         }
377       } else {
378         BotShieldOnTime=(int)(BotRatio*(float)BotShieldTime);
379         Action.shield=1;
380       }
381     }
382   }
383   return(0);
384 }
385 
386 
CalcBotRotation()387 void ServerShip::CalcBotRotation()
388 {
389   float Distance;
390   int Closest;
391   struct Point RelPosition;
392 
393   if ((Closest=FindClosestObject(&Distance))!=-1) {
394     if (Distance < 0.2) {
395       CalcShipRelPosition(ServerObjects[Closest], &RelPosition);
396 
397       if (RelPosition.x > 0.0) {
398         Rotation.y=-1.0;
399       } else {
400         Rotation.y=1.0;
401       }
402 
403       if (RelPosition.y > 0.0) {
404         Rotation.x=-1.0;
405       } else {
406         Rotation.x=1.0;
407       }
408       return;
409     }
410   }
411 
412   if ((Closest=FindClosestShip(&Distance))!=-1) {
413     CalcShipRelPosition(ServerShips[Closest], &RelPosition);
414 
415     if (RelPosition.x > 0.0) {
416       Rotation.y=1.0;
417     } else {
418       Rotation.y=-1.0;
419     }
420 
421     if (RelPosition.y > 0.0) {
422       Rotation.x=1.0;
423     } else {
424       Rotation.x=-1.0;
425     }
426 
427     if (Distance < 0.3) {
428       Rotation.x*=-1.0;
429       Rotation.y*=-1.0;
430     }
431   }
432 }
433 
434 
FindClosestShip(float * Distance)435 int ServerShip::FindClosestShip(float *Distance)
436 {
437   int i;
438   float tempDistance;
439   int ClosestShip=-1;
440 
441   for (i=0; i<MAX_PLAYERS; i++) {
442     if (ServerShips[i] && i!=PlayerNum) {
443       if (ServerShips[i]->AliveTime==-1) {
444         tempDistance=CalcDistance(&Position, &ServerShips[i]->Position);
445         if (ClosestShip==-1 || tempDistance < *Distance) {
446           ClosestShip=i;
447           *Distance=tempDistance-(ObjectSize+ServerShips[i]->ObjectSize);
448         }
449       }
450     }
451   }
452 
453   return(ClosestShip);
454 }
455 
456 
FindClosestObject(float * Distance)457 int ServerShip::FindClosestObject(float *Distance)
458 {
459   int i;
460   float tempDistance1, tempDistance2;
461   struct Point tempPosition1, tempPosition2;
462   int ClosestObject=-1;
463 
464   for (i=0; i<MAX_OBJECTS; i++) {
465     if (ServerObjects[i]) {
466       if (ServerObjects[i]->ObjectType==ASTEROID_TYPE) {
467         tempDistance1=CalcDistance(&Position, &ServerObjects[i]->Position)-(ObjectSize+ServerObjects[i]->ObjectSize);
468         tempPosition1.x=Position.x+Velocity.x/100.0;
469         tempPosition1.y=Position.y+Velocity.y/100.0;
470         tempPosition1.z=Position.z+Velocity.z/100.0;
471         tempPosition2.x=ServerObjects[i]->Position.x+ServerObjects[i]->Velocity.x/100.0;
472         tempPosition2.y=ServerObjects[i]->Position.y+ServerObjects[i]->Velocity.y/100.0;
473         tempPosition2.z=ServerObjects[i]->Position.z+ServerObjects[i]->Velocity.z/100.0;
474         tempDistance2=CalcDistance(&tempPosition1, &tempPosition2)-(ObjectSize+ServerObjects[i]->ObjectSize);
475         if (ClosestObject==-1 || (tempDistance1 > tempDistance2 && tempDistance1 < *Distance)) {
476           ClosestObject=i;
477           *Distance=tempDistance1;
478         }
479       }
480     }
481   }
482 
483   return(ClosestObject);
484 }
485 
486 
CalcShipRelPosition(ServerObject * obj,struct Point * relPosition)487 void ServerShip::CalcShipRelPosition(ServerObject *obj, struct Point *relPosition)
488 {
489   struct Point tmpPoint;
490 
491   tmpPoint.x=obj->Position.x-Position.x;
492   tmpPoint.y=obj->Position.y-Position.y;
493   tmpPoint.z=obj->Position.z-Position.z;
494 
495   if (tmpPoint.x > WorldWidth) {
496     tmpPoint.x-=WorldWidth*2.0;
497   }
498   if (tmpPoint.y > WorldWidth) {
499     tmpPoint.y-=WorldWidth*2.0;
500   }
501   if (tmpPoint.z > WorldWidth) {
502     tmpPoint.z-=WorldWidth*2.0;
503   }
504   if (tmpPoint.x < -WorldWidth) {
505     tmpPoint.x+=WorldWidth*2.0;
506   }
507   if (tmpPoint.y < -WorldWidth) {
508     tmpPoint.y+=WorldWidth*2.0;
509   }
510   if (tmpPoint.z < -WorldWidth) {
511     tmpPoint.z+=WorldWidth*2.0;
512   }
513 
514   relPosition->x=RotationMatrix[0][0]*tmpPoint.x+RotationMatrix[0][1]*tmpPoint.y+RotationMatrix[0][2]*tmpPoint.z;
515   relPosition->y=RotationMatrix[1][0]*tmpPoint.x+RotationMatrix[1][1]*tmpPoint.y+RotationMatrix[1][2]*tmpPoint.z;
516   relPosition->z=RotationMatrix[2][0]*tmpPoint.x+RotationMatrix[2][1]*tmpPoint.y+RotationMatrix[2][2]*tmpPoint.z;
517 }
518 
519 
IncreaseArmor(int ArmorAmount)520 void ServerShip::IncreaseArmor(int ArmorAmount)
521 {
522   Armor+=ArmorAmount;
523 
524   if (Armor > ServerMaxArmor) {
525     Armor=ServerMaxArmor;
526   }
527 }
528 
529 
IncreaseShield(int ShieldAmount)530 void ServerShip::IncreaseShield(int ShieldAmount)
531 {
532   Shield+=ShieldAmount;
533 
534   if (Shield > ServerMaxShield) {
535     Shield=ServerMaxShield;
536   }
537 }
538 
539 
DecreaseShield(int ShieldAmount)540 void ServerShip::DecreaseShield(int ShieldAmount)
541 {
542   Shield-=ShieldAmount;
543 
544   if (Shield < 0) {
545     Shield=0;
546   }
547 }
548 
549 
WarpShip()550 void ServerShip::WarpShip()
551 {
552   if (!WarpTime && Warps && AliveTime==-1) {
553     ShakeTime=0;
554     Warps--;
555     WarpTime=200;
556     Velocity.x=-0.2*RotationMatrix[2][0];
557     Velocity.y=-0.2*RotationMatrix[2][1];
558     Velocity.z=-0.2*RotationMatrix[2][2];
559   }
560 }
561