/*
* Copyright (c) 2003-onwards Shaven Puppy Ltd
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'Shaven Puppy' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package worm.screens;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import net.puppygames.applet.Area;
import net.puppygames.applet.Game;
import net.puppygames.applet.MiniGame;
import net.puppygames.applet.Screen;
import net.puppygames.applet.TickableObject;
import net.puppygames.applet.effects.AdjusterEffect;
import net.puppygames.applet.effects.Effect;
import net.puppygames.applet.effects.FadeEffect;
import net.puppygames.applet.effects.LabelEffect;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Color;
import org.lwjgl.util.Point;
import org.lwjgl.util.ReadableColor;
import org.lwjgl.util.ReadablePoint;
import org.lwjgl.util.ReadableRectangle;
import org.lwjgl.util.Rectangle;
import worm.AttenuatedColor;
import worm.Hints;
import worm.Layers;
import worm.MapRenderer;
import worm.Res;
import worm.SFX;
import worm.ShopItem;
import worm.TimeUtil;
import worm.Worm;
import worm.WormGameState;
import worm.animation.SimpleThingWithLayers;
import worm.buildings.BuildingFeature;
import worm.entities.Building;
import worm.entities.Gidrah;
import worm.features.HintFeature;
import worm.features.LayersFeature;
import worm.features.LevelColorsFeature;
import worm.features.LevelFeature;
import worm.powerups.PowerupFeature;
import worm.powerups.RepairPowerupFeature;
import worm.powerups.ShieldPowerupFeature;
import com.shavenpuppy.jglib.Resources;
import com.shavenpuppy.jglib.interpolators.ColorInterpolator;
import com.shavenpuppy.jglib.interpolators.LinearInterpolator;
import com.shavenpuppy.jglib.openal.ALBuffer;
import com.shavenpuppy.jglib.openal.ALStream;
import com.shavenpuppy.jglib.opengl.ColorUtil;
import com.shavenpuppy.jglib.opengl.GLRenderable;
import com.shavenpuppy.jglib.opengl.GLTextArea;
import com.shavenpuppy.jglib.resources.ColorMapFeature;
import com.shavenpuppy.jglib.resources.MappedColor;
import com.shavenpuppy.jglib.resources.TextResource;
import com.shavenpuppy.jglib.sound.SoundEffect;
import com.shavenpuppy.jglib.sprites.Appearance;
import com.shavenpuppy.jglib.util.FPMath;
import com.shavenpuppy.jglib.util.Util;
import static org.lwjgl.opengl.GL11.*;
/**
* $Id: GameScreen.java,v 1.155 2010/11/06 18:56:33 foo Exp $
*
* @author $Author: foo $
* @version $Revision: 1.155 $
*/
public class GameScreen extends Screen {
private static final long serialVersionUID = 1L;
private static final boolean ALLOW_SCROLL_PAST = true;
private static final GLRenderable SETUP_RENDERING = new GLRenderable() {
@Override
public void render() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);
}
};
private transient boolean debug = false;
private static final int HINT_SCALE = FPMath.fpValue(0.33f);
private static final int SAVE_DURATION = 45;
private static final int ZOOM_SPEED = 32;
private static final int SCROLL_SPEED = 8;
// private static final int MAX_MOUSE_SCROLL_SPEED = 32;
/** How long the shop lurks around for after it's not needed */
private static final int SHOP_LURK = 60;
/** Ticks before full shop info appears */
private static final int SHOP_SENSITIVITY = 60;
/** Shop fade in rate */
private static final int SHOP_FADE_RATE = 32;
/** Hint fade in rate */
private static final int HINT_FADE_RATE = 96;
/** Hud fade rate */
private static final int HUD_ALPHA_FADE_SPEED = 32;
/** Hint duration */
private static final int HINT_DURATION = 10 * 60;
/** Areas */
private static final String ID_BASE_UNDER_ATTACK = "base_attack_alert";
private static final String ID_DESTRUCTION_IMMINENT = "base_critical_alert";
private static final String ID_POWERUP_SHORTCUTS = "id_powerup_quicklaunch_";
private static final String ID_BUILDING_SHORTCUTS = "build_";
private static final String HUD = "hud";
private static final String ID_HIDEABLE_GROUP = "hideable";
private static final String ID_TOP_HUD_GROUP ="hud_top";
private static final String ID_MAP = "map";
private static final String ID_BASE = "shortcut_base_zoom";
private static final String ID_CRYSTAL = "shortcut_crystal_zoom";
private static final String ID_CRYSTAL_REMAINING = "shortcut_crystal_remaining";
private static final String ID_BASE_GROUP = "base_button_group";
private static final String ID_CRYSTAL_GROUP = "crystal_button_group";
private static final String ID_CRYSTAL_MESSAGE_GROUP = "crystal_message";
private static final String ID_INFO_ALERT_GROUP = "info_alert";
private static final String ID_HUD_SIDES = "hud_sides";
private static final String ID_BEZERK_TIMER = "hud_bezerk_timer";
private static final String ID_SHIELD_TIMER = "hud_shield_timer";
private static final String ID_FREEZE_TIMER = "hud_freeze_timer";
private static final String ID_BEZERK_TIMER_BAR = "hud_bezerk_timer_bar";
private static final String ID_SHIELD_TIMER_BAR = "hud_shield_timer_bar";
private static final String ID_FREEZE_TIMER_BAR = "hud_freeze_timer_bar";
private static final String ID_HUD_TOP_HIDE = "hud_top_hide";
private static final String ID_TIMER_BAR = "hud_timer_bar";
private static final String ID_THREAT_LOW = "shortcut_threat_low";
private static final String ID_THREAT_HIGH = "shortcut_threat_high";
private static final String ID_TOOLTIPS = "tooltip";
private static final String ID_SELL = "shortcut_sell";
private static final String ID_SHOWHIDE = "showhide";
private static final String ID_MENU = "shortcut_esc";
private static final String SHOW_ICON_GROUP = "showicon";
// Misc
private static final String COST_GROUP = "cost_group";
private static final String ID_COST = "cost_info";
private static final String ID_BUILDING_DONE = "building_done";
private static final String ID_SELL_DONE = "sell_done";
private static final String SELL_INFO_GROUP = "sell_info_group";
private static final String ID_SELL_INFO_DONE = "sell_info_done";
private static final String ID_HINT_GROUP = "hint";
private static final String ID_HINT_TEXT = "hintscreen-text";
private static final String ID_HINT_CLOSE = "hintscreen-close";
private static final String ID_HINT_SPRITE_LOCATION = "hintscreen-sprite";
// HUD bits
private static final String ID_MONEY = "money";
private static final String ID_LEVEL = "level";
private static final String ID_FASTFORWARD = "shortcut_fastforward";
private static final String ID_MISC_SHORTCUTS = "shortcut";
// chaz hack! build cost info positions - should get from bounds of some areas, but this'll do */
private static final int COST_INFO_Y_HIGH = 46;
private static final int COST_INFO_Y_LOW = 1;
private static final int COST_INFO_BUTTON_OFFSET = 8;
/*
* Static data
*/
private static final String TIME_LEFT_COLOR_BOTTOM = "time-left-color-left";
private static final String TIME_LEFT_COLOR_TOP = "time-left-color-right";
private static final String TIME_PAST_COLOR_BOTTOM = "time-past-color-left";
private static final String TIME_PAST_COLOR_TOP = "time-past-color-right";
private static final Color TEMPCOLOR = new Color();
private static final String POWERUP_TIME_LEFT_COLOR_BOTTOM = "gui-bright";
private static final String POWERUP_TIME_LEFT_COLOR_TOP = "gui-bright";
private static final String POWERUP_TIME_PAST_COLOR_BOTTOM = "gui-dark";
private static final String POWERUP_TIME_PAST_COLOR_TOP = "gui-dark";
private static final String CANT_BUILD_COLOR = "gui-dark";
private static final String BUILD_COLOR = "gui-bright";
/*
* Shop stuff
*/
private static final String ID_BUILDINGS_TITLETEXT = "id_buildings_titletext";
private static final String ID_BUILDINGS_TITLETEXT_NO_KEY = "id_buildings_titletext_no_key";
private static final String ID_BUILDINGS_INFOTEXT = "id_buildings_infotext";
private static final String ID_BUILDINGS_BONUSTEXT = "id_buildings_bonustext";
private static final String ID_BUILDINGS_COSTTEXT = "id_buildings_costtext";
private static final String ID_POWERUPS_LABEL = "id_powerups_label";
private static final String ID_BUILDINGS_INFO_GROUP ="buildings_info";
private static final String ID_POWERUPS_INFO_GROUP ="powerups_info";
private static final String ID_INFO_GROUP ="info";
private static final String ID_BUILDINGS_DATA_GROUP ="buildings_data";
private static final String ID_POWERUPS_DATA_GROUP ="powerups_data";
private static final String[] dataGroups = {ID_BUILDINGS_DATA_GROUP, ID_POWERUPS_DATA_GROUP};
private static final String ID_INFO_SPRITE_LOCATION = "id_info_sprite_location";
private MappedColor shopItemColor;
/** Singleton */
public static GameScreen instance;
/** Cached colour */
private static final Color cachedColor = new Color();
/** Temp rectangle */
private static final Rectangle tempRect = new Rectangle();
/** Current game state */
private static WormGameState gameState;
/** Sprite offset */
private static final Point OFFSET = new Point();
/*
* Resource data
*/
/*
* Transient data
*/
/** Map rendering */
private transient MapRenderer renderer;
/** Locations of stuff */
private transient Area moneyArea, levelArea, costArea, costAreaLabel, crystalArea, mapArea, timerBarArea, threatLowArea, threatHighArea, freezeBarArea, bezerkBarArea, shieldBarArea, crystalRemainingArea;
/** Currently displayed cash amount */
private transient int displayedCash;
/** Currently displayed crystals amount */
private transient int displayedCrystals;
/** Map coordinates */
private transient float mapX, mapY;
/** Shaking */
private transient int shakeTick;
private transient boolean shook;
/** Particle debug */
private transient GLTextArea particleDebug;
/** base destruction klaxon */
private transient SoundEffect baseDestructionEffect;
/** Base attacked effect */
private transient FadeEffect baseAttackedEffect;
/** Base destruction effect */
private transient FadeEffect baseDestructionImminentEffect;
/** Crstals unattended */
private transient FadeEffect unminedCrystalEffect;
/** Tooltip effect */
private transient FadeEffect tooltipEffect;
/** Wet rumble */
private transient SoundEffect wetRumble;
/** Dry rumble */
private transient SoundEffect dryRumble;
/** Rumble gain */
private transient float rumbleGain, targetRumbleGain;
/** Rumble buffers */
private transient ALBuffer wetBuffer;
private transient ALBuffer dryBuffer;
/** Powerup sounds */
private transient SoundEffect bezerkSoundEffect, shieldSoundEffect, freezeSoundEffect;
/** Zooming */
private transient int zoomTick, zoomDuration;
private transient float startZoomX, startZoomY, endZoomX, endZoomY;
/** Side HUD alpha */
private transient int sideHUDAlpha;
/** Timer bar colors */
private transient ReadableColor timeLeftColorBottom, timeLeftColorTop, timePastColorBottom, timePastColorTop;
/** Powerup timer bar colors */
private transient ReadableColor powerupTimeLeftColorBottom, powerupTimeLeftColorTop, powerupTimePastColorBottom, powerupTimePastColorTop;
private transient boolean shieldTimerVisible, freezeTimerVisible, bezerkTimerVisible;
private transient int shieldTimerMax, freezeTimerMax, bezerkTimerMax;
/** build info colors */
private transient ReadableColor buildColor;
private transient ReadableColor cantBuildColor;
/** Rendery stuff */
private transient TickableObject tickableObject;
/** FF processing */
private transient boolean fastForward;
/** Info sprite location */
private transient Area infoSpriteLocationArea;
private transient SimpleThingWithLayers infoLayers;
private transient Area titleTextArea;
private transient Area titleTextNoKeyArea;
private transient Area infoTextArea;
private transient Area bonusTextArea;
private transient Area costTextArea;
/* Tooltippery shop stuff */
private transient ShopItem hover = null;
private transient String currentTooltipID;
private transient int infoTimer;
private transient ShopItem infoItem;
private transient AdjusterEffect shopEffect;
private transient boolean shopSpritesVisible;
/* hints stuff */
private transient AdjusterEffect hintEffect;
private transient HintFeature currentHint;
private transient Area hintTextArea;
private transient SimpleThingWithLayers hintLayers;
private transient boolean hintSpritesVisible;
private transient Area hintSpriteLocationArea;
private transient boolean repairFlagged, shieldFlagged;
/** Show/hide bottom hud */
private transient int hudAlpha, hudAlphaTarget;
/** Show/hide top hud */
private transient int topHudAlpha, topHudAlphaTarget;
/** Showing sell stuff */
private transient boolean sellActive;
/** hint queue */
private transient List<HintFeature> hintQueue;
/** Hint duration ticker */
private transient int hintTick;
/**
* C'tor
*/
public GameScreen(String name) {
super(name);
setAutoCreated();
}
@Override
protected void doRegister() {
instance = this;
}
@Override
protected void doDeregister() {
instance = null;
}
// transient boolean buttonWasDown;
// transient Emitter emitter;
// transient EmitterDiddler diddler;
// transient LevelColourDiddler levelColourDiddler;
public static boolean isDiddlerOpen() {
// return instance.levelColourDiddler != null && instance.levelColourDiddler.isShowing();
return false;
}
// transient int medals;
@Override
protected void doTick() {
if (Game.DEBUG) {
if (Game.wasKeyPressed(Keyboard.KEY_D)) {
debug = !debug;
renderer.setDebug(debug);
}
// if (Game.wasKeyPressed(Keyboard.KEY_F8)) {
// ArrayList a = new ArrayList(MedalFeature.getMedals().keySet());
// if (medals == a.size()) {
// medals = 0;
// }
// String m = (String) a.get(medals ++);
// gameState.awardMedal(m);
// }
//
// if (Game.wasKeyPressed(Keyboard.KEY_1)) {
// Gidrah g = ((GidrahFeature) Resources.get("gidrah.earth.boss")).spawn(this, (getMouseX() - OFFSET.getX()) / MapRenderer.TILE_SIZE, (getMouseY() - OFFSET.getY()) / MapRenderer.TILE_SIZE, 1);
// g.setHitPoints(1);
// }
// if (Game.wasKeyPressed(Keyboard.KEY_2)) {
// Gidrah g = ((GidrahFeature) Resources.get("gidrah.moon.boss")).spawn(this, (getMouseX() - OFFSET.getX()) / MapRenderer.TILE_SIZE, (getMouseY() - OFFSET.getY()) / MapRenderer.TILE_SIZE, 1);
// g.setHitPoints(1);
// }
// if (Game.wasKeyPressed(Keyboard.KEY_3)) {
// Gidrah g = ((GidrahFeature) Resources.get("gidrah.mars.boss")).spawn(this, (getMouseX() - OFFSET.getX()) / MapRenderer.TILE_SIZE, (getMouseY() - OFFSET.getY()) / MapRenderer.TILE_SIZE, 1);
// g.setHitPoints(1);
// }
// if (Game.wasKeyPressed(Keyboard.KEY_4)) {
// Gidrah g = ((GidrahFeature) Resources.get("gidrah.saturn.boss")).spawn(this, (getMouseX() - OFFSET.getX()) / MapRenderer.TILE_SIZE, (getMouseY() - OFFSET.getY()) / MapRenderer.TILE_SIZE, 1);
// g.setHitPoints(1);
// }
// if (Game.wasKeyPressed(Keyboard.KEY_5)) {
// Gidrah g = ((GidrahFeature) Resources.get("gidrah.titan.boss")).spawn(this, (getMouseX() - OFFSET.getX()) / MapRenderer.TILE_SIZE, (getMouseY() - OFFSET.getY()) / MapRenderer.TILE_SIZE, 1);
// g.setHitPoints(1);
// }
//
//
////
// if (Game.wasKeyPressed(Keyboard.KEY_H)) {
// renderer.setDebug(debug);
// // tip test
// HintFeature hf = HintFeature.getNext();
// GameScreen.getInstance().showHint(hf);
// }
//
// if (Game.wasKeyPressed(Keyboard.KEY_Y) && isOpen()) {
// diddler = new EmitterDiddler();
// diddler.addWindowListener(new WindowAdapter() {
// @Override
// public void windowClosed(WindowEvent e) {
// synchronized (this) {
// diddler = null;
// }
// }
// });
// }
//
// if (Mouse.isButtonDown(0) && diddler != null) {
// synchronized (this) {
// if (!buttonWasDown) {
// if (Resources.exists(diddler.getSelectedEmitter())) {
// EmitterFeature ef;
// try {
// if (emitter != null) {
// emitter.remove();
// emitter = null;
// }
// ef = (EmitterFeature) Resources.get(diddler.getSelectedEmitter());
// emitter = ef.spawn(this);
// emitter.setLocation(getMouseX() - OFFSET.getX(), getMouseY() - OFFSET.getY());
// emitter.setOffset(OFFSET);
// //if (ef.isDoYOffset()) {
// // emitter.setFloor(getMouseY() - OFFSET.getY());
// //}
// } catch (Exception e) {
// e.printStackTrace(System.err);
// }
// }
// }
// }
// buttonWasDown = true;
// } else {
// buttonWasDown = false;
// }
//
// if (Game.wasKeyPressed(Keyboard.KEY_C)) {
// levelColourDiddler = new LevelColourDiddler();
// levelColourDiddler.setListener(new ChangeListener() {
// public void stateChanged(ChangeEvent e) {
// if (levelColourDiddler.getSelected() instanceof LevelColorsFeature) {
// LevelColorsFeature levelColors = (LevelColorsFeature) levelColourDiddler.getSelected();
// ColorMapFeature.getDefaultColorMap().copy(levelColors);
// }
// }
// });
// Game.setAlwaysRun(true);
// }
//
// if (levelColourDiddler != null && !levelColourDiddler.isVisible()) {
// levelColourDiddler = null;
// Game.setAlwaysRun(false);
// }
}
if (Game.isPaused()) {
return;
}
// Update the mouse location (scaled by screen size)
if (!fastForward) {
handleMouse();
}
MiniGame.onTicked();
gameState.tick();
renderer.render((int) mapX + renderer.getOriginX(), (int) mapY + renderer.getOriginY());
calcRumble();
Rectangle r = (Rectangle) getArea(ID_HUD_TOP_HIDE).getBounds();
if (r.contains(getMouseX(), getMouseY())) {
topHudAlphaTarget = 0;
} else {
topHudAlphaTarget = 255;
}
if (gameState.isBuilding()) {
setGroupVisible(COST_GROUP, true);
// Get rid of the shop
setHover(null);
boolean canBuild = true;
StringBuilder buildText = new StringBuilder(64);
buildText.append(gameState.getBuilding().getShortTitle());
buildText.append(' ');
if (!gameState.isBuildingAvailable()) {
buildText.append("N/A");
canBuild = false;
} else {
int inv = gameState.getBuilding().getInventory();
int buildingCost = gameState.getBuildingCost();
if (buildingCost == 0) {
buildText.append(Game.getMessage("ultraworm.gamescreen.free"));
} else {
buildText.append('$');
buildText.append(buildingCost);
if (gameState.getBuilding().getMaxAvailable() > 0) {
buildText.append(" [");
buildText.append(inv);
buildText.append("]");
}
}
if (buildingCost > gameState.getMoney()) {
canBuild = false;
}
}
Appearance buildInfoIconAnim;
if (canBuild) {
costArea.setTextColors(buildColor, buildColor);
buildInfoIconAnim = (Appearance) Resources.get("buildInfo."+gameState.getBuilding().getShopIcon()+".on.animation");
} else {
costArea.setTextColors(cantBuildColor, cantBuildColor);
buildInfoIconAnim = (Appearance) Resources.get("buildInfo."+gameState.getBuilding().getShopIcon()+".off.animation");
}
costArea.setMouseOffAppearance(buildInfoIconAnim);
costArea.setMouseOnAppearance(buildInfoIconAnim);
costArea.setText(buildText.toString());
} else {
setGroupVisible(COST_GROUP, false);
}
updateHUD();
}
@Override
protected void onBlocked() {
setPaused(true);
}
@Override
protected void onUnblocked() {
setPaused(false);
}
private void calcRumble() {
if (wetRumble == null || dryRumble == null || wetBuffer == null || dryBuffer == null) {
return;
}
if (isBlocked()) {
targetRumbleGain = 0.0f;
} else {
targetRumbleGain = 1.0f;
}
if (rumbleGain < targetRumbleGain) {
rumbleGain = Math.min(targetRumbleGain, rumbleGain + 0.0125f);
} else if (rumbleGain > targetRumbleGain) {
rumbleGain = Math.max(targetRumbleGain, rumbleGain - 0.0125f);
}
float x = mapX + renderer.getOriginX() + Game.getWidth() / 2.0f;
float y = mapY + renderer.getOriginY() + Game.getHeight() / 2.0f;
ArrayList<Gidrah> gidrahs = gameState.getGidrahs();
int n = gidrahs.size();
float totalDry = 0.0f;
float totalWet = 0.0f;
for (int i = 0; i < n; i ++) {
Gidrah g = gidrahs.get(i);
if (g.isActive() && !g.isFrozen() && !(g.getFeature().isWraith() || g.getFeature().isFlying())) {
float dist = g.getDistanceTo(x, y);
// Wet drops off at distance
totalWet += LinearInterpolator.instance.interpolate(1.0f, 0.0f, dist / Worm.MAX_LOUD_ATTENUATION_DISTANCE);
// Dry drops off much quicker
totalDry += LinearInterpolator.instance.interpolate(1.0f, 0.0f, 4.0f * dist / Worm.MAX_ATTENUATION_DISTANCE);
}
}
totalWet = Math.min(1.0f, totalWet * 0.025f);
totalDry = Math.min(1.0f, totalDry * 0.1f);
wetRumble.setGain(Game.getSFXVolume() * wetBuffer.getGain() * rumbleGain * totalWet, Game.class);
dryRumble.setGain(Game.getSFXVolume() * dryBuffer.getGain() * rumbleGain * totalDry, Game.class);
}
public void scroll(float dx, float dy) {
if (zoomTick > 0) {
// Ignore
return;
}
int adjustWidth = Game.getWidth() % MapRenderer.TILE_SIZE;
int adjWTile = adjustWidth == 0 ? 6 : 7;
int adjustHeight = Game.getHeight() % MapRenderer.TILE_SIZE;
int adjHTile = adjustHeight == 0 ? 6 : 7;
if (dx < 0) {
mapX = Math.max(mapX + dx, -MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
} else if (dx > 0) {
mapX = Math.min(mapX + dx, (gameState.getMap().getWidth() - renderer.getWidth()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjWTile - adjustWidth + MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
gameState.suppressHint(Hints.SCROLL);
}
if (dy < 0) {
mapY = Math.max(mapY + dy, -MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
gameState.suppressHint(Hints.SCROLL);
} else if (dy > 0) {
mapY = Math.min(mapY + dy, (gameState.getMap().getHeight() - renderer.getHeight()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjHTile - adjustHeight + MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
gameState.suppressHint(Hints.SCROLL);
}
OFFSET.setLocation((int) -mapX, (int) -mapY);
setHover(null);
stopInfoTimer();
}
/**
* Handle scrolling using the cursor keys and check for mouse movement at the edges
* of the screen
*/
private void handleMouse() {
if (isBlocked()) {
return;
}
// float dx = Worm.getMouseDX();
// float dy = Worm.getMouseDY();
// double length = Math.sqrt(dx * dx + dy * dy);
// if (length > MAX_MOUSE_SCROLL_SPEED) {
// dx = (float) (MAX_MOUSE_SCROLL_SPEED * dx / length);
// dy = (float) (MAX_MOUSE_SCROLL_SPEED * dy / length);
// }
float dx = 0.0f, dy = 0.0f;
float oldMapX = mapX;
float oldMapY = mapY;
if (zoomTick > 0) {
zoomTick --;
mapX = (int) LinearInterpolator.instance.interpolate(endZoomX, startZoomX, (float) zoomTick / (float) zoomDuration);
mapY = (int) LinearInterpolator.instance.interpolate(endZoomY, startZoomY, (float) zoomTick / (float) zoomDuration);
} else {
int mx = getMouseX();
int my = getMouseY();
int adjustWidth = Game.getWidth() % MapRenderer.TILE_SIZE;
int adjWTile = adjustWidth == 0 ? 6 : 7;
int adjustHeight = Game.getHeight() % MapRenderer.TILE_SIZE;
int adjHTile = adjustHeight == 0 ? 6 : 7;
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN) || Keyboard.isKeyDown(Keyboard.KEY_S)) {
my = 0;
dy = - SCROLL_SPEED;
}
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_A)) {
mx = 0;
dx = - SCROLL_SPEED;
}
if (Keyboard.isKeyDown(Keyboard.KEY_UP) || Keyboard.isKeyDown(Keyboard.KEY_W)) {
my = Game.getHeight() - 1;
dy = SCROLL_SPEED;
}
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) || Keyboard.isKeyDown(Keyboard.KEY_D)) {
mx = Game.getWidth() - 1;
dx = SCROLL_SPEED;
}
if (mx == 0 && dx < 0) {
if (ALLOW_SCROLL_PAST) {
mapX = Math.max(mapX + dx, -MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
} else {
mapX = Math.max(mapX + dx, 0);
}
gameState.suppressHint(Hints.SCROLL);
} else if (mx == Game.getWidth() - 1 && dx > 0) {
if (ALLOW_SCROLL_PAST) {
mapX = Math.min(mapX + dx, (gameState.getMap().getWidth() - renderer.getWidth()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjWTile - adjustWidth + MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
} else {
mapX = Math.min(mapX + dx, (gameState.getMap().getWidth() - renderer.getWidth()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjWTile - adjustWidth);
}
gameState.suppressHint(Hints.SCROLL);
}
if (my == 0 && dy < 0) {
if (ALLOW_SCROLL_PAST) {
mapY = Math.max(mapY + dy, -MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
} else {
mapY = Math.max(mapY + dy, 0);
}
gameState.suppressHint(Hints.SCROLL);
} else if (my == Game.getHeight() - 1 && dy > 0) {
if (ALLOW_SCROLL_PAST) {
mapY = Math.min(mapY + dy, (gameState.getMap().getHeight() - renderer.getHeight()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjHTile - adjustHeight + MapRenderer.TILE_SIZE * (MapRenderer.OPAQUE_SIZE - 1));
} else {
mapY = Math.min(mapY + dy, (gameState.getMap().getHeight() - renderer.getHeight()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * adjHTile - adjustHeight);
}
gameState.suppressHint(Hints.SCROLL);
}
}
OFFSET.setLocation((int) -mapX, (int) -mapY);
if (oldMapX != mapX || oldMapY != mapY) {
setHover(null);
stopInfoTimer();
}
}
/**
* Cleanup after a disaster
*/
public void panic() {
removeAllTickables();
doCleanup();
removeAllSprites();
for (Area a : getAreas()) {
detachTickable(a);
a.destroy();
a.create();
a.spawn(this);
}
}
@Override
protected void doCleanup() {
if (baseDestructionEffect != null) {
baseDestructionEffect.stop(Game.class);
baseDestructionEffect = null;
}
if (wetRumble != null) {
wetRumble.setFade(20, 0.0f, true, Game.class);
wetRumble = null;
}
if (dryRumble != null) {
dryRumble.setFade(20, 0.0f, true, Game.class);
dryRumble = null;
}
if (renderer != null) {
renderer.cleanup();
renderer = null;
}
if (bezerkSoundEffect != null) {
bezerkSoundEffect.setFade(20, 0.0f, true, ID_BEZERK_TIMER);
bezerkSoundEffect = null;
}
if (freezeSoundEffect != null) {
freezeSoundEffect.setFade(20, 0.0f, true, ID_FREEZE_TIMER);
freezeSoundEffect = null;
}
if (shieldSoundEffect != null) {
shieldSoundEffect.setFade(20, 0.0f, true, ID_SHIELD_TIMER);
shieldSoundEffect = null;
}
if (gameState != null) {
gameState.cleanup();
// Don't null it; we'll be needing it most likely.
}
}
@Override
protected void onResized() {
if (renderer == null) {
renderer = new MapRenderer(this);
renderer.setOrigin(-MapRenderer.TILE_SIZE * 4, -MapRenderer.TILE_SIZE * 4);
renderer.setMap(gameState.getMap());
}
renderer.onResized();
renderer.render((int) mapX + renderer.getOriginX(), (int) mapY + renderer.getOriginY());
setHover(null);
}
@Override
protected void onOpen() {
onResized();
currentHint = null;
displayedCash = 0;
displayedCrystals = -1;
Worm.setMouseAppearance(Res.getMousePointer());
sideHUDAlpha = 255;
topHudAlphaTarget = hudAlphaTarget = 255;
enableBuildings();
doOnPowerupsUpdated();
tickableObject = new TickableObject() {
@Override
protected void render() {
glRender(SETUP_RENDERING);
ReadableColor currtimeLeftColorBottom = timeLeftColorBottom;
ReadableColor currtimeLeftColorTop = timeLeftColorTop;
ReadableColor currtimePastColorBottom = timePastColorBottom;
ReadableColor currtimePastColorTop = timePastColorTop;
float ratio;
int h;
if (gameState.getGameMode() != WormGameState.GAME_MODE_SURVIVAL && !gameState.isRushActive()) {
ratio = 1.0f - (float) gameState.getLevelTick() / gameState.getLevelDuration();
ReadableRectangle r = timerBarArea.getBounds();
h = (int) LinearInterpolator.instance.interpolate(0.0f, r.getHeight(), ratio);
if (gameState.getLevelTick() > 0) {
ColorUtil.setGLColorPre(currtimeLeftColorBottom, sideHUDAlpha, this);
short idx = glVertex2f(r.getX(), r.getY());
glVertex2f(r.getX() + r.getWidth(), r.getY());
ColorInterpolator.interpolate(currtimeLeftColorBottom, currtimeLeftColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
glVertex2f(r.getX() + r.getWidth(), r.getY() + h);
glVertex2f(r.getX(), r.getY() + h);
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
if (gameState.getLevelTick() < gameState.getLevelDuration()) {
ColorInterpolator.interpolate(currtimePastColorBottom, currtimePastColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
short idx = glVertex2f(r.getX(), r.getY() + h);
glVertex2f(r.getX() + r.getWidth(), r.getY() + h);
ColorUtil.setGLColorPre(currtimePastColorTop, sideHUDAlpha, this);
glVertex2f(r.getX() + r.getWidth(), r.getY() + r.getHeight());
glVertex2f(r.getX(), r.getY() + r.getHeight());
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
}
currtimeLeftColorBottom = powerupTimeLeftColorBottom;
currtimeLeftColorTop = powerupTimeLeftColorTop;
currtimePastColorBottom = powerupTimePastColorBottom;
currtimePastColorTop = powerupTimePastColorTop;
// BEZERK
if (bezerkTimerVisible) {
ReadableRectangle r2 = bezerkBarArea.getBounds();
ratio = (float) gameState.getBezerkTick() / (float) bezerkTimerMax;
h = (int) LinearInterpolator.instance.interpolate(0.0f, r2.getHeight(), ratio);
if (gameState.getBezerkTick() > 0) {
ColorUtil.setGLColorPre(currtimeLeftColorBottom, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY());
glVertex2f(r2.getX() + r2.getWidth(), r2.getY());
ColorInterpolator.interpolate(currtimeLeftColorBottom, currtimeLeftColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
glVertex2f(r2.getX(), r2.getY() + h);
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
if (gameState.getBezerkTick() < bezerkTimerMax) {
ColorInterpolator.interpolate(currtimePastColorBottom, currtimePastColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY() + h);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
ColorUtil.setGLColorPre(currtimePastColorTop, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + r2.getHeight());
glVertex2f(r2.getX(), r2.getY() + r2.getHeight());
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
}
// SHIELD
if (shieldTimerVisible) {
ReadableRectangle r2 = shieldBarArea.getBounds();
ratio = (float) gameState.getShieldTick() / (float) shieldTimerMax;
h = (int) LinearInterpolator.instance.interpolate(0.0f, r2.getHeight(), ratio);
if (gameState.getShieldTick() > 0) {
ColorUtil.setGLColorPre(currtimeLeftColorBottom, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY());
glVertex2f(r2.getX() + r2.getWidth(), r2.getY());
ColorInterpolator.interpolate(currtimeLeftColorBottom, currtimeLeftColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
glVertex2f(r2.getX(), r2.getY() + h);
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
if (gameState.getShieldTick() < shieldTimerMax) {
ColorInterpolator.interpolate(currtimePastColorBottom, currtimePastColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY() + h);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
ColorUtil.setGLColorPre(currtimePastColorTop, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + r2.getHeight());
glVertex2f(r2.getX(), r2.getY() + r2.getHeight());
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
}
// FREEZE
if (freezeTimerVisible) {
ReadableRectangle r2 = freezeBarArea.getBounds();
ratio = (float) gameState.getFreezeTick() / (float) freezeTimerMax;
h = (int) LinearInterpolator.instance.interpolate(0.0f, r2.getHeight(), ratio);
if (gameState.getFreezeTick() > 0) {
ColorUtil.setGLColorPre(currtimeLeftColorBottom, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY());
glVertex2f(r2.getX() + r2.getWidth(), r2.getY());
ColorInterpolator.interpolate(currtimeLeftColorBottom, currtimeLeftColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
glVertex2f(r2.getX(), r2.getY() + h);
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
if (gameState.getFreezeTick() < freezeTimerMax) {
ColorInterpolator.interpolate(currtimePastColorBottom, currtimePastColorTop, ratio, LinearInterpolator.instance, TEMPCOLOR);
ColorUtil.setGLColorPre(TEMPCOLOR, sideHUDAlpha, this);
short idx = glVertex2f(r2.getX(), r2.getY() + h);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + h);
ColorUtil.setGLColorPre(currtimePastColorTop, sideHUDAlpha, this);
glVertex2f(r2.getX() + r2.getWidth(), r2.getY() + r2.getHeight());
glVertex2f(r2.getX(), r2.getY() + r2.getHeight());
glRender(GL_TRIANGLES, new short[] {(short) (idx + 0), (short) (idx + 1), (short) (idx + 2), (short) (idx + 0), (short) (idx + 2), (short) (idx + 3)});
}
}
}
};
tickableObject.setLayer(Layers.HUD);
tickableObject.spawn(this);
}
@Override
protected void onClose() {
if (tickableObject != null) {
tickableObject.remove();
tickableObject = null;
}
// Weather
LevelFeature levelFeature = gameState.getLevelFeature();
if (levelFeature.getWeather() != null) {
levelFeature.getWeather().remove();
}
}
/**
* Get the game ticks
*/
public static int getTick() {
return gameState.getTick();
}
/**
* Get total ticks
*/
public static int getTotalTicks() {
int oldTotalTicks = gameState.getTotalTicks();
gameState.resetTotalTicks();
return oldTotalTicks;
}
/**
* @return the offset for sprites
*/
public static Point getSpriteOffset() {
return OFFSET;
}
/**
* Begin the game
*/
public static void beginGame(WormGameState newGameState) {
GameScreen.gameState = newGameState;
instance.hintQueue.clear();
instance.open();
}
/**
* Called at the start of a level
*/
public static void onBeginLevel() {
instance.doOnBeginLevel();
}
private void doOnBeginLevel() {
open();
setGroupVisible(ID_BASE_UNDER_ATTACK, false);
setGroupVisible(ID_DESTRUCTION_IMMINENT, false);
setGroupVisible(COST_GROUP, false);
setGroupVisible(ID_INFO_ALERT_GROUP, false);
setGroupVisible(ID_CRYSTAL_MESSAGE_GROUP, false);
setGroupVisible(ID_BEZERK_TIMER, false);
setGroupVisible(ID_SHIELD_TIMER, false);
setGroupVisible(ID_FREEZE_TIMER, false);
setGroupVisible(ID_TOOLTIPS, false);
setGroupVisible(ID_HINT_GROUP, false);
setGroupVisible(SHOW_ICON_GROUP, false);
// chaz hack!
threatLowArea.setVisible(false);
threatHighArea.setVisible(false);
setSellOff();
bezerkTimerVisible = false;
shieldTimerVisible = false;
freezeTimerVisible = false;
getArea(ID_BASE).setMouseOffAppearance((Appearance) Resources.get("quicklaunch.focus.base.off.animation"));
onMapChanged();
doOnPowerupsUpdated();
enableBuildings();
repairFlagged = false;
shieldFlagged = false;
targetRumbleGain = 1.0f;
rumbleGain = 0.0f;
wetRumble = Game.allocateSound(wetBuffer);
dryRumble = Game.allocateSound(dryBuffer);
Building building = gameState.getBase();
if (building == null) {
return;
}
zoom(building.getMapX() + building.getCollisionX() - Game.getWidth() / 2, building.getMapY() + building.getCollisionY() - Game.getHeight() / 2);
}
/**
* Called whenever the map changes
*/
private void onMapChanged() {
// And here's the map...
int levelNumber = gameState.getLevel();
LevelFeature levelFeature = gameState.getLevelFeature();
String levelName = levelFeature.getTitle().toUpperCase();
switch (gameState.getGameMode()) {
case WormGameState.GAME_MODE_ENDLESS:
ColorMapFeature.getDefaultColorMap().copy((ColorMapFeature) Resources.get("earth.colormap"));
break;
case WormGameState.GAME_MODE_XMAS:
ColorMapFeature.getDefaultColorMap().copy((ColorMapFeature) Resources.get("xmas.colormap"));
break;
default:
String world = gameState.getWorld().getUntranslated();
ColorMapFeature.getDefaultColorMap().copy((ColorMapFeature) Resources.get(world+".colormap"));
break;
}
LevelColorsFeature colors = levelFeature.getColors();
renderer.setMap(gameState.getMap());
colors.init(renderer);
AttenuatedColor.setAttenuation(colors.getColor(AttenuatedColor.ATTENUATE));
timeLeftColorBottom = new MappedColor(TIME_LEFT_COLOR_BOTTOM);
timeLeftColorTop = new MappedColor(TIME_LEFT_COLOR_TOP);
timePastColorBottom = new MappedColor(TIME_PAST_COLOR_BOTTOM);
timePastColorTop = new MappedColor(TIME_PAST_COLOR_TOP);
powerupTimeLeftColorBottom = new MappedColor(POWERUP_TIME_LEFT_COLOR_BOTTOM);
powerupTimeLeftColorTop = new MappedColor(POWERUP_TIME_LEFT_COLOR_TOP);
powerupTimePastColorBottom = new MappedColor(POWERUP_TIME_PAST_COLOR_BOTTOM);
powerupTimePastColorTop = new MappedColor(POWERUP_TIME_PAST_COLOR_TOP);
buildColor = new MappedColor(BUILD_COLOR);
cantBuildColor = new MappedColor(CANT_BUILD_COLOR);
if (gameState.getGameMode() == WormGameState.GAME_MODE_SURVIVAL) {
levelArea.setText("00:00:00:00");
} else if (gameState.getGameMode() == WormGameState.GAME_MODE_XMAS) {
levelArea.setText(levelName);
} else if (levelNumber < 9) {
levelArea.setText("0"+String.valueOf(levelNumber + 1)+" "+levelName);
} else {
levelArea.setText(String.valueOf(levelNumber + 1)+" "+levelName);
}
// Ambient music
if (gameState.getGameMode() == WormGameState.GAME_MODE_XMAS) {
Game.playMusic((ALStream) Resources.get("december.stream"), 180);
} else if (levelNumber == -1) {
// Survival mode. Music will change periodically.
} else {
Game.playMusic(Res.getAmbient(levelNumber), 180);
}
// And the map scrolly display
mapX = (gameState.getMap().getWidth() * MapRenderer.TILE_SIZE - Game.getWidth()) / 2;
mapY = (gameState.getMap().getHeight() * MapRenderer.TILE_SIZE - Game.getHeight()) / 2;
// Weather
if (levelFeature.getWeather() != null) {
levelFeature.getWeather().spawn(this);
}
}
public static void onBaseAttacked() {
instance.doOnBaseAttacked();
}
private void doOnBaseAttacked() {
if (baseDestructionImminentEffect != null) {
return;
}
SFX.baseAttacked();
if (baseAttackedEffect != null) {
baseAttackedEffect.remove();
baseAttackedEffect = null;
}
setGroupVisible(ID_BASE_UNDER_ATTACK, true);
baseAttackedEffect = new FadeEffect(120, 60) {
@Override
protected void onTicked() {
setGroupAlpha(ID_BASE_UNDER_ATTACK, getAlpha());
}
@Override
protected void doRemove() {
setGroupVisible(ID_BASE_UNDER_ATTACK, false);
getArea(ID_BASE).setMouseOffAppearance((Appearance) Resources.get("quicklaunch.focus.base.off.animation"));
}
};
getArea(ID_BASE).setMouseOffAppearance((Appearance) Resources.get("quicklaunch.focus.base.flash.animation"));
baseAttackedEffect.spawn(this);
}
public static void onBaseDestructionImminent() {
instance.doOnBaseDestructionImminent();
}
private void doOnBaseDestructionImminent() {
if (baseDestructionImminentEffect != null) {
return;
}
if (baseAttackedEffect != null) {
baseAttackedEffect.remove();
baseAttackedEffect = null;
}
if (baseDestructionEffect == null) {
baseDestructionEffect = SFX.baseDestructionImminent();
}
setGroupVisible(ID_DESTRUCTION_IMMINENT, true);
baseDestructionImminentEffect = new FadeEffect(180, 60) {
@Override
protected void onTicked() {
setGroupAlpha(ID_DESTRUCTION_IMMINENT, getAlpha());
}
@Override
protected void doRemove() {
setGroupVisible(ID_DESTRUCTION_IMMINENT, false);
getArea(ID_BASE).setMouseOffAppearance((Appearance) Resources.get("quicklaunch.focus.base.off.animation"));
baseDestructionImminentEffect = null;
}
};
getArea(ID_BASE).setMouseOffAppearance((Appearance) Resources.get("quicklaunch.focus.base.flash.animation"));
baseDestructionImminentEffect.spawn(this);
if (RepairPowerupFeature.getInstance().isEnabledInShop() && !repairFlagged) {
gameState.flagHint(Hints.REPAIR);
repairFlagged = true;
} else if (ShieldPowerupFeature.getInstance().isEnabledInShop() && !shieldFlagged) {
gameState.flagHint(Hints.SHIELD);
shieldFlagged = true;
}
}
public static void onBaseRepaired() {
instance.doOnBaseRepaired();
}
private void doOnBaseRepaired() {
if (baseDestructionImminentEffect != null) {
baseDestructionImminentEffect.finish();
baseDestructionImminentEffect = null;
}
if (baseDestructionEffect != null) {
baseDestructionEffect.stop(Game.class);
baseDestructionEffect = null;
}
shieldFlagged = false;
repairFlagged = false;
}
/**
* Game over
*/
public static void gameOver() {
instance.doGameOver();
}
private void doGameOver() {
if (baseDestructionEffect != null) {
baseDestructionEffect.stop(Game.class);
baseDestructionEffect = null;
}
Game.playMusic((ALBuffer) null, 180);
// And open the game over screen
GameOverScreen.show();
}
@Override
protected void doCreateScreen() {
moneyArea = getArea(ID_MONEY);
crystalRemainingArea = getArea(ID_CRYSTAL_REMAINING);
crystalArea = getArea(ID_CRYSTAL);
levelArea = getArea(ID_LEVEL);
costArea = getArea(ID_COST);
mapArea = getArea(ID_MAP);
timerBarArea = getArea(ID_TIMER_BAR);
threatLowArea = getArea(ID_THREAT_LOW);
threatHighArea = getArea(ID_THREAT_HIGH);
bezerkBarArea = getArea(ID_BEZERK_TIMER_BAR);
freezeBarArea = getArea(ID_FREEZE_TIMER_BAR);
shieldBarArea = getArea(ID_SHIELD_TIMER_BAR);
infoTextArea = getArea(ID_BUILDINGS_INFOTEXT);
bonusTextArea = getArea(ID_BUILDINGS_BONUSTEXT);
costTextArea = getArea(ID_BUILDINGS_COSTTEXT);
titleTextArea = getArea(ID_BUILDINGS_TITLETEXT);
titleTextNoKeyArea = getArea(ID_BUILDINGS_TITLETEXT_NO_KEY);
infoSpriteLocationArea = getArea(ID_INFO_SPRITE_LOCATION);
hintTextArea = getArea(ID_HINT_TEXT);
hintSpriteLocationArea = getArea(ID_HINT_SPRITE_LOCATION);
particleDebug = new GLTextArea();
particleDebug.setBounds(220, 240, 100, 60);
particleDebug.setFont(net.puppygames.applet.Res.getTinyFont());
// And the default offset for effects
Effect.setDefaultOffset(this, OFFSET);
// And sound attenuation
Effect.setDefaultAttenuator(this, Worm.ATTENUATOR);
wetBuffer = (ALBuffer) Resources.get("rumble_ambience.buffer");
dryBuffer = (ALBuffer) Resources.get("rumble.buffer");
hintQueue = new ArrayList<HintFeature>(4);
}
@Override
protected void preRender() {
if (shakeTick > 0) {
shakeTick --;
shook = true;
glPushMatrix();
glTranslatef(0.0f, Util.random(-shakeTick, shakeTick), 0.0f);
} else {
shook = false;
}
}
public void updateHUD() {
int currentCash = gameState.getMoney();
int oldDisplayedCash = displayedCash;
if (displayedCash > currentCash + 5000) {
displayedCash = Math.max(currentCash, displayedCash - 1000);
} else if (displayedCash > currentCash + 500) {
displayedCash = Math.max(currentCash, displayedCash - 100);
} else if (displayedCash > currentCash) {
displayedCash = Math.max(currentCash, displayedCash - 10);
} else if (displayedCash < currentCash - 5000) {
displayedCash = Math.min(currentCash, displayedCash + 1000);
} else if (displayedCash < currentCash - 500) {
displayedCash = Math.min(currentCash, displayedCash + 100);
} else if (displayedCash < currentCash) {
displayedCash = Math.min(currentCash, displayedCash + 10);
}
if (oldDisplayedCash != displayedCash) {
moneyArea.setText(String.valueOf(displayedCash));
}
int crystals = gameState.getCrystals();
if (crystals != displayedCrystals) {
displayedCrystals = crystals;
if (crystals == 0) {
crystalRemainingArea.setText("{color:gui-dark}0");
} else {
crystalRemainingArea.setText("{color:gui-mid}"+crystals);
}
}
if (gameState.getGameMode() == WormGameState.GAME_MODE_SURVIVAL || gameState.getGameMode() == WormGameState.GAME_MODE_SURVIVAL) {
levelArea.setText(TimeUtil.format(gameState.getLevelTick()).toString());
} else {
if (gameState.isRushActive()) {
threatLowArea.setVisible(false);
threatHighArea.setVisible(true);
} else {
threatLowArea.setVisible(true);
threatHighArea.setVisible(false);
}
}
int numUnminedCrystals = gameState.getNumUnminedCrystals();
if (crystalArea.isEnabled() && numUnminedCrystals == 0) {
if (unminedCrystalEffect != null) {
unminedCrystalEffect.remove();
unminedCrystalEffect = null;
}
setGroupEnabled(ID_CRYSTAL_GROUP, false);
setGroupVisible(ID_CRYSTAL_MESSAGE_GROUP, false);
} else if (!crystalArea.isEnabled() && numUnminedCrystals > 0) {
if (unminedCrystalEffect != null) {
unminedCrystalEffect.reset();
} else {
unminedCrystalEffect = new FadeEffect(180, 60) {
@Override
protected void onTicked() {
setGroupAlpha(ID_CRYSTAL_MESSAGE_GROUP, getAlpha() * sideHUDAlpha / 255);
}
@Override
protected void doRemove() {
setGroupVisible(ID_CRYSTAL_MESSAGE_GROUP, false);
}
};
unminedCrystalEffect.spawn(this);
setGroupVisible(ID_CRYSTAL_MESSAGE_GROUP, true);
}
setGroupEnabled(ID_CRYSTAL_GROUP, true);
}
if (unminedCrystalEffect != null && !unminedCrystalEffect.isActive()) {
unminedCrystalEffect = null;
}
if (gameState.getBezerkTick() == 0 && bezerkTimerVisible) {
setGroupVisible(ID_BEZERK_TIMER, false);
bezerkTimerVisible = false;
if (bezerkSoundEffect != null) {
bezerkSoundEffect.setFade(20, 0.0f, true, ID_BEZERK_TIMER);
bezerkSoundEffect = null;
}
}
if (gameState.getFreezeTick() == 0 && freezeTimerVisible) {
setGroupVisible(ID_FREEZE_TIMER, false);
freezeTimerVisible = false;
if (freezeSoundEffect != null) {
freezeSoundEffect.setFade(20, 0.0f, true, ID_FREEZE_TIMER);
freezeSoundEffect = null;
}
}
if (gameState.getShieldTick() == 0 && shieldTimerVisible) {
setGroupVisible(ID_SHIELD_TIMER, false);
shieldTimerVisible = false;
if (shieldSoundEffect != null) {
shieldSoundEffect.setFade(20, 0.0f, true, ID_SHIELD_TIMER);
shieldSoundEffect = null;
}
}
if (infoTimer > 0) {
infoTimer --;
if (infoTimer == 0) {
setHover(infoItem);
}
}
if (hintEffect != null) {
hintTick ++;
if (hintTick == HINT_DURATION) {
closeHint();
}
if (hintEffect.getCurrent() == 0 && hintEffect.getTarget() == 0) {
hintEffect.remove();
hintEffect = null;
currentHint = null;
if (hintQueue.size() > 0) {
showHint(hintQueue.remove(0));
}
}
}
if (hudAlpha != hudAlphaTarget) {
if (hudAlpha < hudAlphaTarget) {
if (hudAlpha == 0) {
setGroupVisible(ID_HIDEABLE_GROUP, true);
doOnPowerupsUpdated();
enableBuildings();
}
hudAlpha = Math.min(hudAlphaTarget, hudAlpha + HUD_ALPHA_FADE_SPEED);
} else {
hudAlpha = Math.max(hudAlphaTarget, hudAlpha - HUD_ALPHA_FADE_SPEED);
if (hudAlpha == 0) {
setGroupVisible(ID_HIDEABLE_GROUP, false);
}
}
setGroupAlpha(ID_HIDEABLE_GROUP, hudAlpha);
}
if (topHudAlpha != topHudAlphaTarget) {
if (topHudAlpha < topHudAlphaTarget) {
topHudAlpha = Math.min(topHudAlphaTarget, topHudAlpha + HUD_ALPHA_FADE_SPEED);
} else {
topHudAlpha = Math.max(topHudAlphaTarget, topHudAlpha - HUD_ALPHA_FADE_SPEED);
}
setGroupAlpha(ID_TOP_HUD_GROUP, topHudAlpha);
}
if (gameState.isSelling() && !sellActive) {
setSellOn();
}
if (!gameState.isSelling() && sellActive) {
setSellOff();
}
}
public void onBezerkTimerIncreased(int newMax) {
bezerkTimerMax = newMax;
if (!bezerkTimerVisible) {
bezerkTimerVisible = true;
setGroupVisible(ID_BEZERK_TIMER, true);
if (bezerkSoundEffect == null) {
bezerkSoundEffect = Game.allocateSound(Res.getBezerkSound(), 1.0f, 1.0f, ID_BEZERK_TIMER);
}
}
}
public void onFreezeTimerIncreased(int newMax) {
freezeTimerMax = newMax;
if (!freezeTimerVisible) {
freezeTimerVisible = true;
setGroupVisible(ID_FREEZE_TIMER, true);
if (freezeSoundEffect == null) {
freezeSoundEffect = Game.allocateSound(Res.getFreezeSound(), 1.0f, 1.0f, ID_FREEZE_TIMER);
}
}
}
public void onShieldTimerIncreased(int newMax) {
shieldTimerMax = newMax;
if (!shieldTimerVisible) {
shieldTimerVisible = true;
setGroupVisible(ID_SHIELD_TIMER, true);
if (shieldSoundEffect == null) {
shieldSoundEffect = Game.allocateSound(Res.getShieldSound(), 1.0f, 1.0f, ID_SHIELD_TIMER);
}
}
}
@Override
protected void postRender() {
if (renderer != null) {
renderer.postRender();
}
if (shook) {
glPopMatrix();
}
}
/**
* Shake the screen
* @param amount
*/
public static void shake(int amount) {
instance.shakeTick = amount;
}
/**
* @return Returns the instance.
*/
public static GameScreen getInstance() {
return instance;
}
/**
* Called just before app shutdown
*/
public static void onExit() {
if (instance != null && instance.isOpen()) {
MiniGame.saveGame();
}
}
@Override
protected void onHover(final String id, final boolean on) {
// Tooltip manager. No tooltips when building
if (
!gameState.isBuilding() && !gameState.isSelling() && Worm.getShowTooltips()
&& (id.startsWith(ID_POWERUP_SHORTCUTS) || id.startsWith(ID_BUILDING_SHORTCUTS) || id.startsWith(ID_MISC_SHORTCUTS))
)
{
// Make sure its teh same tooltip
if (on) {
if (currentTooltipID != id) {
// No, so remove the previous tooltip if there is one
if (tooltipEffect != null) {
tooltipEffect.finish();
tooltipEffect = null;
}
currentTooltipID = id;
setVisible(id+"_tooltip", true);
setVisible(id+"_tooltip_glow", true);
if ( id.startsWith(ID_BUILDING_SHORTCUTS) ) {
// chaz hack! adjust area length - doesnt take 'I' or 'M' etc. into account tho
ReadableRectangle r = getArea(id+"_tooltip").getBounds();
int w = getArea(id+"_tooltip").getText().length()*6+30;
getArea(id+"_tooltip").setBounds(r.getX(), r.getY(), w, r.getHeight());
getArea(id+"_tooltip_glow").setBounds(r.getX(), r.getY(), w, r.getHeight());
//System.out.println(id+": size=\""+w+","+r.getHeight()+"\"");
}
tooltipEffect = new FadeEffect(90, 5) {
@Override
protected void onTicked() {
getArea(id+"_tooltip").setAlpha(getAlpha());
getArea(id+"_tooltip_glow").setAlpha(getAlpha());
}
@Override
protected void doRemove() {
GameScreen.this.setVisible(id+"_tooltip_glow", false);
GameScreen.this.setVisible(id+"_tooltip", false);
}
};
tooltipEffect.spawn(this);
if (id.startsWith(ID_BUILDING_SHORTCUTS)) {
for (Iterator<BuildingFeature> i = BuildingFeature.getBuildings().iterator(); i.hasNext(); ) {
BuildingFeature bf = i.next();
if (id.equals(bf.getHUD()) && bf.getShopAppearance() != null) {
startInfoTimer(bf);
break;
}
}
} else if (id.startsWith(ID_POWERUP_SHORTCUTS)) {
String powerupName = id.substring(ID_POWERUP_SHORTCUTS.length());
startInfoTimer((PowerupFeature) Resources.get(powerupName));
} else {
stopInfoTimer();
}
}
} else {
if (currentTooltipID == id) {
// No, so remove the previous tooltip if there is one
if (tooltipEffect != null) {
tooltipEffect.finish();
tooltipEffect = null;
}
currentTooltipID = null;
stopInfoTimer();
}
}
} else {
// We're not over a tooltippable thing, so remove any tooltip
if (tooltipEffect != null) {
tooltipEffect.finish();
tooltipEffect = null;
}
stopInfoTimer();
}
}
private void startInfoTimer(ShopItem shopItem) {
if (hover == shopItem) {
setHover(shopItem);
} else if (hover != null) {
setHover(shopItem);
} else {
if (!Worm.getShowInfo()) {
return;
}
infoTimer = SHOP_SENSITIVITY;
infoItem = shopItem;
}
}
private void stopInfoTimer() {
infoTimer = SHOP_LURK;
infoItem = null;
}
@Override
protected void onClicked(String id) {
if (fastForward) {
return;
}
if (ID_BUILDING_DONE.equals(id)) {
gameState.setBuilding(null);
} else if (ID_MENU.equals(id)) {
gameState.handleESC();
} else if (ID_BASE.equals(id)) {
Building building = gameState.getBase();
if (building == null) {
return;
}
zoom(building.getX() - Game.getWidth() / 2, building.getY() - Game.getHeight() / 2);
} else if (ID_CRYSTAL.equals(id)) {
Building building = gameState.getNextUnminedCrystal();
if (building == null) {
return;
}
zoom(building.getX() - Game.getWidth() / 2, building.getY() - Game.getHeight() / 2);
} else if (ID_FASTFORWARD.equals(id)) {
fastForward = true;
} else if (ID_HINT_CLOSE.equals(id)) {
closeHint();
} else if (ID_SHOWHIDE.equals(id)) {
// Toggle visibility of bottom HUD
if (hudAlphaTarget == 0) {
hudAlphaTarget = 255;
setGroupVisible(SHOW_ICON_GROUP, false);
} else {
hudAlphaTarget = 0;
setGroupVisible(SHOW_ICON_GROUP, true);
// remove shop
setHover(null);
}
// set location of build bar
if (gameState.isBuilding()) {
setBuildInfoPanelPosition();
}
// set sell stuff
if (gameState.isSelling()) {
setSellOn();
} else {
setSellOff();
}
doOnPowerupsUpdated();
} else if (ID_SELL.equals(id)) {
gameState.setSellMode(true);
setSellOn();
} else if (ID_SELL_DONE.equals(id) || ID_SELL_INFO_DONE.equals(id)) {
gameState.setSellMode(false);
setSellOff();
} else {
// Maybe clicked on a building shortcut or a powerup shortcut
if (id.startsWith(ID_POWERUP_SHORTCUTS)) {
String powerupName = id.substring(ID_POWERUP_SHORTCUTS.length());
gameState.usePowerup((PowerupFeature) Resources.get(powerupName));
if (powerupName.equals("smartbomb.powerup")) {
setSellOff();
}
} else if (id.startsWith(ID_BUILDING_SHORTCUTS)) {
for (Iterator<BuildingFeature> i = BuildingFeature.getBuildings().iterator(); i.hasNext(); ) {
BuildingFeature bf = i.next();
if (id.equals(bf.getHUD()) && bf.getShopAppearance() != null) {
gameState.setBuilding(bf);
// move pos of build info bar to correct
setBuildInfoPanelPosition();
setSellOff();
break;
}
}
}
}
}
public static void doSaveEffect() {
LabelEffect saveEffect = new LabelEffect(net.puppygames.applet.Res.getBigFont(), Game.getMessage("ultraworm.gamescreen.game_saved"), ReadableColor.WHITE, ReadableColor.BLUE, SAVE_DURATION / 2, SAVE_DURATION / 2);
saveEffect.setLocation(Game.getWidth() / 2, Game.getHeight() / 2 + MapRenderer.TILE_SIZE);
saveEffect.setVisible(true);
saveEffect.spawn(instance);
saveEffect.setOffset(null);
}
public static void doFailedSaveEffect() {
LabelEffect failEffect = new LabelEffect(net.puppygames.applet.Res.getBigFont(), Game.getMessage("ultraworm.gamescreen.failed_to_save"), ReadableColor.WHITE, ReadableColor.RED, SAVE_DURATION / 2, SAVE_DURATION / 2);
failEffect.setLocation(Game.getWidth() / 2, Game.getHeight() / 2 + MapRenderer.TILE_SIZE);
failEffect.setVisible(true);
failEffect.spawn(instance);
failEffect.setOffset(null);
}
public static void onEndLevel() {
instance.doOnEndLevel();
}
private void doOnEndLevel() {
if (baseDestructionEffect != null) {
baseDestructionEffect.stop(Game.class);
baseDestructionEffect = null;
}
closeHint();
}
public static void onPowerupsUpdated() {
instance.doOnPowerupsUpdated();
}
private void doOnPowerupsUpdated() {
boolean hasPowerups = false;
for (PowerupFeature pf : PowerupFeature.getPowerups()) {
if (pf.getShopIcon() != null) {
Area area = getArea(ID_POWERUP_SHORTCUTS + pf.getName());
boolean enabled = pf.isEnabledInShop();
area.setEnabled(enabled);
hasPowerups |= enabled;
getArea("counter_"+ ID_POWERUP_SHORTCUTS + pf.getName()).setMouseOffAppearance(Res.getQuicklaunchCountOff(Math.min(9, gameState.getNumPowerups(pf))));
getArea("counter_"+ ID_POWERUP_SHORTCUTS + pf.getName()).setMouseOnAppearance(Res.getQuicklaunchCountOn(Math.min(9, gameState.getNumPowerups(pf))));
setVisible("counter_"+ ID_POWERUP_SHORTCUTS + pf.getName(), enabled && hudAlphaTarget > 0);
}
}
setEnabled(ID_POWERUPS_LABEL, hasPowerups);
}
public void zoom(float x, float y) {
startZoomX = mapX;
startZoomY = mapY;
if (ALLOW_SCROLL_PAST) {
endZoomX = x;
endZoomY = y;
} else {
endZoomX = Math.max(0, Math.min(x, (gameState.getMap().getWidth() - renderer.getWidth()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * 6));
endZoomY = Math.max(0, Math.min(y, (gameState.getMap().getHeight() - renderer.getHeight()) * MapRenderer.TILE_SIZE + MapRenderer.TILE_SIZE * 6));
}
double dx = startZoomX - endZoomX;
double dy = startZoomY - endZoomY;
double dist = Math.sqrt(dx * dx + dy * dy);
if (dist < ZOOM_SPEED) {
return;
}
zoomTick = zoomDuration = (int) (dist / ZOOM_SPEED);
}
/**
* Enable / disable / hide building HUD buttons
*/
public void enableBuildings() {
Collection<BuildingFeature> buildings = BuildingFeature.getBuildings();
for (Iterator<BuildingFeature> i = buildings.iterator(); i.hasNext(); ) {
BuildingFeature bf = i.next();
if (bf.getHUD() != null && bf.getShopAppearance() != null) {
setEnabled(bf.getHUD(), bf.isAvailable());
int numAvailable = Math.min(99, gameState.getAvailableStock(bf));
if (bf.getNumAvailable() == 0 || !bf.isAvailable() || hudAlphaTarget == 0) {
setVisible("counter_"+bf.getHUD(), false);
setVisible("counter10_"+bf.getHUD(), false);
} else if (numAvailable >= 0 && numAvailable < 10) {
getArea("counter10_"+bf.getHUD()).setMouseOffAppearance(Res.getQuicklaunchCountOff(numAvailable));
getArea("counter10_"+bf.getHUD()).setMouseOnAppearance(Res.getQuicklaunchCountOn(numAvailable));
setVisible("counter10_"+bf.getHUD(), true);
setVisible("counter_"+bf.getHUD(), false);
} else if (numAvailable >= 10) {
getArea("counter10_"+bf.getHUD()).setMouseOffAppearance(Res.getQuicklaunchCount10Off(numAvailable % 10));
getArea("counter10_"+bf.getHUD()).setMouseOnAppearance(Res.getQuicklaunchCount10On(numAvailable % 10));
getArea("counter_"+bf.getHUD()).setMouseOffAppearance(Res.getQuicklaunchCountOff(numAvailable / 10));
getArea("counter_"+bf.getHUD()).setMouseOnAppearance(Res.getQuicklaunchCountOn(numAvailable / 10));
setVisible("counter10_"+bf.getHUD(), true);
setVisible("counter_"+bf.getHUD(), true);
}
}
}
}
public void setSideHUDAlpha(int alpha) {
setGroupAlpha(ID_HUD_SIDES, alpha);
sideHUDAlpha = alpha;
}
public static void onMapGrabbedMouse(boolean grabbed) {
instance.setGrabbed(grabbed? instance.mapArea : null);
}
public static boolean isSomethingElseGrabbingMouse() {
return instance.getGrabbed() != null && instance.getGrabbed() != instance.mapArea;
}
public boolean isFastForward() {
return fastForward;
}
public void clearFastForward() {
fastForward = false;
}
/**
* Sets the currently hovered item
* @param newHover The thing being hovered over, or null, to clear
*/
private void setHover(ShopItem newHover) {
if (newHover == hover) {
return;
}
hover = newHover;
if (hover == null) {
if (shopEffect != null) {
shopEffect.setTarget(0);
}
} else {
if (gameState.getBuilding() != null) {
// Don't open shop in build mode
hover = null;
return;
}
// Turn on entire data group
setGroupVisible(ID_INFO_GROUP, true);
if (hover.getTooltipGraphic()!=null) {
titleTextNoKeyArea.setVisible(false);
titleTextArea.setText(hover.getTitle());
} else {
titleTextArea.setVisible(false);
titleTextNoKeyArea.setText(hover.getTitle());
}
infoTextArea.setText(hover.getDescription());
bonusTextArea.setText(hover.getBonusDescription());
if (infoLayers != null) {
infoLayers.remove();
infoLayers = null;
}
if (shopEffect != null) {
shopEffect.setTarget(255);
showShopSprites();
} else {
shopEffect = new AdjusterEffect(SHOP_FADE_RATE, 0, 255) {
int lastInventory = -999;
ShopItem currentHover;
@Override
protected void onTicked() {
int a = getCurrent();
setGroupAlpha(ID_INFO_GROUP, a);
if (a == 0 && shopSpritesVisible) {
hide();
} else if (a != 0 && !shopSpritesVisible) {
show();
}
if (infoLayers != null) {
for (int i = 0; i < infoLayers.getSprites().length; i ++) {
infoLayers.getSprite(i).setAlpha(a);
}
}
if (a != 0 && hover != null) {
int inventory = hover.getInventory();
if (currentHover != hover || inventory != lastInventory) {
getArea("id_shortcutkey").setMouseOffAppearance(hover.getTooltipGraphic());
currentHover = hover;
lastInventory = inventory;
if (hover.getInitialValue() > 0) {
// It's a building
StringBuilder sb = new StringBuilder(128);
sb.append(Game.getMessage("ultraworm.gamescreen.cost")+": ");
if (hover.isEnabledInShop()) {
int shopValue = hover.getShopValue();
if (shopValue > 0) {
sb.append(shopValue);
} else {
sb.append(Game.getMessage("ultraworm.gamescreen.free"));
}
} else {
sb.append("N/A");
}
if (inventory > 0) {
sb.append(" "+Game.getMessage("ultraworm.gamescreen.available")+": ");
sb.append(inventory);
} else if (inventory == 0 && hover.getNumAvailable() > 0) {
sb.append(" "+Game.getMessage("ultraworm.gamescreen.none_available"));
}
costTextArea.setText(sb.toString());
} else {
// It's a powerup
costTextArea.setText(Game.getMessage("ultraworm.gamescreen.available")+": "+inventory);
}
}
} else {
lastInventory = -999;
currentHover = null;
}
}
void hide() {
setGroupVisible(ID_INFO_GROUP, false);
removeShopSprites();
}
void show() {
showShopSprites();
}
@Override
protected void doRemove() {
super.doRemove();
hide();
shopEffect = null;
}
@Override
protected void doSpawnEffect() {
currentHover = hover;
}
};
shopEffect.spawn(this);
}
}
if (tooltipEffect != null) {
tooltipEffect.remove();
tooltipEffect = null;
}
}
private void removeShopSprites() {
if (infoLayers != null) {
infoLayers.remove();
infoLayers = null;
}
shopSpritesVisible = false;
}
private void showShopSprites() {
removeShopSprites();
LayersFeature shopAppearance = hover.getShopAppearance();
ReadablePoint offset = hover.getShopOffset();
int ox, oy;
if (offset == null) {
ox = 0;
oy = 0;
} else {
ox = offset.getX();
oy = offset.getY();
}
infoLayers = new SimpleThingWithLayers(instance);
shopAppearance.createSprites(instance, infoLayers);
for (int i = 0; i < infoLayers.getSprites().length; i ++) {
infoLayers.getSprite(i).setLocation(infoSpriteLocationArea.getBounds().getX() + ox, infoSpriteLocationArea.getBounds().getY() + oy);
}
shopSpritesVisible = true;
}
public void dequeueHint(HintFeature hintFeature) {
while (hintQueue.remove(hintFeature)) {
;
}
}
/**
* Shows a hint. If there's already a hint being shown, this hint is queued.
*/
public void showHint(HintFeature hintFeature) {
if (!Worm.getShowHints()) {
return;
}
assert hintFeature != null;
if (currentHint != null) {
if (currentHint == hintFeature) {
return;
}
if (hintQueue.contains(hintFeature)) {
return;
}
hintQueue.add(hintFeature);
return;
}
int seq = gameState.getHintSequence(hintFeature);
if (seq == -1) {
// No more hints of this sort
return;
}
currentHint = hintFeature;
// Turn on entire data group
setGroupVisible(ID_HINT_GROUP, true);
if (hintFeature.getText() != null) {
hintTextArea.setText(hintFeature.getText());
} else {
hintTextArea.setText(((TextResource) hintFeature.getHints().getResource(seq)).getText());
}
if (hintEffect != null) {
hintEffect.setTarget(255);
showHintSprites();
} else {
hintEffect = new AdjusterEffect(HINT_FADE_RATE, 0, 255) {
@Override
protected void onTicked() {
int current = getCurrent();
int a = current * topHudAlpha / 255;
setGroupAlpha(ID_HINT_GROUP, a);
if (current == 0 && hintSpritesVisible) {
hide();
} else if (current != 0 && !hintSpritesVisible) {
show();
}
if (hintLayers != null) {
for (int i = 0; i < hintLayers.getSprites().length; i++) {
hintLayers.getSprite(i).setAlpha(a);
}
}
}
void hide() {
setGroupVisible(ID_HINT_GROUP, false);
removeHintSprites();
}
void show() {
showHintSprites();
}
@Override
protected void doRemove() {
super.doRemove();
hide();
hintEffect = null;
}
};
hintEffect.spawn(this);
}
}
public void closeHint() {
if (hintEffect != null && hintEffect.getTarget() != 0) {
hintEffect.setTarget(0);
}
}
public boolean isShowingPausedHint() {
return currentHint != null && currentHint.getPause() && hintEffect != null && hintEffect.getTarget() == hintEffect.getCurrent();
}
private void removeHintSprites() {
if (hintLayers != null) {
hintLayers.remove();
hintLayers = null;
}
hintSpritesVisible = false;
}
private void showHintSprites() {
removeHintSprites();
if (currentHint != null && currentHint.getIcon() != null) {
hintLayers = new SimpleThingWithLayers(instance);
currentHint.getIcon().createSprites(instance, hintLayers);
ReadableRectangle hsb = hintSpriteLocationArea.getBounds();
for (int i = 0; i < hintLayers.getSprites().length; i++) {
hintLayers.getSprite(i).setLocation(hsb.getX() + hsb.getWidth() / 2, hsb.getY() + hsb.getHeight() / 2);
hintLayers.getSprite(i).setAlpha(topHudAlpha);
if (!currentHint.getIcon().getName().contentEquals("hint.info.layers")) {
hintLayers.getSprite(i).setScale(HINT_SCALE);
}
}
hintSpritesVisible = true;
hintTick = 0;
}
}
private void setBuildInfoPanelPosition() {
int buildInfoPos;
if (hudAlphaTarget == 0) {
buildInfoPos = COST_INFO_Y_LOW;
} else {
buildInfoPos = COST_INFO_Y_HIGH;
}
if (getArea(ID_BUILDING_DONE).getPosition().getY()!=buildInfoPos+COST_INFO_BUTTON_OFFSET) {
List<Area> costGroupAreas = getAreas(COST_GROUP);
for (int i = 0; i < costGroupAreas.size(); i ++) {
Area a = costGroupAreas.get(i);
ReadableRectangle aBounds=a.getBounds();
int y = buildInfoPos;
if (a.getID().equals(ID_BUILDING_DONE)) {
y += COST_INFO_BUTTON_OFFSET;
}
a.setBounds(aBounds.getX(), y, aBounds.getWidth(), aBounds.getHeight());
}
}
}
private void setSellOn() {
boolean minimized=false;
if (hudAlphaTarget==0) {
minimized=true;
}
// minimized mini sell panel
setGroupVisible(SELL_INFO_GROUP, minimized);
setGroupEnabled(SELL_INFO_GROUP, minimized);
// sell button on hud
setVisible(ID_SELL, false);
//setEnabled(ID_SELL, false); don't disable, otherwise DEL wont work when hud hidden
// cancel button on hud
setVisible(ID_SELL_DONE, !minimized);
setEnabled(ID_SELL_DONE, !minimized);
setGroupVisible(ID_INFO_GROUP,false);
sellActive = true;
}
private void setSellOff() {
boolean minimized=false;
if (hudAlphaTarget==0) {
minimized=true;
}
// minimized mini sell panel
setGroupVisible(SELL_INFO_GROUP, false);
setGroupEnabled(SELL_INFO_GROUP, false);
if (!minimized) {
// sell button on hud
setVisible(ID_SELL, true);
setEnabled(ID_SELL, true);
}
// cancel button on hud
setVisible(ID_SELL_DONE, false);
setEnabled(ID_SELL_DONE, false);
setGroupVisible(ID_INFO_GROUP,false);
sellActive = false;
}
}