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