package logbook.dto; import java.util.Date; import java.util.List; import java.util.Map; import javax.json.JsonObject; import logbook.config.AppConfig; import logbook.constants.AppConstants; import logbook.data.context.GlobalContext; import logbook.internal.CondTiming; import logbook.util.JsonUtils; import com.dyuproject.protostuff.Tag; /** * 艦娘を表します * */ public final class ShipDto extends ShipBaseDto implements Comparable<ShipDto> { /** 艦娘個人を識別するID */ @Tag(10) private final int id; @Tag(12) private final int sortno; /** 鍵付き */ @Tag(13) private boolean locked; /** 艦隊ID */ @Tag(14) private String fleetid = ""; @Tag(15) private int fleetpos; /** Lv */ @Tag(16) private final int lv; /** 疲労 */ @Tag(17) private int cond; /** 入渠時間 */ @Tag(18) private long docktime; /** 修復資材 燃料 */ @Tag(19) private final int dockfuel; /** 修復資材 鋼材 */ @Tag(20) private final int dockmetal; /** 残弾 */ @Tag(21) private int bull; /** 残燃料 */ @Tag(22) private int fuel; /** 経験値 */ @Tag(23) private final int exp; /** 次のレベルまで */ @Tag(29) private final int nextexp; /** 経験値ゲージの割合 */ @Tag(30) private final float expraito; /** HP */ @Tag(24) private int nowhp; /** MaxHP */ @Tag(25) private final int maxhp; /** 搭載可能装備数 */ @Tag(26) private final int slotnum; /** 艦載機の搭載数 */ @Tag(27) private int[] onslot; /** 補助装備 */ @Tag(34) private final int slotEx; @Tag(35) private final ItemDto slotExItem; @Tag(40) private final String json; /** * コンストラクター * * @param object JSON Object */ public ShipDto(JsonObject object) { super(object); this.id = object.getJsonNumber("api_id").intValue(); this.locked = object.getJsonNumber("api_locked").intValue() == 1; this.sortno = object.getInt("api_sortno"); this.lv = object.getJsonNumber("api_lv").intValue(); this.cond = object.getJsonNumber("api_cond").intValue(); this.docktime = object.getJsonNumber("api_ndock_time").longValue(); this.dockfuel = object.getJsonArray("api_ndock_item").getJsonNumber(0).intValue(); this.dockmetal = object.getJsonArray("api_ndock_item").getJsonNumber(1).intValue(); this.bull = object.getJsonNumber("api_bull").intValue(); this.fuel = object.getJsonNumber("api_fuel").intValue(); this.exp = object.getJsonArray("api_exp").getInt(0); this.nextexp = object.getJsonArray("api_exp").getInt(1); this.expraito = object.getJsonArray("api_exp").getInt(2) / 100f; this.nowhp = this.getParam().getHP(); this.maxhp = this.getMax().getHP(); this.slotnum = object.getJsonNumber("api_slotnum").intValue(); this.onslot = JsonUtils.getIntArray(object, "api_onslot"); int _slotEx = -1; if (object.containsKey("api_slot_ex")) { _slotEx = object.getInt("api_slot_ex"); } this.slotEx = (_slotEx > 0) ? _slotEx : -1; this.slotExItem = GlobalContext.getItem(this.slotEx); this.json = object.toString(); } /** 新規入手艦 */ public ShipDto(int id, ShipInfoDto shipinfo, int[] slot) { super(shipinfo, slot, null, true); this.id = id; this.locked = false; this.sortno = this.getShipInfo().getSortNo(); this.lv = 1; this.cond = 40; this.docktime = 0; this.dockfuel = 0; this.dockmetal = 0; this.bull = shipinfo.getMaxBull(); this.fuel = shipinfo.getMaxFuel(); this.exp = 0; this.nextexp = 100; this.expraito = 0; this.nowhp = this.maxhp = this.getParam().getHP(); this.slotnum = shipinfo.getSlotNum(); this.onslot = new int[] { 0, 0, 0, 0, 0 }; List<ItemDto> items = this.getItem2(); int[] maxeq = shipinfo.getMaxeq2(); for (int i = 0; i < items.size(); ++i) { ItemDto item = items.get(i); if ((item != null) && item.isPlane()) { this.onslot[i] = maxeq[i]; } } this.slotEx = -1; this.slotExItem = null; this.json = null; } /** * 艦娘個人を識別するID * @return 艦娘個人を識別するID */ public int getId() { return this.id; } /** * 改造前初期艦のID * @return 改造前初期艦のID */ public int getCharId() { return this.shipInfo.getCharId(); } /** * sortno * @return sortno */ public int getSortno() { return this.sortno; } /** * 鍵付き * @return 鍵付き */ public boolean getLocked() { return this.locked; } /** */ public void setLocked(boolean locked) { this.locked = locked; } /** * @return 艦隊ID */ public String getFleetid() { return this.fleetid; } /** * 艦隊IDを設定する * * @param fleetid 艦隊ID */ public void setFleetid(String fleetid) { this.fleetid = fleetid; } /** * 艦隊に所属しているか? * @return */ public boolean isFleetMember() { return (this.fleetid != null) && (this.fleetid.length() > 0); } /** * 艦隊での位置 * @return fleetpos */ public int getFleetpos() { return this.fleetpos; } /** * @param fleetpos セットする fleetpos */ public void setFleetpos(int fleetpos) { this.fleetpos = fleetpos; } /** * Lv * @return Lv */ @Override public int getLv() { return this.lv; } /** * 疲労 * @return 疲労 */ public int getCond() { return this.cond; } /** * @param cond 疲労 */ public void setCond(int cond) { this.cond = cond; } /** * 現在の疲労推定値(下限値) * @return 現在の疲労推定値(下限値) */ public int getEstimatedCond(CondTiming timer) { if (this.cond >= 49) return this.cond; int estimatedCond = this.cond + (timer.calcPastCycles() * 3); if (estimatedCond > 49) return 49; return estimatedCond; } /** * 入渠時間 * @return 入渠時間 */ public long getDocktime() { return this.docktime; } /** * 泊地修理による修理時間 * @return */ public long getAkashiTime() { return this.docktime + (30 * 1000); // 最大30秒の遅延 } /** * 入渠時間をセット */ public void setDockTime(long docktime) { this.docktime = docktime; } /** * 修復資材 燃料 * @return 修復資材 燃料 */ public int getDockfuel() { return this.dockfuel; } /** * 修復資材 鋼材 * @return 修復資材 鋼材 */ public int getDockmetal() { return this.dockmetal; } /** * 残弾 * @return 残弾 */ public int getBull() { return this.bull; } /** * @param bull 残弾 */ public void setBull(int bull) { this.bull = bull; } /** * 燃料 * @return 燃料 */ public int getFuel() { return this.fuel; } /** * @param fuel 残燃料 */ public void setFuel(int fuel) { this.fuel = fuel; } /** * 経験値 * @return 経験値 */ public int getExp() { return this.exp; } public void setNowhp(int v) { this.nowhp = v; } /** * 経験値ゲージの割合 * @return 経験値ゲージの割合 */ public float getExpraito() { return this.expraito; } /** * 現在のHP * @return HP */ public int getNowhp() { return this.nowhp; } /** * 最大HP * @return MaxHP */ public int getMaxhp() { return this.maxhp; } /** * 装備可能スロット数 * @return */ public int getSlotNum() { return this.slotnum; } /** * 現在の艦載機搭載数 * @return 現在の艦載機搭載数 */ @Override public int[] getOnSlot() { return this.onslot; } /** * 次のレベルまでの経験値 * @return 次のレベルまでの経験値 */ public int getNext() { return this.nextexp; } /** * 疲労が抜けるまでの時間 * @return 疲労が抜けるまでの時間 */ public Date getCondClearTime(CondTiming timer, Date ndockCompleteTime, int okCond) { if (this.cond >= okCond) { return null; } return timer.calcCondClearTime2(ndockCompleteTime, this.cond, okCond); } /** * 疲労が抜けるまでの時間 * @return 疲労が抜けるまでの時間 */ public Date getCondClearTime(CondTiming timer, Date ndockCompleteTime) { return this.getCondClearTime(timer, ndockCompleteTime, AppConfig.get().getOkCond()); } /** * 艦娘が轟沈しているかを調べます * @return 轟沈したの場合 */ public boolean isSunk() { return (this.nowhp == 0); } /** * 艦娘が大破しているかを調べます * @return 大破以上の場合 */ public boolean isBadlyDamage() { return ((float) this.nowhp / (float) this.maxhp) <= AppConstants.BADLY_DAMAGE; } /** * 艦娘が中破しているかを調べます * @return 中破以上の場合 */ public boolean isHalfDamage() { return ((float) this.nowhp / (float) this.maxhp) <= AppConstants.HALF_DAMAGE; } /** * 艦娘が小破しているかを調べます * @return 小破以上の場合 */ public boolean isSlightDamage() { return ((float) this.nowhp / (float) this.maxhp) <= AppConstants.SLIGHT_DAMAGE; } @Override public int compareTo(ShipDto o) { return Integer.compare(this.id, o.id); } /** * 装備で加算された命中 * @return 装備の命中 */ public int getAccuracy() { int accuracy = 0; for (int itemid : this.slot) { if (-1 != itemid) { Map<Integer, ItemDto> itemMap = GlobalContext.getItemMap(); ItemDto item = itemMap.get(itemid); if (item != null) { accuracy += item.getParam().getHoum(); } } } return accuracy; } /** * 砲撃戦火力 * @return 砲撃戦火力 */ public int getHougekiPower() { switch (this.getStype()) { case 7: // 軽空母 case 11: // 正規空母 case 16: // 水上機母艦 case 18: // 装甲空母 // (火力 + 雷装) × 1.5 + 爆装 × 2 + 55 int rai = 0; int baku = 0; Map<Integer, ItemDto> itemMap = GlobalContext.getItemMap(); for (int itemid : this.slot) { if (-1 != itemid) { ItemDto item = itemMap.get(itemid); if (item != null) { rai += item.getParam().getRaig(); baku += item.getParam().getBaku(); } } } return (int) Math.round(((this.getKaryoku() + rai) * 1.5d) + (baku * 2) + 55); default: return this.getKaryoku() + 5; } } /** * 雷撃戦火力 * @return 雷撃戦火力 */ public int getRaigekiPower() { return this.getRaisou() + 5; } /** * 対潜火力 * @return 対潜火力 */ public int getTaisenPower() { // [ 艦船の対潜 ÷ 5 ] + 装備の対潜 × 2 + 25 int taisenShip = this.getTaisen(); int taisenItem = 0; Map<Integer, ItemDto> itemMap = GlobalContext.getItemMap(); for (int itemid : this.slot) { if (-1 != itemid) { ItemDto item = itemMap.get(itemid); if (item != null) { int taisen = item.getParam().getTais(); taisenShip -= taisen; taisenItem += taisen; } } } return (int) Math.round(Math.floor(taisenShip / 5d) + (taisenItem * 2) + 25); } /** * 夜戦火力 * @return 夜戦火力 */ public int getYasenPower() { return this.getKaryoku() + this.getRaisou(); } /** * データの更新に使ったJSON * @return json */ public JsonObject getJson() { if (this.json == null) return null; return JsonUtils.fromString(this.json); } /** * @param onslot2 */ public void setOnslot(int[] onslot) { this.onslot = onslot; } /** * 補助装備ID * @return */ public int getSlotEx() { return this.slotEx; } /** * 補助装備 * @return */ public ItemDto getSlotExItem() { return this.slotExItem; } }