Update with some jass changes and a config file for using my high resolution test assets

This commit is contained in:
Retera 2021-07-31 09:58:53 -04:00
parent a4b5da5af0
commit 4753bc1555
20 changed files with 764 additions and 158 deletions

View File

@ -1,5 +1,5 @@
[DataSources]
Count=8
Count=9
Type00=MPQ
Path00="D:\Games\Warcraft III Patch 1.22\war3.mpq"
Type01=MPQ
@ -8,48 +8,13 @@ Type02=MPQ
Path02="D:\Games\Warcraft III Patch 1.22\War3xlocal.mpq"
Type03=MPQ
Path03="D:\Games\Warcraft III Patch 1.22\War3Patch.mpq"
Type04=Folder
Path04="..\..\resources"
Type04=MPQ
Path04="D:\Games\Warcraft III Patch 1.22\Warsmash\War3Mod.mpq"
Type05=Folder
Path05="D:\Backups\Warsmash\Data"
Path05="..\..\resources"
Type06=Folder
Path06="D:\Games\Warcraft III Patch 1.22\Maps"
Path06="D:\Backups\Warsmash\Data"
Type07=Folder
Path07="."
Type08=MPQ
Path08="C:\Users\micro\Downloads\Warcraft III All In One\war3g.exe"
[Map]
//FilePath="CombatUnitTests.w3x"
//FilePath="PitchRoll.w3x"
//FilePath="PeonStartingBase_Simple.w3x"
FilePath="PeonStartingBase_Scythe.w3x"
//FilePath="MyStromguarde.w3m"
//FilePath="ColdArrows.w3m"
//FilePath="DungeonGoldMine.w3m"
//FilePath="PlayerPeasants.w3m"
//FilePath="FireLord.w3x"
//FilePath="Maps\Campaign\NightElf03.w3m"
//FilePath="PhoenixAttack.w3x"
//FilePath="LightEnvironmentTest.w3x"
//FilePath="TorchLight2.w3x"
//FilePath="OrcAssault.w3x"
//FilePath="FrostyVsFarm.w3m"
//FilePath="ModelTest.w3x"
//FilePath="SpinningSample.w3x"
//FilePath="Maps\Campaign\Prologue02.w3m"
//FilePath="Pathing.w3x"
//FilePath="ItemFacing.w3x"
//FilePath=SomeParticleTests.w3x
//FilePath="PeonMiningMultiHall.w3x"
//FilePath="QuadtreeBugs.w3x"
//FilePath="test2.w3x"
//FilePath="FarseerHoldPositionTest.w3x"
//FilePath="Ramps.w3m"
//FilePath="V1\Farm.w3x"
//FilePath="PenguinWorld.w3x"
//FilePath="Maps\FrozenThrone\Campaign\UndeadX09.w3x"
//FilePath="LavellaLagoon.w3x"
//FilePath="WiceOrc.w3x"
//FilePath="NorthrendPathingDoodle.w3x"
//FilePath="Maps\Campaign\Prologue01.w3m"
Path07="D:\Games\Warcraft III Patch 1.22\Maps"
Type08=Folder
Path08="."

View File

@ -0,0 +1,47 @@
[DataSources]
Count=5
Type00=Folder
Path00="D:\Backups\Warcraft\Data\HiResFlat"
Type01=Folder
Path01="..\..\resources"
Type02=Folder
Path02="D:\Backups\Warsmash\Data"
Type03=Folder
Path03="D:\Games\Warcraft III Patch 1.22\Maps"
Type04=Folder
Path04="."
[Map]
//FilePath="CombatUnitTests.w3x"
//FilePath="PitchRoll.w3x"
//FilePath="PeonStartingBase_Simple.w3x"
FilePath="PeonStartingBase_Scythe.w3x"
//FilePath="MyStromguarde.w3m"
//FilePath="ColdArrows.w3m"
//FilePath="DungeonGoldMine.w3m"
//FilePath="PlayerPeasants.w3m"
//FilePath="FireLord.w3x"
//FilePath="Maps\Campaign\NightElf03.w3m"
//FilePath="PhoenixAttack.w3x"
//FilePath="LightEnvironmentTest.w3x"
//FilePath="TorchLight2.w3x"
//FilePath="OrcAssault.w3x"
//FilePath="FrostyVsFarm.w3m"
//FilePath="ModelTest.w3x"
//FilePath="SpinningSample.w3x"
//FilePath="Maps\Campaign\Prologue02.w3m"
//FilePath="Pathing.w3x"
//FilePath="ItemFacing.w3x"
//FilePath=SomeParticleTests.w3x
//FilePath="PeonMiningMultiHall.w3x"
//FilePath="QuadtreeBugs.w3x"
//FilePath="test2.w3x"
//FilePath="FarseerHoldPositionTest.w3x"
//FilePath="Ramps.w3m"
//FilePath="V1\Farm.w3x"
//FilePath="PenguinWorld.w3x"
//FilePath="Maps\FrozenThrone\Campaign\UndeadX09.w3x"
//FilePath="LavellaLagoon.w3x"
//FilePath="WiceOrc.w3x"
//FilePath="NorthrendPathingDoodle.w3x"
//FilePath="Maps\Campaign\Prologue01.w3m"

View File

@ -2408,6 +2408,96 @@ public class Jass2 {
return new HandleJassValue(unitType, ((CommonTriggerExecutionScope) triggerScope).getLeavingUnit());
}
});
jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTrackableHitEvent",
new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException(
"TriggerRegisterTrackableHitEvent not yet implemented ???");
// dont feel like implementing this atm, although it probably wouldnt be that
// hard to do
}
});
jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTrackableTrackEvent",
new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException(
"TriggerRegisterTrackableTrackEvent not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetTriggeringTrackable", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetTriggeringTrackable not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetClickedButton", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetClickedButton not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetClickedDialog", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetClickedDialog not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishSoonTimeRemaining",
new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException(
"GetTournamentFinishSoonTimeRemaining not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishNowRule", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetTournamentFinishNowRule not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishNowPlayer", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetTournamentFinishNowPlayer not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetTournamentScore", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetTournamentScore not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetSaveBasicFilename", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
throw new UnsupportedOperationException("GetSaveBasicFilename not yet implemented ???");
}
});
jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterPlayerEvent", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
final Trigger whichTrigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance());
final CPlayerJass whichPlayer = arguments.get(1).visit(ObjectJassValueVisitor.getInstance());
final JassGameEventsWar3 whichPlayerEvent = arguments.get(2)
.visit(ObjectJassValueVisitor.getInstance());
return new HandleJassValue(eventType,
whichPlayer.addEvent(globalScope, whichTrigger, whichPlayerEvent));
}
});
}
private void registerConfigNatives(final JassProgramVisitor jassProgramVisitor, final War3MapConfig mapConfig,

View File

@ -1,47 +1,139 @@
package com.etheller.warsmash.parsers.jass.scope;
import com.etheller.interpreter.ast.scope.TriggerExecutionScope;
import com.etheller.interpreter.ast.scope.trigger.Trigger;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegion;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimerJass;
public class CommonTriggerExecutionScope extends TriggerExecutionScope {
private final CUnit triggeringUnit;
private final CUnit filterUnit;
private final CUnit enumUnit;
private final CDestructable filterDestructable;
private final CDestructable enumDestructable;
private final CItem filterItem;
private final CItem enumItem;
private final CPlayerJass filterPlayer;
private final CPlayerJass enumPlayer;
private final CTimerJass expiringTimer;
private final CUnit enteringUnit;
private final CUnit leavingUnit;
private final CRegion triggeringRegion;
private CUnit triggeringUnit;
private CUnit filterUnit;
private CUnit enumUnit;
private CDestructable filterDestructable;
private CDestructable enumDestructable;
private CItem filterItem;
private CItem enumItem;
private CPlayerJass filterPlayer;
private CPlayerJass enumPlayer;
private CTimerJass expiringTimer;
private CUnit enteringUnit;
private CUnit leavingUnit;
private CRegion triggeringRegion;
private CPlayerJass triggeringPlayer;
private CUnit levelingUnit;
private CUnit learningUnit;
private int learnedSkill;
private int learnedSkillLevel;
private CUnit revivableUnit;
private CUnit revivingUnit;
private CUnit attacker;
private CUnit rescuer;
private CUnit dyingUnit;
private CUnit killingUnit;
private CUnit decayingUnit;
private CUnit constructingStructure;
private CUnit cancelledStructure;
private CUnit constructedStructure;
private CUnit researchingUnit;
private int researched;
private int trainedUnitType;
private CUnit trainedUnit;
private CUnit detectedUnit;
private CUnit summoningUnit;
private CUnit summonedUnit;
private CUnit transportUnit;
private CUnit loadedUnit;
private CUnit sellingUnit;
private CUnit soldUnit;
private CUnit buyingUnit;
private CUnit soldItem;
private CUnit changingUnit;
private CPlayerJass changingUnitPrevOwner;
private CUnit manipulatingUnit;
private CItem manipulatedItem;
private CUnit orderedUnit;
private int issuedOrderId;
private float orderPointX;
private float orderPointY;
private CWidget orderTarget;
private CDestructable orderTargetDestructable;
private CItem orderTargetItem;
private CUnit orderTargetUnit;
public CommonTriggerExecutionScope(final TriggerExecutionScope parentScope, final CUnit triggeringUnit,
final CUnit filterUnit, final CUnit enumUnit, final CDestructable filterDestructable,
final CDestructable enumDestructable, final CItem filterItem, final CItem enumItem,
final CPlayerJass filterPlayer, final CPlayerJass enumPlayer, final CTimerJass expiringTimer,
final CUnit enteringUnit, final CUnit leavingUnit, final CRegion triggeringRegion) {
public CommonTriggerExecutionScope(final Trigger triggeringTrigger) {
super(triggeringTrigger);
}
public CommonTriggerExecutionScope(final TriggerExecutionScope parentScope) {
super(parentScope.getTriggeringTrigger());
this.triggeringUnit = triggeringUnit;
this.filterUnit = filterUnit;
this.enumUnit = enumUnit;
this.filterDestructable = filterDestructable;
this.enumDestructable = enumDestructable;
this.filterItem = filterItem;
this.enumItem = enumItem;
this.filterPlayer = filterPlayer;
this.enumPlayer = enumPlayer;
this.expiringTimer = expiringTimer;
this.enteringUnit = enteringUnit;
this.leavingUnit = leavingUnit;
this.triggeringRegion = triggeringRegion;
if (parentScope instanceof CommonTriggerExecutionScope) {
copyFrom((CommonTriggerExecutionScope) parentScope);
}
}
public CommonTriggerExecutionScope(final CommonTriggerExecutionScope parentScope) {
super(parentScope.getTriggeringTrigger());
copyFrom(parentScope);
}
private void copyFrom(final CommonTriggerExecutionScope parentScope) {
this.triggeringUnit = parentScope.triggeringUnit;
this.filterUnit = parentScope.filterUnit;
this.enumUnit = parentScope.enumUnit;
this.filterDestructable = parentScope.filterDestructable;
this.enumDestructable = parentScope.enumDestructable;
this.filterItem = parentScope.filterItem;
this.enumItem = parentScope.enumItem;
this.filterPlayer = parentScope.filterPlayer;
this.enumPlayer = parentScope.enumPlayer;
this.expiringTimer = parentScope.expiringTimer;
this.enteringUnit = parentScope.enteringUnit;
this.leavingUnit = parentScope.leavingUnit;
this.triggeringRegion = parentScope.triggeringRegion;
this.triggeringPlayer = parentScope.triggeringPlayer;
this.levelingUnit = parentScope.levelingUnit;
this.learningUnit = parentScope.learningUnit;
this.learnedSkill = parentScope.learnedSkill;
this.learnedSkillLevel = parentScope.learnedSkillLevel;
this.revivableUnit = parentScope.revivableUnit;
this.attacker = parentScope.attacker;
this.rescuer = parentScope.rescuer;
this.dyingUnit = parentScope.dyingUnit;
this.killingUnit = parentScope.killingUnit;
this.decayingUnit = parentScope.decayingUnit;
this.constructingStructure = parentScope.constructingStructure;
this.cancelledStructure = parentScope.cancelledStructure;
this.constructedStructure = parentScope.constructedStructure;
this.researchingUnit = parentScope.researchingUnit;
this.researched = parentScope.researched;
this.trainedUnitType = parentScope.trainedUnitType;
this.trainedUnit = parentScope.trainedUnit;
this.detectedUnit = parentScope.detectedUnit;
this.summoningUnit = parentScope.summoningUnit;
this.summonedUnit = parentScope.summonedUnit;
this.transportUnit = parentScope.transportUnit;
this.loadedUnit = parentScope.loadedUnit;
this.sellingUnit = parentScope.sellingUnit;
this.soldUnit = parentScope.soldUnit;
this.buyingUnit = parentScope.buyingUnit;
this.soldItem = parentScope.soldItem;
this.changingUnit = parentScope.changingUnit;
this.changingUnitPrevOwner = parentScope.changingUnitPrevOwner;
this.manipulatingUnit = parentScope.manipulatingUnit;
this.manipulatedItem = parentScope.manipulatedItem;
this.orderedUnit = parentScope.orderedUnit;
this.issuedOrderId = parentScope.issuedOrderId;
this.orderPointX = parentScope.orderPointX;
this.orderPointY = parentScope.orderPointY;
this.orderTarget = parentScope.orderTarget;
this.orderTargetDestructable = parentScope.orderTargetDestructable;
this.orderTargetItem = parentScope.orderTargetItem;
this.orderTargetUnit = parentScope.orderTargetUnit;
}
public CUnit getEnumUnit() {
@ -96,44 +188,225 @@ public class CommonTriggerExecutionScope extends TriggerExecutionScope {
return this.triggeringRegion;
}
public CPlayerJass getTriggeringPlayer() {
return this.triggeringPlayer;
}
public CUnit getLevelingUnit() {
return this.levelingUnit;
}
public CUnit getLearningUnit() {
return this.learningUnit;
}
public int getLearnedSkill() {
return this.learnedSkill;
}
public int getLearnedSkillLevel() {
return this.learnedSkillLevel;
}
public CUnit getRevivableUnit() {
return this.revivableUnit;
}
public CUnit getRevivingUnit() {
return this.revivingUnit;
}
public CUnit getAttacker() {
return this.attacker;
}
public CUnit getRescuer() {
return this.rescuer;
}
public CUnit getDyingUnit() {
return this.dyingUnit;
}
public CUnit getKillingUnit() {
return this.killingUnit;
}
public CUnit getDecayingUnit() {
return this.decayingUnit;
}
public CUnit getConstructingStructure() {
return this.constructingStructure;
}
public CUnit getCancelledStructure() {
return this.cancelledStructure;
}
public CUnit getConstructedStructure() {
return this.constructedStructure;
}
public CUnit getResearchingUnit() {
return this.researchingUnit;
}
public int getResearched() {
return this.researched;
}
public int getTrainedUnitType() {
return this.trainedUnitType;
}
public CUnit getTrainedUnit() {
return this.trainedUnit;
}
public CUnit getDetectedUnit() {
return this.detectedUnit;
}
public CUnit getSummoningUnit() {
return this.summoningUnit;
}
public CUnit getSummonedUnit() {
return this.summonedUnit;
}
public CUnit getTransportUnit() {
return this.transportUnit;
}
public CUnit getLoadedUnit() {
return this.loadedUnit;
}
public CUnit getSellingUnit() {
return this.sellingUnit;
}
public CUnit getSoldUnit() {
return this.soldUnit;
}
public CUnit getBuyingUnit() {
return this.buyingUnit;
}
public CUnit getSoldItem() {
return this.soldItem;
}
public CUnit getChangingUnit() {
return this.changingUnit;
}
public CPlayerJass getChangingUnitPrevOwner() {
return this.changingUnitPrevOwner;
}
public CUnit getManipulatingUnit() {
return this.manipulatingUnit;
}
public CItem getManipulatedItem() {
return this.manipulatedItem;
}
public CUnit getOrderedUnit() {
return this.orderedUnit;
}
public int getIssuedOrderId() {
return this.issuedOrderId;
}
public float getOrderPointX() {
return this.orderPointX;
}
public float getOrderPointY() {
return this.orderPointY;
}
public CWidget getOrderTarget() {
return this.orderTarget;
}
public CDestructable getOrderTargetDestructable() {
return this.orderTargetDestructable;
}
public CItem getOrderTargetItem() {
return this.orderTargetItem;
}
public CUnit getOrderTargetUnit() {
return this.orderTargetUnit;
}
public static CommonTriggerExecutionScope filterScope(final TriggerExecutionScope parentScope,
final CUnit filterUnit) {
return new CommonTriggerExecutionScope(parentScope, null, filterUnit, null, null, null, null, null, null, null,
null, null, null, null);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.filterUnit = filterUnit;
return scope;
}
public static CommonTriggerExecutionScope enumScope(final TriggerExecutionScope parentScope, final CUnit enumUnit) {
return new CommonTriggerExecutionScope(parentScope, null, null, enumUnit, null, null, null, null, null, null,
null, null, null, null);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.enumUnit = enumUnit;
return scope;
}
public static CommonTriggerExecutionScope filterScope(final TriggerExecutionScope parentScope,
final CPlayerJass filterPlayer) {
return new CommonTriggerExecutionScope(parentScope, null, null, null, null, null, null, null, filterPlayer,
null, null, null, null, null);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.filterPlayer = filterPlayer;
return scope;
}
public static CommonTriggerExecutionScope enumScope(final TriggerExecutionScope parentScope,
final CPlayerJass enumPlayer) {
return new CommonTriggerExecutionScope(parentScope, null, null, null, null, null, null, null, null, enumPlayer,
null, null, null, null);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.enumPlayer = enumPlayer;
return scope;
}
public static CommonTriggerExecutionScope expiringTimer(final CTimerJass cTimerJass) {
return new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY, null, null, null, null, null, null, null,
null, null, cTimerJass, null, null, null);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY);
scope.expiringTimer = cTimerJass;
return scope;
}
public static CommonTriggerExecutionScope unitEnterRegionScope(final TriggerExecutionScope parentScope,
final CUnit enteringUnit, final CRegion triggeringRegion) {
return new CommonTriggerExecutionScope(parentScope, null, null, null, null, null, null, null, null, null, null,
enteringUnit, null, triggeringRegion);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.enteringUnit = enteringUnit;
scope.triggeringRegion = triggeringRegion;
return scope;
}
public static CommonTriggerExecutionScope unitLeaveRegionScope(final TriggerExecutionScope parentScope,
final CUnit leavingUnit, final CRegion triggeringRegion) {
return new CommonTriggerExecutionScope(parentScope, null, null, null, null, null, null, null, null, null, null,
null, leavingUnit, triggeringRegion);
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope);
scope.leavingUnit = leavingUnit;
scope.triggeringRegion = triggeringRegion;
return scope;
}
public static CommonTriggerExecutionScope playerHeroLevelScope(final CUnit hero) {
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY);
scope.levelingUnit = hero;
return scope;
}
public static CommonTriggerExecutionScope playerHeroRevivableScope(final CUnit hero) {
final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY);
scope.revivableUnit = hero;
return scope;
}
}

View File

@ -29,4 +29,11 @@ public class WarsmashConstants {
public static final boolean VERBOSE_LOGGING = true;
public static final boolean ENABLE_DEBUG = false;
public static final char SPECIAL_ESCAPE_KEYCODE = 0x7E;
// My tileset loader is "always on top", even for local files. This is different
// from some MPQ loader engines that would use
// load index as a numeric value and could be changed. For now, I have this
// workaround to fix it if you need the local files
// to take priority over built-ins for tilesets.
public static final boolean FIX_FLAT_FILES_TILESET_LOADING = false;
}

View File

@ -516,7 +516,7 @@ public class MdxComplexInstance extends ModelInstance {
}
final int glGetError = Gdx.gl.glGetError();
if (glGetError != GL20.GL_NO_ERROR) {
if ((glGetError != GL20.GL_NO_ERROR) && WarsmashConstants.ENABLE_DEBUG) {
throw new IllegalStateException("GL ERROR: " + glGetError + " ON " + model.name + " (Opaque)");
}
}
@ -532,7 +532,7 @@ public class MdxComplexInstance extends ModelInstance {
group.render(this, this.scene.camera.viewProjectionMatrix);
final int glGetError = Gdx.gl.glGetError();
if (glGetError != GL20.GL_NO_ERROR) {
if ((glGetError != GL20.GL_NO_ERROR) && WarsmashConstants.ENABLE_DEBUG) {
throw new IllegalStateException("GL ERROR: " + glGetError + " ON " + model.name + " (Translucent)");
}
}
@ -883,22 +883,20 @@ public class MdxComplexInstance extends ModelInstance {
public void setFrameByRatio(final float ratioOfAnimationCompleted) {
if (this.sequence != -1) {
final Sequence currentlyPlayingSequence = ((MdxModel) this.model).sequences.get(this.sequence);
long start = currentlyPlayingSequence.getInterval()[0];
final long start = currentlyPlayingSequence.getInterval()[0];
final int lastIntegerFrame = this.frame;
float lastFloatingFrame = this.floatingFrame;
long sequenceLength = currentlyPlayingSequence.getInterval()[1] - start;
float newFloatingFrame = start
+ (sequenceLength
* ratioOfAnimationCompleted);
float frameTime = newFloatingFrame-lastFloatingFrame;
if(frameTime < 0) {
final float lastFloatingFrame = this.floatingFrame;
final long sequenceLength = currentlyPlayingSequence.getInterval()[1] - start;
final float newFloatingFrame = start + (sequenceLength * ratioOfAnimationCompleted);
float frameTime = newFloatingFrame - lastFloatingFrame;
if (frameTime < 0) {
frameTime += sequenceLength;
}
this.floatingFrame = newFloatingFrame;
this.frame = (int) this.floatingFrame;
this.blendTimeRemaining -= frameTime;
int integerFrameTime = this.frame - lastIntegerFrame;
if(integerFrameTime < 0) {
if (integerFrameTime < 0) {
integerFrameTime += sequenceLength;
}
this.counter += integerFrameTime;
@ -910,14 +908,14 @@ public class MdxComplexInstance extends ModelInstance {
}
}
public int clampFrame(int frameToClamp) {
public int clampFrame(final int frameToClamp) {
final MdxModel model = (MdxModel) this.model;
final int sequenceId = this.sequence;
if(sequenceId >= 0 && sequenceId < model.sequences.size()) {
if ((sequenceId >= 0) && (sequenceId < model.sequences.size())) {
final Sequence sequence = model.sequences.get(sequenceId);
final long[] interval = sequence.getInterval();
return (int)Math.max(interval[0], Math.min(interval[1], frameToClamp));
return (int) Math.max(interval[0], Math.min(interval[1], frameToClamp));
}
return frameToClamp;
}
}
}

View File

@ -132,8 +132,23 @@ public class TgaFile {
}
}
}
else if ((header[17] >> 4) == 2) {
// flip horizontally and vertically
for (int y = 0; y < h; y++) {
final int w2 = w / 2;
for (int x = 0; x < w2; x++) {
final int a = (y * w) + x;
final int b = ((h - 1 - y) * w) + (w - 1 - x);
final int t = pixels[a];
pixels[a] = pixels[b];
pixels[b] = t;
}
}
}
else {
throw new UnsupportedOperationException("Error " + name);
final int headerval = header[17] >> 4;
throw new UnsupportedOperationException("Error " + name + " (" + headerval + ")");
}
return dst;

View File

@ -466,24 +466,30 @@ public class War3MapViewer extends AbstractMdxModelViewer {
// from either the map or the game, giving the map priority.
SeekableByteChannel sbc;
final CompoundDataSource compoundDataSource = war3Map.getCompoundDataSource();
try (InputStream mapStream = compoundDataSource.getResourceAsStream(tileset + ".mpq")) {
if (mapStream == null) {
if (WarsmashConstants.FIX_FLAT_FILES_TILESET_LOADING) {
tilesetSource = new CompoundDataSource(
Arrays.asList(compoundDataSource, new SubdirDataSource(compoundDataSource, tileset + ".mpq/")));
}
else {
try (InputStream mapStream = compoundDataSource.getResourceAsStream(tileset + ".mpq")) {
if (mapStream == null) {
tilesetSource = new CompoundDataSource(Arrays.asList(compoundDataSource,
new SubdirDataSource(compoundDataSource, tileset + ".mpq/"),
new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/")));
}
else {
final byte[] mapData = IOUtils.toByteArray(mapStream);
sbc = new SeekableInMemoryByteChannel(mapData);
final DataSource internalMpqContentsDataSource = new MpqDataSource(new MPQArchive(sbc), sbc);
tilesetSource = new CompoundDataSource(
Arrays.asList(compoundDataSource, internalMpqContentsDataSource));
}
}
catch (final IOException exc) {
tilesetSource = new CompoundDataSource(Arrays.asList(compoundDataSource,
new SubdirDataSource(compoundDataSource, tileset + ".mpq/"),
new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/")));
}
else {
final byte[] mapData = IOUtils.toByteArray(mapStream);
sbc = new SeekableInMemoryByteChannel(mapData);
final DataSource internalMpqContentsDataSource = new MpqDataSource(new MPQArchive(sbc), sbc);
tilesetSource = new CompoundDataSource(
Arrays.asList(compoundDataSource, internalMpqContentsDataSource));
}
}
catch (final IOException exc) {
tilesetSource = new CompoundDataSource(
Arrays.asList(compoundDataSource, new SubdirDataSource(compoundDataSource, tileset + ".mpq/"),
new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/")));
}
}
catch (final MPQException e) {
@ -723,29 +729,30 @@ public class War3MapViewer extends AbstractMdxModelViewer {
}
@Override
public void heroRevived(CUnit source) {
public void heroRevived(final CUnit source) {
final AbilityUI reviveUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_REVIVE_RAWCODE);
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source);
CPlayer player = simulation.getPlayer(source.getPlayerIndex());
final CPlayer player = War3MapViewer.this.simulation.getPlayer(source.getPlayerIndex());
final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal());
spawnFxOnOrigin(renderUnit, heroReviveArt);
MutableGameObject row = allObjectData.getUnits().get(source.getTypeId());
final MutableGameObject row = War3MapViewer.this.allObjectData.getUnits()
.get(source.getTypeId());
// Recreate unit shadow.... is needed here
final String unitShadow = row.getFieldAsString(UNIT_SHADOW, 0);
float unitX = source.getX();
float unitY = source.getY();
final float unitX = source.getX();
final float unitY = source.getY();
if ((unitShadow != null) && !"_".equals(unitShadow)) {
final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp";
final float shadowX = row.getFieldAsFloat(UNIT_SHADOW_X, 0);
final float shadowY = row.getFieldAsFloat(UNIT_SHADOW_Y, 0);
final float shadowWidth = row.getFieldAsFloat(UNIT_SHADOW_W, 0);
final float shadowHeight = row.getFieldAsFloat(UNIT_SHADOW_H, 0);
if (mapMpq.has(texture)) {
if (War3MapViewer.this.mapMpq.has(texture)) {
final float x = unitX - shadowX;
final float y = unitY - shadowY;
renderUnit.shadow = terrain.addUnitShadowSplat(texture, x, y,
renderUnit.shadow = War3MapViewer.this.terrain.addUnitShadowSplat(texture, x, y,
x + shadowWidth, y + shadowHeight, 3, 0.5f);
}
}
@ -770,8 +777,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
}
@Override
public void spawnSpellEffectOnUnit(CUnit unit, War3ID alias) {
AbilityUI abilityUI = abilityDataUI.getUI(alias);
public void spawnSpellEffectOnUnit(final CUnit unit, final War3ID alias) {
final AbilityUI abilityUI = War3MapViewer.this.abilityDataUI.getUI(alias);
spawnEffectOnUnit(unit, abilityUI.getTargetArt(0));
}
@ -861,11 +868,10 @@ public class War3MapViewer extends AbstractMdxModelViewer {
loadLightsAndShading(tileset);
}
public void spawnFxOnOrigin(RenderUnit renderUnit, String heroLevelUpArt) {
public void spawnFxOnOrigin(final RenderUnit renderUnit, final String heroLevelUpArt) {
final MdxModel heroLevelUpModel = loadModel(heroLevelUpArt);
if (heroLevelUpModel != null) {
final MdxComplexInstance modelInstance = (MdxComplexInstance) heroLevelUpModel
.addInstance();
final MdxComplexInstance modelInstance = (MdxComplexInstance) heroLevelUpModel.addInstance();
modelInstance.setTeamColor(renderUnit.playerIndex);
final MdxModel model = (MdxModel) renderUnit.instance.model;
@ -880,15 +886,15 @@ public class War3MapViewer extends AbstractMdxModelViewer {
if (index != -1) {
final MdxNode attachment = renderUnit.instance.getAttachment(index);
modelInstance.setParent(attachment);
} else {
}
else {
modelInstance.setLocation(renderUnit.location);
}
modelInstance.setScene(War3MapViewer.this.worldScene);
SequenceUtils.randomBirthSequence(modelInstance);
War3MapViewer.this.projectiles
.add(new RenderAttackInstant(modelInstance, War3MapViewer.this,
(float) Math.toRadians(renderUnit.getSimulationUnit().getFacing())));
War3MapViewer.this.projectiles.add(new RenderAttackInstant(modelInstance, War3MapViewer.this,
(float) Math.toRadians(renderUnit.getSimulationUnit().getFacing())));
}
}

View File

@ -364,6 +364,7 @@ public class Terrain {
final String fileName = waterInfo.getField("texFile");
final List<BufferedImage> waterTextures = new ArrayList<>();
boolean anyWaterTextureNeedsSRGB = false;
int waterImageDimension = 128;
for (int i = 0; i < this.waterTextureCount; i++) {
final AnyExtensionImage imageInfo = ImageUtils.getAnyExtensionImageFixRGB(dataSource,
fileName + (i < 10 ? "0" : "") + Integer.toString(i) + texturesExt, "water texture");
@ -371,13 +372,15 @@ public class Terrain {
if ((image.getWidth() != 128) || (image.getHeight() != 128)) {
System.err
.println("Odd water texture size detected of " + image.getWidth() + " x " + image.getHeight());
waterImageDimension = image.getWidth();
}
anyWaterTextureNeedsSRGB |= imageInfo.isNeedsSRGBFix();
waterTextures.add(image);
}
gl.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, anyWaterTextureNeedsSRGB ? GL30.GL_SRGB8_ALPHA8 : GL30.GL_RGBA8,
128, 128, this.waterTextureCount, 0, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, null);
waterImageDimension, waterImageDimension, this.waterTextureCount, 0, GL30.GL_RGBA,
GL30.GL_UNSIGNED_BYTE, null);
gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_BASE_LEVEL, 0);

View File

@ -153,7 +153,8 @@ public class TerrainShaders {
" float hU = texelFetch(height_texture, height_pos + off.zy, 0).r;\r\n" + //
" vec3 normal = normalize(vec3(hL - hR, hD - hU, 2.0));\r\n" + //
"\r\n" + //
" UV = vec2(vPosition.x, 1 - vPosition.y);\r\n" + //
// " UV = vec2(vPosition.x, 1 - vPosition.y);\r\n" + //
" UV = vec2(vPosition.x==0?0.01:0.99, vPosition.y==0?0.99:0.01);\r\n" + //
" texture_indices = texelFetch(terrain_texture_list, pos, 0);\r\n" + //
" pathing_map_uv = (vPosition + pos) * 4; \r\n" + //
"\r\n" + //

View File

@ -41,6 +41,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CUnitData;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CPathfindingProcessor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegionManager;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimer;
@ -67,7 +68,6 @@ public class CSimulation implements CPlayerAPI {
private final PathingGrid pathingGrid;
private final CWorldCollision worldCollision;
private final CPathfindingProcessor[] pathfindingProcessors;
private final List<CUnit>[] playerHeroes;
private final CGameplayConstants gameplayConstants;
private final Random seededRandom;
private float currentGameDayTimeElapsed;
@ -104,17 +104,15 @@ public class CSimulation implements CPlayerAPI {
this.worldCollision = new CWorldCollision(entireMapBounds, this.gameplayConstants.getMaxCollisionRadius());
this.regionManager = new CRegionManager(entireMapBounds, pathingGrid);
this.pathfindingProcessors = new CPathfindingProcessor[WarsmashConstants.MAX_PLAYERS];
this.playerHeroes = new ArrayList[WarsmashConstants.MAX_PLAYERS];
for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) {
this.pathfindingProcessors[i] = new CPathfindingProcessor(pathingGrid, this.worldCollision);
this.playerHeroes[i] = new ArrayList<>();
}
this.seededRandom = seededRandom;
this.players = new ArrayList<>();
for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) {
final CBasePlayer configPlayer = config.getPlayer(i);
final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex());
CRace defaultRace = CRace.ORC;
final CRace defaultRace = CRace.ORC;
final CPlayer newPlayer = new CPlayer(defaultRace, new float[] { startLoc.getX(), startLoc.getY() },
configPlayer);
this.players.add(newPlayer);
@ -183,7 +181,7 @@ public class CSimulation implements CPlayerAPI {
this.newUnits.add(unit);
this.handleIdToUnit.put(unit.getHandleId(), unit);
this.worldCollision.addUnit(unit);
if(unit.getHeroData() != null) {
if (unit.getHeroData() != null) {
heroCreateEvent(unit);
}
return unit;
@ -269,7 +267,7 @@ public class CSimulation implements CPlayerAPI {
}
this.handleIdToUnit.remove(unit.getHandleId());
this.simulationRenderController.removeUnit(unit);
this.playerHeroes[unit.getPlayerIndex()].remove(unit);
getPlayerHeroes(unit.getPlayerIndex()).remove(unit);
unit.onRemove(this);
}
}
@ -316,7 +314,7 @@ public class CSimulation implements CPlayerAPI {
}
this.handleIdToUnit.remove(unit.getHandleId());
this.simulationRenderController.removeUnit(unit);
this.playerHeroes[unit.getPlayerIndex()].remove(unit);
getPlayerHeroes(unit.getPlayerIndex()).remove(unit);
unit.onRemove(this);
}
this.removedUnits.clear();
@ -390,6 +388,7 @@ public class CSimulation implements CPlayerAPI {
public void unitTrainedEvent(final CUnit trainingUnit, final CUnit trainedUnit) {
this.simulationRenderController.spawnUnitReadySound(trainedUnit);
}
public void heroReviveEvent(final CUnit trainingUnit, final CUnit trainedUnit) {
this.simulationRenderController.heroRevived(trainedUnit);
this.simulationRenderController.spawnUnitReadySound(trainedUnit);
@ -404,11 +403,12 @@ public class CSimulation implements CPlayerAPI {
}
public void unitGainLevelEvent(final CUnit unit) {
this.players.get(unit.getPlayerIndex()).fireHeroLevelEvents(unit);
this.simulationRenderController.spawnGainLevelEffect(unit);
}
public void heroCreateEvent(final CUnit hero) {
this.playerHeroes[hero.getPlayerIndex()].add(hero);
getPlayerHeroes(hero.getPlayerIndex()).add(hero);
}
public void unitPickUpItemEvent(final CUnit cUnit, final CItem item) {
@ -420,7 +420,7 @@ public class CSimulation implements CPlayerAPI {
}
public List<CUnit> getPlayerHeroes(final int playerIndex) {
return this.playerHeroes[playerIndex];
return this.players.get(playerIndex).getHeroes();
}
public void unitsLoaded() {
@ -455,8 +455,8 @@ public class CSimulation implements CPlayerAPI {
this.simulationRenderController.spawnEffectOnUnit(unit, effectPath);
}
public void createSpellEffectOnUnit(CUnit unit, War3ID alias) {
simulationRenderController.spawnSpellEffectOnUnit(unit, alias);
public void createSpellEffectOnUnit(final CUnit unit, final War3ID alias) {
this.simulationRenderController.spawnSpellEffectOnUnit(unit, alias);
}
public void unitSoundEffectEvent(final CUnit caster, final War3ID alias) {
@ -480,16 +480,16 @@ public class CSimulation implements CPlayerAPI {
};
}
public void heroDeathEvent(CUnit cUnit) {
getPlayer(cUnit.getPlayerIndex()).onHeroDeath();
public void heroDeathEvent(final CUnit cUnit) {
getPlayer(cUnit.getPlayerIndex()).onHeroDeath(cUnit);
}
public void removeItem(CItem cItem) {
public void removeItem(final CItem cItem) {
cItem.setHidden(true); // TODO fix
cItem.setLife(this, 0);
}
}
private static final class TimeOfDayVariableEvent extends VariableEvent {
private static final class TimeOfDayVariableEvent extends VariableEvent {
private final GlobalScope globalScope;
public TimeOfDayVariableEvent(final Trigger trigger, final CLimitOp limitOp, final double doubleValue,
@ -502,4 +502,20 @@ public class CSimulation implements CPlayerAPI {
fire(this.globalScope);
}
}
public RemovableTriggerEvent registerEventPlayerDefeat(final GlobalScope globalScope, final Trigger whichTrigger,
final CPlayerJass whichPlayer) {
if (true) {
throw new UnsupportedOperationException("registerEventPlayerDefeat is NYI");
}
return RemovableTriggerEvent.DO_NOTHING;
}
public RemovableTriggerEvent registerEventPlayerVictory(final GlobalScope globalScope, final Trigger whichTrigger,
final CPlayerJass whichPlayer) {
if (true) {
throw new UnsupportedOperationException("registerEventPlayerVictory is NYI");
}
return RemovableTriggerEvent.DO_NOTHING;
}
}

View File

@ -11,7 +11,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerStat
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState;
public class CBasePlayer implements CPlayerJass {
public abstract class CBasePlayer implements CPlayerJass {
private final int id;
private String name;
private int team;
@ -59,6 +59,7 @@ public class CBasePlayer implements CPlayerJass {
}
}
@Override
public int getId() {
return this.id;
}
@ -138,6 +139,7 @@ public class CBasePlayer implements CPlayerJass {
}
}
@Override
public boolean hasAlliance(final int otherPlayerIndex, final CAllianceType allianceType) {
final EnumSet<CAllianceType> alliancesWithOtherPlayer = this.alliances[otherPlayerIndex];
return alliancesWithOtherPlayer.contains(allianceType);

View File

@ -30,7 +30,7 @@ public class War3MapConfig implements CPlayerAPI {
this.players = new CBasePlayer[maxPlayers];
for (int i = 0; i < maxPlayers; i++) {
this.startLocations[i] = new War3MapConfigStartLoc();
this.players[i] = new CBasePlayer(i);
this.players[i] = new War3MapConfigPlayer(i);
}
}

View File

@ -0,0 +1,29 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config;
import com.etheller.interpreter.ast.scope.GlobalScope;
import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent;
import com.etheller.interpreter.ast.scope.trigger.Trigger;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerEvent;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3;
public class War3MapConfigPlayer extends CBasePlayer {
public War3MapConfigPlayer(final CBasePlayer other) {
super(other);
}
public War3MapConfigPlayer(final int id) {
super(id);
}
@Override
public RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger,
final JassGameEventsWar3 eventType) {
return RemovableTriggerEvent.DO_NOTHING;
}
@Override
public void removeEvent(final CPlayerEvent playerEvent) {
}
}

View File

@ -1,14 +1,22 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.etheller.interpreter.ast.scope.GlobalScope;
import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent;
import com.etheller.interpreter.ast.scope.trigger.Trigger;
import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener.CPlayerStateNotifier;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3;
public class CPlayer extends CBasePlayer {
private final CRace race;
@ -18,6 +26,9 @@ public class CPlayer extends CBasePlayer {
private int foodCap;
private int foodUsed;
private final Map<War3ID, Integer> rawcodeToTechtreeUnlocked = new HashMap<>();
private final List<CUnit> heroes = new ArrayList<>();
private final EnumMap<JassGameEventsWar3, List<CPlayerEvent>> eventTypeToEvents = new EnumMap<>(
JassGameEventsWar3.class);
// if you use triggers for this then the transient tag here becomes really
// questionable -- it already was -- but I meant for those to inform us
@ -139,7 +150,7 @@ public class CPlayer extends CBasePlayer {
this.stateNotifier.goldChanged();
}
public void refund(int gold, int lumber) {
public void refund(final int gold, final int lumber) {
this.gold += gold;
this.lumber += lumber;
this.stateNotifier.lumberChanged();
@ -156,7 +167,57 @@ public class CPlayer extends CBasePlayer {
this.stateNotifier.foodChanged();
}
public void onHeroDeath() {
stateNotifier.heroDeath();
}
public void onHeroDeath(final CUnit hero) {
this.stateNotifier.heroDeath();
firePlayerUnitEvents(hero, CommonTriggerExecutionScope.playerHeroRevivableScope(hero),
JassGameEventsWar3.EVENT_PLAYER_HERO_REVIVABLE);
}
private void firePlayerUnitEvents(final CUnit hero, final CommonTriggerExecutionScope eventScope,
final JassGameEventsWar3 eventType) {
final List<CPlayerEvent> eventList = getEventList(eventType);
if (eventList != null) {
for (final CPlayerEvent event : eventList) {
event.fire(hero, eventScope);
}
}
}
public List<CUnit> getHeroes() {
return this.heroes;
}
public void fireHeroLevelEvents(final CUnit hero) {
firePlayerUnitEvents(hero, CommonTriggerExecutionScope.playerHeroRevivableScope(hero),
JassGameEventsWar3.EVENT_PLAYER_HERO_LEVEL);
}
private List<CPlayerEvent> getOrCreateEventList(final JassGameEventsWar3 eventType) {
List<CPlayerEvent> playerEvents = this.eventTypeToEvents.get(eventType);
if (playerEvents == null) {
playerEvents = new ArrayList<>();
this.eventTypeToEvents.put(eventType, playerEvents);
}
return playerEvents;
}
private List<CPlayerEvent> getEventList(final JassGameEventsWar3 eventType) {
return this.eventTypeToEvents.get(eventType);
}
@Override
public RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger,
final JassGameEventsWar3 eventType) {
final CPlayerEvent playerEvent = new CPlayerEvent(globalScope, this, whichTrigger, eventType);
getOrCreateEventList(eventType).add(playerEvent);
return playerEvent;
}
@Override
public void removeEvent(final CPlayerEvent playerEvent) {
final List<CPlayerEvent> eventList = getEventList(playerEvent.getEventType());
if (eventList != null) {
eventList.remove(playerEvent);
}
}
}

View File

@ -0,0 +1,40 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
import com.etheller.interpreter.ast.scope.GlobalScope;
import com.etheller.interpreter.ast.scope.TriggerExecutionScope;
import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent;
import com.etheller.interpreter.ast.scope.trigger.Trigger;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3;
public class CPlayerEvent implements RemovableTriggerEvent {
private final GlobalScope globalScope;
private final CPlayerJass player;
private final Trigger trigger;
private final JassGameEventsWar3 eventType;
public CPlayerEvent(final GlobalScope globalScope, final CPlayerJass player, final Trigger trigger,
final JassGameEventsWar3 eventType) {
this.globalScope = globalScope;
this.player = player;
this.trigger = trigger;
this.eventType = eventType;
}
public Trigger getTrigger() {
return this.trigger;
}
public JassGameEventsWar3 getEventType() {
return this.eventType;
}
@Override
public void remove() {
this.player.removeEvent(this);
}
public void fire(final CUnit hero, final TriggerExecutionScope scope) {
this.trigger.evaluate(this.globalScope, scope);
}
}

View File

@ -1,5 +1,9 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
import com.etheller.interpreter.ast.scope.GlobalScope;
import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent;
import com.etheller.interpreter.ast.scope.trigger.Trigger;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState;
public interface CPlayerJass {
@ -46,4 +50,9 @@ public interface CPlayerJass {
boolean isRacePrefSet(CRacePreference pref);
String getName();
RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger,
final JassGameEventsWar3 eventType);
void removeEvent(CPlayerEvent playerEvent);
}

View File

@ -0,0 +1,25 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.uidialog;
import java.util.ArrayList;
import java.util.List;
public class JassUIDialog {
private String title;
private final List<JassUIDialogButton> buttons = new ArrayList<>();
public void setTitle(final String title) {
this.title = title;
}
public String getTitle() {
return this.title;
}
public void add(final JassUIDialogButton button) {
this.buttons.add(button);
}
public boolean remove(final JassUIDialogButton button) {
return this.buttons.remove(button);
}
}

View File

@ -0,0 +1,13 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.uidialog;
public class JassUIDialogButton {
private String text;
public String getText() {
return this.text;
}
public void setText(final String text) {
this.text = text;
}
}

View File

@ -2,4 +2,10 @@ package com.etheller.interpreter.ast.scope.trigger;
public interface RemovableTriggerEvent {
void remove();
RemovableTriggerEvent DO_NOTHING = new RemovableTriggerEvent() {
@Override
public void remove() {
}
};
}