This repository was archived by the owner on Dec 7, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameCore.java
More file actions
1675 lines (1530 loc) · 59.7 KB
/
GameCore.java
File metadata and controls
1675 lines (1530 loc) · 59.7 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
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
/**
*
* @author Kevin
*/
public class GameCore implements GameCoreInterface {
private final PlayerList playerList;
private final Map map;
protected DailyLogger dailyLogger;
private HashMap<Integer,Shop> shoplist;
private Ghoul ghoul;
private PrintWriter pw;
// Accounts and Login
private final PlayerAccountManager accountManager;
private final Object loginLock = new Object();
private final Object createAccountLock = new Object();
private Logger playerLogger = Logger.getLogger("connections");
private FriendsManager friendsManager;
private final Object friendsLock = new Object();
/**
* Creates a new GameCoreObject. Namely, creates the map for the rooms in the
* game, and establishes a new, empty, player list.
*
* This is the main core that both the RMI and non-RMI based servers will
* interface with.
*
* @throws Exception
*
*/
public GameCore(String playerAccountsLocation, String worldFile) throws Exception {
// Generate the game map.
map = new Map(worldFile);
this.dailyLogger = new DailyLogger();
dailyLogger.write("SERVER STARTED");
playerList = new PlayerList();
// Builds a list of shops mapped to their map id (can be expanded as needed)
shoplist = new HashMap<Integer,Shop>();
shoplist.put(new Integer(1), new Shop("Clocktower shop", "The shopping destination for all of your gaming needs."));
// Builds a list of shops mapped to their map id (can be expanded as needed)
shoplist = new HashMap<Integer,Shop>();
shoplist.put(new Integer(1), new Shop("Clocktower shop", "The shopping destination for all of your gaming needs."));
pw = new PrintWriter(new FileWriter("chatlog.txt"));
pw.flush();
pw.close();
initConnectionsLogger();
accountManager = new PlayerAccountManager(playerAccountsLocation);
friendsManager = FriendsManager.Create(new File("friends.json"));
Thread objectThread = new Thread(new Runnable() {
@Override
public void run() {
Random rand = new Random();
Room room;
Item object;
ArrayList<Item> objects = new ArrayList<Item>();
try
{
double inWeight = 0;
double inValue = 0;
String inName = "";
Scanner scanner = new Scanner(new File("./items.csv"));
scanner.nextLine();
scanner.useDelimiter(",|\\r\\n|\\n|\\r");
while(scanner.hasNext())
{
inName = scanner.next();
inWeight = Double.parseDouble(scanner.next().replace(",", ""));
inValue = Double.parseDouble(scanner.next().replace("\\r\\n|\\r|\\n", ""));
Item newItem = new Item(inName, inWeight, inValue);
objects.add(newItem);
}
}
catch(IOException e)
{
objects.add(new Item("Flower", 1.0, 0.0));
objects.add(new Item("Textbook", 10.3, 5.2));
objects.add(new Item("Phone", 2.9, 1.0));
objects.add(new Item("Newspaper", 10.0, 9.0));
}
while(true) {
try {
Thread.sleep(rand.nextInt(60000));
object = objects.get(rand.nextInt(objects.size()));
room = map.randomRoom();
room.addObject(object);
GameCore.this.broadcast(room, "You see a student rush past and drop a " + object + " on the ground.");
} catch (InterruptedException ex) {
Logger.getLogger(GameObject.class.getName()).log(Level.SEVERE, null, ex);}
}}});
Thread hbThread = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(5000);
List<String> expiredPlayers = playerList.getExpiredPlayers();
expiredPlayers.forEach(s -> {
leave(s);
});
} catch (InterruptedException ex) {
}
}
}
});
hbThread.setDaemon(true);
hbThread.setName("heartbeatChecker");
hbThread.start();
// new thread awake and control the action of Ghoul.
// team5 added in 10/13/2018
Thread awakeDayGhoul = new Thread(new Runnable() {
@Override
public void run() {
Random rand = new Random();
Room room = map.randomRoom();
ghoul = new Ghoul(room.getId());
room.hasGhoul = true;
GameCore.this.broadcast(room, "You see a Ghoul appear in this room");
while (true) {
try {
// Ghoul move in each 10-15 seconds.
Thread.sleep(12000 + rand.nextInt(5000));
// make Ghoul walk to other room;
GameCore.this.ghoulWander(ghoul, room);
room.hasGhoul = false;
GameCore.this.broadcast(room, "You see a Ghoul leave this room");
room = map.findRoom(ghoul.getRoom());
room.hasGhoul = true;
GameCore.this.broadcast(room, "You see a Ghoul enter this room");
} catch (InterruptedException ex) {
Logger.getLogger(GameObject.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
objectThread.setDaemon(true);
awakeDayGhoul.setDaemon(true);
objectThread.start();
awakeDayGhoul.start();
}
public void ghoulWander(Ghoul g, Room room) {
Random rand = new Random();
int[] candinateRoom = new int[4];
// easiest way to get all possible room;
candinateRoom[0] = room.getLink(Direction.NORTH);
candinateRoom[1] = room.getLink(Direction.SOUTH);
candinateRoom[2] = room.getLink(Direction.WEST);
candinateRoom[3] = room.getLink(Direction.EAST);
// random walk.
while (true) {
int roomID = candinateRoom[rand.nextInt(4)];
if (roomID != 0) {
g.setRoom(roomID);
return;
}
}
}
/**
* @author Group 4: King
* Adds the player to list of players in store, and returns shop they just entered
* @param name Name of the player to add to shop
* @return The id of the shop the player will enter, -1 otherwise
*/
public int shop(String name) {
Player player = this.playerList.findPlayer(name);
Room room = map.findRoom(player.getCurrentRoom());
// Add player to shop in room if applicable
if (map.isShoppable(room)) {
return room.getId();
}
return -1;
}
/**
* Returns Shop.tostring
* @param id The shop's id in the hashmap
* @return a reference to the shop
*/
public String getShopStr(int id) {
return this.shoplist.get(id).toString();
}
/**
* Allows player to sell an item to a shop, and increases their money
* @author Team 4: King
* @param name Name of the player
* @param shopId The ID of the shop the player is selling an item to
* @param item The item the player is selling (eventually will be an Item obj)
*/
public double sellItem(String name, int shopId, String item) {
Player player = this.playerList.findPlayer(name);
Shop s = shoplist.get(shopId);
double value = 0;
Item removed = player.removeObjectFromInventory(item);
if (removed != null) {
s.add(removed);
value = removed.price;
player.changeMoney(value);
}
//int value = removed.getValue();
return value;
}
public String bribeGhoul(String playerName, String item){
item = item.toLowerCase();
Player player = playerList.findPlayer(playerName);
Room room = this.map.findRoom(player.getCurrentRoom());
Item object = player.removeObjectFromInventory(item);
if(player == null){
return null;
}
if(room.hasGhoul){
//LinkedList<Item> itemList = player.getCurrentInventory();
//boolean giveAble = false;
//if (player.currentyInventory.size() > 0){
// giveAble = true;
// break;
//}
//for (String thing : itemList){
//if(thing.equalsIgnoreCase(item)){
// giveAble = itemList.remove(thing);
// break;
//}
boolean giveAble = false;
if (object != null){
giveAble = true;
}
if(giveAble){
try {
GhoulLog myLog = new GhoulLog();
myLog.glLog("GameCore","bribeGhoul", "Player" + " " + playerName + " has just given a " + object + " to the Ghoul");
} catch (Exception e){
e.printStackTrace();
}
ghoul.modifyAngryLevel(-1);
int angryLv = ghoul.getAngryLevel();
String message = "Ghoul gets " + item + ", " + "and its anger level decreases to " + angryLv + ".";
return message;
}else{
return "Do not have this item......";
}
}else{
return "No Ghoul in this room";
}
}
public String pokeGhoul(String playerName) {
Player player = playerList.findPlayer(playerName);
Room room = this.map.findRoom(player.getCurrentRoom());
if (player != null) {
if (!room.hasGhoul) {
return "There is no ghoul in this room.";
}
try {
GhoulLog myLog = new GhoulLog();
myLog.glLog("GameCore","pokeGhoul", "Player" + " " + playerName + " has just poked the Ghoul");
} catch (Exception e){
e.printStackTrace();
}
ghoul.modifyAngryLevel(1);
int angerLvl = ghoul.getAngryLevel();
if (angerLvl >= 7) {
ghoul.Drag(player);
draggedToSpawn(player);
}
return ("Ghoul anger level has increased to " + angerLvl);
} else {
return null;
}}
/**
* 605B_buy_method
* Allows player to sell an item to a shop, and increases their money
* @author Team 4: Mistry
* @param name Name of the player
* @param shopId The ID of the shop the player is selling an item to
* @param item The item the player is buying (eventually will be an Item obj)
*/
public String buyItem(String name, int shopId, String itemName)
{
double val = 0;
Player player = this.playerList.findPlayer(name);
Shop s = shoplist.get(shopId);
Item item = null;
for (Item ii : s.getInven())
if (ii.name.compareToIgnoreCase(itemName) == 0)
item = ii;
if (item == null) return "Item not in stock!!!";
if(s.getInven().contains(item))
{
if (player.getMoney() > item.price) {
s.remove(item);
}
else {
return "Not enough money!!!";
}
}
player.addObjectToInventory(item);
//val = removed.getValue() * 1.2;
val = item.price;
player.changeMoney(-val);
return "Thank you, that will be $" + val + ".";
}
/**
* Takes the player into venmo. The new and improved way to exchange money with other players.
*
* @author Team 4: Alaqeel
* @param name Name of the player enter the bank
*/ @Override
public String venmo(String name, ArrayList<String> tokens) {
// checks if the player forgot to enter enough commands
if (tokens.isEmpty()) return "You need to provide more arguments.\n" + Venmo.instructions();
// Gets the object of the caller player
Player player1 = this.playerList.findPlayer(name);
// Executes the relevant commands
switch(tokens.remove(0).toUpperCase()) {
case "SEND": // sending a transaction
if (tokens.isEmpty()) return "Specify recipient and amount.";
// gets the object of the receiving player
Player player2 = this.playerList.findPlayer(tokens.remove(0));
// checks that the name is correct
if (player2 == null) return "Incorrect player name.";
// checks if user entered a transaction amount
if (tokens.isEmpty()) return "Specify transaction amount";
float amount;
// checks if the player entered a valid number
try {
amount = Float.parseFloat(tokens.remove(0));
} catch (NumberFormatException e) {
return "Please enter a valid number.";
}
return Venmo.send(player1, player2, amount);
case "HELP": // prints the help menu
return "This is how you can use Venmo:\n" + Venmo.instructions();
case "DEMO": // helpful for demo purposes
if (!tokens.isEmpty() && tokens.remove(0).equalsIgnoreCase("********")) {
player1.changeMoney(10);
System.out.printf("[Venmo] %s excuted the demo command\n", player1.getName());
return "Shush! Don't tell anyone that I added $10.00 to your wallet.";
}
default:
return "Unknown argument.\n" + Venmo.instructions();
}
}
/**
* Shows player how much money they have
* @param name Name of the player
* @return A string representation of the player's money
*/
public String wallet(String name) {
Player player = this.playerList.findPlayer(name);
double m = player.getMoney();
return "$" + String.format("%.02f", m);
}
/**
* Returns a Shop's inventory as a formatted string
* @param id The shop ID
* @return A formatted string representing the Shop's inventory
*/
public String getShopInv(int id) {
Shop s = this.shoplist.get(new Integer(id));
return s.getObjects();
}
/**
* Attempts to pick up all objects in the room. Will return a message on any success or failure.
* @param name Name of the player to move
* @return Message showing success.
*/
public String pickupAll(String name) {
Player player = this.playerList.findPlayer(name);
if(player != null) {
Room room = map.findRoom(player.getCurrentRoom());
LinkedList<Item> objects = room.removeAllObjects();
if(objects != null && objects.size() > 0) {
for (Item object : objects)
{
player.addObjectToInventory(object);
}
this.broadcast(player, player.getName() + " bends over to pick up all objects that were on the ground.");
return "You bend over and pick up all objects on the ground.";
}
else {
this.broadcast(player, player.getName() + " bends over to pick up something, but doesn't find anything.");
return "You look around for objects but can't find any.";
}
}
else {
return null;
}
}
/**
* Returns a string of what and who you plan to offer an item to
* @param srcName Name of player making offer
* @param dstName Name of player receiving offer
* @param message Object item being offered
* @return Message showing status of offer
*/
public String offer(String srcName, String dstName, String message){
Player srcPlayer = this.playerList.findPlayer(srcName);
Player dstPlayer = this.playerList.findPlayer(dstName);
Room room = map.findRoom(srcPlayer.getCurrentRoom());
String returnMessage;
Item object = srcPlayer.removeObjectFromInventory(message);
if (srcPlayer == dstPlayer)
returnMessage = "So now we talking to ourselves? Is that what's hot?";
else if (dstPlayer != null && (dstPlayer.getCurrentRoom() != srcPlayer.getCurrentRoom()))
returnMessage = "Player ain't in your room, or your life";
else if (object == null)
returnMessage = "You ain't got that fool: " + message;
else if (dstPlayer == null)
returnMessage = "Player " + dstName + " not found.";
else if (srcPlayer == null)
returnMessage = "Messge failed, check connection to server.";
else {
dstPlayer.getReplyWriter().println(srcPlayer.getName() + " offers you an item: " + message);
returnMessage = "You offer to " + dstPlayer.getName() + " an item: " + message;
}
if (object != null)
srcPlayer.addObjectToInventory(object);
return returnMessage;
}
//Same functionality as bribe_ghoul, not currently used
//public String giveToGhoul(String object, String playerName) {
// Player player = playerList.findPlayer(playerName);
// Room room = this.map.findRoom(player.getCurrentRoom());
// boolean isItem = false;
// if (player != null) {
// if (!room.hasGhoul) {
// return "There is no ghoul in this room.";
// }
// else {
// for (String s : player.getCurrentInventory()) {
// if (s.equals(object)) {
// isItem = true;
// }
// }
// if (! isItem) {
// return "you don't have" + object + "!";
// }
// player.getCurrentInventory().remove(object);
// ghoul.modifyAngryLevel(-1);
// return("the ghoul is a little more calm");
// }
// }
// else {
// return "failed to give ghoul item.";
// }
//}
/**
* Broadcasts a message to all other players in the same room as player.
*
* @param player Player initiating the action.
* @param message Message to broadcast.
*/
@Override
public void broadcast(Player player, String message) {
for (Player otherPlayer : this.playerList) {
if(otherPlayer != player && !otherPlayer.isIgnoring(player) && otherPlayer.getCurrentRoom() == player.getCurrentRoom()) {
dailyLogger.write(message);
String newMessage = otherPlayer.filterMessage(message);
otherPlayer.getReplyWriter().println(newMessage);
/* Can delete this. Was causing merge conflict. Functionality remains unchanged.
if (otherPlayer != player && otherPlayer.getCurrentRoom() == player.getCurrentRoom()) {
dailyLogger.write(message);
otherPlayer.getReplyWriter().println(message);
*/
}
}
}
/**
* Broadcasts a message to all players in the specified room.
*
* @param room Room to broadcast the message to.
* @param message Message to broadcast.
*/
@Override
public void broadcast(Room room, String message) {
for (Player player : this.playerList) {
if (player.getCurrentRoom() == room.getId()) {
dailyLogger.write(message);
String newMessage = player.filterMessage(message);
player.getReplyWriter().println(newMessage);
/* Delete this, functionality remains unchanged
dailyLogger.write(message);
player.getReplyWriter().println(message);
*/
}
}
}
/**
* Returns the player with the given name or null if no such player.
*
* @param name Name of the player to find.
* @return Player found or null if none.
*/
@Override
public Player findPlayer(String name) {
for (Player player : this.playerList) {
if (player.getName().equalsIgnoreCase(name)) {
return player;
}
}
return null;
}
/**
* Prints message to player if request can processed, contacts other player about their request
* @param requestingTrader Name of the player who has requested the trade
* @param traderToRequest Name of the player whom the first player has requested to trade with
*/
public void requestPlayer(String requestingTrader, String traderToRequest){
Player playerToRequest = this.playerList.findPlayer(traderToRequest);
Player requestingPlayer = this.playerList.findPlayer(requestingTrader);
if(requestingTrader.equals(traderToRequest)){
requestingPlayer.getReplyWriter().println("You cannot trade with yourself.");
return;
}
else if(playerToRequest == null){
requestingPlayer.getReplyWriter().println("This player does not exist, choose an existing trade partner");
return;
}
boolean tradeInProgress = false;
for(Player player : this.playerList) {
if(player.isInTrade()) {
tradeInProgress = true;
}
}
if(tradeInProgress){
requestingPlayer.getReplyWriter().println("There is already a trade in progress. ");
return;
}
playerToRequest.setTradeRequest(true);
playerToRequest.getReplyWriter().println(requestingTrader + " has requested a trade. You may ignore this request or type: A_TRADE " +requestingTrader+" to proceed. ");
requestingPlayer.getReplyWriter().println("Player has been contacted. You will receive a notification when they accept. ");
}
/**
* Allows a player to join the game. If a player with the same name
* (case-insensitive) is already in the game, then this returns false.
* Otherwise, adds a new player of that name to the game. The next step is
* non-coordinated, waiting for the player to open a socket for message events
* not initiated by the player (ie. other player actions)
*
* @param name
* @param password password hash for corresponding account.
* @return Player is player is added, null if player name is already registered
* to someone else
*/
@Override
public Player joinGame(String name, String password) {
synchronized (loginLock) {
// Check to see if the player of that name is already in game.
Player player = this.playerList.findPlayer(name);
if (player != null)
return null;
PlayerAccountManager.AccountResponse resp = accountManager.getAccount(name, password);
if (!resp.success())
return null;
player = resp.player;
this.playerList.addPlayer(player);
this.broadcast(player, player.getName() + " has arrived.");
connectionLog(true, player.getName());
return player;
}
}
/**
* Allows a player to create an account. If the player name already exists this
* returns the corresponding enum. If the players name is of an invalid format
* this returns that corresponding emum. Otherwise this returns success and
* calls joinGame.
*
* @param name
* @param password
* @param recovery List of recovery questions and answers, ordered q1,a1,q2,a2,q3,a3
* @return an enumeration representing the creation status.
*/
@Override
public synchronized Responses createAccountAndJoinGame(String name, String password, ArrayList<String> recovery) {
synchronized (createAccountLock) {
PlayerAccountManager.AccountResponse resp = accountManager.createNewAccount(name, password, recovery);
if (!resp.success())
return resp.error;
if (joinGame(name, password) != null)
return Responses.SUCCESS;
return Responses.UNKNOWN_FAILURE;
}
}
/**
* Returns a look at the area of the specified player.
*
* @param playerName Player Name
* @return String representation of the current area the player is in.
*/
@Override
public String look(String playerName) {
Player player = playerList.findPlayer(playerName);
if (player != null) {
// Find the room the player is in.
Room room = this.map.findRoom(player.getCurrentRoom());
// Send a message to all other players in the room that this player is looking
// around.
this.broadcast(player, player.getName() + " takes a look around.");
// Return a string representation of the room state.
// return room.toString(this.playerList, player);
// modified in 2018.10.17, which for player can look ghoul.
if (room.hasGhoul) {
String watchGhoul = "\n\nTHERE IS A GHOUL IN THE ROOM!!!!!!\n\n";
return room.toString(this.playerList, player) + watchGhoul;
} else {
return room.toString(this.playerList, player);
}
}
// No such player exists
else {
return null;
}
}
/**
* Turns the player left.
*
* @param name Player Name
* @return String message of the player turning left.
*/
@Override
public String left(String name) {
Player player = this.playerList.findPlayer(name);
if (player != null) {
// Compel the player to turn left 90 degrees.
player.turnLeft();
// Send a message to every other player in the room that the player has turned
// left.
this.broadcast(player, player.getName() + " turns to the left.");
// Return a string back to the calling function with an update.
return "You turn to the left to face " + player.getCurrentDirection();
} else {
return null;
}
}
/**
* Turns the player right.
*
* @param name Player Name
* @return String message of the player turning right.
*/
@Override
public String right(String name) {
Player player = this.playerList.findPlayer(name);
if (player != null) {
// Compel the player to turn left 90 degrees.
player.turnRight();
// Send a message to every other player in the room that the player has turned
// right.
this.broadcast(player, player.getName() + " turns to the right.");
// Return a string back to the calling function with an update.
return "You turn to the right to face " + player.getCurrentDirection();
} else {
return null;
}
}
/**
* Says "message" to everyone in the current area.
*
* @param name Name of the player to speak
* @param message Message to speak
* @return Message showing success.
*/
@Override
public String say(String name, String message) {
Player player = this.playerList.findPlayer(name);
if (player != null) {
// this.broadcast(player, player.getName() + " says, \"" + message + "\"");
this.sayToAll(message, player);
String newMessage = player.filterMessage(message);
try {
chatLog(player, 0, "\""+message+"\"", "Room " + player.getCurrentRoom());
} catch (IOException e) {
System.out.println("Failed to log chat");
}
return "You say, \"" + newMessage + "\"";
} else {
return null;
}
}
public String draggedToSpawn(Player player) {
if (player == null) {
return null;
}
this.broadcast(player, player.getName() + "has been knocked out by the ghoul!");
player.setCurrentRoom(1);
this.broadcast(player, player.getName() + " woke up in the area");
player.getReplyWriter().println(this.map.findRoom(player.getCurrentRoom()).toString(playerList, player));
if (player.getCurrentInventory().size() > 0) {
Random rn = new Random();
int rand = rn.nextInt((player.getCurrentInventory().size() - 1) - 0 + 1) + 0;
player.getCurrentInventory().remove(player.getCurrentInventory().get(rand));
}
return "You wake up and find yourself at the clock tower, with a lighter burden.";
}
/**
* Attempts to walk forward < distance > times. If unable to make it all the
* way, a message will be returned. Will display LOOK on any partial success.
*
* @param name Name of the player to move
* @param distance Number of rooms to move forward through.
* @return Message showing success.
*/
public String move(String name, int distance) {
Player player = this.playerList.findPlayer(name);
if (player == null || distance <= 0) {
return null;
}
Room room;
while (distance-- != 0) {
room = map.findRoom(player.getCurrentRoom());
if (room.canExit(player.getDirection())) {
this.broadcast(player, player.getName() + " has walked off to the " + player.getCurrentDirection());
player.getReplyWriter().println(room.exitMessage(player.getDirection()));
player.setCurrentRoom(room.getLink(player.getDirection()));
this.broadcast(player, player.getName() + " just walked into the area.");
Ghost g = new Ghost(player);
g.start();
player.getReplyWriter()
.println(this.map.findRoom(player.getCurrentRoom()).toString(playerList, player));
} else {
player.getReplyWriter().println(room.exitMessage(player.getDirection()));
return "You grumble a little and stop moving.";
}
}
return "You stop moving and begin to stand around again.";
}
/**
* Attempts to walk towards <direction> 1 time. If unable to make it all the way,
* a message will be returned. Will display LOOK on any partial success.
* @param name Name of the player to move
* @param distance Number of rooms to move forward through.
* @return Message showing success.
*/
public String move(String name, Direction direction) {
Player player = this.playerList.findPlayer(name);
if(player == null) {
return null;
}
Room room = map.findRoom(player.getCurrentRoom());
if(room.canExit(direction)) {
this.broadcast(player, player.getName() + " has walked off to the " + direction);
player.getReplyWriter().println(room.exitMessage(direction));
player.setCurrentRoom(room.getLink(direction));
String logMessage = String.format("%s used command MOVE %s [moved from %s to %s]", player.getName(), direction.toString(), room.getTitle(), map.findRoom(player.getCurrentRoom()).getTitle());
this.broadcast(player, player.getName() + " just walked into the area.");
Ghost g = new Ghost(player);
g.start();
player.getReplyWriter().println(this.map.findRoom(player.getCurrentRoom()).toString(playerList, player));
} else {
String logMessage = String.format("%s used command MOVE %s [unable to move in direction]", player.getName(), direction.toString());
player.getReplyWriter().println(room.exitMessage(direction));
return "You grumble a little and stop moving.";
}
return "You stop moving and begin to stand around again.";
}
/**
* Attempts to pick up an object < target >. Will return a message on any
* success or failure.
*
* @param name Name of the player to move
* @param target The case-insensitive name of the object to pickup.
* @return Message showing success.
*/
/**
* Attempts to pick up an object < target >. Will return a message on any success or failure.
* @param name Name of the player to move
* @param target The case-insensitive name of the object to pickup.
* @return Message showing success.
*/
public String pickup(String name, String target) {
Player player = this.playerList.findPlayer(name);
if(player != null) {
if (player.currentInventory.size() <10){
Room room = map.findRoom(player.getCurrentRoom());
Item object = room.removeObject(target);
if(object != null) {
player.addObjectToInventory(object);
this.broadcast(player, player.getName() + " bends over to pick up a " + target + " that was on the ground.");
return "You bend over and pick up a " + target + ".";
}
else {
this.broadcast(player, player.getName() + " bends over to pick up something, but doesn't seem to find what they were looking for.");
return "You look around for a " + target + ", but can't find one.";
}
}
else {
return " your inventory is full.";
}
}
else {
return null;
}
}
/**
* Attempts to drops an object < target >. Will return a message on any success or failure.
* @param name Name of the player to move
* @param target The case-insensitive name of the object to drop.
* @return Message showing success.
*/
public String drop(String name, String target) {
Player player = this.playerList.findPlayer(name);
if(player != null) {
Room room = map.findRoom(player.getCurrentRoom());
Item object = player.removeObjectFromInventory(target);
if(object != null) {
room.addObject(object);
this.broadcast(player, player.getName() + " rummages their inventory to find a " + target);
return "You drop a " + target + " into the room.";
}
else {
this.broadcast(player, player.getName() + " tries to drop something, but doesn't seem to find what they were looking for.");
return "You look around for a " + target + " in your pockets, but can't find one.";
}
}
else {
return null;
}
}
/**
* Attempts to erase the whiteboard in the room. Will return a message on any success or failure.
* @param name Name of the player to erase the whiteboard
* @return Message showing success.
*/
public String whiteboardErase(String name) {
Player player = this.playerList.findPlayer(name);
if(player != null) {
Room room = map.findRoom(player.getCurrentRoom());
room.whiteboardErase();
this.broadcast(player, player.getName() + " erases the text on the whiteboard.");
dailyLogger.write(player.getName(), "WHITEBOARD ERASE", room.getTitle());
return "You erase the text on the whiteboard.";
}
else {
return null;
}
}
/**
* Attempts to read the whiteboard in the room. Will return a message on any success or failure.
* @param name Name of the player to erase the whiteboard
* @return Message showing success.
*/
public String whiteboardRead(String name) {
Player player = this.playerList.findPlayer(name);
if(player != null) {
Room room = map.findRoom(player.getCurrentRoom());
String text = room.getWhiteboardText();
dailyLogger.write(player.getName(), "WHITEBOARD READ", room.getTitle());
this.broadcast(player, player.getName() + " reads the text on the whiteboard.");
if (text != null && !text.isEmpty()) {
return "The whiteboard says: \"" + text + "\".";
}
else {
return "The whiteboard is empty";
}
}
else {
return null;
}
}
/**
* Attempts to the whiteboard in the room. Will return a message on any success or failure.
* @param name Name of the player to erase the whiteboard
* @param text Text to write on the whiteboard
* @return Message showing success.
*/
public String whiteboardWrite(String name, String text) {
try {
Player player = this.playerList.findPlayer(name);
if(player != null) {
Room room = map.findRoom(player.getCurrentRoom());
boolean success = room.addWhiteboardText(text);
dailyLogger.write(player.getName(), "WHITEBOARD WRITE", text, room.getTitle());
if (success) {
this.broadcast(player, player.getName() + " writes on the whiteboard.");
return "You write text on the whiteboard.";
}
else {
this.broadcast(player, player.getName() + " tries to write on the whiteboard, but it's full.");
return "You try to write text on the whiteboard, but there's not enough space.";
}
}
else {