package org.skfiy.typhon.spi.troop;
import javax.inject.Inject;
import org.skfiy.typhon.AbstractComponent;
import org.skfiy.typhon.domain.Bag.Node;
import org.skfiy.typhon.domain.Player;
import org.skfiy.typhon.packet.PacketError;
import org.skfiy.typhon.session.SessionUtils;
import org.skfiy.typhon.spi.RoleProvider;
import org.skfiy.typhon.util.ComponentUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.skfiy.typhon.Typhons;
import org.skfiy.typhon.dobj.TroopItemDobj;
import org.skfiy.typhon.domain.Bag;
import org.skfiy.typhon.domain.ITroop;
import org.skfiy.typhon.domain.Normal;
import org.skfiy.typhon.domain.Troop;
import org.skfiy.typhon.domain.item.AcePack;
import org.skfiy.typhon.domain.item.SimpleItem;
import org.skfiy.typhon.domain.item.TroopItem;
import org.skfiy.typhon.packet.MultipleValue;
import org.skfiy.typhon.packet.Packet;
import org.skfiy.typhon.packet.SingleValue;
import org.skfiy.typhon.packet.TroopStrengPacket;
import org.skfiy.typhon.spi.role.ExpLevel;
import org.skfiy.typhon.util.FastRandom;
/**
*
* @author Kevin Zou <kevinz@skfiy.org>
*/
public class TroopProvider extends AbstractComponent {
private static final int TROOP_MAX_LEVEL = 15;
private static final Random RANDOM = new FastRandom();
private static final String[] STRONG_SECONDARY_KEYS = {"critRate", "critMagn", "decritRate",
"parryRate", "parryValue", "deparryRate"};
@Inject
private RoleProvider roleProvider;
private final Map<ITroop.Type, JSONArray> TROOP_CONFIGS = new HashMap<>();
private final JSONArray COST_ARRAY = new JSONArray();
private JSONObject strongSecondaryProperties;
@Override
protected void doInit() {
TROOP_CONFIGS.put(ITroop.Type.XF,
JSON.parseArray(ComponentUtils.readDataFile("troop_xf_property.json")));
TROOP_CONFIGS.put(ITroop.Type.JS,
JSON.parseArray(ComponentUtils.readDataFile("troop_js_property.json")));
TROOP_CONFIGS.put(ITroop.Type.YB,
JSON.parseArray(ComponentUtils.readDataFile("troop_yb_property.json")));
TROOP_CONFIGS.put(ITroop.Type.ZJ,
JSON.parseArray(ComponentUtils.readDataFile("troop_zj_property.json")));
TROOP_CONFIGS.put(ITroop.Type.ZZ,
JSON.parseArray(ComponentUtils.readDataFile("troop_zz_property.json")));
COST_ARRAY.addAll(JSON.parseArray(ComponentUtils.readDataFile("troop_cost.json")));
strongSecondaryProperties =
JSON.parseObject(ComponentUtils
.readDataFile("troop_strong_secondary_properties.json"));
}
@Override
protected void doDestroy() {
}
@Override
protected void doReload() {}
// New begin
public boolean isMaxLevel(TroopItem troopItem) {
return (troopItem.getLevel() >= TROOP_MAX_LEVEL);
}
/**
* 战位强化的最大等级.
*
* @param roleLevel
* @param troopLevel
* @return
*/
public boolean isMaxLevel(int roleLevel, int troopLevel) {
ExpLevel expLevel = roleProvider.getExpLevel(roleLevel);
return (troopLevel >= expLevel.getTroopMaxLevel());
}
private void isCost(int level, int exp) {
int cost = exp * COST_ARRAY.getJSONObject(level).getIntValue("cost");
SessionUtils.decrementCopper(cost);
}
/**
* 升级强化锦囊.
*
* @param packet 协议包
*/
public void harden(SingleValue packet) {
Player player = SessionUtils.getPlayer();
Bag bag = player.getBag();
int pos = (int) packet.getVal();
Node node = bag.findNode(pos);
if (node == null) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("No troopItem[" + pos + "]");
player.getSession().write(error);
return;
}
TroopItem troopItem = node.getItem();
if (isMaxLevel(troopItem)) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("MaxLevel");
player.getSession().write(error);
return;
}
TroopItemDobj troopItemDobj = troopItem.getItemDobj();
int upgradeTexp = troopItemDobj.getUpgradeTexp(troopItem.getLevel());
if (player.getNormal().getTexp() < upgradeTexp) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("Not enough texp");
player.getSession().write(error);
return;
}
int level = troopItem.getLevel();
int masterLevel = troopItemDobj.getMasterLevel(level);
if (player.getRole().getLevel() < masterLevel) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("Don't enough master level");
player.getSession().write(error);
return;
}
//锦囊强化
int count = player.getNormal().getDailyTask().getTaskHardenStreng();
if (count >= 0) {
player.getNormal().getDailyTask().setTaskHardenStreng(count + 1);
}
int copper = troopItemDobj.getCopper(level);
SessionUtils.decrementCopper(copper);
int newLevel = level + 1;
Normal normal = player.getNormal();
normal.setTexp(normal.getTexp() - upgradeTexp);
int atk = troopItem.getAtk() + getUpVal(troopItemDobj.getAtkUps(), level);
int def = troopItem.getDef() + getUpVal(troopItemDobj.getDefUps(), level);
int matk = troopItem.getMatk() + getUpVal(troopItemDobj.getMatkUps(), level);
int mdef = troopItem.getMdef() + getUpVal(troopItemDobj.getMdefUps(), level);
int hp = troopItem.getHp() + getUpVal(troopItemDobj.getHpUps(), level);
// 强化至满级时增加额外的属性
if (newLevel >= TROOP_MAX_LEVEL) {
double f = Typhons.getDouble("typhon.spi.troop.harden.maxLevel.factor", 1.5);
atk *= f;
def *= f;
matk *= f;
mdef *= f;
hp *= f;
}
// 增加属性
troopItem.setAtk(atk);
troopItem.setDef(def);
troopItem.setMatk(matk);
troopItem.setMdef(mdef);
troopItem.setHp(hp);
troopItem.setLevel(newLevel);
// 增加随机属性
if (newLevel != TROOP_MAX_LEVEL && newLevel % 3 == 0) {
String key = STRONG_SECONDARY_KEYS[RANDOM.nextInt(STRONG_SECONDARY_KEYS.length)];
JSONObject json = strongSecondaryProperties.getJSONObject(key);
int min = json.getIntValue("min");
int max = json.getIntValue("max");
int v = min + RANDOM.nextInt(max - min + 1);
switch (key) {
case "critRate":
troopItem.setCritRate(troopItem.getCritRate() + v);
break;
case "critMagn":
troopItem.setCritMagn(troopItem.getCritMagn() + v);
break;
case "decritRate":
troopItem.setDecritRate(troopItem.getDecritRate() + v);
break;
case "parryRate":
troopItem.setParryRate(troopItem.getParryRate() + v);
break;
case "parryValue":
troopItem.setParryValue(troopItem.getParryValue() + v);
break;
case "deparryRate":
troopItem.setDeparryRate(troopItem.getDeparryRate() + v);
break;
}
}
// 强化升级时重新计算属性
if (troopItem.getActiveType() != null) {
calculateTroopProps(player);
}
player.getSession().write(Packet.createResult(packet));
}
/**
* 分解锦囊.
*
* @param packet 协议包
*/
public void resolve(MultipleValue packet) {
Player player = SessionUtils.getPlayer();
Bag bag = player.getBag();
Normal normal = player.getNormal();
Node node;
TroopItem troopItem;
int sumTexp = 0;
for (Object obj : packet.getVals()) {
node = bag.findNode((int) obj);
if (node == null) {
continue;
}
troopItem = node.getItem();
if (troopItem.getActiveType() != null) {
continue;
}
sumTexp += troopItem.getItemDobj().getSplitTexp(troopItem.getLevel());
bag.decrementTotal(node, 1);
}
normal.setTexp(normal.getTexp() + sumTexp);
player.getSession().write(Packet.createResult(packet));
}
/**
* 计算锦囊属性.
*
* @param player 玩家信息
*/
public void calculateTroopProps(Player player) {
Normal normal = player.getNormal();
for (Troop troop : normal.getTroops()) {
AcePack acePack = new AcePack();
troop.setAcePack(acePack);
calculateTroopProps(player.getBag(), acePack, troop.getFirst());
calculateTroopProps(player.getBag(), acePack, troop.getSecond());
calculateTroopProps(player.getBag(), acePack, troop.getThird());
calculateTroopProps(player.getBag(), acePack, troop.getFour());
calculateTroopProps(player.getBag(), acePack, troop.getFive());
}
}
//==============================================================================================
// 经验,等级
private void pushExp(TroopStrengPacket packet, Troop troop, JSONArray array) {
Player player = SessionUtils.getPlayer();
int roleLevel = player.getRole().getLevel();
// 站位强化等级限制
if (isMaxLevel(roleLevel, troop.getLevel())) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("Level limit");
player.getSession().write(error);
return;
}
ExpLevel expLevel = roleProvider.getExpLevel(troop.getLevel() + 1);
// 站位强化等级限制
if (troop.getExp() >= expLevel.getTroopExp()) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("Exp limit");
player.getSession().write(error);
return;
}
List<Integer> list = packet.getIntensities();
Set<Integer> set = new HashSet<>();
int expAdd = 0;
// 把消耗的东西归类放到set中
for (int i = 0; i < list.size(); i++) {
set.add(list.get(i));
}
// 包消耗的同一类物品统一销毁
for (int e : set) {
int count = 0;
Node node = player.getBag().findNode(e);
SimpleItem simpleitem = (SimpleItem) node.getItem();
for (int j = 0; j < list.size(); j++) {
if (e == list.get(j)) {
count++;
}
if (j == list.size() - 1) {
expAdd += (int) simpleitem.getItemDobj().getAnnex() * count;
if (!player.getBag().decrementTotal(node, count)) {
PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict);
error.setText("node is enought troopStreng");
player.getSession().write(error);
return;
}
}
}
}
int newExp = troop.getExp() + expAdd;
int newLevel = troop.getLevel();
while (true) {
expLevel = roleProvider.getExpLevel(newLevel + 1);
if (newExp < expLevel.getTroopExp()) {
break;
}
newExp -= expLevel.getTroopExp();
newLevel++;
// 超过部分经验清零不计算金币花销
if (isMaxLevel(roleLevel, newLevel)) {
newExp = 0;
break;
}
}
//站位强化
int count = player.getNormal().getDailyTask().getTaskTroopStreng();
if (count >= 0) {
player.getNormal().getDailyTask().setTaskTroopStreng(count + 1);
}
// 玩家没有升级扣除金币
if (troop.getLevel() == newLevel) {
isCost(troop.getLevel(), expAdd);
} else {
// 玩家升级扣除最低级的金币
isCost(troop.getLevel(), roleProvider.getExpLevel(troop.getLevel() + 1).getTroopExp()
- troop.getExp());
}
counting(newExp, newLevel, troop, array, roleLevel);
player.getSession().write(Packet.createResult(packet));
}
// 站位升级
public void rise(TroopStrengPacket packet) {
Player player = SessionUtils.getPlayer();
Normal normal = player.getNormal();
ITroop.Type type = ITroop.Type.valueOf(packet.getTid());
Troop troop = normal.getTroop(type);
JSONArray array = TROOP_CONFIGS.get(type);
pushExp(packet, troop, array);
}
//计算升级的属性
private void counting(int newExp, int newLevel, Troop troop, JSONArray array, int roleLevel) {
int level = troop.getLevel();
if (newLevel > level) {
int a = newLevel - level;
JSONObject json;
for (int i = 0; i < a; i++) {
json = array.getJSONObject(troop.getLevel() + i);
troop.setAtk(troop.getAtk() + json.getIntValue("atkUp"));
troop.setDef(troop.getDef() + json.getIntValue("defUp"));
troop.setMatk(troop.getMatk() + json.getIntValue("matkUp"));
troop.setMdef(troop.getMdef() + json.getIntValue("mdefUp"));
troop.setHp(troop.getHp() + json.getIntValue("hpUp"));
troop.setCritRate(troop.getCritRate() + json.getIntValue("critRateUp"));
troop.setDecritRate(troop.getDecritRate() + json.getIntValue("decritRateUp"));
troop.setCritMagn(troop.getCritMagn() + json.getIntValue("critMagn"));
troop.setParryRate(troop.getParryRate() + json.getIntValue("parryRate"));
troop.setDeparryRate(troop.getDeparryRate() + json.getIntValue("deparryRate"));
troop.setParryValue(troop.getParryValue() + json.getIntValue("parryValue"));
//扣去玩家升级的当前等级的金币
if (0 < i && i <= a - 1) {
isCost(level + i, roleProvider.getExpLevel(level + i + 1).getTroopExp());
}
}
troop.setLevel(newLevel);
if (!isMaxLevel(roleLevel, newLevel)) {
//扣去不足以升级的剩下的经验金币
isCost(troop.getLevel(), newExp);
}
}
troop.setExp(newExp);
}
private void calculateTroopProps(Bag bag, AcePack acePack, int pos) {
Node node = bag.findNode(pos);
if (node != null) {
TroopItem troopItem = node.getItem();
acePack.setAtk(acePack.getAtk() + troopItem.getAtk());
acePack.setDef(acePack.getDef() + troopItem.getDef());
acePack.setMatk(acePack.getMatk() + troopItem.getMatk());
acePack.setMdef(acePack.getMdef() + troopItem.getMdef());
acePack.setHp(acePack.getHp() + troopItem.getHp());
acePack.setCritRate(acePack.getCritRate() + troopItem.getCritRate());
acePack.setCritMagn(acePack.getCritMagn() + troopItem.getCritMagn());
acePack.setDecritRate(acePack.getDecritRate() + troopItem.getDecritRate());
acePack.setParryRate(acePack.getParryRate() + troopItem.getParryRate());
acePack.setParryValue(acePack.getParryValue() + troopItem.getParryValue());
acePack.setDeparryRate(acePack.getDeparryRate() + troopItem.getDeparryRate());
}
}
// public void update
private int getUpVal(int[] ups, int level) {
if (ups != null && ups.length > level) {
return ups[level];
}
return 0;
}
}