package ring.server.shells;
import ring.comms.Communicator;
import ring.mobiles.Alignment;
import ring.mobiles.MobileBaseModel;
import ring.mobiles.Race;
import ring.mobiles.RaceFactory;
import ring.mobiles.Alignment.Ethical;
import ring.mobiles.Alignment.Moral;
import ring.mobiles.MobileBaseModel.Gender;
import ring.mobiles.mobclass.MobileClass;
import ring.persistence.DataStoreFactory;
import ring.players.PlayerCharacter;
/**
* Class for creating a player character.
*
* @author projectmoon
*
*/
public class PlayerCharacterCreation {
private Communicator comms;
public PlayerCharacterCreation(Communicator comms) {
this.comms = comms;
}
/**
* This method handles the actual creation of a new character given a name.
* The method is further broken down into several smaller helper methods so
* as to not clutter the code.
*
* @param playerName
* @return A completed PlayerCharacter object.
* @throws java.io.IOException
* If there is an error saving the player to a file.
*/
public PlayerCharacter doCreateNewCharacter() {
String name;
Gender gender;
Race race;
Alignment alignment;
MobileClass playerClass;
PlayerCharacter newPlayer = new PlayerCharacter();
name = chooseName();
comms.printlnNoSuffix("[CYAN][B]Name chosen: [WHITE]" + name);
comms.println();
race = chooseRace();
comms.printlnNoSuffix("[CYAN][B]Race chosen: [WHITE]" + race.getName());
comms.println();
gender = chooseGender(race);
comms.printlnNoSuffix("[CYAN][B]Gender chosen: [WHITE]" + gender);
comms.println();
alignment = chooseAlignment();
comms.printlnNoSuffix("[CYAN][B]Alignment chosen: [WHITE]" + alignment.toString());
comms.println();
playerClass = chooseClass();
//comms.printlnNoSuffix("[CYAN][B]Class chosen: [WHITE]" + playerClass.getDisplayName() + "[R]\n");
comms.println();
System.out.println("Setting various player attributes...");
// Set basic info
newPlayer.getBaseModel().setName(name);
newPlayer.getBaseModel().setType(MobileBaseModel.Type.MORTAL);
//newPlayer.setMobileClass goes here.
// Set some physical and alignment characteristics
newPlayer.getBaseModel().setRace(race);
newPlayer.getBaseModel().setBody(race.getBody());
newPlayer.getDynamicModel().setSpeed(30);
newPlayer.getBaseModel().setGender(gender);
newPlayer.getBaseModel().setAlignment(alignment);
newPlayer.getBaseModel().setDescription("You see nothing special about " + newPlayer.getBaseModel().getGender().getObject() + ".");
// Set class, skills, etc.
newPlayer.getBaseModel().setMobileClass(playerClass);
// Save the player and print a message
comms.printlnNoSuffix("[CYAN]The [B][WHITE]"
+ newPlayer.getBaseModel().getType().getName() + "[R][CYAN] "
+ newPlayer.getBaseModel().getRace().getName() + " [R][WHITE]"
//+ newPlayer.getBaseModel().getMobileClass().getDisplayName() + " "
+ newPlayer.getBaseModel().getName() + " [CYAN]has been created.\n");
return newPlayer;
}
/**
* This method returns a race based on a letter choice the user inputs. It
* will print errors until the player chooses the right race.
*
* @return The race chosen by the user in the form of a Race object.
*/
public Race chooseRace() {
Race race = null;
do {
comms.printlnNoSuffix("Please select a race:");
comms.println("[R][CYAN]a) Human [B][RED]g) Drow Elf[R][CYAN]\nb) Moon Elf [B][RED]h) Ogre[R][CYAN]\nc) Dwarf [B][RED]i) Duergar Dwarf[R][CYAN]\nd) Half-Elf [B][RED]j) Illithid[R][CYAN]\ne) Gnome [B][RED]k) Troll[R][CYAN]\nf) Aasimar [B][RED]l) Tiefling[R][WHITE]");
comms.print("Enter choice: ");
String choice = comms.receiveData();
race = RaceFactory.determineRace(choice);
if (race == null) {
comms.printlnNoSuffix("That is not a valid choice.");
}
} while (race == null);
return race;
}
/**
* This helper method allows the user to choose their character's gender.
* The genders allowed are based on the race object passed to the method.
*
* @param race
* The player's chosen race determines what genders they can be.
* @return An integer representing the player's gender
* (Male/female/asexual);
*/
public Gender chooseGender(Race race) {
String raceName = race.getShortName();
// Illithids are only asexual
if (raceName.equals("Ill")) {
return Gender.IT; // Otherwise we move on to choosing M/F
}
String choice = "";
Gender gender = null;
do {
comms.print("Please enter a gender (M/F): ");
choice = comms.receiveData();
if (choice.toLowerCase().equals("m")) {
gender = Gender.MALE;
} else if (choice.toLowerCase().equals("f")) {
gender = Gender.FEMALE;
}
} while (gender == null);
return gender;
}
/**
* This method asks the user to input an ethical and moral alignment in:
* Lawful Good, Chaotic Evil, etc.
*
* @return The constructed alignment object.
*/
public Alignment chooseAlignment() {
Ethical ethical = null;
Moral moral = null;
String choice = "";
do {
comms.print("Please choose an ethical perspective (L, N, C): ");
choice = comms.receiveData();
if (choice.toLowerCase().equals("l")) {
ethical = Ethical.LAWFUL;
} else if (choice.toLowerCase().equals("n")) {
ethical = Ethical.NEUTRAL;
} else if (choice.toLowerCase().equals("c")) {
ethical = Ethical.CHAOTIC;
}
} while (ethical == null);
do {
comms.print("Please input a moral perspective (G, N, E): ");
choice = comms.receiveData();
if (choice.toLowerCase().equals("g")) {
moral = Moral.GOOD;
} else if (choice.toLowerCase().equals("n")) {
moral = Moral.NEUTRAL;
} else if (choice.toLowerCase().equals("e")) {
moral = Moral.EVIL;
}
} while (moral == null);
Alignment a = new Alignment(ethical, moral);
return a;
}
/**
* This helper method allows the user to type in the name of the class they
* wish to play. It accepts full names (barbarian, sorcerer, etc).
*
* @return The MobileClass object representing the chosen class.
*/
public MobileClass chooseClass() {
/*
String choice = "";
MobileClass mc = null;
do {
comms
.printlnNoSuffix("Please choose from the following classes. Type in the full name to choose it.");
comms
.print("Barbarian, Cleric, Druid, Fighter, Monk, Paladin, Ranger, Rogue, Sorcerer, Wizard");
choice = comms.receiveData();
mc = MobileClassFactory.determineClass(choice);
} while (mc == null);
return mc;
*/
comms.println("Class choosing not implemented yet");
return null;
}
public String chooseName() {
String playerName = null;
String allowableCharacters = "abcdefghijklmnopqrstuvwxyz";
//This loop runs forever until a user creates a name that meets the following:
//2 - 15 characters long.
//Letters only.
//The validation conditions use continue to iterate the loop again.
//A break is at the very end to kill the loop if the name is valid.
while (true) {
comms.print("Enter a character name: ");
playerName = comms.receiveData();
if (playerName.length() > 15 || playerName.length() < 2) {
comms.println("[RED]Sorry, character names must be between 2 and 15 characters long.");
continue;
}
else {
for (char ch : playerName.toCharArray()) {
if (allowableCharacters.indexOf(ch) < 0) {
comms.println("[RED]Character names must contain letters only.");
continue;
}
}
}
PlayerCharacter pc = DataStoreFactory.getDefaultStore().retrievePlayerCharacter(playerName);
if (pc != null) {
comms.println("[RED]Sorry, that character name is already in use.");
continue;
}
//The name is valid at this point. End the loop.
break;
}
//Capitalize first letter of name.
playerName = playerName.substring(0, 1).toUpperCase() + playerName.substring(1);
return playerName;
}
}