Java tutorial
/* Copyright 2010 Jeremie Gottero, Nicolas Bosc This file is part of Fallen Galaxy. Fallen Galaxy is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fallen Galaxy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Fallen Galaxy. If not, see <http://www.gnu.org/licenses/>. */ package fr.fg.client.core; import java.util.ArrayList; import java.util.HashMap; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventPreview; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import fr.fg.client.ajax.Action; import fr.fg.client.ajax.ActionCallback; import fr.fg.client.ajax.ActionCallbackAdapter; import fr.fg.client.animation.WidthUpdater; import fr.fg.client.data.AbilityData; import fr.fg.client.data.AnswerData; import fr.fg.client.data.GroupData; import fr.fg.client.data.ReportActionAbilityData; import fr.fg.client.data.ReportActionData; import fr.fg.client.data.ReportDamageData; import fr.fg.client.data.ReportData; import fr.fg.client.data.ReportSlotData; import fr.fg.client.data.ReportSlotStateData; import fr.fg.client.data.ShipData; import fr.fg.client.data.Sounds; import fr.fg.client.data.WeaponGroupData; import fr.fg.client.i18n.DynamicMessages; import fr.fg.client.i18n.Formatter; import fr.fg.client.i18n.StaticMessages; import fr.fg.client.openjwt.OpenJWT; import fr.fg.client.openjwt.animation.TimerHandler; import fr.fg.client.openjwt.animation.TimerManager; import fr.fg.client.openjwt.core.BaseWidget; import fr.fg.client.openjwt.core.Config; import fr.fg.client.openjwt.core.EventManager; import fr.fg.client.openjwt.core.SoundManager; import fr.fg.client.openjwt.core.TextManager; import fr.fg.client.openjwt.core.ToolTipManager; import fr.fg.client.openjwt.core.TextManager.OutlineText; import fr.fg.client.openjwt.ui.DialogListener; import fr.fg.client.openjwt.ui.JSButton; import fr.fg.client.openjwt.ui.JSDialog; import fr.fg.client.openjwt.ui.JSRowLayout; public class BattleReport implements ClickListener, DialogListener, ActionCallback, EventPreview { // ------------------------------------------------------- CONSTANTES -- // private final static int DEFAULT_SHOTS_SPEED = 10; private final static int[] SHIPS_POSITION = { 2, 3, 1, 4, 0 }; // Effets spciaux sur les tirs private final static int EFFECT_STARS = 1 << 0, EFFECT_IMPACT = 1 << 1, EFFECT_FRAG = 1 << 2, EFFECT_PARTICLES = 1 << 3; // -------------------------------------------------------- ATTRIBUTS -- // private HashMap<Integer, ReportData> reports; private boolean standalone; private int currentReportId; private Slot[] fleetsSlots; private SlotToolTip[] fleetsToolTips; private AbsolutePanel environmentPanel, battlePanel, effectsPanel, toolTipPanel, fleetTactics[]; private JSButton exitBt, restartBt; private JSDialog roundsDialog; private ArrayList<Shot> shots; private ArrayList<Effect> effects; private ArrayList<FloatingText> floatingTexts; private ArrayList<Destruction> destructions; private TimeShift timeShift; private ArrayList<Sound> sounds; private BattleUpdater battleUpdater; private int currentAction; private int[] slotsPosition; private Action downloadAction; private Ability[][] abilities; private PowerBar[] powerBars; private XpView[] xpViews; // ---------------------------------------------------- CONSTRUCTEURS -- // public BattleReport(boolean standalone) { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); // Charge les sons des combats SoundManager.getInstance().loadSound(Sounds.SMALL_SHOT1); SoundManager.getInstance().loadSound(Sounds.SMALL_SHOT2); SoundManager.getInstance().loadSound(Sounds.IMPACT); SoundManager.getInstance().loadSound(Sounds.EXPLOSION); SoundManager.getInstance().loadSound(Sounds.AVERAGE_SHOT1); SoundManager.getInstance().loadSound(Sounds.AVERAGE_SHOT2); SoundManager.getInstance().loadSound(Sounds.AVERAGE_SHOT2); this.standalone = standalone; this.reports = new HashMap<Integer, ReportData>(); this.currentReportId = -1; this.shots = new ArrayList<Shot>(); this.effects = new ArrayList<Effect>(); this.floatingTexts = new ArrayList<FloatingText>(); this.sounds = new ArrayList<Sound>(); this.destructions = new ArrayList<Destruction>(); this.timeShift = null; this.xpViews = new XpView[] { new XpView(false), new XpView(true) }; // Tactique employe par chaque flotte fleetTactics = new AbsolutePanel[2]; fleetTactics[0] = new AbsolutePanel(); fleetTactics[0].setStyleName("bottomFleetTactics"); fleetTactics[1] = new AbsolutePanel(); fleetTactics[1].setStyleName("topFleetTactics"); // Environnment de la bataille environmentPanel = new AbsolutePanel(); environmentPanel.setStyleName("environmentPanel"); // Champ de bataille battlePanel = new AbsolutePanel(); battlePanel.setStyleName("battlePanel"); fleetsSlots = new Slot[10]; // Flotte en haut de l'cran for (int i = 0; i < 5; i++) { Slot slot = new Slot(5 + i); fleetsSlots[5 + i] = slot; battlePanel.add(slot, 0, 0); } // Flotte en bas de l'cran for (int i = 0; i < 5; i++) { Slot slot = new Slot(i); fleetsSlots[i] = slot; battlePanel.add(slot, 0, 0); } // Tooltips toolTipPanel = new AbsolutePanel(); toolTipPanel.setStyleName("toolTipPanel"); fleetsToolTips = new SlotToolTip[10]; // Flotte en haut de l'cran for (int i = 0; i < 5; i++) { SlotToolTip toolTip = new SlotToolTip(5 + i); fleetsToolTips[5 + i] = toolTip; toolTipPanel.add(toolTip, 0, 0); } // Flotte en bas de l'cran for (int i = 0; i < 5; i++) { SlotToolTip toolTip = new SlotToolTip(i); fleetsToolTips[i] = toolTip; toolTipPanel.add(toolTip, 0, 0); } // Zone o les explosions et les dgts sont affichs effectsPanel = new AbsolutePanel(); effectsPanel.addStyleName("effectsArea"); RootPanel.get().sinkEvents(Event.KEYEVENTS); toolTipPanel.sinkEvents(Event.KEYEVENTS); fleetTactics[0].sinkEvents(Event.KEYEVENTS); fleetTactics[1].sinkEvents(Event.KEYEVENTS); // Round prcdent if (!standalone) { exitBt = new JSButton("Quitter"); exitBt.setPixelWidth(120); exitBt.addClickListener(this); restartBt = new JSButton("Revoir"); restartBt.setPixelWidth(120); restartBt.addClickListener(this); roundsDialog = new JSDialog(messages.battleTitle(), false, true, false); // Mise en forme des boutons JSRowLayout layout = new JSRowLayout(); layout.addComponent(exitBt); layout.addComponent(restartBt); roundsDialog.setComponent(layout); roundsDialog.setLocation(10, 10, false); } } // --------------------------------------------------------- METHODES -- // public void onClick(Widget sender) { if (sender == exitBt) { dialogClosed(roundsDialog); } if (sender == restartBt) { setAction(0, reports.get(currentReportId)); } } public void dialogClosed(Widget sender) { clearReport(); roundsDialog.setVisible(false); Client.getInstance().setFullScreenMode(false); Client.getInstance().getAreaContainer().getMap().setVisible(true); Client.getInstance().getAreaContainer() .setNebula(Client.getInstance().getAreaContainer().getArea().getNebula(), false); } public void cacheReport(ReportData report) { reports.put(report.getId(), report); } public void showReport(int id) { if (reports.containsKey(id)) { currentReportId = id; ReportData report = reports.get(id); // Son lorsque les rapports de combat sont visualiss en standalone if (standalone && report.hasGeneralVolume() && report.hasSoundVolume()) { SoundManager.getInstance().setGeneralVolume(report.getGeneralVolume()); SoundManager.getInstance().setSoundVolume(report.getSoundVolume()); Config.setGraphicsQuality(report.getGraphicsQuality()); } if (this.powerBars == null) this.powerBars = new PowerBar[] { new PowerBar(false), new PowerBar(true) }; buildEnvironment(report); buildTactics(report); // Charge les flottes for (int i = 0; i < 10; i++) fleetsSlots[i].load(report); for (int i = 0; i < 10; i++) fleetsToolTips[i].load(report); setAction(-1, report); Client.getInstance().setFullScreenMode(true); Client.getInstance().getAreaContainer().getMap().setVisible(false); Client.getInstance().getAreaContainer().setNebula(report.getNebula(), true); Client.getInstance().getAreaContainer().setVisible(true); Client.getInstance().getFullScreenPanel().add(environmentPanel); Client.getInstance().getFullScreenPanel().add(battlePanel); Client.getInstance().getFullScreenPanel().add(effectsPanel); Client.getInstance().getFullScreenPanel().add(toolTipPanel); Client.getInstance().getFullScreenPanel().add(fleetTactics[0]); Client.getInstance().getFullScreenPanel().add(fleetTactics[1]); Client.getInstance().getFullScreenPanel().add(powerBars[0]); Client.getInstance().getFullScreenPanel().add(powerBars[1]); Client.getInstance().getFullScreenPanel().add(xpViews[0]); Client.getInstance().getFullScreenPanel().add(xpViews[1]); EventManager.addEventHook(this); if (roundsDialog != null) roundsDialog.setVisible(true); } else { if (downloadAction != null && downloadAction.isPending()) return; HashMap<String, String> params = new HashMap<String, String>(); params.put("report", String.valueOf(id)); downloadAction = new Action("getreport", params, this); } } public void onFailure(String error) { ActionCallbackAdapter.onFailureDefaultBehavior(error); } public void onSuccess(AnswerData data) { downloadAction = null; cacheReport(data.getReport()); showReport(data.getReport().getId()); } public boolean onEventPreview(Event event) { switch (event.getTypeInt()) { case Event.ONKEYDOWN: if (event.getKeyCode() == 32) { if (battleUpdater != null) battleUpdater.setPaused(!battleUpdater.isPaused()); event.preventDefault(); event.cancelBubble(true); } break; } return true; } // ------------------------------------------------- METHODES PRIVEES -- // private void clearReport() { EventManager.removeEventHook(this); if (battleUpdater != null) { TimerManager.unregister(battleUpdater); battleUpdater = null; } // Supprime les objets des rounds prcdents shots.clear(); effects.clear(); floatingTexts.clear(); sounds.clear(); destructions.clear(); effectsPanel.clear(); timeShift = null; } private void setAction(int action, ReportData report) { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); clearReport(); currentAction = action; String message = null; if (action == -1) { message = messages.battleStartMessage(); } else if (action == report.getActionsCount()) { if (report.isRetreat()) message = messages.battleRetreatMessage(); else message = messages.battleEndMessage(); } if (message != null) { FloatingText text = new FloatingText(0, "<div class=\"floatingText\">" + message + "</div>", 0, 300, 500); effectsPanel.add(text); floatingTexts.add(text); } slotsPosition = buildFleets(report, action); for (int i = 0; i < 2; i++) for (int j = 0; j < abilities[i].length; j++) { abilities[i][j].setSelected(false); } // Gnre l'animation de l'action en cours int length = 50; if (action >= 0 && action < report.getActionsCount()) { ReportActionData reportAction = report.getActionsAt(action); abilities[reportAction.getSlotIndex() < 5 ? 0 : 1][reportAction.getActionIndex()].setSelected(true); length = buildAction(report, action, slotsPosition); // Slots dtruits for (int i = 0; i < fleetsSlots.length; i++) { if (fleetsSlots[i].getCount(action + 1) == 0 && fleetsSlots[i].getCount(action) > 0) { // Explosion principale Effect destruction = new Effect(length, getSlotX(i), getSlotY(i, action), Effect.TYPE_DESTRUCTION); effectsPanel.add(destruction); effects.add(destruction); // Explosions secondaires for (int j = 0; j < 6; j++) { Effect explosion = new Effect(length + 1 + (int) (Math.random() * 14), getSlotX(i) + (int) (Math.random() * 51 - 25), getSlotY(i, action) + (int) (Math.random() * 51 - 25), Effect.TYPE_EXPLOSION); effectsPanel.add(explosion); effects.add(explosion); } destructions.add(new Destruction(length + 3, i)); // Sons sounds.add(new Sound(length - 2, Sounds.IMPACT)); sounds.add(new Sound(length, Sounds.EXPLOSION)); sounds.add(new Sound(length + 3, Sounds.IMPACT)); sounds.add(new Sound(length + 5, Sounds.IMPACT)); length += 15; } } } // Calcule la puissance des flottes et l'XP gagne la fin du round int[] initialPower = { 0, 0 }; int[] currentPower = { 0, 0 }; for (int i = 0; i < fleetsSlots.length; i++) { int shipId = fleetsSlots[i].getShipId(); if (shipId != 0) { initialPower[i / 5] += (int) (fleetsSlots[i].getCount(-1) * ShipData.CLASSES_POWER[ShipData.SHIPS[shipId].getShipClass()]); currentPower[i / 5] += (int) (fleetsSlots[i].getCount(action) * ShipData.CLASSES_POWER[ShipData.SHIPS[shipId].getShipClass()]); } } int[] initialPowerLevel = { GroupData.getLevelAtPower(initialPower[0]), GroupData.getLevelAtPower(initialPower[1]), }; for (int i = 0; i < 2; i++) powerBars[i].setPower(currentPower[i]); int xpFactorDef = report.getDefenderBeforeXpFactor(); int xpFactorAtt = report.getAttackerBeforeXpFactor(); xpViews[1].setXp((int) Math.floor((initialPower[0] - currentPower[0]) * xpFactorDef * .02 * 0.01), xpFactorDef); xpViews[0].setXp((int) Math.floor((initialPower[1] - currentPower[1]) * xpFactorAtt * .02 * 0.01), xpFactorAtt); // for (int i = 0; i < 2; i++) { // powerBars[i].setPower(currentPower[i]); // // int j = i == 1 ? 0 : 1; // double xpFactor = FleetData.getXpFactor(initialPowerLevel[i], initialPowerLevel[j]); // xpViews[i].setXp((int) Math.floor((initialPower[j] - currentPower[j]) * xpFactor * .02), xpFactor); // } // // Lance l'animation if (action <= report.getActionsCount()) { battleUpdater = new BattleUpdater(length); TimerManager.register(battleUpdater); } } private void buildEnvironment(ReportData report) { environmentPanel.getElement().setInnerHTML(""); boolean systemVisible = false; for (int player = 0; player < 2; player++) { String[] environments; int offset; if (player == 0) { environments = report.getAttackerEnvironment().split(","); offset = 400; } else { environments = report.getDefenderEnvironment().split(","); offset = 100; } for (String environment : environments) { if (environment.startsWith("asteroid")) { if (environment.equals("asteroid")) { for (int i = 0; i < 2; i++) { int[] x = { 185, 310 }; int[] y = { offset - 5, offset + 10 }; Element asteroid = DOM.createDiv(); asteroid.setClassName("asteroid env_" + "normal"); asteroid.getStyle().setProperty("left", x[i] + "px"); asteroid.getStyle().setProperty("top", y[i] + "px"); environmentPanel.getElement().appendChild(asteroid); } } else { for (int i = 0; i < 3; i++) { int[] x = { 125, 250, 370 }; int[] y = { offset - 5, offset + 5, offset - 15 }; Element asteroid = DOM.createDiv(); asteroid.setClassName("asteroid " + (i == 1 ? environment : "") + " env_" + "normal"); asteroid.getStyle().setProperty("left", x[i] + "px"); asteroid.getStyle().setProperty("top", y[i] + "px"); environmentPanel.getElement().appendChild(asteroid); } } } else if (!systemVisible && environment.startsWith("system") && (player == 0 || !report.getAttackerEnvironment().contains("system"))) { Integer starImage = Integer.parseInt(environment.substring("system".length())); Element system = DOM.createDiv(); system.setClassName("system"); system.getStyle().setProperty("backgroundPosition", -120 * (starImage - 1) + "px 0"); environmentPanel.getElement().appendChild(system); systemVisible = true; } else if (environment.equals("spaceStation") && (player == 0 || !report.getAttackerEnvironment().contains("spaceStation"))) { Element spaceStation = DOM.createDiv(); spaceStation.setClassName("spaceStation"); spaceStation.setInnerHTML("<div class=\"shield\"></div>"); environmentPanel.getElement().appendChild(spaceStation); } } } } // Affiche la tactique employe par chaque flotte private void buildTactics(ReportData report) { DynamicMessages dynamicMessages = (DynamicMessages) GWT.create(DynamicMessages.class); fleetTactics[0].clear(); fleetTactics[1].clear(); fleetTactics[0].add(new Ability(-1, -2, null)); fleetTactics[1].add(new Ability(-1, -2, null)); int length; if (report.getActionsCount() > 0) { length = report.getActionsAt(report.getActionsCount() - 1).getActionIndex(); length = (5 * (1 + length / 5)); } else { length = 0; } abilities = new Ability[2][length]; for (int i = 0; i < length; i++) { for (int j = 0; j < 2; j++) { int action = -1; int type = 0; String tooltip = null; for (int k = 0; k < report.getActionsCount(); k++) { ReportActionData reportAction = report.getActionsAt(k); if (reportAction.getActionIndex() == i && ((j == 0 && reportAction.getSlotIndex() < 5) || (j == 1 && reportAction.getSlotIndex() >= 5))) { int shipId = report.getSlotAt(j, reportAction.getSlotIndex() - (j == 1 ? 5 : 0)).getId(); ShipData ship = ShipData.SHIPS[shipId]; int ability = reportAction.getActionAbilityAt(0).getAbility(); action = k; type = ability == -1 ? -1 : ship.getAbilities()[ability].getType(); tooltip = "<div unselectable=\"on\" class=\"title\">" + dynamicMessages.getString("ship" + shipId) + "</div>" + "<div unselectable=\"on\" class=\"small\" style=\"font-weight: bold;\">"; if (ability == -1) { tooltip += "Tir"; } else { tooltip += ship.getAbilities()[ability].getName(); } tooltip += "</div><div unselectable=\"on\" class=\"x-small\">"; if (ability == -1) { // Armement du vaisseau for (WeaponGroupData weaponGroup : ship.getWeapons()) { tooltip += "<div unselectable=\"on\">" + weaponGroup.getCount() + "x " //$NON-NLS-1$//$NON-NLS-2$ + dynamicMessages.getString("weapon" + weaponGroup.getIdWeapon()) + " " + //$NON-NLS-1$ "<img unselectable=\"on\" class=\"stat s-damage\" src=\"" //$NON-NLS-1$ + Config.getMediaUrl() + "images/misc/blank.gif\"/> <b unselectable=\"on\">" + weaponGroup.getWeapon().getDamageMin() + "-" + weaponGroup.getWeapon().getDamageMax() + "</b></div>"; //$NON-NLS-2$ } } else { tooltip += ship.getAbilities()[ability].getDesc(shipId); } break; } } Ability ability = new Ability(action, type, tooltip); abilities[j][i] = ability; fleetTactics[j].add(ability); } } } // Affiche les vaisseaux et tooltip des deux flottes private int[] buildFleets(ReportData report, int action) { int[] slotsPosition = new int[10]; // Positionne les slots des deux flottes for (int i = 0; i < 10; i++) { Slot slot = fleetsSlots[i]; OpenJWT.setElementOpacity(slot.getElement(), 1); // Compte le nombre de slots sur la meme range que le vaisseau int count = 0; if (slot.getShipId() != 0) { for (int k = 5 * (i / 5); k < i; k++) { Slot slot2 = fleetsSlots[k]; if (slot2.getShipId() != 0 && slot2.getCount(action) > 0 && slot2.isFront(action) == slot.isFront(action)) count++; } slotsPosition[i] = SHIPS_POSITION[count]; battlePanel.setWidgetPosition(slot, slotsPosition[i] * 100, i < 5 ? (slot.isFront(action) ? 400 : 500) : (slot.isFront(action) ? 100 : 0)); toolTipPanel.setWidgetPosition(fleetsToolTips[i], slotsPosition[i] * 100, i < 5 ? (slot.isFront(action) ? 400 : 500) : (slot.isFront(action) ? 100 : 0)); } } for (Slot slot : fleetsSlots) slot.setAction(action); for (SlotToolTip slotToolTip : fleetsToolTips) slotToolTip.setAction(action); return slotsPosition; } private int buildAction(ReportData report, int action, int[] slotsPosition) { // Buffs des actions prcdentes for (int i = 0; i <= action; i++) { ReportActionData reportAction = report.getActionsAt(i); ReportActionAbilityData lastReportActionAbility = reportAction .getActionAbilityAt(reportAction.getActionAbilitiesCount() - 1); if (lastReportActionAbility.getAbility() != -1 && (reportAction.getModifiers() & ReportActionData.INHIBITED) == 0) { ShipData ship = ShipData.SHIPS[lastReportActionAbility.getSlotId()]; AbilityData ability = ship.getAbilities()[lastReportActionAbility.getAbility()]; switch (ability.getType()) { case AbilityData.TYPE_RETRIBUTION: // Vengeance int actionIndex = report.getActionsAt(action).getActionIndex(); int fleetOffset = reportAction.getSlotIndex() / 5; int retributionEnd = reportAction.getActionIndex() + ability.getRetributionLength(); if ((fleetOffset == 0 && actionIndex <= retributionEnd) || (fleetOffset == 1 && (actionIndex < retributionEnd || (actionIndex == retributionEnd && report.getActionsAt(action).getSlotIndex() / 5 == fleetOffset)))) { Effect buff = new Effect(0, getSlotX(reportAction.getSlotIndex()), getSlotY(reportAction.getSlotIndex(), action), Effect.TYPE_RETRIBUTION); effectsPanel.add(buff); effects.add(buff); } break; } } } ReportActionData reportAction = report.getActionsAt(action); int slotIndex = reportAction.getSlotIndex(); int fleetIndex = slotIndex < 5 ? 0 : 5; int otherFleetIndex = slotIndex < 5 ? 5 : 0; Slot slot = fleetsSlots[slotIndex]; // Dtermine si l'action a t inhibe if ((reportAction.getModifiers() & ReportActionData.INHIBITED) != 0) { for (int j = 0; j < 6; j++) { Effect effect = new Effect(j * 5 + 2, getSlotX(reportAction.getSlotIndex()), getSlotY(reportAction.getSlotIndex(), action), Effect.TYPE_TAUNT); effectsPanel.add(effect); effects.add(effect); } FloatingText text = new FloatingText(14, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">Inhib !</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; } AbilityData ability = null; ReportActionAbilityData lastReportActionAbility = reportAction .getActionAbilityAt(reportAction.getActionAbilitiesCount() - 1); if (lastReportActionAbility.getAbility() != -1) ability = ShipData.SHIPS[lastReportActionAbility.getSlotId()].getAbilities()[lastReportActionAbility .getAbility()]; if (ability == null) { // Tir normal FloatingText text = new FloatingText(0, "<div unselectable=\"on\" class=\"floatingText ability-shot\">" + "<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" " + "class=\"miniAbility\" style=\"vertical-align: middle; " + "background-position: 0 -125px;\"/> Tir !</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); buildAttack(reportAction, slotIndex, action); return 65; } else { // Capacit FloatingText text = new FloatingText(0, "<div unselectable=\"on\" class=\"floatingText ability-" + ability.getCategory() + "\"><img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" " + "class=\"miniAbility\" style=\"vertical-align: middle; " + "background-position: -" + (16 * AbilityData.GRAPHICS[ability.getType()]) + "px -125px;\"/> " + ability.getName() + "</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); switch (ability.getType()) { case AbilityData.TYPE_INHIBITOR_FIELD: // Champ inhibiteur for (int j = 0; j < 6; j++) { Effect effect = new Effect(j * 5 + 2, getSlotX(reportAction.getSlotIndex()), getSlotY(reportAction.getSlotIndex(), action), Effect.TYPE_TAUNT); effectsPanel.add(effect); effects.add(effect); } return 35; case AbilityData.TYPE_ACTIVE_LEECH: case AbilityData.TYPE_RAGE: // Vol de vaisseaux int length = 65; for (int i = 0; i < reportAction.getDamageCount(); i++) { ReportDamageData reportDamage = reportAction.getDamageAt(i); if (5 * (reportDamage.getTargetSlot() / 5) == otherFleetIndex) { int modifiers = reportDamage.getAmount() > 0 ? EFFECT_IMPACT : 0; buildShots(slotIndex, reportDamage.getTargetSlot(), slotsPosition, modifiers, 0, action); buildDamage(reportDamage, 29, slotsPosition, action, true); } else if (slotIndex == reportDamage.getTargetSlot() && reportDamage.getAmount() < 0) { Effect regeneration = new Effect(60, getSlotX(slotIndex), getSlotY(slotIndex, action) + 3, Effect.TYPE_REGENERATION); effectsPanel.add(regeneration); effects.add(regeneration); // Nombre de vaisseaux regnrs text = new FloatingText(65, "<div class=\"floatingText\" " + "style=\"color: #59cdff;\">+" + -reportDamage.getKills() + "<img class=\"stat s-struct\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); length += 30; } else if (slotIndex == reportDamage.getTargetSlot() && reportDamage.getAmount() > 0) { // Animation - impact buildImpacts(slotIndex, slotsPosition, 0, action); buildDamage(reportDamage, 29, slotsPosition, action, false); } } return length; case AbilityData.TYPE_TAUNT: // Persecution - force l'attaque for (int i = 0; i < 6; i++) { Effect effect = new Effect(i * 5 + 2, getSlotX(reportAction.getSlotIndex()), getSlotY(reportAction.getSlotIndex(), action), Effect.TYPE_TAUNT); effectsPanel.add(effect); effects.add(effect); } text = new FloatingText(14, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Cible obligatoire !</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; case AbilityData.TYPE_DAMAGE_RETURN_AURA: // Pnitence - renvoi de dgts for (int j = fleetIndex; j < fleetIndex + 5; j++) { if (fleetsSlots[j].getCount(action) > 0 && fleetsSlots[j].isFront(action) == slot.isFront(action)) { for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } text = new FloatingText(14 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Renvoi dgts<br/>+" + (int) Math.round(100 * ability.getDamageReturnAuraValue()) + "%</div>", getSlotX(j) - 100, getSlotY(j, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } return 35; case AbilityData.TYPE_PROXIMITY_CHARGE: // Charge de proximit - renvoi de dgts for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(reportAction.getSlotIndex()) + (int) (Math.random() * 41 - 20), getSlotY(reportAction.getSlotIndex(), action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(reportAction.getSlotIndex()) + (int) (Math.random() * 41 - 20), getSlotY(reportAction.getSlotIndex(), action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } text = new FloatingText(14 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Renvoi dgts<br/>+" + (int) Math.round(100 * ability.getDamageReturnAuraValue()) + "%</div>", getSlotX(reportAction.getSlotIndex()) - 100, getSlotY(reportAction.getSlotIndex(), action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; case AbilityData.TYPE_RAPID_FIRE_V2: case AbilityData.TYPE_RAPID_FIRE: case AbilityData.TYPE_DEVASTATE: case AbilityData.TYPE_PARTICLE_PROJECTION: case AbilityData.TYPE_OVERHEAT: buildAttack(reportAction, slotIndex, action); return 65; case AbilityData.TYPE_RIFT: for (int j = 0; j < 10; j++) { if (fleetsSlots[j].getCount(action) > 0) { if (fleetsToolTips[j].damageModifiers[action] > 1 || fleetsToolTips[j].hullModifiers[action] > 1 || fleetsToolTips[j].protectionModifiers[action] > 0) { for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_DEBUFF_1 : Effect.TYPE_DEBUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_DEBUFF_1 : Effect.TYPE_DEBUFF_2); effectsPanel.add(buff); effects.add(buff); } } if (fleetsToolTips[j].damageModifiers[action] < 1 || fleetsToolTips[j].hullModifiers[action] < 1 || fleetsToolTips[j].protectionModifiers[action] < 0) { for (int i = 0; i < 10; i += 2) { Effect debuff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(debuff); effects.add(debuff); } for (int i = 10; i < 35; i += 3) { Effect debuff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(debuff); effects.add(debuff); } } } } return 35; case AbilityData.TYPE_BARRAGE: // Tir de barrage int targetClass = ability.getBarrageClassTarget(); ArrayList<Integer> targets = new ArrayList<Integer>(); for (int i = otherFleetIndex; i < otherFleetIndex + 5; i++) { int shipId = fleetsSlots[i].getShipId(); if (shipId != 0 && fleetsSlots[i].getCount(action) > 0 && ShipData.SHIPS[shipId].getShipClass() == targetClass) targets.add(i); } if (targets.size() > 0) { // Tirs sur les vaisseaux affects for (Integer target : targets) { buildShots(slotIndex, target, slotsPosition, EFFECT_FRAG, 0, action); text = new FloatingText(45 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Dgts -" + (int) Math.round( 100 * (1 - (slot.isFront(action) ? ability.getBarrageFrontMalus() : ability.getBarrageBackMalus()))) + "%</div>", getSlotX(target) - 100, getSlotY(target, action), 200); effectsPanel.add(text); floatingTexts.add(text); } return 70; } else { // Aucun vaisseau affect text = new FloatingText(10, "<div class=\"floatingText\" style=\"color: red;\">" + "Sans effet" + "</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 40; } case AbilityData.TYPE_BARRAGE_V2: // Tir de barrage V2 for (int i = otherFleetIndex; i < otherFleetIndex + 5; i++) { int shipId = fleetsSlots[i].getShipId(); if (shipId != 0 && fleetsSlots[i].getCount(action) > 0) { // Tirs sur les vaisseaux affects buildShots(slotIndex, i, slotsPosition, EFFECT_FRAG, 0, action); text = new FloatingText(45 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Dgts -" + (int) Math.round( 100 * (1 - (slot.isFront(action) ? ability.getBarrageV2FrontMalus() : ability.getBarrageV2BackMalus()))) + "%</div>", getSlotX(i) - 100, getSlotY(i, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } return 70; case AbilityData.TYPE_HULL_ENERGY_TRANSFER: case AbilityData.TYPE_DAMAGE_ENERGY_TRANSFER: // Transfert d'nergie for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_DEBUFF_1 : Effect.TYPE_DEBUFF_2); effectsPanel.add(buff); effects.add(buff); } return 30; case AbilityData.TYPE_FOCUSED_FIRE: // Tir concentr for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } text = new FloatingText(14, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Dgts +" + (int) Math.round(100 * (ability.getFocusFireBonus() - 1)) + "%</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; case AbilityData.TYPE_ALL_RESISTANCE: case AbilityData.TYPE_RESISTANCE: for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(slotIndex) + (int) (Math.random() * 41 - 20), getSlotY(slotIndex, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } return 35; case AbilityData.TYPE_FRAG_CHARGE: // Charges fragmentation for (int j = fleetIndex; j < fleetIndex + 5; j++) { if (fleetsSlots[j].getCount(action) > 0 && fleetsSlots[j].isFront(action) == slot.isFront(action)) { for (int i = 0; i < 10; i += 2) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } for (int i = 10; i < 35; i += 3) { Effect buff = new Effect(i, getSlotX(j) + (int) (Math.random() * 41 - 20), getSlotY(j, action) + 7 + (int) (Math.random() * 11 - 5), Math.random() < .5 ? Effect.TYPE_BUFF_1 : Effect.TYPE_BUFF_2); effectsPanel.add(buff); effects.add(buff); } text = new FloatingText(14 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Dgts +" + (int) Math.round(100 * (ability.getFragChargeBonus() - 1)) + "%</div>", getSlotX(j) - 100, getSlotY(j, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } return 35; case AbilityData.TYPE_FORCE_FIELD: // Champ de force for (int j = fleetIndex; j < fleetIndex + 5; j++) { if (fleetsSlots[j].getCount(action) > 0) { Effect forceField = new Effect(0, getSlotX(j), getSlotY(j, action) + 3, Effect.TYPE_FORCE_FIELD); effectsPanel.add(forceField); effects.add(forceField); long sourceHull = slot.getCount(action) * ShipData.SHIPS[slot.getShipId()].getHull(); long targetHull = fleetsSlots[j].getCount(action) * ShipData.SHIPS[fleetsSlots[j].getShipId()].getHull(); int modifier; if (sourceHull >= targetHull) modifier = ability.getForceFieldHighProtectionModifier(); else modifier = ability.getForceFieldLowProtectionModifier(); text = new FloatingText(10 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">+" + modifier + " <img class=\"stat s-shield\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(j) - 100, getSlotY(j, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } return 35; case AbilityData.TYPE_DEFLECTOR: // Dflecteur for (int j = fleetIndex; j < fleetIndex + 5; j++) { if (fleetsSlots[j].getCount(action) > 0 && ShipData.SHIPS[fleetsSlots[j].getShipId()] .getShipClass() == ability.getDeflectorClassesTarget()) { Effect forceField = new Effect(0, getSlotX(j), getSlotY(j, action) + 3, Effect.TYPE_FORCE_FIELD); effectsPanel.add(forceField); effects.add(forceField); text = new FloatingText(10 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">+" + ability.getDeflectorProtectionModifier() + " " + "<img class=\"stat s-shield\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(j) - 100, getSlotY(j, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } return 35; case AbilityData.TYPE_TIME_SHIFT: // Faille temporelle timeShift = new TimeShift(0, reportAction.getSlotIndex()); return 28; case AbilityData.TYPE_RECUP: case AbilityData.TYPE_DAMAGE_REPARTITION: // Rcupration if (reportAction.getDamageCount() > 0) { //for (int j = fleetIndex; j < fleetIndex + 5; j++) { for (int j = 0; j < reportAction.getDamageCount(); j++) { ReportDamageData reportDamage = reportAction.getDamageAt(j); //if(reportDamage.getHullDamage()>0 && reportDamage.getTargetSlot()==j){ Effect regeneration = new Effect(0, getSlotX(reportDamage.getTargetSlot()), getSlotY(reportDamage.getTargetSlot(), action) + 3, Effect.TYPE_REGENERATION); effectsPanel.add(regeneration); effects.add(regeneration); // Nombre de vaisseaux regnrs text = new FloatingText(5, "<div class=\"floatingText\" " + "style=\"color: #59cdff;\">+" + -reportDamage.getKills() + "<img class=\"stat s-struct\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(reportDamage.getTargetSlot()) - 100, getSlotY(reportDamage.getTargetSlot(), action), 200); effectsPanel.add(text); floatingTexts.add(text); } } if (reportAction.getDamageCount() > 0) { return 35; } else { return 15; } case AbilityData.TYPE_REPAIR: // Rparation if (reportAction.getDamageCount() > 0) { ReportDamageData reportDamage = reportAction.getDamageAt(0); Effect regeneration = new Effect(0, getSlotX(reportDamage.getTargetSlot()), getSlotY(reportDamage.getTargetSlot(), action) + 3, Effect.TYPE_REGENERATION); effectsPanel.add(regeneration); effects.add(regeneration); // Nombre de vaisseaux regnrs text = new FloatingText(5, "<div class=\"floatingText\" " + "style=\"color: #59cdff;\">+" + -reportDamage.getKills() + "<img class=\"stat s-struct\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(reportDamage.getTargetSlot()) - 100, getSlotY(reportDamage.getTargetSlot(), action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; } else { return 15; } case AbilityData.TYPE_REPERCUTE: // rpercussion if (reportAction.getDamageCount() > 0) { ReportDamageData reportDamage = reportAction.getDamageAt(0); Effect regeneration = new Effect(0, getSlotX(reportDamage.getTargetSlot()), getSlotY(reportDamage.getTargetSlot(), action) + 3, Effect.TYPE_REGENERATION); effectsPanel.add(regeneration); effects.add(regeneration); // Nombre de vaisseaux dtruit text = new FloatingText(5, "<div class=\"floatingText\" " + "style=\"color: red;\">-" + reportDamage.getKills() + "<img class=\"stat s-death\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(reportDamage.getTargetSlot()) - 100, getSlotY(reportDamage.getTargetSlot(), action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; } else { return 15; } case AbilityData.TYPE_RETRIBUTION: // Vengeance text = new FloatingText(14, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + "Renvoi de dgts !</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 35; case AbilityData.TYPE_SACRIFICE: // Sacrifice if (slot.isFront(action)) { for (int j = otherFleetIndex; j < otherFleetIndex + 5; j++) { if (fleetsSlots[j].getCount(action) > 0 && fleetsSlots[j].isFront(action)) { long attackingHull = slot.getCount(action) * ShipData.SHIPS[slot.getShipId()].getHull(); long defendingHull = fleetsSlots[j].getCount(action) * ShipData.SHIPS[fleetsSlots[j].getShipId()].getHull(); int modifier; if (attackingHull >= defendingHull) modifier = ability.getSacrificeHighProtectionModifier(); else modifier = ability.getSacrificeLowProtectionModifier(); text = new FloatingText(35 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + modifier + " <img class=\"stat s-shield\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(j) - 100, getSlotY(j, action), 200); effectsPanel.add(text); floatingTexts.add(text); } } text = new FloatingText(35 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">" + ability.getSacrificeSelfProtectionModifier() + " <img class=\"stat s-shield\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); if (reportAction.getDamageCount() > 0) { text = new FloatingText(16, "<div class=\"floatingText\">" + reportAction.getDamageAt(0).getKills() + "<img class=\"stat s-death\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); } buildImpacts(slotIndex, slotsPosition, 0, action); return 65; } else { return 25; } case AbilityData.TYPE_CONFUSION: // Confusion if (reportAction.getDamageCount() > 0) { // Tirs sur le vaisseau affect ReportDamageData reportDamage = reportAction.getDamageAt(0); buildShots(slotIndex, reportDamage.getTargetSlot(), slotsPosition, EFFECT_FRAG, 0, action); text = new FloatingText(45 + (int) (Math.random() * 5 - 2), "<div class=\"floatingText\" style=\"" + "font-size: 10px !important\">Dgts minimum !</div>", getSlotX(reportDamage.getTargetSlot()) - 100, getSlotY(reportDamage.getTargetSlot(), action), 200); effectsPanel.add(text); floatingTexts.add(text); return 70; } else { // Aucun vaisseau affect text = new FloatingText(10, "<div class=\"floatingText\" style=\"color: red;\">" + "Sans effet" + "</div>", getSlotX(slotIndex) - 100, getSlotY(slotIndex, action), 200); effectsPanel.add(text); floatingTexts.add(text); return 40; } } } return 15; } private void buildShots(int fromSlot, int targetSlot, int[] slotsPosition, int animationEffects, int frameOffset, int action) { // Position du vaisseau qui tire boolean isTopFleet = fromSlot >= 5; Slot slot = fleetsSlots[fromSlot]; int fromPosition = slotsPosition[fromSlot]; int fromX = fromPosition * 100 + 50; int fromY = (isTopFleet ? 0 : 200) + 200 + (slot.isFront(action) ? 0 : (isTopFleet ? -100 : 100)); // Calcule la position de la cible int targetPosition = slotsPosition[targetSlot]; boolean targetSlotFront = fleetsSlots[targetSlot].isFront(action); int targetX = targetPosition * 100 + 50; int targetY = (isTopFleet ? 300 : 0) + 150 + (targetSlotFront ? 0 : (isTopFleet ? 100 : -100)); // Gnre les animations for (int k = 0; k < 10; k++) { int frame = (int) (4 * k + Math.round(Math.random() * 5) + frameOffset); int angle = targetPosition - fromPosition + 4; int offsetX; if (fromPosition > targetPosition) offsetX = (int) Math.round(Math.random() * -10) - 2; else if (fromPosition < targetPosition) offsetX = (int) Math.round(Math.random() * 10) + 2; else offsetX = (int) Math.round(Math.random() * 10) - 5; int offsetY = (int) Math.round(Math.random() * 21) - 10; // Sons des tirs for (int l = 0; l < 2; l++) switch (ShipData.SHIPS[slot.getShipId()].getShipClass()) { case ShipData.FIGHTER: case ShipData.CORVETTE: sounds.add(new Sound(frame + l, Math.random() < .5 ? Sounds.SMALL_SHOT1 : Sounds.SMALL_SHOT2)); break; case ShipData.FRIGATE: case ShipData.DESTROYER: sounds.add( new Sound(frame + l, Math.random() < .5 ? Sounds.AVERAGE_SHOT1 : Sounds.AVERAGE_SHOT2)); break; } Shot shot = new Shot(frame, fromX + offsetX, fromY + offsetY, targetX + offsetX, targetY + offsetY + (isTopFleet ? -50 : 50), angle, ShipData.SHIPS[slot.getShipId()].getShipClass()); effectsPanel.add(shot); shots.add(shot); // Animation - toiles if ((animationEffects & EFFECT_STARS) != 0) { for (int l = 0; l < DEFAULT_SHOTS_SPEED; l++) { double percent = l / (double) DEFAULT_SHOTS_SPEED; Effect specialShot = new Effect(frame + l, (int) Math.round(percent * shot.getEndX() + (1 - percent) * shot.getStartX() + Math.random() * 12 - 6), (int) Math.round(percent * shot.getEndY() + (1 - percent) * shot.getStartY() + Math.random() * 12 - 6), Effect.TYPE_SPECIAL_SHOT_1 + (int) (Math.random() * 2) + (isTopFleet ? 0 : 2)); effectsPanel.add(specialShot); effects.add(specialShot); } } // Animation - particules if ((animationEffects & EFFECT_PARTICLES) != 0) { for (int l = 0; l < DEFAULT_SHOTS_SPEED; l++) { double percent = l / (double) DEFAULT_SHOTS_SPEED; Effect specialShot = new Effect(frame + l, (int) Math.round(percent * shot.getEndX() + (1 - percent) * shot.getStartX() + Math.random() * 12 - 6), (int) Math.round(percent * shot.getEndY() + (1 - percent) * shot.getStartY() + Math.random() * 12 - 6), Effect.TYPE_PARTICLE_1 + (int) (Math.random() * 3) + (isTopFleet ? 0 : 3)); effectsPanel.add(specialShot); effects.add(specialShot); } } // Animation - fragmentation if ((animationEffects & EFFECT_FRAG) != 0) { Effect specialShot = new Effect(frame + DEFAULT_SHOTS_SPEED, targetX + offsetX, targetY + offsetY + (isTopFleet ? -40 : 40), Effect.TYPE_WEAPON_BONUS_1 + (isTopFleet ? 1 : 0)); effectsPanel.add(specialShot); effects.add(specialShot); } // Animation - impact if ((animationEffects & EFFECT_IMPACT) != 0) { Effect explosion = new Effect(frame + DEFAULT_SHOTS_SPEED, (int) (targetX + Math.round(Math.random() * 31) - 15), (int) (targetY + (isTopFleet ? -25 : 25) + Math.round(Math.random() * 31) - 15), Effect.TYPE_EXPLOSION); effectsPanel.add(explosion); effects.add(explosion); if (Math.random() < .3 || k % 4 == 0) sounds.add(new Sound(frame + DEFAULT_SHOTS_SPEED, Sounds.IMPACT)); } } } private void buildImpacts(int targetSlot, int[] slotsPosition, int frameOffset, int action) { // Calcule la position de la cible des impacts boolean isTopFleet = targetSlot < 5; boolean targetSlotFront = fleetsSlots[targetSlot].isFront(action); int targetPosition = slotsPosition[targetSlot]; int targetX = targetPosition * 100 + 50; int targetY = (isTopFleet ? 300 : 0) + 150 + (targetSlotFront ? 0 : (isTopFleet ? 100 : -100)); // Impact for (int k = 0; k < 10; k++) { int frame = (int) (4 * k + Math.round(Math.random() * 5) + frameOffset); Effect explosion = new Effect(frame + DEFAULT_SHOTS_SPEED, (int) (targetX + Math.round(Math.random() * 31) - 15), (int) (targetY + (isTopFleet ? -25 : 25) + Math.round(Math.random() * 31) - 15), Effect.TYPE_EXPLOSION); effectsPanel.add(explosion); effects.add(explosion); if (Math.random() < .3 || k % 4 == 0) sounds.add(new Sound(frame + DEFAULT_SHOTS_SPEED, Sounds.IMPACT)); } } private void buildAttack(ReportActionData reportAction, int slotIndex, int action) { int otherFleetIndex = slotIndex < 5 ? 5 : 0; for (int i = 0; i < reportAction.getDamageCount(); i++) { ReportDamageData reportDamage = reportAction.getDamageAt(i); if (5 * (reportDamage.getTargetSlot() / 5) == otherFleetIndex) { int modifiers = 0; if (reportDamage.getAmount() > 0) modifiers |= EFFECT_IMPACT; if ((reportDamage.getModifiers() & ReportDamageData.CRITICAL_HIT) != 0) modifiers |= EFFECT_STARS; if ((reportDamage.getModifiers() & ReportDamageData.PARTICLES) != 0) modifiers |= EFFECT_PARTICLES; buildShots(slotIndex, reportDamage.getTargetSlot(), slotsPosition, modifiers, 0, action); buildDamage(reportDamage, 29, slotsPosition, action, true); } else { // Animation - impact buildImpacts(reportDamage.getTargetSlot(), slotsPosition, 0, action); buildDamage(reportDamage, 29, slotsPosition, action, false); } } } private void buildDamage(ReportDamageData reportDamage, int frame, int[] slotsPosition, int action, boolean miss) { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); int targetSlot = reportDamage.getTargetSlot(); boolean isTopFleet = targetSlot < 5; int targetX = getSlotX(targetSlot); int targetY = getSlotY(targetSlot, action); int damage = reportDamage.getAmount(); int offset = 0; // Texte - Coup critique if ((reportDamage.getModifiers() & ReportDamageData.CRITICAL_HIT) != 0) { FloatingText text = new FloatingText(frame + offset, "<div class=\"floatingText\" style=\"font-size: 10px !important;\">" + messages.criticalHitShot() + "</div>", targetX - 95, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); offset -= 8; } // Texte - Esquive if ((reportDamage.getModifiers() & ReportDamageData.DODGED) != 0) { FloatingText text = new FloatingText(frame + offset, "<div class=\"floatingText\" style=\"font-size: 10px !important;\">" + messages.dodged() + "</div>", targetX - 95, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); offset -= 8; } // Texte - Sublimation if ((reportDamage.getModifiers() & ReportDamageData.SUBLIMATION) != 0) { FloatingText text = new FloatingText(frame + offset, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important;\">Sublimation</div>", targetX - 95, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); offset -= 8; } // Texte - Dphasage if ((reportDamage.getModifiers() & ReportDamageData.PHASED) != 0) { FloatingText text = new FloatingText(frame + offset, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important;\">" + messages.phased() + "</div>", targetX - 95, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); offset -= 8; } // Ressources voles for (int i = 0; i < reportDamage.getStealedResourcesCount(); i++) { if ((long) reportDamage.getStealedResourceAt(i) > 0) { FloatingText text = new FloatingText(frame + offset, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important;\">-" + Formatter.formatNumber((long) reportDamage.getStealedResourceAt(i), true) + " <img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"resource r" + i + "\"/></div>", targetX - 95, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); offset -= 8; } } if (damage > 0) { // Affiche les dgats int kills = reportDamage.getKills(); double targetHullModifier = fleetsToolTips[targetSlot].getHullModifier(action); FloatingText text = new FloatingText(frame + 8, "<div class=\"floatingText\" style=\"" + "font-size: 10px !important;\">" + (int) Math.floor(damage * targetHullModifier) + "<img class=\"stat s-damage\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", targetX - 103, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); // Affiche le nombre de vaisseaux dtruits if (kills > 0) { text = new FloatingText(frame + 16, "<div class=\"floatingText\">" + kills + "<img class=\"stat s-death\" src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\"/></div>", targetX - 97, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); } } else { // Affiche un texte "chec" du tir FloatingText text = new FloatingText(frame + 16, "<div class=\"floatingText\">" + (miss ? messages.miss() : "Sans effet") + "</div>", targetX - 100, targetY + (isTopFleet ? -20 : 20), 200); effectsPanel.add(text); floatingTexts.add(text); } } private int getSlotX(int slotIndex) { return slotsPosition[slotIndex] * 100 + 50; } private int getSlotY(int slotIndex, int action) { return slotIndex < 5 ? (fleetsSlots[slotIndex].isFront(action) ? 425 : 525) : (fleetsSlots[slotIndex].isFront(action) ? 175 : 75); } private long[] computeCount(ReportData report, int position) { ReportSlotData reportSlot = report.getSlotAt(position < 5 ? 0 : 1, position < 5 ? position : position - 5); long[] count = new long[report.getActionsCount() + 1]; // Calcule l'volution du nombre de vaisseaux sur le slot au cours // du combat if (reportSlot.getId() != 0) { count[0] = reportSlot.getCount(); for (int i = 0; i < report.getActionsCount(); i++) { ReportActionData reportAction = report.getActionsAt(i); count[i + 1] = count[i]; for (int j = 0; j < reportAction.getDamageCount(); j++) { ReportDamageData reportDamage = reportAction.getDamageAt(j); if (reportDamage.getTargetSlot() == position) { count[i + 1] -= reportDamage.getKills(); count[i + 1] = Math.max(count[i + 1], 0); } } } } return count; } private int[] computeHull(ReportData report, int position) { ReportSlotData reportSlot = report.getSlotAt(position < 5 ? 0 : 1, position < 5 ? position : position - 5); int[] hull = new int[report.getActionsCount() + 1]; // Calcule l'volution du nombre de vaisseaux sur le slot au cours // du combat if (reportSlot.getId() != 0) { int baseHull = ShipData.SHIPS[reportSlot.getId()].getHull(); hull[0] = baseHull; for (int i = 0; i < report.getActionsCount(); i++) { ReportActionData reportAction = report.getActionsAt(i); hull[i + 1] = hull[i]; for (int j = 0; j < reportAction.getDamageCount(); j++) { ReportDamageData reportDamage = reportAction.getDamageAt(j); if (reportDamage.getTargetSlot() == position) hull[i + 1] = baseHull - reportDamage.getHullDamage(); } } } return hull; } // -------------------------------------------------- CLASSES PRIVEES -- // private class XpView extends BaseWidget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private OutlineText xpValue; // ------------------------------------------------ CONSTRUCTEURS -- // public XpView(boolean top) { Element element = getElement(); element.setClassName("xpView " + (top ? "top" : "bottom")); element.setAttribute("unselectable", "on"); xpValue = TextManager.getText(""); getElement().appendChild(xpValue.getElement()); } // ----------------------------------------------------- METHODES -- // public void setXp(int xp, double xpFactor) { xpValue.setText("<div class=\"xpLabel\" unselectable=\"on\">" + Utilities.getXpImage() + " " + xp + "</div>"); StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); setToolTipText("<div class=\"title\">" + messages.experience() + "</div>" + "<div class=\"justify\">L'exprience gagne en combat " + "dpend du nombre de vaisseaux que vous dtruisez et de " + "la puissance des flottes qui s'affrontent. Attaquer des " + "flottes de puissance moindre rapporte moins d'XP, et " + "inversement.</div><div class=\"emphasize\">Coefficient XP : " + (int) (xpFactor) + "%</div>", 180); } // --------------------------------------------- METHODES PRIVEES -- // } private class PowerBar extends BaseWidget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private Element powerBarContainer, currentPower, side; private OutlineText powerValue; private WidthUpdater updater; // ------------------------------------------------ CONSTRUCTEURS -- // public PowerBar(boolean top) { Element element = getElement(); element.setClassName("powerBar " + (top ? "top" : "bottom")); element.setAttribute("unselectable", "on"); powerBarContainer = DOM.createDiv(); powerBarContainer.setClassName("container"); powerBarContainer.setAttribute("unselectable", "on"); element.appendChild(powerBarContainer); currentPower = DOM.createDiv(); currentPower.setClassName("currentProgress"); currentPower.setAttribute("unselectable", "on"); powerBarContainer.appendChild(currentPower); side = DOM.createDiv(); side.setClassName("side"); side.setAttribute("unselectable", "on"); side.setAttribute("style", "display:none;"); if (top) { side.setInnerHTML("<b>Defenseur</b>"); } else { side.setInnerHTML("<b>Attaquant</b>"); } element.appendChild(side); powerValue = TextManager.getText(""); powerBarContainer.appendChild(powerValue.getElement()); if (Config.getGraphicsQuality() > Config.VALUE_QUALITY_LOW) { updater = new WidthUpdater(currentPower, 0); TimerManager.register(updater); } } // ----------------------------------------------------- METHODES -- // public void setPower(int power) { int powerLevel = GroupData.getLevelAtPower(power); int currentPowerLevel = GroupData.getPowerAtLevel(powerLevel); int nextPowerLevel = GroupData.getPowerAtLevel(powerLevel + 1) - 1; StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); setToolTipText(null); setToolTipText("<div class=\"title\">Puissance</div>" + "<div><b>Vaisseaux : <span class=\"emphasize\">" + Formatter.formatNumber(power) + "</span> / " + Formatter.formatNumber(nextPowerLevel) + "</b></div>" + "<div class=\"justify\">" + messages.swapPowerHelp() + "</div>", 200); setCurrentProgress((power - currentPowerLevel) / (double) (nextPowerLevel - currentPowerLevel)); powerValue.setText( "<div class=\"barLabel\" unselectable=\"on\">" + "Puissance " + powerLevel + "<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"stat s-power\"/></div>"); } // --------------------------------------------- METHODES PRIVEES -- // private void setCurrentProgress(double width) { if (updater != null) updater.setTargetWidth(width); else currentPower.getStyle().setProperty("width", Math.floor(100 * width) + "%"); } } private class Slot extends Widget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int position; private int shipId; private boolean[] front; private long[] count; private boolean hyperspace; // ------------------------------------------------ CONSTRUCTEURS -- // public Slot(int position) { setElement(DOM.createDiv()); this.position = position; if (position < 5) addStyleName("bottomFleet"); else addStyleName("topFleet"); } // ----------------------------------------------------- METHODES -- // public void load(ReportData report) { ReportSlotData reportSlot = report.getSlotAt(position < 5 ? 0 : 1, position < 5 ? position : position - 5); hyperspace = (position < 5 ? report.getAttackerEnvironment() : report.getDefenderEnvironment()) .contains("hyperspace"); shipId = reportSlot.getId(); count = computeCount(report, position); front = new boolean[report.getActionsCount() + 1]; front[0] = reportSlot.isFront(); for (int i = 0; i < report.getActionsCount(); i++) front[i + 1] = report.getActionsAt(i).isFrontSlot(position); } public int getShipId() { return shipId; } public long getCount(int action) { return count[action == -1 ? 0 : action]; } public boolean isFront(int action) { return front[action == -1 ? 0 : action]; } public void setAction(int action) { if (action == -1) action = 0; DynamicMessages dynamicMessages = (DynamicMessages) GWT.create(DynamicMessages.class); // Affiche le vaisseau if (shipId != 0 && count[action] > 0) { OutlineText label = TextManager.getText("<div class=\"spaceship-label\"><span class=\"type\">" + dynamicMessages.getString("ships" + shipId) + "</span>" + "<br/>" + count[action] + "</div>"); label.getElement().getStyle().setProperty("position", "absolute"); label.getElement().getStyle().setProperty("top", (position < 5 ? 54 : 22) + "px"); label.setWidth(100); getElement().setInnerHTML((hyperspace ? "<div class=\"hyperspace hyperspaceIn\" style=\"" + "margin: " + (position < 5 ? -2 : 48) + "px 0 0 23px;\"></div>" : "") + "<div class=\"spaceship\" " + "style=\"background-position: -" + (shipId * 50) + "px 0\"></div>"); getElement().appendChild(label.getElement()); setVisible(true); } else { getElement().setInnerHTML(""); setVisible(false); } } // --------------------------------------------- METHODES PRIVEES -- // } private class SlotToolTip extends Widget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int position; private int shipId; private int availableAbilities; private long[] count; private int[] hull; private int[] protectionModifiers; private double[] damageModifiers; private double[] hullModifiers; private double damageFactor; private String[] extraTexts; // ------------------------------------------------ CONSTRUCTEURS -- // public SlotToolTip(int position) { setElement(DOM.createDiv()); this.position = position; addStyleName("fleetToolTip"); } // ----------------------------------------------------- METHODES -- // public void load(ReportData report) { ReportSlotData reportSlot = report.getSlotAt(position < 5 ? 0 : 1, position < 5 ? position : position - 5); damageFactor = (position < 5 ? report.getAttackerDamageFactor() : report.getDefenderDamageFactor()); shipId = reportSlot.getId(); count = computeCount(report, position); hull = computeHull(report, position); availableAbilities = reportSlot.getAvailableAbilities(); protectionModifiers = new int[report.getActionsCount() + 1]; damageModifiers = new double[report.getActionsCount() + 1]; hullModifiers = new double[report.getActionsCount() + 1]; extraTexts = new String[report.getActionsCount() + 1]; for (int i = 0; i < extraTexts.length; i++) extraTexts[i] = ""; if (shipId != 0) { protectionModifiers[report.getActionsCount()] = 0; damageModifiers[report.getActionsCount()] = 1 * damageFactor; hullModifiers[report.getActionsCount()] = 1; for (int i = 0; i < report.getActionsCount(); i++) { ReportActionData reportAction = report.getActionsAt(i); if (count[i] > 0) { for (int j = 0; j < reportAction.getSlotStatesCount(); j++) { ReportSlotStateData reportSlotState = reportAction.getSlotStateAt(j); if (reportSlotState.getSlotIndex() == position) { protectionModifiers[i] = reportSlotState.getProtectionModifier(); damageModifiers[i] = reportSlotState.getDamageModifier() * damageFactor; hullModifiers[i] = reportSlotState.getHullModifier(); break; } } } } } } public void setAction(int action) { if (shipId != 0 && count[action == -1 ? 0 : action] > 0) { ToolTipManager.getInstance().register(getElement(), ShipData.getDesc(shipId, 1, availableAbilities, ShipData.SHOW_PASSIVE_ABILITIES, action == -1 ? ShipData.SHIPS[shipId].getHull() : hull[action], action == -1 ? 0 : protectionModifiers[action], action == -1 ? 1 * damageFactor : damageModifiers[action], action == -1 ? 1 : hullModifiers[action]) + extraTexts[action == -1 ? 0 : action], 200); setVisible(true); } else { ToolTipManager.getInstance().unregister(getElement()); setVisible(false); } } public double getHullModifier(int action) { return hullModifiers[action == -1 ? 0 : action]; } // --------------------------------------------- METHODES PRIVEES -- // } private class Shot extends Widget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private int startX, startY, endX, endY; // ------------------------------------------------ CONSTRUCTEURS -- // public Shot(int frame, int startX, int startY, int endX, int endY, int angle, int shipClass) { setElement(DOM.createDiv()); setStyleName("shoot top"); getElement().getStyle().setProperty("backgroundPosition", "-" + (angle * 30) + "px " + "-" + (1320 + (startY < endY ? 90 : 0) + ((shipClass - 1) / 2) * 30) + "px"); setVisible(false); this.frame = frame; this.startX = startX; this.startY = startY; this.endX = endX; this.endY = endY; } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public int getStartX() { return startX; } public int getStartY() { return startY; } public int getEndX() { return endX; } public int getEndY() { return endY; } // --------------------------------------------- METHODES PRIVEES -- // } private class TimeShift { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private int slotIndex; // ------------------------------------------------ CONSTRUCTEURS -- // public TimeShift(int frame, int slotIndex) { this.frame = frame; this.slotIndex = slotIndex; } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public int getSlotIndex() { return slotIndex; } // --------------------------------------------- METHODES PRIVEES -- // } private class Effect extends Widget { // --------------------------------------------------- CONSTANTES -- // public final static int TYPE_EXPLOSION = 1, TYPE_DESTRUCTION = 2, TYPE_SPECIAL_SHOT_1 = 3, TYPE_SPECIAL_SHOT_2 = 4, TYPE_SPECIAL_SHOT_3 = 5, TYPE_SPECIAL_SHOT_4 = 6, TYPE_REGENERATION = 7, TYPE_FORCE_FIELD = 8, TYPE_WEAPON_BONUS_1 = 9, TYPE_WEAPON_BONUS_2 = 10, TYPE_BUFF_1 = 11, TYPE_BUFF_2 = 12, TYPE_DEBUFF_1 = 13, TYPE_DEBUFF_2 = 14, TYPE_RETRIBUTION = 15, TYPE_TAUNT = 16, TYPE_PARTICLE_1 = 17, TYPE_PARTICLE_2 = 18, TYPE_PARTICLE_3 = 19, TYPE_PARTICLE_4 = 20, TYPE_PARTICLE_5 = 21, TYPE_PARTICLE_6 = 22; // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private int type; // ------------------------------------------------ CONSTRUCTEURS -- // public Effect(int frame, int x, int y, int type) { setElement(DOM.createDiv()); setStyleName("effect"); getElement().getStyle().setProperty("left", x + "px"); getElement().getStyle().setProperty("top", y + "px"); setVisible(false); this.frame = frame; this.type = type; } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public int getType() { return type; } // --------------------------------------------- METHODES PRIVEES -- // } private class FloatingText extends SimplePanel { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private int x, y; // ------------------------------------------------ CONSTRUCTEURS -- // public FloatingText(int frame, String text, int x, int y, int width) { this.frame = frame; getElement().getStyle().setProperty("position", "absolute"); OutlineText outlineText = TextManager.getText(text); add(outlineText); setLocation(x, y); outlineText.setWidth(width); setVisible(false); } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public int getX() { return x; } public int getY() { return y; } public void setLocation(int x, int y) { this.x = x; this.y = y; getElement().getStyle().setProperty("left", x + "px"); getElement().getStyle().setProperty("top", y + "px"); } // --------------------------------------------- METHODES PRIVEES -- // } private class Sound { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private String soundName; // ------------------------------------------------ CONSTRUCTEURS -- // public Sound(int frame, String soundName) { this.frame = frame; this.soundName = soundName; } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public String getSound() { return soundName; } // --------------------------------------------- METHODES PRIVEES -- // } private class Destruction { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int frame; private int slotIndex; // ------------------------------------------------ CONSTRUCTEURS -- // public Destruction(int frame, int slotIndex) { this.frame = frame; this.slotIndex = slotIndex; } // ----------------------------------------------------- METHODES -- // public int getFrame() { return frame; } public int getSlotIndex() { return slotIndex; } // --------------------------------------------- METHODES PRIVEES -- // } private class Ability extends Widget { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int action; // ------------------------------------------------ CONSTRUCTEURS -- // public Ability(int action, int ability, String toolTip) { this.action = action; setElement(DOM.createDiv()); setStylePrimaryName("action"); if (action != -1) { int graphics = ability == -1 ? 0 : AbilityData.GRAPHICS[ability]; getElement().setInnerHTML( "<div id=\"a" + action + "\" class=\"actionAbility\" " + "style=\"background-position: -" + (graphics * 25) + "px -100px;\">" + "<div class=\"selection\"></div></div>"); ToolTipManager.getInstance().register(getElement(), toolTip, 220); } sinkEvents(Event.ONCLICK | Event.KEYEVENTS); } // ----------------------------------------------------- METHODES -- // public void setSelected(boolean selected) { if (selected) addStyleDependentName("selected"); else removeStyleDependentName("selected"); } @Override public void onBrowserEvent(Event event) { switch (event.getTypeInt()) { case Event.ONCLICK: if (action != -1) setAction(action, reports.get(currentReportId)); break; case Event.ONKEYDOWN: onEventPreview(event); break; } } // --------------------------------------------- METHODES PRIVEES -- // } private class BattleUpdater implements TimerHandler { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private int length; private int frame; private boolean pause; // ------------------------------------------------ CONSTRUCTEURS -- // public BattleUpdater(int length) { this.length = length; this.frame = 0; } // ----------------------------------------------------- METHODES -- // public boolean isPaused() { return pause; } public void setPaused(boolean pause) { this.pause = pause; } public boolean isFinished() { return false; } public void update(int interpolation) { if (pause) return; // Mise jour de l'animation des tirs for (int i = 0; i < shots.size(); i++) { Shot shot = shots.get(i); if (frame == shot.getFrame()) { shot.getElement().getStyle().setProperty("left", shot.getStartX() + "px"); shot.getElement().getStyle().setProperty("top", shot.getStartY() + "px"); shot.setVisible(true); } else if (frame > shot.getFrame() && shot.isVisible()) { double percent = (frame - shot.getFrame()) / (double) DEFAULT_SHOTS_SPEED; if (percent >= 1) { shot.setVisible(false); } else { shot.getElement().getStyle().setProperty("left", (int) Math.round((1 - percent) * shot.getStartX() + percent * shot.getEndX()) + "px"); shot.getElement().getStyle().setProperty("top", (int) Math.round((1 - percent) * shot.getStartY() + percent * shot.getEndY()) + "px"); } } } // Mise jour des animations (explosions...) for (Effect effect : effects) { int length = 0; int offsetX = 0, offsetY = 0; int df = frame - effect.getFrame(); int size = 0; switch (effect.getType()) { case Effect.TYPE_EXPLOSION: length = 12; offsetX = df * 32; offsetY = 450; size = 32; break; case Effect.TYPE_DESTRUCTION: length = 12; offsetX = (df % 5) * 100; offsetY = 150 + (df / 5) * 100; size = 100; break; case Effect.TYPE_SPECIAL_SHOT_1: case Effect.TYPE_SPECIAL_SHOT_2: case Effect.TYPE_SPECIAL_SHOT_3: case Effect.TYPE_SPECIAL_SHOT_4: length = 2; offsetX = 200 + (effect.getType() - Effect.TYPE_SPECIAL_SHOT_1) * 13; offsetY = 430; size = 13; break; case Effect.TYPE_PARTICLE_1: case Effect.TYPE_PARTICLE_2: case Effect.TYPE_PARTICLE_3: case Effect.TYPE_PARTICLE_4: case Effect.TYPE_PARTICLE_5: case Effect.TYPE_PARTICLE_6: length = 1; offsetX = 252 + (effect.getType() - Effect.TYPE_PARTICLE_1) * 20; offsetY = 430; size = 20; break; case Effect.TYPE_REGENERATION: length = 11; offsetX = (df % 6) * 75; offsetY = (df / 6) * 75; size = 75; break; case Effect.TYPE_FORCE_FIELD: length = 2000; offsetX = 350; offsetY = 350; size = 80; break; case Effect.TYPE_WEAPON_BONUS_1: case Effect.TYPE_WEAPON_BONUS_2: length = 3; offsetX = 200 + df * 40; offsetY = 350 + (effect.getType() - Effect.TYPE_WEAPON_BONUS_1) * 40; size = 40; break; case Effect.TYPE_BUFF_1: case Effect.TYPE_BUFF_2: length = 4; offsetX = 500; offsetY = df * 9 + 90 * (effect.getType() - Effect.TYPE_BUFF_1); size = 60; break; case Effect.TYPE_DEBUFF_1: case Effect.TYPE_DEBUFF_2: length = 4; offsetX = 500; offsetY = -df * 9 + 216 + 90 * (effect.getType() - Effect.TYPE_DEBUFF_1); size = 60; break; case Effect.TYPE_RETRIBUTION: length = 100; offsetX = 430; offsetY = 350; size = 70; break; case Effect.TYPE_TAUNT: length = 5; offsetX = df * 70; offsetY = 482; size = 70; break; } if (frame >= effect.getFrame() && frame < effect.getFrame() + length) { // Mise jour de l'animation effect.getElement().getStyle().setProperty("backgroundPosition", "-" + offsetX + "px -" + offsetY + "px"); if (frame == effect.getFrame()) { effect.setSize(size + "px", size + "px"); effect.getElement().getStyle().setProperty("margin", (-size / 2) + "px 0 0 " + (-size / 2) + "px"); effect.setVisible(true); } // Secoue l'cran lorsqu'un vaisseau est dtruit if (effect.getType() == Effect.TYPE_DESTRUCTION) { String offset = frame > effect.getFrame() + length / 2 ? (int) (Math.random() * 5 - 2) + "px 0 0 " + (int) (Math.random() * 5 - 2) + "px" : (int) (Math.random() * 11 - 5) + "px 0 0 " + (int) (Math.random() * 11 - 5) + "px"; Client.getInstance().getFullScreenPanel().getElement().getStyle().setProperty("margin", offset); Client.getInstance().getAreaContainer().getElement().getStyle().setProperty("margin", offset); } } else if (frame == effect.getFrame() + length) { // Fin de l'animation effect.setVisible(false); if (effect.getType() == Effect.TYPE_DESTRUCTION) { Client.getInstance().getFullScreenPanel().getElement().getStyle().setProperty("margin", ""); Client.getInstance().getAreaContainer().getElement().getStyle().setProperty("margin", ""); } } } // Mise jour de l'animation des textes for (FloatingText floatingText : floatingTexts) { if (frame == floatingText.getFrame()) { floatingText.setVisible(true); } else if (frame >= floatingText.getFrame() && frame < floatingText.getFrame() + 25) { floatingText.setLocation(floatingText.getX(), floatingText.getY() - 2); } else if (frame == floatingText.getFrame() + 25) { floatingText.setVisible(false); } } // Mise jour des sons for (Sound sound : sounds) { if (frame == sound.getFrame()) { SoundManager.getInstance().playSound(sound.getSound()); } } // Mise jour de l'affichage des vaisseaux dtruits for (Destruction destruction : destructions) { if (frame == destruction.getFrame()) { fleetsSlots[destruction.getSlotIndex()].getElement().setInnerHTML(""); ToolTipManager.getInstance() .unregister(fleetsToolTips[destruction.getSlotIndex()].getElement()); } } // Faille temporelle if (timeShift != null && frame >= timeShift.getFrame() && frame < timeShift.getFrame() + 25) { int dframe = frame - timeShift.getFrame(); if (dframe <= 10) { OpenJWT.setElementOpacity(fleetsSlots[timeShift.getSlotIndex()].getElement(), 1 - dframe / 10.); } else if (dframe > 15) { OpenJWT.setElementOpacity(fleetsSlots[timeShift.getSlotIndex()].getElement(), (dframe - 15) / 10.); } if (dframe == 10) fleetsSlots[timeShift.getSlotIndex()].setAction(currentAction + 1); } frame++; // Round suivant si le round est fini if (frame == length) { ReportData report = reports.get(currentReportId); if (currentAction < report.getActionsCount()) { setAction(currentAction + 1, report); } } } public void destroy() { // Sans effet } // --------------------------------------------- METHODES PRIVEES -- // } }