-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlayer.java
More file actions
548 lines (504 loc) · 19.8 KB
/
Player.java
File metadata and controls
548 lines (504 loc) · 19.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
import java.net.*;
import java.util.*;
import java.awt.geom.*;
import java.io.*;
import java.awt.*;
import java.awt.geom.*;
/*
* Player class that handles player thread, attributes, and any player-server messages
*/
public class Player extends GameObject implements Runnable {
private int x;
private int y;
// x and y are player center
private String name;
private Team team; // 0 -> Red Team | 1 -> Blue Team
private int playerId;
private Agent agent;
private boolean ready;
private boolean loaded;
private Gun primaryGun;
private Gun secondaryGun;
private int holdingSlot; // 1 -> primary gun | 2 -> secondary gun
private int health;
private int shield;
private boolean alive;
private int numCredits;
private boolean hasBomb;
private boolean moving;
private boolean firing;
private int moveDirection;
private double movementSpeed;
private final double defaultMovementSpeed;
private int direction; // degrees
private Room room;
private int radius;
private Server server;
private Socket socket;
private PrintWriter output;
private BufferedReader input;
private GameState state;
private Queue<String> messages;
Player(int playerId, Socket socket, Server server) throws IOException {
this.playerId = playerId;
this.loaded = false;
this.server = server;
this.socket = socket;
this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.output = new PrintWriter(socket.getOutputStream());
this.health = Const.STARTING_HEALTH;
this.shield = Const.STARTING_SHIELD;
this.holdingSlot = 2;
this.moving = false;
this.firing = false;
this.moveDirection = 0;
this.defaultMovementSpeed = Const.PLAYER_MOVEMENT_SPEED;
this.movementSpeed = this.defaultMovementSpeed;
this.radius = Const.PLAYER_RADIUS;
this.state = this.server.state;
this.messages = new LinkedList<String>();
}
public int getX() {
return x;
}
public void setX(double x) {
this.x = (int)x;
}
public int getY() {
return y;
}
public void setY(double y) {
this.y = (int)y;
}
public Ellipse2D.Double getCircleHitbox() {
return new Ellipse2D.Double(this.x - Const.PLAYER_RADIUS, this.y - Const.PLAYER_RADIUS, Const.PLAYER_RADIUS * 2, Const.PLAYER_RADIUS * 2);
}
public void run() {
try {
while (true) {
String msg = input.readLine();
if (msg.length() > 0) {
this.messages.add(msg);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Update Player and read Client inputs
public void update() throws InterruptedException{
while(!messages.isEmpty()){
if(messages.peek() != null){
String[] msg = messages.poll().split(" ");
String command = msg[0];
String[] args = Arrays.copyOfRange(msg, 1, msg.length);
switch(state.name()){
case "PREGAME":
switch(command){
case "NAME": this.name(args); break;
case "TEAM": this.team(args); break;
case "AGENT": this.agent(args); break;
case "READY": this.ready(); break;
}
case "LOADING":
switch(command){
case "LOADED": this.loaded(); break;
}
case "INGAME":
switch(command){
case "SWAP": if(this.alive) this.swap(args); break;
case "AIM": if(this.alive) this.aim(args); break;
case "MOVE": if(this.alive) this.move(args); break;
case "FIRE": if(this.alive) this.fire(args); break;
case "UTIL": if(this.alive) this.util(args); break;
case "RELOAD": if(this.alive) this.reload(); break;
case "BOMB": if(this.alive) this.bomb(); break;
}
case "BUYMENU":
switch(command){
case "BUY": this.buy(args); break;
}
}
} else {messages.poll();}
}
// Movement and Firing toggles
if(this.moving){
this.move(new String[]{this.moveDirection + ""});
}
if(this.firing){
int[] bullet = this.getHolding().fire();
if(bullet[0] == 1){
int bulletDirection = bullet[1] + this.getDirection();
this.server.shoot(new BulletTracer(this.getX(), this.getY(), bulletDirection, GunModel.valueOf(this.getHolding().getModel()).getDamage(), this.team), this);
}
}
try{
Thread.sleep(10);
} catch (InterruptedException e){ e.printStackTrace(); }
}
// Print information to Client
public void print(String text) {
if (this.socket == null) {
System.out.println("Dead socket, message send failure");
return;
}
this.output.println(text);
System.out.println(text);
this.output.flush();
}
public void printInformation(){
this.server.printTeam("NAME " + this.getPlayerId() + " " + this.getName(), this.team);
if(this.getAgent() != null){
this.server.printTeam("AGENT " + this.getPlayerId() + " " + this.getAgent().toString(), this.team);
}
if(this.getReady()){
this.server.printTeam("READY " + this.getPlayerId(), this.team);
}
}
public boolean collides(Obstacle obstacle) {
return this.getCircleHitbox().intersects(obstacle.getHitbox());
}
public void resetMovementSpeed() {
this.movementSpeed = defaultMovementSpeed;
}
// ------------------------------------------------------------------------------------------------
// Client to server commands
private void name(String[] args) {
if(!this.ready){
String playerName = "";
for(String name: args){
playerName = playerName+name;
}
this.name = playerName;
this.server.printAll("NAME " + this.getPlayerId() + " " + playerName);
}
}
private void team(String[] args){
if(!this.ready){
int teamId = Integer.parseInt(args[0]);
switch(teamId){
case 0:
if(this.server.redTeam.addPlayer(this)){
this.setTeam(this.server.redTeam);
this.print("JOINED");
this.server.printAll("TEAM " + this.server.redTeam.getTeamSize() + " " + this.server.blueTeam.getTeamSize());
for(Player player: this.server.redTeam.getTeam()){
if(player != this) player.printInformation();
}
} else { System.out.println("team full"); }
break;
case 1:
if(this.server.blueTeam.addPlayer(this)){
this.setTeam(this.server.blueTeam);
this.print("JOINED");
this.server.printAll("TEAM " + server.redTeam.getTeamSize() + " " + server.blueTeam.getTeamSize());
for(Player player: this.server.blueTeam.getTeam()){
if(player != this) player.printInformation();
}
} else { System.out.println("team full"); }
break;
}
this.server.printAll("PLAYER_TEAM " + this.getPlayerId() + " " + this.getTeam());
}
}
private void agent(String[] args){
if(!this.ready){
String agentName = args[0];
this.setAgent(agentName);
this.server.printTeam("AGENT " + this.getPlayerId() + " " + agentName, this.team);
}
}
private void ready(){
if(this.agent != null && this.team != null && this.team.addAgent(this.agent)){
this.setReady();
this.server.printAll("READY " + this.getPlayerId());
}
}
private void loaded(){
this.setLoaded();
}
private void swap(String[] args){
int slot = Integer.parseInt(args[0]);
if(slot != this.holdingSlot){
switch(slot){
case Const.PRIMARY_SLOT:
if(this.primaryGun != null){
this.setHoldingSlot(Const.PRIMARY_SLOT);
this.getHolding().takeOut();
this.getHolding().setActive(true);
this.secondaryGun.setActive(false);
this.server.printAll("PLAYER_GUN " + this.getPlayerId() + " " + this.primaryGun.getModel());
} break;
case Const.SECONDARY_SLOT:
this.setHoldingSlot(Const.SECONDARY_SLOT);
this.getHolding().takeOut();
this.getHolding().setActive(true);
this.primaryGun.setActive(false);
this.server.printAll("PLAYER_GUN " + this.getPlayerId() + " " + this.secondaryGun.getModel());
break;
}
}
}
private void aim(String[] args){
int angle = Integer.parseInt(args[0]);
this.direction = angle;
this.server.printAll("PLAYER_TURN " + this.getPlayerId() + " " + this.direction);
}
private void move(String[] args) throws InterruptedException{
this.moveDirection = Integer.parseInt(args[0]);
switch(this.moveDirection){
case 0: // not moving
this.moving = false;
break;
case 1: // up
this.moving = true;
this.setY(this.y - this.movementSpeed); break;
case 2: // down
this.moving = true;
this.setY(this.y + this.movementSpeed); break;
case 3: // left
this.moving = true;
this.setX(this.x - this.movementSpeed); break;
case 4: // right
this.moving = true;
this.setX(this.x + this.movementSpeed); break;
case 5: // up-right
this.moving = true;
this.setX(this.x + (this.movementSpeed / Math.sqrt(2)));
this.setY(this.y - (this.movementSpeed / Math.sqrt(2))); break;
case 6: // up-left
this.moving = true;
this.setX(this.x - (this.movementSpeed / Math.sqrt(2)));
this.setY(this.y - (this.movementSpeed / Math.sqrt(2))); break;
case 7: // down-left
this.moving = true;
this.setX(this.x - (this.movementSpeed / Math.sqrt(2)));
this.setY(this.y + (this.movementSpeed / Math.sqrt(2))); break;
case 8: // down-right
this.moving = true;
this.setX(this.x + (this.movementSpeed / Math.sqrt(2)));
this.setY(this.y + (this.movementSpeed / Math.sqrt(2))); break;
}
if(this.moveDirection != 0){
if((this.x - this.radius) < 0) { this.setX(this.radius); }
if((this.y - this.radius) < 0) { this.setY(this.radius); }
if((this.x + this.radius) > this.getRoom().getWidth()) { this.setX(this.getRoom().getWidth() - this.radius); }
if((this.y + this.radius) > this.getRoom().getHeight()){ this.setY(this.getRoom().getHeight() - this.radius); }
// Check for Obstacle collision
for(Obstacle obstacle: this.room.getObstacles()){
if(this.collides(obstacle)){
Rectangle2D collision = this.getHitBox().createIntersection(obstacle.getHitbox());
switch(this.moveDirection){
case 1: // up
this.setY(obstacle.getDoubleY() + obstacle.getHeight() + this.radius); break;
case 2: // down
this.setY(obstacle.getDoubleY() + this.radius); break;
case 3: // left
this.setX(obstacle.getDoubleX() + obstacle.getWidth() + this.radius); break;
case 4: // right
this.setX(obstacle.getDoubleX() + this.getWidth()); break;
case 5:
if(collision.getWidth() >= collision.getHeight()){
this.setY(obstacle.getDoubleY() + obstacle.getHeight() + this.radius); // up
} else {
this.setX(obstacle.getDoubleX() + this.getWidth()); // right
} break;
case 6:
if(collision.getWidth() >= collision.getHeight()){
this.setY(obstacle.getDoubleY() + obstacle.getHeight() + this.radius); // up
} else {
this.setX(obstacle.getDoubleX() + obstacle.getWidth() + this.radius); // left
} break;
case 7:
if(collision.getWidth() >= collision.getHeight()){
this.setY(obstacle.getDoubleY() + this.radius); // down
} else {
this.setX(obstacle.getDoubleX() + obstacle.getWidth() + this.radius); // left
} break;
case 8:
if(collision.getWidth() >= collision.getHeight()){
this.setY(obstacle.getDoubleY() + this.radius); // down
} else {
this.setX(obstacle.getDoubleX() + this.getWidth()); // right
} break;
}
}
}
// Check for Door entry
for(Door door: this.room.getDoors()){
if(this.getCircleHitbox().intersects(door.getHitBox()) && door.cooldown.finished()){
this.room.removePlayer(this);
this.setRoom(door.getExit().getThisRoom());
this.room.addPlayer(this);
this.setX(door.getExit().thisExitLocation()[0]);
this.setY(door.getExit().thisExitLocation()[1]);
door.getExit().exit();
this.server.printAll("PLAYER_ROOM " + this.getPlayerId() + " " + this.getRoom().getId());
break;
}
}
this.server.printAll("PLAYER_LOCATION " + this.getPlayerId() + " " + this.getX() + " " + this.getY());
}
Thread.sleep(10);
}
private void fire(String[] args){
int toggle = Integer.parseInt(args[0]); // shooting press and release
int[] bullet;
if(this.getHolding().model.getSemiAuto()) {
this.firing = (toggle == 1);
} else if(toggle == 1){
bullet = this.getHolding().fire();
if(bullet[0] == 1){
int bulletDirection = bullet[1] + this.getDirection();
this.server.shoot(new BulletTracer(this.getX(), this.getY(), bulletDirection, GunModel.valueOf(this.getHolding().getModel()).getDamage(), this.team), this);
}
}
}
private void util(String[] args){ // Could not be implemented
}
private void reload(){
this.getHolding().reload();
}
private void bomb(){ // Could not be Implemented
}
public void buy(String[] args){
String gunName = args[0];
if(!gunName.equals("0")){
GunModel gun = GunModel.valueOf(gunName);
if(gun.getPrice() <= this.getCredits()){
this.setCredits(this.getCredits() - gun.getPrice());
this.print("CREDS " + this.getCredits());
if( gun.toString().equals("Robin") ||
gun.toString().equals("Duck") ||
gun.toString().equals("Finch") ||
gun.toString().equals("Hummingbird") ||
gun.toString().equals("Raven")){
this.setGun(Const.SECONDARY_SLOT, new Gun(gun.toString(), gun.getMaxAmmo()));
} else {
this.setGun(Const.PRIMARY_SLOT, new Gun(gun.toString(), gun.getMaxAmmo()));
}
this.server.printAll("PLAYER_GUN " + this.getPlayerId() + " " + this.getHolding().getModel());
this.print("PICKUP " + gun.name());
}
}
}
// ------------------------------------------------------------------------------------------------
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getTeam() {
if(team != null){
return this.team.getTeamNum();
}
return -1;
}
public void setTeam(Team team) {
this.team = team;
}
public int getPlayerId() {
return this.playerId;
}
public Agent getAgent() {
return this.agent;
}
public void setAgent(String agentName) {
this.agent = Agent.valueOf(agentName);
}
public int getCredits() {
return this.numCredits;
}
public void setCredits(int credits) {
this.numCredits = credits;
}
public boolean getAlive() {
return this.alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public Gun getPrimGun() {
return this.primaryGun;
}
public Gun getSecGun() {
return this.secondaryGun;
}
public void setGun(int slot, Gun gun) {
switch (slot) {
case Const.PRIMARY_SLOT:
this.primaryGun = gun;
break;
case Const.SECONDARY_SLOT:
this.secondaryGun = gun;
break;
}
}
public Gun getHolding() {
if (this.holdingSlot == Const.PRIMARY_SLOT)
return primaryGun;
if (this.holdingSlot == Const.SECONDARY_SLOT)
return secondaryGun;
else
return null;
}
public int getHoldingSlot(){
return this.holdingSlot;
}
public void setHoldingSlot(int gunSlot) {
this.holdingSlot = gunSlot;
}
public int getHealth() {
return this.health;
}
public void setHealth(int health) {
if(health < 0) {
this.health = 0;
} else {
this.health = health;
}
}
public int getShield(){
return this.shield;
}
public void setShield(int shield){
this.shield = shield;
}
public double getMovementSpeed() {
return this.movementSpeed;
}
public void setMovementSpeed(double newSpeed) {
this.movementSpeed = newSpeed;
}
public int getDirection() {
return this.direction;
}
public void setDirection(int degrees) {
this.direction = degrees % 360;
}
public boolean checkSpike() {
return this.hasBomb;
}
public void setSpike(boolean hasSpike) {
this.hasBomb = hasSpike;
}
public boolean getLoaded(){
return this.loaded;
}
public void setLoaded(){
this.loaded = true;
}
public boolean getReady(){
return this.ready;
}
public void setReady() {
this.ready = true;
}
public Room getRoom() {
return room;
}
public void setRoom(Room room) {
this.room = room;
}
}