So I am working on a small RPG in Unity. Right now I am writing some business classes, POCOs, that have no link to Unity except being in the required C# flavor and using Debug.Log and stuff.
I have been doing a lot of Java for years and some C++11, but no C#, so some concepts are not familiar to me.
I think most of the code is so-so, I'd like some advice, maybe someone might see future issues or stuff like that.
Entity class :
using UnityEngine;
using System.Collections;
public abstract class Entity {
public LevelingManager LevelingManager {get; set;}
public EntityStats EntityStats{get; set;}
public int CurrentLifePoints{ get; set;}
}
Fighter class :
using UnityEngine;
using System.Collections;
public class Fighter : Entity {
public Fighter(){
this.EntityStats = new FighterStats ();
this.LevelingManager = new FighterLeveling (EntityStats);
}
}
EntityStats class :
using UnityEngine;
using System.Collections;
using System;
public class EntityStats : IComparable {
public int PhysicalForce{ get; set; }
public int PhysicalDefense{ get; set; }
public int MagicalDefense{ get; set; }
public int MagicalForce{ get; set; }
public int Speed{ get; set; }
public int Life{ get; set; }
public int Level{ get; set; }
public EntityStats(){
Level = 1;
}
#region IComparable implementation
public int CompareTo (object obj)
{
if (null != obj && obj is EntityStats) {
EntityStats stats = obj as EntityStats;
if (stats.Level >= Level
&& stats.Life >= Life
&& stats.MagicalDefense >= MagicalDefense
&& stats.MagicalForce >= MagicalForce
&& stats.PhysicalDefense >= PhysicalDefense
&& stats.PhysicalForce >= PhysicalForce
&& stats.Level >= Level
&& stats.Speed >= Speed) {
return 0;
}
}
return -1;
}
#endregion
}
Fighter stats :
using UnityEngine;
using System.Collections;
public class FighterStats : EntityStats {
public FighterStats(){
PhysicalForce = 10;
PhysicalDefense = 10;
MagicalDefense = 5;
MagicalForce = 0;
Speed = 5;
Life = 10;
}
}
LevelingManager class :
using UnityEngine;
using System.Collections;
public abstract class LevelingManager {
public int ExperiencePoints{ get; set; }
public EntityStats ComparableStats{ get; set;}
public int ExperienceNeededForNextLevel (){
return Mathf.FloorToInt (Mathf.Log (ComparableStats.Level + 1) * 100);
}
public LevelingManager(EntityStats comparableEntityStats){
ComparableStats = comparableEntityStats;
ExperiencePoints = 0;
}
public void AddXP(int points){
int threshold = ExperienceNeededForNextLevel();
if (ExperiencePoints + points >= threshold) {
int remainder = points - threshold;
LevelUp (remainder);
//FIXME be careful with recursion .. (small stack on some systems ?)
if(remainder > 0)
AddXP (remainder);
}
else {
ExperiencePoints += points;
}
}
protected virtual void LevelUp(int remainder){
ComparableStats.Level++;
ExperiencePoints = 0;
}
}
Fighter leveling :
using UnityEngine;
using System.Collections;
public class FighterLeveling : LevelingManager {
public FighterLeveling(EntityStats comparableEntityStats) : base(comparableEntityStats){
}
protected override void LevelUp(int remainder){
base.LevelUp (remainder);
int adder = Mathf.FloorToInt (Mathf.Log (ComparableStats.Level + 1));
ComparableStats.PhysicalForce += adder * 3;
ComparableStats.PhysicalDefense += adder * 3;
ComparableStats.MagicalDefense += adder;
ComparableStats.Speed += adder;
ComparableStats.Life += adder * 2;
}
}
Stuff Class :
using UnityEngine;
using System.Collections;
using System;
public abstract class Stuff {
public EntityStats RequiredStatsToUse {get; set;}
public string StuffName { get; set; }
public Stuff(EntityStats stats, string stuffName){
this.RequiredStatsToUse = stats;
StuffName = stuffName;
}
public bool CanBeUsedBy(Entity entity){
return this.RequiredStatsToUse.CompareTo(entity.EntityStats) == 0;
}
}
WoodenSword class :
public class WoodenSword : Stuff {
public WoodenSword() : base(new EntityStats () , "Wooden sword"){
RequiredStatsToUse.PhysicalForce = 10;
}
}
Tests :
[Test]
public void should_go_to_level_2()
{
var leveling = new FighterLeveling (new FighterStats());
leveling.AddXP (75);
Assert.AreEqual (2, leveling.ComparableStats.Level);
Assert.AreEqual (6, leveling.ExperiencePoints);
}
[Test]
public void should_go_to_level_5()
{
var leveling = new FighterLeveling (new FighterStats());
//should be 478, but there's a small diff due to the rounding
leveling.AddXP (476);
Assert.AreEqual (5, leveling.ComparableStats.Level);
Assert.AreEqual (0, leveling.ExperiencePoints);
}
[Test]
public void object_should_be_usable_by_a_level_1_fighter()
{
var fighter = new Fighter ();
var weapon = new WoodenSword ();
Assert.AreEqual (true, weapon.CanBeUsedBy (fighter));
}
[Test]
public void object_should_not_be_usable_by_a_level_1_fighter()
{
var fighter = new Fighter ();
var weapon = new WoodenSword ();
weapon.RequiredStatsToUse.MagicalForce = 10;
Assert.AreEqual (false, weapon.CanBeUsedBy (fighter));
}
EntityStats : IComparable
? When are you going to compare the user's stats as a whole ? \$\endgroup\$