diff --git a/core/src/com/etheller/warsmash/viewer5/Texture.java b/core/src/com/etheller/warsmash/viewer5/Texture.java index fc75b47..d55596f 100644 --- a/core/src/com/etheller/warsmash/viewer5/Texture.java +++ b/core/src/com/etheller/warsmash/viewer5/Texture.java @@ -2,7 +2,7 @@ package com.etheller.warsmash.viewer5; import com.etheller.warsmash.viewer5.handlers.ResourceHandler; -public abstract class Texture extends HandlerResource { +public abstract class Texture extends HandlerResource implements ViewerTextureRenderable { public Texture(final ModelViewer viewer, final String extension, final PathSolver pathSolver, final String fetchUrl, final ResourceHandler handler) { @@ -17,8 +17,10 @@ public abstract class Texture extends HandlerResource { public abstract int getHeight(); + @Override public abstract int getGlTarget(); + @Override public abstract int getGlHandle(); public abstract void setWrapS(final boolean wrapS); diff --git a/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java b/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java new file mode 100644 index 0000000..7f29f0e --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java @@ -0,0 +1,29 @@ +package com.etheller.warsmash.viewer5; + +import com.badlogic.gdx.graphics.Texture; + +public interface ViewerTextureRenderable { + // TODO bind method makes more sense here + + int getGlTarget(); + + int getGlHandle(); + + class GdxViewerTextureRenderable implements ViewerTextureRenderable { + private final com.badlogic.gdx.graphics.Texture gdxTexture; + + public GdxViewerTextureRenderable(final Texture texture) { + this.gdxTexture = texture; + } + + @Override + public int getGlTarget() { + return this.gdxTexture.glTarget; + } + + @Override + public int getGlHandle() { + return this.gdxTexture.getTextureObjectHandle(); + } + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java index 95e8167..0f8f348 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java @@ -9,7 +9,7 @@ import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.GL30; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.Texture; +import com.etheller.warsmash.viewer5.ViewerTextureRenderable; /** * TODO this is copied from RivSoft stuff. @@ -22,7 +22,7 @@ import com.etheller.warsmash.viewer5.Texture; */ public class SplatModel { private static final int MAX_VERTICES = 65000; - private final Texture texture; + private final ViewerTextureRenderable texture; private final List batches; public final float[] color; private final List locations; @@ -30,8 +30,9 @@ public class SplatModel { private final boolean unshaded; private final boolean noDepthTest; - public SplatModel(final GL30 gl, final Texture texture, final List locations, final float[] centerOffset, - final List> unitMapping, final boolean unshaded, final boolean noDepthTest) { + public SplatModel(final GL30 gl, final ViewerTextureRenderable texture, final List locations, + final float[] centerOffset, final List> unitMapping, final boolean unshaded, + final boolean noDepthTest) { this.texture = texture; this.unshaded = unshaded; this.noDepthTest = noDepthTest; @@ -245,9 +246,9 @@ public class SplatModel { return this.noDepthTest; } - public SplatMover add(final float x, final float y, final float w, final float h, final float zDepthUpward, + public SplatMover add(final float x, final float y, final float x2, final float y2, final float zDepthUpward, final float[] centerOffset) { - this.locations.add(new float[] { x, y, w, h, zDepthUpward }); + this.locations.add(new float[] { x, y, x2, y2, zDepthUpward }); final SplatMover splatMover; if (this.splatInstances != null) { splatMover = new SplatMover(this); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java index 19810e0..7c77740 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java @@ -910,8 +910,14 @@ public class War3MapViewer extends ModelViewer { buildingPathingPixelMap = getBuildingPathingPixelMap(row); if (buildingPathingPixelMap != null) { - unitX = Math.round(unitX / 64f) * 64f; - unitY = Math.round(unitY / 64f) * 64f; + unitX = (float) Math.floor(unitX / 64f) * 64f; + unitY = (float) Math.floor(unitY / 64f) * 64f; + if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { + unitX += 32f; + } + if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { + unitY += 32f; + } pathingInstance = this.terrain.pathingGrid.blitRemovablePathingOverlayTexture(unitX, unitY, (int) Math.toDegrees(unitAngle), buildingPathingPixelMap); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java index 0912d7e..8c2f90d 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java @@ -141,91 +141,37 @@ public class PathingGrid { short anyPathingTypeWithUnit = 0; if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.AMPHIBIOUS)) { + System.out.println("intersects amph unit"); anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FLOAT)) { + System.out.println("intersects float unit"); anyPathingTypesInRegion |= PathingFlags.UNSWIMABLE; anyPathingTypeWithUnit |= PathingFlags.UNSWIMABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FLY)) { + System.out.println("intersects fly unit"); anyPathingTypesInRegion |= PathingFlags.UNFLYABLE; anyPathingTypeWithUnit |= PathingFlags.UNFLYABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FOOT)) { + System.out.println("intersects foot unit"); anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; } pathingTypesFillingRegion &= anyPathingTypeWithUnit; for (final CBuildingPathingType pathingType : preventPathingTypes) { - switch (pathingType) { - case BLIGHTED: - throw new IllegalArgumentException("Blight pathing check system is Not Yet Implemented"); - case UNAMPH: - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNWALKABLE) - && PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNSWIMABLE)) { - return false; - } - break; - case UNBUILDABLE: - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNBUILDABLE)) { - return false; - } - break; - case UNFLOAT: - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNSWIMABLE)) { - return false; - } - break; - case UNFLYABLE: - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNFLYABLE)) { - return false; - } - break; - case UNWALKABLE: - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, PathingFlags.UNWALKABLE)) { - return false; - } - break; - default: - break; + if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, pathingType)) { + return false; } } for (final CBuildingPathingType pathingType : requirePathingTypes) { - switch (pathingType) { - case BLIGHTED: - throw new IllegalArgumentException("Blight pathing check system is Not Yet Implemented"); - case UNAMPH: - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNWALKABLE) - || !PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNSWIMABLE)) { - return false; - } - break; - case UNBUILDABLE: - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNBUILDABLE)) { - return false; - } - break; - case UNFLOAT: - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNSWIMABLE)) { - return false; - } - break; - case UNFLYABLE: - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNFLYABLE)) { - return false; - } - break; - case UNWALKABLE: - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, PathingFlags.UNWALKABLE)) { - return false; - } - break; - default: - break; + if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, pathingType)) { + return false; } } return true; @@ -383,6 +329,26 @@ public class PathingGrid { return (pathingValue & flag) != 0; } + public static boolean isPathingFlag(final short pathingValue, final CBuildingPathingType pathingType) { + switch (pathingType) { + case BLIGHTED: + throw new IllegalArgumentException("Blight pathing check system is Not Yet Implemented"); + case UNAMPH: + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE) + && PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); + case UNBUILDABLE: + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNBUILDABLE); + case UNFLOAT: + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); + case UNFLYABLE: + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNFLYABLE); + case UNWALKABLE: + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); + default: + return false; + } + } + private PathingFlags() { } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java index 72735c0..b488988 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java @@ -190,6 +190,9 @@ public class CWorldCollision { @Override public boolean onIntersect(final CUnit intersectingObject) { + if (intersectingObject.isHidden()) { + return false; + } return (intersectingObject != this.firstUnit) && (intersectingObject != this.secondUnit); } } @@ -208,6 +211,9 @@ public class CWorldCollision { @Override public boolean onIntersect(final CUnit intersectingObject) { + if (intersectingObject.isHidden()) { + return false; + } if (this.done) { return true; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java index 36f0e51..27289ca 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java @@ -1,5 +1,6 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; +import java.awt.image.BufferedImage; import java.util.List; import com.etheller.warsmash.util.War3ID; @@ -41,6 +42,18 @@ public class CAbilityOrcBuild extends AbstractCAbilityBuild { @Override public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final AbilityPointTarget point) { + final BufferedImage buildingPathingPixelMap = game.getUnitData().getUnitType(new War3ID(orderId)) + .getBuildingPathingPixelMap(); + if (buildingPathingPixelMap != null) { + point.x = (float) Math.floor(point.x / 64f) * 64f; + point.y = (float) Math.floor(point.y / 64f) * 64f; + if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { + point.x += 32f; + } + if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { + point.y += 32f; + } + } return this.buildBehavior.reset(point, orderId, getBaseOrderId()); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java index 0c05cf2..957e7d7 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java @@ -44,7 +44,6 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPa import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; public class CUnitData { - private static final War3ID RALLY_RAWCODE = War3ID.fromString("ARal"); private static final War3ID MANA_INITIAL_AMOUNT = War3ID.fromString("umpi"); private static final War3ID MANA_MAXIMUM = War3ID.fromString("umpm"); private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("uhpm"); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java index 61c9ce2..4997cd2 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java @@ -11,11 +11,15 @@ import javax.imageio.ImageIO; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Pixmap.Blending; +import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.glutils.PixmapTextureData; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; @@ -43,6 +47,7 @@ import com.etheller.warsmash.util.RenderMathUtils; import com.etheller.warsmash.util.War3ID; import com.etheller.warsmash.util.WarsmashConstants; import com.etheller.warsmash.viewer5.Scene; +import com.etheller.warsmash.viewer5.ViewerTextureRenderable; import com.etheller.warsmash.viewer5.handlers.mdx.Attachment; import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; @@ -54,6 +59,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; +import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel; import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; @@ -61,6 +67,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset; import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates; import com.etheller.warsmash.viewer5.handlers.w3x.camera.GameCameraManager; import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager; +import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.PathingFlags; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI; @@ -101,6 +108,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileSplash; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderListener; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityTargetCheckReceiver; @@ -113,6 +121,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.QueueIconListener; public class MeleeUI implements CUnitStateListener, CommandButtonListener, CommandCardCommandListener, QueueIconListener { + private static final String BUILDING_PATHING_PREVIEW_KEY = "buildingPathingPreview"; public static final float DEFAULT_COMMAND_CARD_ICON_WIDTH = 0.039f; public static final float DEFAULT_COMMAND_CARD_ICON_PRESSED_WIDTH = 0.037f; private static final int COMMAND_CARD_WIDTH = 4; @@ -192,6 +201,11 @@ public class MeleeUI private MdxComplexInstance cursorModelInstance = null; private MdxComplexInstance rallyPointInstance = null; private BufferedImage cursorModelPathing; + private Pixmap cursorModelUnderneathPathingRedGreenPixmap; + private Texture cursorModelUnderneathPathingRedGreenPixmapTexture; + private PixmapTextureData cursorModelUnderneathPathingRedGreenPixmapTextureData; + private SplatModel cursorModelUnderneathPathingRedGreenSplatModel; + private CUnitType cursorBuildingUnitType; private SplatMover placementCursor = null; private final CursorTargetSetupVisitor cursorTargetSetupVisitor; @@ -632,11 +646,15 @@ public class MeleeUI this.cursorModelInstance = null; this.cursorFrame.setVisible(true); } - else if (this.placementCursor != null) { + if (this.placementCursor != null) { this.placementCursor.destroy(Gdx.gl30, this.war3MapViewer.terrain.centerOffset); this.placementCursor = null; this.cursorFrame.setVisible(true); } + if (this.cursorModelUnderneathPathingRedGreenSplatModel != null) { + this.war3MapViewer.terrain.removeSplatBatchModel(BUILDING_PATHING_PREVIEW_KEY); + this.cursorModelUnderneathPathingRedGreenSplatModel = null; + } if (down) { if (left) { this.cursorFrame.setSequence("Scroll Down Left"); @@ -832,6 +850,7 @@ public class MeleeUI if (MeleeUI.this.cursorModelInstance == null) { final MutableObjectData unitData = viewer.getAllObjectData().getUnits(); final War3ID buildingTypeId = new War3ID(MeleeUI.this.activeCommandOrderId); + MeleeUI.this.cursorBuildingUnitType = viewer.simulation.getUnitData().getUnitType(buildingTypeId); final String unitModelPath = viewer.getUnitModelPath(unitData.get(buildingTypeId)); final MdxModel model = (MdxModel) viewer.load(unitModelPath, viewer.mapPathSolver, viewer.solverParams); MeleeUI.this.cursorModelInstance = (MdxComplexInstance) model.addInstance(); @@ -843,14 +862,75 @@ public class MeleeUI viewer.simulation.getGameplayConstants().getBuildingAngle())); MeleeUI.this.cursorModelInstance.setAnimationSpeed(0f); justLoaded = true; - final CUnitType buildingUnitType = viewer.simulation.getUnitData().getUnitType(buildingTypeId); + final CUnitType buildingUnitType = MeleeUI.this.cursorBuildingUnitType; MeleeUI.this.cursorModelPathing = buildingUnitType.getBuildingPathingPixelMap(); + + if (MeleeUI.this.cursorModelPathing != null) { + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap = new Pixmap( + MeleeUI.this.cursorModelPathing.getWidth(), MeleeUI.this.cursorModelPathing.getHeight(), + Format.RGBA8888); + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.setBlending(Blending.None); + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData = new PixmapTextureData( + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap, Format.RGBA8888, false, false); + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture = new Texture( + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData); + final ViewerTextureRenderable greenPixmap = new ViewerTextureRenderable.GdxViewerTextureRenderable( + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture); + MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel = new SplatModel(Gdx.gl30, greenPixmap, + new ArrayList<>(), viewer.terrain.centerOffset, new ArrayList<>(), true, false); + MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel.color[3] = 0.20f; + } } viewer.getClickLocation(clickLocationTemp, this.baseMouseX, Gdx.graphics.getHeight() - this.baseMouseY); if (MeleeUI.this.cursorModelPathing != null) { - clickLocationTemp.x = Math.round(clickLocationTemp.x / 64f) * 64f; - clickLocationTemp.y = Math.round(clickLocationTemp.y / 64f) * 64f; + clickLocationTemp.x = (float) Math.floor(clickLocationTemp.x / 64f) * 64f; + clickLocationTemp.y = (float) Math.floor(clickLocationTemp.y / 64f) * 64f; + if (((MeleeUI.this.cursorModelPathing.getWidth() / 2) % 2) == 1) { + clickLocationTemp.x += 32f; + } + if (((MeleeUI.this.cursorModelPathing.getHeight() / 2) % 2) == 1) { + clickLocationTemp.y += 32f; + } clickLocationTemp.z = viewer.terrain.getGroundHeight(clickLocationTemp.x, clickLocationTemp.y); + + final float halfRenderWidth = MeleeUI.this.cursorModelPathing.getWidth() * 16; + final float halfRenderHeight = MeleeUI.this.cursorModelPathing.getHeight() * 16; + for (int i = 0; i < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getWidth(); i++) { + for (int j = 0; j < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight(); j++) { + boolean blocked = false; + final short pathing = viewer.simulation.getPathingGrid().getPathing( + (clickLocationTemp.x + (i * 32)) - halfRenderWidth, + (clickLocationTemp.y + (j * 32)) - halfRenderHeight); + for (final CBuildingPathingType preventedType : MeleeUI.this.cursorBuildingUnitType + .getPreventedPathingTypes()) { + if (PathingFlags.isPathingFlag(pathing, preventedType)) { + blocked = true; + } + } + for (final CBuildingPathingType requiredType : MeleeUI.this.cursorBuildingUnitType + .getRequiredPathingTypes()) { + if (!PathingFlags.isPathingFlag(pathing, requiredType)) { + blocked = true; + } + } + final int color = blocked ? Color.rgba8888(1, 0, 0, 1.0f) : Color.rgba8888(0, 1, 0, 1.0f); + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.drawPixel(i, + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight() - 1 - j, color); + } + } + MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture + .load(MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData); + + if (justLoaded) { + viewer.terrain.addSplatBatchModel(BUILDING_PATHING_PREVIEW_KEY, + MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel); + MeleeUI.this.placementCursor = MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel.add( + clickLocationTemp.x - halfRenderWidth, clickLocationTemp.y - halfRenderHeight, + clickLocationTemp.x + halfRenderWidth, clickLocationTemp.y + halfRenderHeight, 10, + viewer.terrain.centerOffset); + } + MeleeUI.this.placementCursor.setLocation(clickLocationTemp.x, clickLocationTemp.y, + viewer.terrain.centerOffset); } MeleeUI.this.cursorModelInstance.setLocation(clickLocationTemp); SequenceUtils.randomSequence(MeleeUI.this.cursorModelInstance, PrimaryTag.STAND);