diff --git a/src/main/java/org/ultramine/economy/Account.java b/src/main/java/org/ultramine/economy/Account.java index 50a3342..3f7958a 100644 --- a/src/main/java/org/ultramine/economy/Account.java +++ b/src/main/java/org/ultramine/economy/Account.java @@ -3,24 +3,25 @@ import java.util.HashMap; import java.util.Map; +import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; public abstract class Account { - protected final Map holdings = new HashMap(); + protected final Map holdings = new HashMap(); public abstract String getName(); - protected abstract void onHoldingsChange(Holdings holdings); + public abstract void onHoldingsChange(IHoldings holdings); - protected abstract void onHoldingsCreate(Holdings holdings); + public abstract void onHoldingsCreate(IHoldings holdings); - public Holdings getHoldingsOf(Currency cur) + public IHoldings getHoldingsOf(Currency cur) { - Holdings hlds = holdings.get(cur); + IHoldings hlds = holdings.get(cur); if(hlds == null) { - hlds = new Holdings(this, cur); + hlds = cur.createHoldings(this); holdings.put(cur, hlds); onHoldingsCreate(hlds); } @@ -29,9 +30,11 @@ public void writeToNBT(NBTTagCompound nbt) { - for(Map.Entry ent : holdings.entrySet()) + for(Map.Entry ent : holdings.entrySet()) { - nbt.setDouble(ent.getKey().getCode(), ent.getValue().getBalance()); + NBTTagCompound nbt1 = new NBTTagCompound(); + ent.getValue().writeToNBT(nbt1); + nbt.setTag(ent.getKey().getCode(), nbt1); } } @@ -41,7 +44,15 @@ { Currency cur = CurrencyRegistry.getCurrency((String)code); if(cur != null) - holdings.put(cur, new Holdings(this, cur, nbt.getDouble((String)code))); + { + IHoldings hlds = cur.createHoldings(this); + NBTBase b = nbt.getTag((String)code); + if(b instanceof NBTTagCompound) + hlds.readFromNBT((NBTTagCompound)b); + else + hlds.setBalanceSilently(nbt.getDouble((String)code));//TODO remove backward compatibility + holdings.put(cur, hlds); + } } } } diff --git a/src/main/java/org/ultramine/economy/BasicHoldings.java b/src/main/java/org/ultramine/economy/BasicHoldings.java new file mode 100644 index 0000000..c91e9e9 --- /dev/null +++ b/src/main/java/org/ultramine/economy/BasicHoldings.java @@ -0,0 +1,151 @@ +package org.ultramine.economy; + +import net.minecraft.command.CommandException; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.MathHelper; + +public class BasicHoldings implements IHoldings +{ + private final Account acc; + private final Currency cur; + + private long balance; + + public BasicHoldings(Account acc, Currency cur) + { + this.acc = acc; + this.cur = cur; + } + + public BasicHoldings(Account acc, Currency cur, double balance) + { + this(acc, cur); + this.balance = (int)(balance*100); + } + + public BasicHoldings(Account acc, Currency cur, long balanceInternal) + { + this(acc, cur); + this.balance = balanceInternal; + } + + long getBalanceInternal() + { + return this.balance; + } + + @Override + public Account getAccount() + { + return acc; + } + + @Override + public Currency getCurrency() + { + return cur; + } + + @Override + public double getBalance() + { + return balance / 100.0d; + } + + @Override + public void setBalanceSilently(double balance) + { + this.balance = (int)(balance*100); + } + + @Override + public void setBalance(double balance) + { + this.balance = (int)(balance*100); + acc.onHoldingsChange(this); + } + + @Override + public void add(double amount) + { + if(amount <= 0.0d) + throw new CommandException("economy.fail.negativeamount"); + this.balance += MathHelper.floor_double(amount*100); + acc.onHoldingsChange(this); + } + + @Override + public void subtract(double amount) + { + if(amount <= 0.0d) + throw new CommandException("economy.fail.negativeamount"); + this.balance -= MathHelper.ceiling_double_int(amount*100); + acc.onHoldingsChange(this); + } + + @Override + public void subtractChecked(double amount) + { + if((balance - MathHelper.ceiling_double_int(amount*100)) < 0L) + throw new CommandException("economy.fail.notenough"); + subtract(amount); + } + + @Override + public void divide(double amount) + { + this.balance /= amount; + acc.onHoldingsChange(this); + } + + @Override + public void multiply(double amount) + { + this.balance *= amount; + acc.onHoldingsChange(this); + } + + @Override + public boolean isNegative() + { + return this.balance < 0L; + } + + @Override + public boolean hasEnough(double amount) + { + return MathHelper.ceiling_double_int(amount*100) <= this.balance; + } + + @Override + public boolean hasOver(double amount) + { + return MathHelper.ceiling_double_int(amount*100) < this.balance; + } + + @Override + public void transact(IHoldings to, double amount) + { + this.subtract(amount); + to.add(amount); + } + + @Override + public void transactChecked(IHoldings to, double amount) + { + this.subtractChecked(amount); + to.add(amount); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) + { + nbt.setLong("b", this.balance); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) + { + this.balance = nbt.getLong("b"); + } +} diff --git a/src/main/java/org/ultramine/economy/Currency.java b/src/main/java/org/ultramine/economy/Currency.java index e5ac3f4..d868d23 100644 --- a/src/main/java/org/ultramine/economy/Currency.java +++ b/src/main/java/org/ultramine/economy/Currency.java @@ -1,5 +1,6 @@ package org.ultramine.economy; +import java.lang.reflect.Constructor; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -7,12 +8,21 @@ { private static final NumberFormat dformat = new DecimalFormat("#0.##"); + private final Constructor cls; private final String code; private final String sign; private final String dispName; - Currency(String code, String sign, String dispName) + Currency(Class cls, String code, String sign, String dispName) { + try + { + this.cls = cls.getDeclaredConstructor(Account.class, Currency.class); + } + catch(NoSuchMethodException e) + { + throw new RuntimeException(e); + } this.code = code; this.sign = sign; this.dispName = dispName; @@ -37,4 +47,16 @@ { return dformat.format(amount) + sign; } + + IHoldings createHoldings(Account acc) + { + try + { + return cls.newInstance(acc, this); + } + catch(Exception e) + { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/org/ultramine/economy/CurrencyRegistry.java b/src/main/java/org/ultramine/economy/CurrencyRegistry.java index 2b45f2c..ff7129a 100644 --- a/src/main/java/org/ultramine/economy/CurrencyRegistry.java +++ b/src/main/java/org/ultramine/economy/CurrencyRegistry.java @@ -7,14 +7,14 @@ { private static final Map currencies = new HashMap(); - public static final Currency GSC = registerCurrency("GSC", "$", "dollar"); + public static final Currency GSC = registerCurrency(BasicHoldings.class, "GSC", "$", "dollar"); - public static Currency registerCurrency(String code, String sign, String dispName) + public static Currency registerCurrency(Class cls, String code, String sign, String dispName) { code = code.toUpperCase(); if(currencies.containsKey(code)) throw new IllegalStateException("Currency with code "+code+" is already registered"); - Currency cur = new Currency(code, sign, dispName); + Currency cur = new Currency(cls, code, sign, dispName); currencies.put(code, cur); return cur; } diff --git a/src/main/java/org/ultramine/economy/EconomyCommands.java b/src/main/java/org/ultramine/economy/EconomyCommands.java index 9371931..088ddfa 100644 --- a/src/main/java/org/ultramine/economy/EconomyCommands.java +++ b/src/main/java/org/ultramine/economy/EconomyCommands.java @@ -21,8 +21,8 @@ { Currency cur = ctx.contains("currency") ? CurrencyRegistry.getCurrency(ctx.get("currency").asString()) : CurrencyRegistry.GSC; ctx.check(cur != null, "economy.fail.currency"); - Holdings from = ctx.getSenderAsPlayer().getData().core().getAccount().getHoldingsOf(cur); - Holdings to = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); + IHoldings from = ctx.getSenderAsPlayer().getData().core().getAccount().getHoldingsOf(cur); + IHoldings to = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); double amount = ctx.get("amount").asDouble(); from.transactChecked(to, amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.pay.sended", ctx.get("player").asString(), cur.format(amount)); @@ -44,7 +44,7 @@ ctx.checkPermissionIfArg("player", "command.economy.money.other", "command.money.other.fail.perm"); Currency cur = ctx.contains("currency") ? CurrencyRegistry.getCurrency(ctx.get("currency").asString()) :CurrencyRegistry.GSC; ctx.check(cur != null, "economy.fail.currency"); - Holdings holdings = (ctx.contains("player") ? ctx.get("player").asPlayerData() : ctx.getSenderAsPlayer().getData()).core().getAccount().getHoldingsOf(cur); + IHoldings holdings = (ctx.contains("player") ? ctx.get("player").asPlayerData() : ctx.getSenderAsPlayer().getData()).core().getAccount().getHoldingsOf(cur); ctx.sendMessage(DARK_GREEN, GREEN, "command.money.info", holdings.getAccount().getName(), cur.format(holdings.getBalance())); } @@ -62,8 +62,8 @@ { Currency cur = ctx.contains("currency") ? CurrencyRegistry.getCurrency(ctx.get("currency").asString()) : CurrencyRegistry.GSC; ctx.check(cur != null, "economy.fail.currency"); - Holdings from = ctx.getSenderAsPlayer().getData().core().getAccount().getHoldingsOf(cur); - Holdings to = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); + IHoldings from = ctx.getSenderAsPlayer().getData().core().getAccount().getHoldingsOf(cur); + IHoldings to = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); double amount = ctx.get("amount").asDouble(); ctx.check(amount > 0.0d, "economy.fail.negativeamount"); to.subtract(amount); //result may be negative @@ -85,7 +85,7 @@ { Currency cur = ctx.contains("currency") ? CurrencyRegistry.getCurrency(ctx.get("currency").asString()) : CurrencyRegistry.GSC; ctx.check(cur != null, "economy.fail.currency"); - Holdings holdings = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); + IHoldings holdings = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); double amount = ctx.get("amount").asDouble(); holdings.add(amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.mgive.sended", ctx.get("player").asString(), cur.format(amount)); @@ -105,7 +105,7 @@ { Currency cur = ctx.contains("currency") ? CurrencyRegistry.getCurrency(ctx.get("currency").asString()) : CurrencyRegistry.GSC; ctx.check(cur != null, "economy.fail.currency"); - Holdings holdings = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); + IHoldings holdings = ctx.get("player").asPlayerData().core().getAccount().getHoldingsOf(cur); double amount = ctx.get("amount").asDouble(); //may be negative double last = holdings.getBalance(); holdings.setBalance(amount); diff --git a/src/main/java/org/ultramine/economy/Holdings.java b/src/main/java/org/ultramine/economy/Holdings.java deleted file mode 100644 index 4ddcf00..0000000 --- a/src/main/java/org/ultramine/economy/Holdings.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.ultramine.economy; - -import net.minecraft.command.CommandException; -import net.minecraft.util.MathHelper; - -public class Holdings -{ - private final Account acc; - private final Currency cur; - - private long balance; - - Holdings(Account acc, Currency cur) - { - this.acc = acc; - this.cur = cur; - } - - Holdings(Account acc, Currency cur, double balance) - { - this(acc, cur); - this.balance = (int)(balance*100); - } - - Holdings(Account acc, Currency cur, long balanceInternal) - { - this(acc, cur); - this.balance = balanceInternal; - } - - long getBalanceInternal() - { - return this.balance; - } - - public Account getAccount() - { - return acc; - } - - public Currency getCurrency() - { - return cur; - } - - public double getBalance() - { - return balance / 100.0d; - } - - void setBalanceSilently(double balance) - { - this.balance = (int)(balance*100); - } - - public void setBalance(double balance) - { - this.balance = (int)(balance*100); - acc.onHoldingsChange(this); - } - - public void add(double amount) - { - if(amount <= 0.0d) - throw new CommandException("economy.fail.negativeamount"); - this.balance += MathHelper.floor_double(amount*100); - acc.onHoldingsChange(this); - } - - public void subtract(double amount) - { - if(amount <= 0.0d) - throw new CommandException("economy.fail.negativeamount"); - this.balance -= MathHelper.ceiling_double_int(amount*100); - acc.onHoldingsChange(this); - } - - public void subtractChecked(double amount) - { - if((balance - MathHelper.ceiling_double_int(amount*100)) < 0L) - throw new CommandException("economy.fail.notenough"); - subtract(amount); - } - - public void divide(double amount) - { - this.balance /= amount; - acc.onHoldingsChange(this); - } - - public void multiply(double amount) - { - this.balance *= amount; - acc.onHoldingsChange(this); - } - - public boolean isNegative() - { - return this.balance < 0L; - } - - public boolean hasEnough(double amount) - { - return MathHelper.ceiling_double_int(amount*100) <= this.balance; - } - - public boolean hasOver(double amount) - { - return MathHelper.ceiling_double_int(amount*100) < this.balance; - } - - public void transact(Holdings to, double amount) - { - this.subtract(amount); - to.add(amount); - } - - public void transactChecked(Holdings to, double amount) - { - this.subtractChecked(amount); - to.add(amount); - } -} diff --git a/src/main/java/org/ultramine/economy/HoldingsEvent.java b/src/main/java/org/ultramine/economy/HoldingsEvent.java index c597163..9f4b9f0 100644 --- a/src/main/java/org/ultramine/economy/HoldingsEvent.java +++ b/src/main/java/org/ultramine/economy/HoldingsEvent.java @@ -4,9 +4,9 @@ public class HoldingsEvent extends Event { - public final Holdings holdings; + public final IHoldings holdings; - protected HoldingsEvent(Holdings holdings) + protected HoldingsEvent(IHoldings holdings) { this.holdings = holdings; } diff --git a/src/main/java/org/ultramine/economy/IHoldings.java b/src/main/java/org/ultramine/economy/IHoldings.java new file mode 100644 index 0000000..03df020 --- /dev/null +++ b/src/main/java/org/ultramine/economy/IHoldings.java @@ -0,0 +1,40 @@ +package org.ultramine.economy; + +import net.minecraft.nbt.NBTTagCompound; + +public interface IHoldings +{ + Account getAccount(); + + public Currency getCurrency(); + + double getBalance(); + + void setBalanceSilently(double balance); + + void setBalance(double balance); + + void add(double amount); + + void subtract(double amount); + + void subtractChecked(double amount); + + void divide(double amount); + + void multiply(double amount); + + boolean isNegative(); + + boolean hasEnough(double amount); + + boolean hasOver(double amount); + + void transact(IHoldings to, double amount); + + void transactChecked(IHoldings to, double amount); + + void writeToNBT(NBTTagCompound nbt); + + void readFromNBT(NBTTagCompound nbt); +} diff --git a/src/main/java/org/ultramine/economy/PlayerAccount.java b/src/main/java/org/ultramine/economy/PlayerAccount.java index 74ed8ca..2a70e57 100644 --- a/src/main/java/org/ultramine/economy/PlayerAccount.java +++ b/src/main/java/org/ultramine/economy/PlayerAccount.java @@ -20,14 +20,14 @@ } @Override - protected void onHoldingsChange(Holdings holdings) + public void onHoldingsChange(IHoldings holdings) { MinecraftForge.EVENT_BUS.post(new PlayerHoldingsEvent.ChangeEvent(holdings, data)); data.save(); } @Override - protected void onHoldingsCreate(Holdings holdings) + public void onHoldingsCreate(IHoldings holdings) { MinecraftForge.EVENT_BUS.post(new PlayerHoldingsEvent.CreateEvent(holdings, data)); } diff --git a/src/main/java/org/ultramine/economy/PlayerHoldingsEvent.java b/src/main/java/org/ultramine/economy/PlayerHoldingsEvent.java index 09a3e76..a71cf7f 100644 --- a/src/main/java/org/ultramine/economy/PlayerHoldingsEvent.java +++ b/src/main/java/org/ultramine/economy/PlayerHoldingsEvent.java @@ -6,7 +6,7 @@ { public final PlayerData player; - protected PlayerHoldingsEvent(Holdings holdings, PlayerData player) + protected PlayerHoldingsEvent(IHoldings holdings, PlayerData player) { super(holdings); this.player = player; @@ -14,7 +14,7 @@ public static class CreateEvent extends PlayerHoldingsEvent { - public CreateEvent(Holdings holdings, PlayerData player) + public CreateEvent(IHoldings holdings, PlayerData player) { super(holdings, player); } @@ -22,7 +22,7 @@ public static class ChangeEvent extends PlayerHoldingsEvent { - public ChangeEvent(Holdings holdings, PlayerData player) + public ChangeEvent(IHoldings holdings, PlayerData player) { super(holdings, player); }