Skip to content

Instantly share code, notes, and snippets.

@Zren
Created December 7, 2011 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Zren/1444276 to your computer and use it in GitHub Desktop.
Save Zren/1444276 to your computer and use it in GitHub Desktop.
RPG Mechanics (Exp/Stat/Equipment)
public class Character {
private Map<Stat, Integer> stats = new HashMap<Stat, Integer>();
private Map<Stat, Integer> statOffsets = new HashMap<Stat, Integer>();
private Job job;
private LevelCurve levelCurve;
private int level = 1;
private int experience = 0;
private final EquipmentInventory equipmentInventory = new EquipmentInventory();
public Character(Job job) {
setJob(job);
setLevelCurve(LevelCurve.none());
resetStatMap(stats);
resetStatMap(statOffsets);
}
public Job getJob() {
return job;
}
public void setJob(Job job) {
this.job = job;
}
public EquipmentInventory getEquipmentInventory() {
return equipmentInventory;
}
public void setLevelCurve(LevelCurve levelCurve) {
this.levelCurve = levelCurve;
}
public LevelCurve getLevelCurve() {
return levelCurve;
}
public int getExperience() {
return experience;
}
public void setExperience(int experience) {
this.experience = experience;
}
public void addExperience(int value) {
setExperience(getExperience() + value);
}
public int getExperienceToNextLevel() {
if (getLevel() >= levelCurve.getMaxLevel())
return 0;
return levelCurve.getExpirienceRequiredForLevel(getLevel() + 1) - getExperience();
}
public void setLevelAndExperience(int level) {
setLevel(level);
setExperience(getLevelCurve().getExpirienceRequiredForLevel(level));
}
public void setLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
public void nextLevel() {
setLevel(getLevel() + 1);
}
private void resetStatMap(Map<Stat, Integer> statMap) {
for (Stat stat : Stat.values()) {
statMap.put(stat, 0);
}
}
public int getStat(Stat stat) {
return stats.get(stat);
}
public int getStatOffset(Stat stat) {
return statOffsets.get(stat);
}
public int getCalcStatValue(Stat stat) {
return getStat(stat) + getStatOffset(stat);
}
public void setStat(Stat stat, int value) {
stats.put(stat, value);
statOffsets.put(stat, 0); // Reset statOffset
}
public void addToStat(Stat stat, int value) {
setStat(stat, getStat(stat) + value);
}
public void setStatOffset(Stat stat, int value) {
statOffsets.put(stat, value);
}
public void addToStatOffset(Stat stat, int value) {
setStatOffset(stat, getStatOffset(stat) + value);
}
/**
* Main method used for testing.
*
* @param args
*/
public static void main(String[] args) {
Character c = Character.random();
while (true) {
// Print status of character
System.out.println(String.format("[%s]", c.toString()));
System.out.println(String.format(" Level: %s", c.getLevel()));
System.out.println(String.format(" Exp: %s", c.getExperience()));
System.out.println(String.format(" Exp To Next Level: %s", c.getExperienceToNextLevel()));
System.out.println(String.format(" Job: %s", c.getJob()));
System.out.println(String.format(" Equipment:"));
Weapon weapon = c.getEquipmentInventory().getWeapon();
if (weapon != null) {
System.out.println(String.format(" Weapon: %s [Atk: %d, Acc: %d, Crit: %d] ",
weapon,
weapon.getAttack(),
weapon.getAccuracy(),
weapon.getCritical()));
} else {
System.out.println(String.format(" Weapon: -"));
}
System.out.println(String.format(" Armor:"));
for (Armor.Type armorType : Armor.Type.values()) {
Armor armor = c.getEquipmentInventory().getArmor(armorType);
if (armor != null) {
System.out.println(String.format(" %s: %s [Def: %d, Weight: %d, Eva: %d] ",
armorType,
armor,
armor.getDefence(),
armor.getWeight(),
armor.getEvasion()));
} else {
System.out.println(String.format(" %s: -", armorType));
}
}
System.out.println(String.format(" Stats:"));
for (Stat stat : Stat.values()) {
System.out.println(String.format(" %s: %d/%d", stat, c.getCalcStatValue(stat), c.getStat(stat)));
}
// Give experience
c.addExperience(25);
// Level up if need be.
while (c.getLevel() < c.getLevelCurve().getMaxLevel() && c.getExperienceToNextLevel() <= 0) {
// A proper engine will call a CHARACTER_LEVEL_UP event.
c.nextLevel();
for (Stat stat : Stat.values()) {
c.addToStat(stat, (int)(Math.random() * 10));
}
}
// Create a ticking effect.
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Factor method to generate a random character.
*
* @return A character with a random inventory and stats.
*/
public static Character random() {
Character c = new Character(Job.values()[(int)(Math.random() * Job.values().length)]);
// Level
c.setLevelCurve(LevelCurve.quadratic(100, 10, 5));
// Stats
for (Stat stat : Stat.values()) {
c.setStat(stat, (int)(Math.random() * 100));
//c.setStatOffset(stat, (int)(Math.random() * 10) - 5);
}
// Note that Inventory is checked to see if it's compatible with Job.
// Weapon
c.getEquipmentInventory().setWeapon(Weapon.values()[(int)(Math.random() * Weapon.values().length)]);
// Armor
for (Armor.Type armorType : Armor.Type.values()) {
List<Armor> armorOfType = Armor.getArmorOfType(armorType);
c.getEquipmentInventory().setArmor(armorType, armorOfType.get((int)(Math.random() * armorOfType.size())));
}
return c;
}
}
public class EquipmentInventory {
Weapon weapon;
Map<Armor.Type, Armor> armor = new HashMap<Armor.Type, Armor>();
public EquipmentInventory() {
setWeapon(null);
for (Armor.Type armorType : Armor.Type.values()) {
setArmor(armorType, null);
}
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public Armor getArmor(Armor.Type armorType) {
return armor.get(armorType);
}
public boolean setArmor(Armor.Type armorType, Armor armor) {
if (armor == null || armor.getType() == armorType) {
this.armor.put(armorType, armor);
return true;
} else {
return false;
}
}
}
public enum Job {
WARRIOR,
THIEF,
MONK,
RED_MAGE,
WHITE_MAGE,
BLACK_MAGE,
KNIGHT,
NINJA,
MASTER,
RED_WIZARD,
WHITE_WIZARD,
BLACK_WIZARD
;
public final static Job[] knifeWeilders = new Job[] {
Job.WARRIOR,
Job.KNIGHT,
Job.THIEF,
Job.NINJA,
Job.RED_MAGE,
Job.RED_WIZARD,
Job.BLACK_MAGE,
Job.BLACK_WIZARD
};
public final static Job[] nunchakusWeilders = new Job[] {
Job.MONK,
Job.MASTER,
Job.NINJA
};
public final static Job[] heavyArmorWeilders = new Job[] {
Job.WARRIOR,
Job.KNIGHT,
Job.NINJA
};
@Override
public String toString() {
return StringUtil.capitalize(name()).replace('_', ' ');
}
}
public enum Stat {
//LEVEL,
//EXP,
HP,
MP,
STRENTH,
SPEED,
STAMINA,
MAGIC,
ATTACK,
DEFENCE,
EVASION,
MAGIC_DEFENCE,
MAGIC_EVASION
;
@Override
public String toString() {
return StringUtil.capitalize(name()).replace('_', ' ');
}
}
public enum Weapon {
// Knife
KNIFE(Type.KNIFE, 5, 10, 2, Job.knifeWeilders),
DAGGER(Type.KNIFE, 7, 10, 10, Job.knifeWeilders),
MYTHRIL_KNIFE(Type.KNIFE, 10, 15, 16, Job.knifeWeilders),
// Nunchakus
NUNCHUCK(Type.NUNCHAKUS, 12, 0, 1, Job.nunchakusWeilders),
IRON_NUNCHUCK(Type.NUNCHAKUS, 16, 0, 9, Job.nunchakusWeilders),
;
public enum Type {
KNIFE,
NUNCHAKUS,
}
private final Type type;
private final int attack, accuracy, critical;
private final Job[] jobs;
private Weapon(Type type, int defence, int weight, int evasion, Job[] jobs) {
this.type = type;
this.attack = defence;
this.accuracy = weight;
this.critical = evasion;
this.jobs = jobs;
}
@Override
public String toString() {
return StringUtil.capitalize(name()).replace('_', ' ');
}
public Type getType() {
return type;
}
public Job[] getJobs() {
return jobs;
}
public int getAttack() {
return attack;
}
public int getAccuracy() {
return accuracy;
}
public int getCritical() {
return critical;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment