From 0e34a7d539a3b64282055ec870c26583f1837355 Mon Sep 17 00:00:00 2001 From: Retera Date: Sat, 7 Mar 2020 16:18:56 -0600 Subject: [PATCH] Some small updates --- .../warsmash/util/WarsmashConstants.java | 2 +- .../viewer5/handlers/w3x/War3MapViewer.java | 33 +++++++++++++------ .../w3x/rendersim/RenderAttackProjectile.java | 33 +++++++------------ .../handlers/w3x/simulation/CSimulation.java | 6 ++-- .../handlers/w3x/simulation/CUnit.java | 16 +++++++-- .../w3x/simulation/data/CUnitData.java | 23 ++++++++++--- .../w3x/simulation/orders/CAttackOrder.java | 10 +++--- .../projectile/CAttackProjectile.java | 11 +++---- 8 files changed, 83 insertions(+), 51 deletions(-) diff --git a/core/src/com/etheller/warsmash/util/WarsmashConstants.java b/core/src/com/etheller/warsmash/util/WarsmashConstants.java index 1205058..ea441be 100644 --- a/core/src/com/etheller/warsmash/util/WarsmashConstants.java +++ b/core/src/com/etheller/warsmash/util/WarsmashConstants.java @@ -3,5 +3,5 @@ package com.etheller.warsmash.util; public class WarsmashConstants { public static final int MAX_PLAYERS = 16; public static final int REPLACEABLE_TEXTURE_LIMIT = 64; - public static final float SIMULATION_STEP_TIME = 1 / 60f; + public static final float SIMULATION_STEP_TIME = 1 / 20f; } 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 94b4e9c..21a2e12 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java @@ -310,11 +310,16 @@ public class War3MapViewer extends ModelViewer { @Override public CAttackProjectile create(final CSimulation simulation, final CUnit source, final int attackIndex, final CWidget target) { - final int a1ProjectileSpeed = simulation.getUnitData().getA1ProjectileSpeed(source.getTypeId()); - final float a1ProjectileArc = simulation.getUnitData().getA1ProjectileArc(source.getTypeId()); - String a1MissileArt = simulation.getUnitData().getA1MissileArt(source.getTypeId()); - final int a1MinDamage = simulation.getUnitData().getA1MinDamage(source.getTypeId()); - final int a1MaxDamage = simulation.getUnitData().getA1MaxDamage(source.getTypeId()); + final War3ID typeId = source.getTypeId(); + final int a1ProjectileSpeed = simulation.getUnitData().getA1ProjectileSpeed(typeId); + final float a1ProjectileArc = simulation.getUnitData().getA1ProjectileArc(typeId); + String a1MissileArt = simulation.getUnitData().getA1MissileArt(typeId); + final int a1MinDamage = simulation.getUnitData().getA1MinDamage(typeId); + final int a1MaxDamage = simulation.getUnitData().getA1MaxDamage(typeId); + final float projectileLaunchX = simulation.getUnitData().getProjectileLaunchX(typeId); + final float projectileLaunchY = simulation.getUnitData().getProjectileLaunchY(typeId); + final float projectileLaunchZ = simulation.getUnitData().getProjectileLaunchZ(typeId); + final int damage = War3MapViewer.this.seededRandom.nextInt(a1MaxDamage - a1MinDamage) + a1MinDamage; if (a1MissileArt.toLowerCase().endsWith(".mdl")) { @@ -323,15 +328,23 @@ public class War3MapViewer extends ModelViewer { if (!a1MissileArt.toLowerCase().endsWith(".mdx")) { a1MissileArt += ".mdx"; } - final float x = source.getX(); - final float y = source.getY(); - final float height = War3MapViewer.this.terrain.getGroundHeight(x, y) + source.getFlyHeight(); + final float facing = (float) Math.toRadians(source.getFacing()); + final float sinFacing = (float) Math.sin(facing); + final float cosFacing = (float) Math.cos(facing); + final float x = (source.getX() + (projectileLaunchX * cosFacing)) + - (projectileLaunchY * sinFacing); + final float y = source.getY() + (projectileLaunchX * sinFacing) + + (projectileLaunchY * cosFacing); + + final float height = War3MapViewer.this.terrain.getGroundHeight(x, y) + source.getFlyHeight() + + projectileLaunchZ; final CAttackProjectile simulationAttackProjectile = new CAttackProjectile(x, y, height, a1ProjectileSpeed, a1ProjectileArc, target, source, damage); final MdxModel model = (MdxModel) load(a1MissileArt, War3MapViewer.this.mapPathSolver, War3MapViewer.this.solverParams); final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance(); + modelInstance.setTeamColor(source.getPlayerIndex()); modelInstance.setScene(War3MapViewer.this.worldScene); StandSequence.randomBirthSequence(modelInstance); modelInstance.setLocation(x, y, height); @@ -567,8 +580,8 @@ public class War3MapViewer extends ModelViewer { else { angle = (float) Math.toDegrees(unit.getAngle()); } - final CUnit simulationUnit = this.simulation.createUnit(row.getAlias(), unit.getLocation()[0], - unit.getLocation()[1], angle); + final CUnit simulationUnit = this.simulation.createUnit(row.getAlias(), unit.getPlayer(), + unit.getLocation()[0], unit.getLocation()[1], angle); final RenderUnit renderUnit = new RenderUnit(this, model, row, unit, soundset, portraitModel, simulationUnit); this.units.add(renderUnit); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java index bb5f6dd..f5da9f9 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java @@ -4,7 +4,6 @@ import java.util.List; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; import com.etheller.warsmash.parsers.mdlx.Sequence; import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; @@ -15,7 +14,6 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.projectile.CAttackP public class RenderAttackProjectile { private static final Quaternion pitchHeap = new Quaternion(); - private static final Vector3 skewVector = new Vector3(); private final CAttackProjectile simulationProjectile; private final MdxComplexInstance modelInstance; @@ -37,7 +35,7 @@ public class RenderAttackProjectile { final MdxModel model = (MdxModel) this.modelInstance.model; final List sequences = model.getSequences(); final IndexedSequence sequence = StandSequence.selectSequence("death", sequences); - if (this.modelInstance.sequence != sequence.index) { + if ((sequence != null) && (this.modelInstance.sequence != sequence.index)) { this.modelInstance.setSequence(sequence.index); } } @@ -61,27 +59,20 @@ public class RenderAttackProjectile { this.z = this.z + ((speed * simDz) / simD); } - final float dxToTarget = this.simulationProjectile.getTarget().getX() - this.x; - final float dyToTarget = this.simulationProjectile.getTarget().getY() - this.y; - final float dzToTarget = this.simulationProjectile.getTarget().getFlyHeight() - this.z; + final float targetX = this.simulationProjectile.getTarget().getX(); + final float dxToTarget = targetX - this.x; + final float targetY = this.simulationProjectile.getTarget().getY(); + final float dyToTarget = targetY - this.y; + final float dzToTarget = (war3MapViewer.terrain.getGroundHeight(targetX, targetY) + + this.simulationProjectile.getTarget().getFlyHeight()) - this.z; final float d2DToTarget = (float) Math.sqrt((dxToTarget * dxToTarget) + (dyToTarget * dyToTarget)); - final float yaw = (float) Math.atan2(dxToTarget, dyToTarget); + final float yaw = (float) Math.atan2(dyToTarget, dxToTarget); - final float pitch = (float) Math.atan2(dzToTarget, d2DToTarget); + final float pitch = (float) Math.atan2(simDz, simD); - final float arcCurrentHeight = this.simulationProjectile.getArcCurrentHeight(); - final float oppositeYaw = yaw + (float) Math.PI; - skewVector.set((float) (Math.cos(oppositeYaw) * Math.cos(Math.PI / 4)), - (float) (Math.sin(oppositeYaw) * Math.cos(Math.PI / 4)), (float) (Math.sin(Math.PI / 4))); - - final float skewX = arcCurrentHeight * skewVector.x; - final float skewY = arcCurrentHeight * skewVector.y; - final float skewZ = arcCurrentHeight * skewVector.z; - - this.modelInstance.setLocation(this.x + skewX, this.y + skewY, this.z + skewZ); -// this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, yaw); - this.modelInstance.localRotation.setFromAxisRad(0, -1, 0, pitch); -// this.modelInstance.rotateLocal(pitchHeap.setFromAxisRad(0, -1, 0, pitch)); + this.modelInstance.setLocation(this.x, this.y, this.z); + this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, yaw); + this.modelInstance.rotate(pitchHeap.setFromAxisRad(0, -1, 0, pitch)); war3MapViewer.worldScene.grid.moved(this.modelInstance); final boolean everythingDone = this.simulationProjectile.isDone() && this.modelInstance.sequenceEnded; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java index 8272670..708335c 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java @@ -42,8 +42,10 @@ public class CSimulation { return this.units; } - public CUnit createUnit(final War3ID typeId, final float x, final float y, final float facing) { - final CUnit unit = this.unitData.create(this, this.handleIdAllocator.createId(), typeId, x, y, facing); + public CUnit createUnit(final War3ID typeId, final int playerIndex, final float x, final float y, + final float facing) { + final CUnit unit = this.unitData.create(this, this.handleIdAllocator.createId(), playerIndex, typeId, x, y, + facing); this.units.add(unit); return unit; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java index 336c5a8..356de5b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java @@ -17,15 +17,16 @@ public class CUnit extends CWidget { private int speed; private int cooldownEndTime = 0; private float flyHeight; + private int playerIndex; private final List abilities = new ArrayList<>(); private COrder currentOrder; private final Queue orderQueue = new LinkedList<>(); - public CUnit(final int handleId, final float x, final float y, final float life, final War3ID typeId, - final float facing, final float mana, final int maximumLife, final int maximumMana, final int speed, - final float defaultFlyingHeight) { + public CUnit(final int handleId, final int playerIndex, final float x, final float y, final float life, + final War3ID typeId, final float facing, final float mana, final int maximumLife, final int maximumMana, + final int speed, final float defaultFlyingHeight) { super(handleId, x, y, life); this.typeId = typeId; this.facing = facing; @@ -132,6 +133,7 @@ public class CUnit extends CWidget { return this.cooldownEndTime; } + @Override public float getFlyHeight() { return this.flyHeight; } @@ -140,4 +142,12 @@ public class CUnit extends CWidget { this.flyHeight = flyHeight; } + public int getPlayerIndex() { + return this.playerIndex; + } + + public void setPlayerIndex(final int playerIndex) { + this.playerIndex = playerIndex; + } + } 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 79bb8de..9f96282 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 @@ -20,6 +20,9 @@ public class CUnitData { private static final War3ID TURN_RATE = War3ID.fromString("umvr"); private static final War3ID IS_BLDG = War3ID.fromString("ubdg"); private static final War3ID NAME = War3ID.fromString("unam"); + private static final War3ID PROJECTILE_LAUNCH_X = War3ID.fromString("ulpx"); + private static final War3ID PROJECTILE_LAUNCH_Y = War3ID.fromString("ulpy"); + private static final War3ID PROJECTILE_LAUNCH_Z = War3ID.fromString("ulpz"); private static final War3ID ATTACK1_DMG_BASE = War3ID.fromString("ua1b"); private static final War3ID ATTACK1_DMG_DICE = War3ID.fromString("ua1d"); private static final War3ID ATTACK1_DMG_SIDES_PER_DIE = War3ID.fromString("ua1s"); @@ -42,16 +45,16 @@ public class CUnitData { this.unitData = unitData; } - public CUnit create(final CSimulation simulation, final int handleId, final War3ID typeId, final float x, - final float y, final float facing) { + public CUnit create(final CSimulation simulation, final int playerIndex, final int handleId, final War3ID typeId, + final float x, final float y, final float facing) { final MutableGameObject unitType = this.unitData.get(typeId); final int life = unitType.getFieldAsInteger(HIT_POINT_MAXIMUM, 0); final int manaInitial = unitType.getFieldAsInteger(MANA_INITIAL_AMOUNT, 0); final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0); final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0); final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0); - final CUnit unit = new CUnit(handleId, x, y, life, typeId, facing, manaInitial, life, manaMaximum, speed, - moveHeight); + final CUnit unit = new CUnit(handleId, playerIndex, x, y, life, typeId, facing, manaInitial, life, manaMaximum, + speed, moveHeight); if (speed > 0) { unit.add(simulation, CAbilityMove.INSTANCE); unit.add(simulation, CAbilityPatrol.INSTANCE); @@ -139,4 +142,16 @@ public class CUnitData { public float getA2Cooldown(final War3ID unitTypeId) { return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_COOLDOWN, 0); } + + public float getProjectileLaunchX(final War3ID unitTypeId) { + return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_X, 0); + } + + public float getProjectileLaunchY(final War3ID unitTypeId) { + return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Y, 0); + } + + public float getProjectileLaunchZ(final War3ID unitTypeId) { + return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Z, 0); + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/CAttackOrder.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/CAttackOrder.java index cd92835..3513b06 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/CAttackOrder.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/CAttackOrder.java @@ -28,11 +28,11 @@ public class CAttackOrder implements COrder { if (goalAngle < 0) { goalAngle += 360; } - final float facing = this.unit.getFacing(); + float facing = this.unit.getFacing(); float delta = goalAngle - facing; - final float absDelta = Math.abs(delta); final float propulsionWindow = simulation.getUnitData().getPropulsionWindow(this.unit.getTypeId()); final float turnRate = simulation.getUnitData().getTurnRate(this.unit.getTypeId()); + final int speed = this.unit.getSpeed(); if (delta < -180) { delta = 360 + delta; @@ -40,16 +40,18 @@ public class CAttackOrder implements COrder { if (delta > 180) { delta = -360 + delta; } + final float absDelta = Math.abs(delta); if ((absDelta <= 1.0) && (absDelta != 0)) { this.unit.setFacing(goalAngle); } else { - float angleToAdd = ((Math.signum(delta) * turnRate) * WarsmashConstants.SIMULATION_STEP_TIME) * 360; + float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate); if (absDelta < Math.abs(angleToAdd)) { angleToAdd = delta; } - this.unit.setFacing(facing + angleToAdd); + facing += angleToAdd; + this.unit.setFacing(facing); } if (absDelta < propulsionWindow) { this.wasWithinPropWindow = true; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/projectile/CAttackProjectile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/projectile/CAttackProjectile.java index 7727ee9..708f998 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/projectile/CAttackProjectile.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/projectile/CAttackProjectile.java @@ -11,7 +11,6 @@ public class CAttackProjectile { private float z; private final float startingHeight; private final float speed; - private final float arc; private final CWidget target; private final float halfStartingDistance; private final float arcPeakHeight; @@ -28,7 +27,6 @@ public class CAttackProjectile { this.z = z; this.startingHeight = z; this.speed = speed; - this.arc = arc; this.target = target; final float dx = target.getX() - x; final float dy = target.getY() - y; @@ -70,10 +68,11 @@ public class CAttackProjectile { this.x = this.x + dx; this.y = this.y + dy; - float firstTerm = ((1 / this.halfStartingDistance) * (this.totalTravelDistance - this.halfStartingDistance)); - firstTerm = firstTerm * firstTerm; - this.arcCurrentHeight = (-firstTerm + 1) * this.arcPeakHeight; - this.z = this.startingHeight + dz; + final float distanceToPeak = this.totalTravelDistance - this.halfStartingDistance; + final float normPeakDist = distanceToPeak / this.halfStartingDistance; + final float currentHeightPercentage = 1 - (normPeakDist * normPeakDist); + this.arcCurrentHeight = currentHeightPercentage * this.arcPeakHeight; + this.z = this.startingHeight + dz + this.arcCurrentHeight; return this.done; }