From 55bdfcb9fc8c6a42a075225340e1f44a2b5e300e Mon Sep 17 00:00:00 2001 From: Retera Date: Sat, 20 Mar 2021 14:54:38 -0400 Subject: [PATCH] Update with some beginning on a jass API that does not run and is not usable yet --- .../warsmash/WarsmashGdxMapScreen.java | 8 +- .../warsmash/WarsmashGdxMenuScreen.java | 2 +- .../etheller/warsmash/parsers/jass/Jass2.java | 1451 +++++++++++++++++ .../warsmash/parsers/jass/Tmpgen.java | 22 + .../warsmash/parsers/jass/Tmpgen2.java | 29 + .../warsmash/util/WarsmashConstants.java | 2 +- .../com/etheller/warsmash/viewer5/Model.java | 2 +- .../handlers/mdx/MdxComplexInstance.java | 18 +- .../viewer5/handlers/mdx/Sequence.java | 9 + .../viewer5/handlers/w3x/War3MapViewer.java | 32 +- .../w3x/simulation/CGameplayConstants.java | 16 + .../handlers/w3x/simulation/CSimulation.java | 75 +- .../handlers/w3x/simulation/CUnit.java | 2 +- .../handlers/w3x/simulation/CUnitType.java | 31 +- .../w3x/simulation/ai/AIDifficulty.java | 9 + .../w3x/simulation/config/CBasePlayer.java | 185 +++ .../w3x/simulation/config/CPlayerAPI.java | 5 + .../w3x/simulation/config/War3MapConfig.java | 153 ++ .../config/War3MapConfigStartLoc.java | 44 + .../w3x/simulation/data/CItemData.java | 8 + .../w3x/simulation/data/CUnitData.java | 49 +- .../w3x/simulation/item/CItemTypeJass.java | 15 + .../w3x/simulation/orders/OrderIdUtils.java | 38 + .../w3x/simulation/players/CAllianceType.java | 2 + .../w3x/simulation/players/CMapControl.java | 2 + .../w3x/simulation/players/CMapFlag.java | 44 + .../w3x/simulation/players/CMapPlacement.java | 10 + .../w3x/simulation/players/CPlayer.java | 76 +- .../w3x/simulation/players/CPlayerColor.java | 25 + .../simulation/players/CPlayerGameResult.java | 10 + .../w3x/simulation/players/CPlayerJass.java | 47 + .../w3x/simulation/players/CPlayerScore.java | 31 + .../w3x/simulation/players/CPlayerState.java | 42 + .../players/CPlayerUnitOrderExecutor.java | 51 +- .../w3x/simulation/players/CRace.java | 2 + .../simulation/players/CRacePreference.java | 15 + .../w3x/simulation/players/CStartLocPrio.java | 9 + .../w3x/simulation/state/CGameState.java | 9 + .../w3x/simulation/state/CUnitState.java | 10 + .../w3x/simulation/timers/CTimer.java | 89 + .../w3x/simulation/timers/CTimerJass.java | 25 + .../trigger/JassGameEventsWar3.java | 248 +++ .../trigger/enumtypes/CAttackTypeJass.java | 9 + .../trigger/enumtypes/CBlendMode.java | 12 + .../trigger/enumtypes/CCameraField.java | 13 + .../trigger/enumtypes/CDamageType.java | 32 + .../trigger/enumtypes/CEffectType.java | 13 + .../trigger/enumtypes/CFogState.java | 22 + .../trigger/enumtypes/CGameSpeed.java | 11 + .../trigger/enumtypes/CGameType.java | 27 + .../trigger/enumtypes/CLimitOp.java | 12 + .../trigger/enumtypes/CMapDensity.java | 10 + .../trigger/enumtypes/CMapDifficulty.java | 10 + .../trigger/enumtypes/CPathingTypeJass.java | 14 + .../trigger/enumtypes/CPlayerSlotState.java | 9 + .../trigger/enumtypes/CRarityControl.java | 8 + .../trigger/enumtypes/CSoundType.java | 8 + .../trigger/enumtypes/CSoundVolumeGroup.java | 14 + .../trigger/enumtypes/CTexMapFlags.java | 10 + .../trigger/enumtypes/CVersion.java | 8 + .../enumtypes/CWeaponSoundTypeJass.java | 40 + .../w3x/simulation/unit/CUnitTypeJass.java | 39 + .../viewer5/handlers/w3x/ui/MeleeUI.java | 122 +- .../ast/scope/TriggerExecutionScope.java | 2 + .../ast/value/StringJassValue.java | 8 +- 65 files changed, 3208 insertions(+), 197 deletions(-) create mode 100644 core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java create mode 100644 core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CLimitOp.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java b/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java index 9d7b9c6..086b7dc 100644 --- a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java +++ b/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java @@ -35,6 +35,7 @@ import com.etheller.warsmash.units.DataTable; import com.etheller.warsmash.units.Element; import com.etheller.warsmash.util.DataSourceFileHandle; import com.etheller.warsmash.util.ImageUtils; +import com.etheller.warsmash.util.WarsmashConstants; import com.etheller.warsmash.viewer5.CanvasProvider; import com.etheller.warsmash.viewer5.Model; import com.etheller.warsmash.viewer5.ModelInstance; @@ -48,6 +49,7 @@ import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; 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.simulation.config.War3MapConfig; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderExecutor; import com.etheller.warsmash.viewer5.handlers.w3x.ui.MeleeUI; import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.SettableCommandErrorListener; @@ -105,7 +107,8 @@ public class WarsmashGdxMapScreen implements CanvasProvider, InputProcessor, Scr final SettableCommandErrorListener commandErrorListener = new SettableCommandErrorListener(); this.codebase = parseDataSources(this.warsmashIni); - this.viewer = new War3MapViewer(this.codebase, this, commandErrorListener); + this.viewer = new War3MapViewer(this.codebase, this, commandErrorListener, + new War3MapConfig(WarsmashConstants.MAX_PLAYERS)); if (ENABLE_AUDIO) { this.viewer.worldScene.enableAudio(); @@ -218,7 +221,8 @@ public class WarsmashGdxMapScreen implements CanvasProvider, InputProcessor, Scr WarsmashGdxMapScreen.this.currentMusic = music; } } - }, new CPlayerUnitOrderExecutor(this.viewer.simulation, commandErrorListener)); + }, new CPlayerUnitOrderExecutor(this.viewer.simulation, this.viewer.getLocalPlayerIndex(), + commandErrorListener)); commandErrorListener.setDelegate(this.meleeUI); final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "", this.viewer.mapPathSolver, "").addInstance(); diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java b/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java index 8721dd9..4788545 100644 --- a/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java +++ b/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java @@ -187,7 +187,7 @@ public class WarsmashGdxMenuScreen implements CanvasProvider, InputProcessor, Sc final String musicPath = musics[(int) (Math.random() * musics.length)]; final Music music = Gdx.audio.newMusic( new DataSourceFileHandle(WarsmashGdxMenuScreen.this.viewer.dataSource, musicPath)); - music.setVolume(0.2f); +// music.setVolume(0.2f); music.setLooping(true); music.play(); WarsmashGdxMenuScreen.this.currentMusic = music; diff --git a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java b/core/src/com/etheller/warsmash/parsers/jass/Jass2.java index fd8fc9b..5d1fe78 100644 --- a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java +++ b/core/src/com/etheller/warsmash/parsers/jass/Jass2.java @@ -1,7 +1,9 @@ package com.etheller.warsmash.parsers.jass; +import java.awt.geom.Point2D; import java.io.IOException; import java.util.List; +import java.util.Locale; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.CharStreams; @@ -23,7 +25,9 @@ import com.etheller.interpreter.ast.value.HandleJassType; import com.etheller.interpreter.ast.value.HandleJassValue; import com.etheller.interpreter.ast.value.IntegerJassValue; import com.etheller.interpreter.ast.value.JassValue; +import com.etheller.interpreter.ast.value.RealJassValue; import com.etheller.interpreter.ast.value.StringJassValue; +import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; import com.etheller.interpreter.ast.value.visitor.IntegerJassValueVisitor; import com.etheller.interpreter.ast.value.visitor.JassFunctionJassValueVisitor; import com.etheller.interpreter.ast.value.visitor.ObjectJassValueVisitor; @@ -45,12 +49,101 @@ import com.etheller.warsmash.parsers.jass.triggers.BoolExprOr; import com.etheller.warsmash.parsers.jass.triggers.TriggerAction; import com.etheller.warsmash.parsers.jass.triggers.TriggerCondition; import com.etheller.warsmash.units.Element; +import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; +import com.etheller.warsmash.util.War3ID; import com.etheller.warsmash.viewer5.Scene; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; +import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.ItemUI; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructableType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.ai.AIDifficulty; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CPlayerAPI; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.item.CItemTypeJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIdUtils; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapFlag; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapPlacement; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerColor; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerGameResult; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerScore; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerState; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CStartLocPrio; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.state.CGameState; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.state.CUnitState; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimerJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CAttackTypeJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CBlendMode; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CCameraField; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CDamageType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CEffectType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CFogState; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameSpeed; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CLimitOp; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDensity; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDifficulty; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPathingTypeJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CRarityControl; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CSoundType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CSoundVolumeGroup; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CTexMapFlags; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CVersion; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CWeaponSoundTypeJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.unit.CUnitTypeJass; public class Jass2 { public static final boolean REPORT_SYNTAX_ERRORS = true; + public static CommonEnvironment loadCommon(final DataSource dataSource, final Viewport uiViewport, + final Scene uiScene, final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener, + final String... files) { + + final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor(); + final CommonEnvironment environment = new CommonEnvironment(jassProgramVisitor, dataSource, uiViewport, uiScene, + war3MapViewer, rootFrameListener); + for (final String jassFile : files) { + try { + JassLexer lexer; + try { + lexer = new JassLexer(CharStreams.fromStream(dataSource.getResourceAsStream(jassFile))); + } + catch (final IOException e) { + throw new RuntimeException(e); + } + final JassParser parser = new JassParser(new CommonTokenStream(lexer)); +// parser.removeErrorListener(ConsoleErrorListener.INSTANCE); + parser.addErrorListener(new BaseErrorListener() { + @Override + public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, + final int line, final int charPositionInLine, final String msg, + final RecognitionException e) { + if (!REPORT_SYNTAX_ERRORS) { + return; + } + + final String sourceName = String.format("%s:%d:%d: ", jassFile, line, charPositionInLine); + + System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); + } + }); + jassProgramVisitor.visit(parser.program()); + } + catch (final Exception e) { + e.printStackTrace(); + } + } + jassProgramVisitor.getJassNativeManager().checkUnregisteredNatives(); + return environment; + } + public static JUIEnvironment loadJUI(final DataSource dataSource, final Viewport uiViewport, final Scene uiScene, final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener, final String... files) { @@ -455,4 +548,1362 @@ public class Jass2 { }); } } + + private static final class CommonEnvironment { + private GameUI gameUI; + private Element skin; + + public CommonEnvironment(final JassProgramVisitor jassProgramVisitor, final DataSource dataSource, + final Viewport uiViewport, final Scene uiScene, final War3MapViewer war3MapViewer, + final RootFrameListener rootFrameListener) { + final GlobalScope globals = jassProgramVisitor.getGlobals(); + final HandleJassType agentType = globals.registerHandleType("agent"); + final HandleJassType eventType = globals.registerHandleType("event"); + final HandleJassType playerType = globals.registerHandleType("player"); + final HandleJassType widgetType = globals.registerHandleType("widget"); + final HandleJassType unitType = globals.registerHandleType("unit"); + final HandleJassType destructableType = globals.registerHandleType("destructable"); + final HandleJassType itemType = globals.registerHandleType("item"); + final HandleJassType abilityType = globals.registerHandleType("ability"); + final HandleJassType buffType = globals.registerHandleType("buff"); + final HandleJassType forceType = globals.registerHandleType("force"); + final HandleJassType groupType = globals.registerHandleType("group"); + final HandleJassType triggerType = globals.registerHandleType("trigger"); + final HandleJassType triggerconditionType = globals.registerHandleType("triggercondition"); + final HandleJassType triggeractionType = globals.registerHandleType("triggeraction"); + final HandleJassType timerType = globals.registerHandleType("timer"); + final HandleJassType locationType = globals.registerHandleType("location"); + final HandleJassType regionType = globals.registerHandleType("region"); + final HandleJassType rectType = globals.registerHandleType("rect"); + final HandleJassType boolexprType = globals.registerHandleType("boolexpr"); + final HandleJassType soundType = globals.registerHandleType("sound"); + final HandleJassType conditionfuncType = globals.registerHandleType("conditionfunc"); + final HandleJassType filterfuncType = globals.registerHandleType("filterfunc"); + final HandleJassType unitpoolType = globals.registerHandleType("unitpool"); + final HandleJassType itempoolType = globals.registerHandleType("itempool"); + final HandleJassType raceType = globals.registerHandleType("race"); + final HandleJassType alliancetypeType = globals.registerHandleType("alliancetype"); + final HandleJassType racepreferenceType = globals.registerHandleType("racepreference"); + final HandleJassType gamestateType = globals.registerHandleType("gamestate"); + final HandleJassType igamestateType = globals.registerHandleType("igamestate"); + final HandleJassType fgamestateType = globals.registerHandleType("fgamestate"); + final HandleJassType playerstateType = globals.registerHandleType("playerstate"); + final HandleJassType playerscoreType = globals.registerHandleType("playerscore"); + final HandleJassType playergameresultType = globals.registerHandleType("playergameresult"); + final HandleJassType unitstateType = globals.registerHandleType("unitstate"); + final HandleJassType aidifficultyType = globals.registerHandleType("aidifficulty"); + final HandleJassType eventidType = globals.registerHandleType("eventid"); + final HandleJassType gameeventType = globals.registerHandleType("gameevent"); + final HandleJassType playereventType = globals.registerHandleType("playerevent"); + final HandleJassType playeruniteventType = globals.registerHandleType("playerunitevent"); + final HandleJassType uniteventType = globals.registerHandleType("unitevent"); + final HandleJassType limitopType = globals.registerHandleType("limitop"); + final HandleJassType widgeteventType = globals.registerHandleType("widgetevent"); + final HandleJassType dialogeventType = globals.registerHandleType("dialogevent"); + final HandleJassType unittypeType = globals.registerHandleType("unittype"); + final HandleJassType gamespeedType = globals.registerHandleType("gamespeed"); + final HandleJassType gamedifficultyType = globals.registerHandleType("gamedifficulty"); + final HandleJassType gametypeType = globals.registerHandleType("gametype"); + final HandleJassType mapflagType = globals.registerHandleType("mapflag"); + final HandleJassType mapvisibilityType = globals.registerHandleType("mapvisibility"); + final HandleJassType mapsettingType = globals.registerHandleType("mapsetting"); + final HandleJassType mapdensityType = globals.registerHandleType("mapdensity"); + final HandleJassType mapcontrolType = globals.registerHandleType("mapcontrol"); + final HandleJassType playerslotstateType = globals.registerHandleType("playerslotstate"); + final HandleJassType volumegroupType = globals.registerHandleType("volumegroup"); + final HandleJassType camerafieldType = globals.registerHandleType("camerafield"); + final HandleJassType camerasetupType = globals.registerHandleType("camerasetup"); + final HandleJassType playercolorType = globals.registerHandleType("playercolor"); + final HandleJassType placementType = globals.registerHandleType("placement"); + final HandleJassType startlocprioType = globals.registerHandleType("startlocprio"); + final HandleJassType raritycontrolType = globals.registerHandleType("raritycontrol"); + final HandleJassType blendmodeType = globals.registerHandleType("blendmode"); + final HandleJassType texmapflagsType = globals.registerHandleType("texmapflags"); + final HandleJassType effectType = globals.registerHandleType("effect"); + final HandleJassType effecttypeType = globals.registerHandleType("effecttype"); + final HandleJassType weathereffectType = globals.registerHandleType("weathereffect"); + final HandleJassType terraindeformationType = globals.registerHandleType("terraindeformation"); + final HandleJassType fogstateType = globals.registerHandleType("fogstate"); + final HandleJassType fogmodifierType = globals.registerHandleType("fogmodifier"); + final HandleJassType dialogType = globals.registerHandleType("dialog"); + final HandleJassType buttonType = globals.registerHandleType("button"); + final HandleJassType questType = globals.registerHandleType("quest"); + final HandleJassType questitemType = globals.registerHandleType("questitem"); + final HandleJassType defeatconditionType = globals.registerHandleType("defeatcondition"); + final HandleJassType timerdialogType = globals.registerHandleType("timerdialog"); + final HandleJassType leaderboardType = globals.registerHandleType("leaderboard"); + final HandleJassType multiboardType = globals.registerHandleType("multiboard"); + final HandleJassType multiboarditemType = globals.registerHandleType("multiboarditem"); + final HandleJassType trackableType = globals.registerHandleType("trackable"); + final HandleJassType gamecacheType = globals.registerHandleType("gamecache"); + final HandleJassType versionType = globals.registerHandleType("version"); + final HandleJassType itemtypeType = globals.registerHandleType("itemtype"); + final HandleJassType texttagType = globals.registerHandleType("texttag"); + final HandleJassType attacktypeType = globals.registerHandleType("attacktype"); + final HandleJassType damagetypeType = globals.registerHandleType("damagetype"); + final HandleJassType weapontypeType = globals.registerHandleType("weapontype"); + final HandleJassType soundtypeType = globals.registerHandleType("soundtype"); + final HandleJassType lightningType = globals.registerHandleType("lightning"); + final HandleJassType pathingtypeType = globals.registerHandleType("pathingtype"); + final HandleJassType imageType = globals.registerHandleType("image"); + final HandleJassType ubersplatType = globals.registerHandleType("ubersplat"); + final HandleJassType hashtableType = globals.registerHandleType("hashtable"); + + jassProgramVisitor.getJassNativeManager().createNative("ConvertRace", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(raceType, CRace.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertAllianceType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(alliancetypeType, CAllianceType.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertRacePref", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(racepreferenceType, CRacePreference.getById(i)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertIGameState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(igamestateType, CGameState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertFGameState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(fgamestateType, CGameState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playerstateType, CPlayerState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerScore", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playerscoreType, CPlayerScore.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertGameResult", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playergameresultType, CPlayerGameResult.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(unitstateType, CUnitState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertAIDifficulty", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(aidifficultyType, AIDifficulty.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertGameEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(gameeventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playereventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerUnitEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playeruniteventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertWidgetEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(widgeteventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertDialogEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(dialogeventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitEvent", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(uniteventType, JassGameEventsWar3.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertLimitOp", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(limitopType, CLimitOp.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(unittypeType, CUnitTypeJass.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertGameSpeed", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(gamespeedType, CGameSpeed.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlacement", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(placementType, CMapPlacement.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertStartLocPrio", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(startlocprioType, CStartLocPrio.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertGameDifficulty", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(gamedifficultyType, CMapDifficulty.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertGameType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(gametypeType, CGameType.getById(i)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertMapFlag", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(gametypeType, CMapFlag.getById(i)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertMapVisibility", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(mapvisibilityType, null); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertMapSetting", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(mapsettingType, null); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertMapDensity", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(mapdensityType, CMapDensity.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertMapControl", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(mapcontrolType, CMapControl.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerColor", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playercolorType, CMapControl.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerSlotState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(playerslotstateType, CPlayerSlotState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertVolumeGroup", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(volumegroupType, CSoundVolumeGroup.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertCameraField", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(camerafieldType, CCameraField.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertBlendMode", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(blendmodeType, CBlendMode.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertRarityControl", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(raritycontrolType, CRarityControl.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertTexMapFlags", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(texmapflagsType, CTexMapFlags.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertFogState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(fogstateType, CFogState.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertEffectType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(effecttypeType, CEffectType.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertVersion", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(versionType, CVersion.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertItemType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(itemtypeType, CItemTypeJass.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertAttackType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(attacktypeType, CAttackTypeJass.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertDamageType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(attacktypeType, CDamageType.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertWeaponType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(weapontypeType, CWeaponSoundTypeJass.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertSoundType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(soundtypeType, CSoundType.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ConvertPathingType", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(pathingtypeType, CPathingTypeJass.VALUES[i]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("OrderId", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String idString = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + final int orderId = OrderIdUtils.getOrderId(idString); + return new IntegerJassValue(orderId); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("OrderId2String", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new StringJassValue(OrderIdUtils.getStringFromOrderId(id)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("UnitId", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String idString = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + final CUnitType unitType = war3MapViewer.simulation.getUnitData() + .getUnitTypeByJassLegacyName(idString); + if (unitType == null) { + return new IntegerJassValue(0); + } + return new IntegerJassValue(unitType.getTypeId().getValue()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("UnitId2String", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final War3ID war3id = new War3ID(id); + return new StringJassValue( + war3MapViewer.simulation.getUnitData().getUnitType(war3id).getLegacyName()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("AbilityId", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new IntegerJassValue(0); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("AbilityId2String", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new StringJassValue(""); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetObjectName", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final War3ID war3id = new War3ID(id); + final CSimulation simulation = war3MapViewer.simulation; + final CUnitType unitType = simulation.getUnitData().getUnitType(war3id); + if (unitType != null) { + return new StringJassValue(unitType.getName()); + } + // TODO for now this looks in the ability editor data, not the fast symbol table + // layer on top, because the layer on top forgot to have a name value... + final MutableGameObject abilityEditorData = war3MapViewer.getAllObjectData().getAbilities() + .get(war3id); + if (abilityEditorData != null) { + return new StringJassValue(abilityEditorData.getName()); + } + final ItemUI itemUI = war3MapViewer.getAbilityDataUI().getItemUI(war3id); + if (itemUI != null) { + return new StringJassValue(itemUI.getName()); + } + final CDestructableType destructableType = simulation.getDestructableData().getUnitType(war3id); + if (destructableType != null) { + return new StringJassValue(destructableType.getName()); + } + return new StringJassValue(""); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Deg2Rad", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new RealJassValue(StrictMath.toRadians(value)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Rad2Deg", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new RealJassValue(StrictMath.toDegrees(value)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Sin", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new RealJassValue(StrictMath.sin(value)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Cos", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new RealJassValue(StrictMath.cos(value)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Tan", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new RealJassValue(StrictMath.tan(value)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Asin", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.asin(value); + if (Double.isNaN(result)) { + return new RealJassValue(0); + } + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Acos", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.acos(value); + if (Double.isNaN(result)) { + return new RealJassValue(0); + } + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Atan", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.atan(value); + if (Double.isNaN(result)) { + return new RealJassValue(0); + } + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Atan2", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double y = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.atan2(y, x); + if (Double.isNaN(result)) { + return new RealJassValue(0); + } + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SquareRoot", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.sqrt(value); + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("Pow", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double y = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); + final double result = StrictMath.pow(y, x); + if (Double.isNaN(result)) { + return new RealJassValue(0); + } + return new RealJassValue(result); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("I2R", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new RealJassValue(i.doubleValue()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("R2I", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new IntegerJassValue(r.intValue()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("I2S", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new StringJassValue(i.toString()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("R2S", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + return new StringJassValue(r.toString()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("R2SW", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); + final int width = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + final int precision = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); + return new StringJassValue(String.format("%" + precision + "." + width + "f", r)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("S2I", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + try { + final int intValue = Integer.parseInt(s); + return new IntegerJassValue(intValue); + } + catch (final Exception exc) { + return new IntegerJassValue(0); + } + } + }); + jassProgramVisitor.getJassNativeManager().createNative("S2R", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + try { + final double parsedValue = Double.parseDouble(s); + return new RealJassValue(parsedValue); + } + catch (final Exception exc) { + return new RealJassValue(0); + } + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SubString", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + final int start = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + final int end = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); + return new StringJassValue(s.substring(start, end)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("StringLength", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + return new IntegerJassValue(s.length()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("StringCase", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + final boolean upper = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); + return new StringJassValue(upper ? s.toUpperCase(Locale.US) : s.toLowerCase(Locale.US)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("StringHash", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + return new IntegerJassValue(s.hashCode()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetLocalizedString", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String key = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + // TODO this might be wrong, or a subset of the needed return values + final String decoratedString = war3MapViewer.getGameUI().getTemplates().getDecoratedString(key); + if (key.equals(decoratedString)) { + System.err.println("GetLocalizedString: NOT FOUND: " + key); + } + return new StringJassValue(decoratedString); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetLocalizedHotkey", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String key = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + // TODO this might be wrong, or a subset of the needed return values + final String decoratedString = war3MapViewer.getGameUI().getTemplates().getDecoratedString(key); + if (key.equals(decoratedString)) { + System.err.println("GetLocalizedHotkey: NOT FOUND: " + key); + } + return new IntegerJassValue(decoratedString.charAt(0)); + } + }); + final War3MapConfig mapConfig = war3MapViewer.getMapConfig(); + registerConfigNatives(jassProgramVisitor, mapConfig, startlocprioType, gametypeType, placementType, + gamespeedType, gamedifficultyType, mapdensityType, locationType, playerType, playercolorType, + mapcontrolType, playerslotstateType, war3MapViewer.simulation); + + jassProgramVisitor.getJassNativeManager().createNative("CreateTimer", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(timerType, new CTimerJass(globalScope)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("DestroyTimer", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + war3MapViewer.simulation.unregisterTimer(timer); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("TimerStart", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + final Double timeout = arguments.get(1).visit(RealJassValueVisitor.getInstance()); + final boolean periodic = arguments.get(2).visit(BooleanJassValueVisitor.getInstance()); + final JassFunction handlerFunc = arguments.get(3).visit(JassFunctionJassValueVisitor.getInstance()); + if (!timer.isRunning()) { + timer.setTimeoutTime(timeout.floatValue()); + timer.setRepeats(periodic); + timer.setHandlerFunc(handlerFunc); + timer.start(war3MapViewer.simulation); + } + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("TimerGetElapsed", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + return new RealJassValue(timer.getElapsed(war3MapViewer.simulation)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("TimerGetRemaining", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + return new RealJassValue(timer.getRemaining(war3MapViewer.simulation)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("TimerGetTimeout", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + return new RealJassValue(timer.getTimeoutTime()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("PauseTimer", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + timer.pause(war3MapViewer.simulation); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ResumeTimer", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + timer.resume(war3MapViewer.simulation); + return null; + } + }); + } + + private void registerConfigNatives(final JassProgramVisitor jassProgramVisitor, final War3MapConfig mapConfig, + final HandleJassType startlocprioType, final HandleJassType gametypeType, + final HandleJassType placementType, final HandleJassType gamespeedType, + final HandleJassType gamedifficultyType, final HandleJassType mapdensityType, + final HandleJassType locationType, final HandleJassType playerType, + final HandleJassType playercolorType, final HandleJassType mapcontrolType, + final HandleJassType playerslotstateType, final CPlayerAPI playerAPI) { + jassProgramVisitor.getJassNativeManager().createNative("SetMapName", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String name = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + mapConfig.setMapName(name); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetMapDescription", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final String name = arguments.get(0).visit(StringJassValueVisitor.getInstance()); + mapConfig.setMapDescription(name); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetTeams", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer teamCount = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + mapConfig.setTeamCount(teamCount); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayers", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer playerCount = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + mapConfig.setPlayerCount(playerCount); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("DefineStartLocation", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); + final Double y = arguments.get(2).visit(RealJassValueVisitor.getInstance()); + mapConfig.getStartLoc(whichStartLoc).setX(x.floatValue()); + mapConfig.getStartLoc(whichStartLoc).setY(y.floatValue()); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("DefineStartLocationLoc", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Point2D.Double whichLocation = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.getStartLoc(whichStartLoc).setX((float) whichLocation.x); + mapConfig.getStartLoc(whichStartLoc).setY((float) whichLocation.y); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetStartLocPrioCount", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Integer prioSlotCount = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + mapConfig.getStartLoc(whichStartLoc).setStartLocPrioCount(prioSlotCount); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetStartLocPrio", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + final Integer otherStartLocIndex = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); + final CStartLocPrio priority = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.getStartLoc(whichStartLoc).setStartLocPrio(prioSlotIndex, otherStartLocIndex, priority); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetStartLocPrioSlot", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + return new IntegerJassValue( + mapConfig.getStartLoc(whichStartLoc).getOtherStartIndices()[prioSlotIndex]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetStartLocPrio", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(startlocprioType, + mapConfig.getStartLoc(whichStartLoc).getOtherStartLocPriorities()[prioSlotIndex]); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetGameTypeSupported", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CGameType gameType = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); + mapConfig.setGameTypeSupported(gameType, value); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetMapFlag", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapFlag mapFlag = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); + mapConfig.setMapFlag(mapFlag, value); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetGamePlacement", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapPlacement placement = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.setPlacement(placement); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetGameSpeed", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CGameSpeed gameSpeed = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.setGameSpeed(gameSpeed); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetGameDifficulty", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapDifficulty gameDifficulty = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.setGameDifficulty(gameDifficulty); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetResourceDensity", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapDensity resourceDensity = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.setResourceDensity(resourceDensity); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetCreatureDensity", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapDensity creatureDensity = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + mapConfig.setCreatureDensity(creatureDensity); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetTeams", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new IntegerJassValue(mapConfig.getTeamCount()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayers", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new IntegerJassValue(mapConfig.getPlayerCount()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("IsGameTypeSupported", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CGameType gameType = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + return new BooleanJassValue(mapConfig.isGameTypeSupported(gameType)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetGameTypeSelected", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(gametypeType, mapConfig.getGameTypeSelected()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("IsMapFlagSet", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CMapFlag mapFlag = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); + return new BooleanJassValue(mapConfig.isMapFlagSet(mapFlag)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetGamePlacement", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(placementType, mapConfig.getPlacement()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetGameSpeed", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(gamespeedType, mapConfig.getGameSpeed()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetGameDifficulty", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(gamedifficultyType, mapConfig.getGameDifficulty()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetResourceDensity", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(mapdensityType, mapConfig.getResourceDensity()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetCreatureDensity", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + return new HandleJassValue(mapdensityType, mapConfig.getCreatureDensity()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationX", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new RealJassValue(mapConfig.getStartLoc(whichStartLoc).getX()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationY", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new RealJassValue(mapConfig.getStartLoc(whichStartLoc).getY()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationLoc", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); + return new HandleJassValue(locationType, new Point2D.Double( + mapConfig.getStartLoc(whichStartLoc).getX(), mapConfig.getStartLoc(whichStartLoc).getY())); + } + }); + // PlayerAPI + + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerTeam", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final Integer whichTeam = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + player.setTeam(whichTeam); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerStartLocation", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final Integer startLocIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + player.setStartLocationIndex(startLocIndex); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("ForcePlayerStartLocation", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final Integer startLocIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); + player.forceStartLocation(startLocIndex); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerColor", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerColor playerColor = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + player.setColor(playerColor.ordinal()); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerAlliance", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerJass otherPlayer = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + final CAllianceType whichAllianceSetting = arguments.get(2) + .visit(ObjectJassValueVisitor.getInstance()); + final Boolean value = arguments.get(3).visit(BooleanJassValueVisitor.getInstance()); + player.setAlliance(otherPlayer.getId(), whichAllianceSetting, value); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerTaxRate", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerJass otherPlayer = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerState whichResource = arguments.get(2) + .visit(ObjectJassValueVisitor.getInstance()); + final int taxRate = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); + player.setTaxRate(otherPlayer.getId(), whichResource, taxRate); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerRacePreference", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CRacePreference whichRacePreference = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + player.setRacePref(whichRacePreference); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerRaceSelectable", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); + player.setRaceSelectable(value); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerController", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CMapControl controlType = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + player.setController(controlType); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerName", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final String name = arguments.get(1).visit(StringJassValueVisitor.getInstance()); + player.setName(name); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("SetPlayerOnScoreScreen", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); + player.setOnScoreScreen(value); + return null; + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerTeam", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new IntegerJassValue(player.getTeam()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerStartLocation", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new IntegerJassValue(player.getStartLocationIndex()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerColor", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new HandleJassValue(playercolorType, CPlayerColor.getColorByIndex(player.getColor())); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerSelectable", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new BooleanJassValue(player.isSelectable()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerController", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new HandleJassValue(mapcontrolType, player.getController()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerSlotState", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new HandleJassValue(playerslotstateType, player.getController()); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerTaxRate", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerJass otherPlayer = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + final CPlayerState whichResource = arguments.get(2) + .visit(ObjectJassValueVisitor.getInstance()); + return new IntegerJassValue(player.getTaxRate(otherPlayer.getId(), whichResource)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("IsPlayerRacePrefSet", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + final CRacePreference racePref = arguments.get(1) + .visit(ObjectJassValueVisitor.getInstance()); + return new BooleanJassValue(player.isRacePrefSet(racePref)); + } + }); + jassProgramVisitor.getJassNativeManager().createNative("GetPlayerName", new JassFunction() { + @Override + public JassValue call(final List arguments, final GlobalScope globalScope, + final TriggerExecutionScope triggerScope) { + final CPlayerJass player = arguments.get(0) + .visit(ObjectJassValueVisitor.getInstance()); + return new StringJassValue(player.getName()); + } + }); + } + } } diff --git a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java new file mode 100644 index 0000000..7d32790 --- /dev/null +++ b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java @@ -0,0 +1,22 @@ +package com.etheller.warsmash.parsers.jass; + +import java.util.Scanner; + +public class Tmpgen { + + public static void main(final String[] args) { + // final HandleJassType eventType = globals.registerHandleType("event"); + + final Scanner scanner = new Scanner(System.in); + while (scanner.hasNextLine()) { + final String line = scanner.nextLine(); + if (line.startsWith("type ")) { + final String[] splitLine = line.split("\\s+"); + System.out.println("final HandleJassType " + splitLine[1] + "Type = globals.registerHandleType(\"" + + splitLine[1] + "\");"); + } + } + + } + +} diff --git a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java new file mode 100644 index 0000000..b9124c1 --- /dev/null +++ b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java @@ -0,0 +1,29 @@ +package com.etheller.warsmash.parsers.jass; + +import java.util.Scanner; + +public class Tmpgen2 { + + public static void main(final String[] args) { + // final HandleJassType eventType = globals.registerHandleType("event"); + + final Scanner scanner = new Scanner(System.in); + while (scanner.hasNextLine()) { + final String line = scanner.nextLine(); + final String[] splitLine = line.trim().split("\\s+"); + if (line.trim().startsWith("//")) { + System.out.println(line); + } + else { + if (splitLine.length > 3) { + System.out.println(splitLine[2] + ","); + } + else { + System.out.println(); + } + } + } + + } + +} diff --git a/core/src/com/etheller/warsmash/util/WarsmashConstants.java b/core/src/com/etheller/warsmash/util/WarsmashConstants.java index 6b2e4ab..694d5b2 100644 --- a/core/src/com/etheller/warsmash/util/WarsmashConstants.java +++ b/core/src/com/etheller/warsmash/util/WarsmashConstants.java @@ -6,7 +6,7 @@ public class WarsmashConstants { * With version, we use 0 for RoC, 1 for TFT emulation, and probably 2+ or * whatever for custom mods and other stuff */ - public static int GAME_VERSION = 1; + public static int GAME_VERSION = 0; public static final int REPLACEABLE_TEXTURE_LIMIT = 64; public static final float SIMULATION_STEP_TIME = 1 / 20f; public static final int PORT_NUMBER = 6115; diff --git a/core/src/com/etheller/warsmash/viewer5/Model.java b/core/src/com/etheller/warsmash/viewer5/Model.java index 379781d..fbedd8f 100644 --- a/core/src/com/etheller/warsmash/viewer5/Model.java +++ b/core/src/com/etheller/warsmash/viewer5/Model.java @@ -6,7 +6,7 @@ import java.util.List; import com.etheller.warsmash.viewer5.handlers.ModelHandler; public abstract class Model extends HandlerResource { - public Bounds bounds; + public final Bounds bounds; public List preloadedInstances; public Model(final HANDLER handler, final ModelViewer viewer, final String extension, final PathSolver pathSolver, diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java index 67ba901..7336f62 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java @@ -13,6 +13,7 @@ import com.badlogic.gdx.math.Quaternion; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.collision.Ray; import com.etheller.warsmash.util.WarsmashConstants; +import com.etheller.warsmash.viewer5.Bounds; import com.etheller.warsmash.viewer5.GenericNode; import com.etheller.warsmash.viewer5.ModelInstance; import com.etheller.warsmash.viewer5.Node; @@ -748,8 +749,23 @@ public class MdxComplexInstance extends ModelInstance { throw new UnsupportedOperationException("NOT API"); } + public Bounds getBounds() { + if (this.sequence == -1) { + return this.model.bounds; + } + else { + final Bounds sequenceBounds = ((MdxModel) this.model).sequences.get(this.sequence).getBounds(); + if (sequenceBounds.r == 0) { + return this.model.bounds; + } + else { + return sequenceBounds; + } + } + } + public void intersectRayBounds(final Ray ray, final Vector3 intersection) { - this.model.bounds.intersectRay(ray, intersection); + getBounds().intersectRay(ray, intersection); } /** diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java index 1de9dbe..d3b916a 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java @@ -2,6 +2,7 @@ package com.etheller.warsmash.viewer5.handlers.mdx; import java.util.EnumSet; +import com.etheller.warsmash.viewer5.Bounds; 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; @@ -10,12 +11,16 @@ import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence; public class Sequence { private final MdlxSequence sequence; + private final Bounds bounds; private final EnumSet primaryTags = EnumSet.noneOf(AnimationTokens.PrimaryTag.class); private final EnumSet secondaryTags = EnumSet .noneOf(AnimationTokens.SecondaryTag.class); public Sequence(final MdlxSequence sequence) { this.sequence = sequence; + this.bounds = new Bounds(); + final MdlxExtent sequenceExtent = sequence.getExtent(); + this.bounds.fromExtents(sequenceExtent.getMin(), sequenceExtent.getMax(), sequenceExtent.getBoundsRadius()); populateTags(); } @@ -64,6 +69,10 @@ public class Sequence { return this.sequence.getSyncPoint(); } + public Bounds getBounds() { + return this.bounds; + } + public MdlxExtent getExtent() { return this.sequence.getExtent(); } 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 e5f2409..4b4c67b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java @@ -42,6 +42,7 @@ import com.etheller.warsmash.parsers.w3x.doo.War3MapDoo; import com.etheller.warsmash.parsers.w3x.objectdata.Warcraft3MapObjectData; import com.etheller.warsmash.parsers.w3x.unitsdoo.War3MapUnitsDoo; import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; +import com.etheller.warsmash.parsers.w3x.w3i.Player; import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; import com.etheller.warsmash.parsers.w3x.wpm.War3MapWpm; import com.etheller.warsmash.units.DataTable; @@ -103,6 +104,10 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUni import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; @@ -144,6 +149,7 @@ public class War3MapViewer extends AbstractMdxModelViewer { public static final Vector3 intersectionHeap = new Vector3(); private static final Rectangle rectangleHeap = new Rectangle(); public static final StreamDataCallbackImplementation streamDataCallback = new StreamDataCallbackImplementation(); + private static final boolean ENABLE_WORLDEDIT_AS_GAMEPLAY_DATA_HACK = true; public WorldScene worldScene; public boolean anyReady; @@ -218,8 +224,10 @@ public class War3MapViewer extends AbstractMdxModelViewer { public final List textTags = new ArrayList<>(); + private final War3MapConfig mapConfig; + public War3MapViewer(final DataSource dataSource, final CanvasProvider canvas, - final CommandErrorListener errorListener) { + final CommandErrorListener errorListener, final War3MapConfig mapConfig) { super(dataSource, canvas); this.gameDataSource = dataSource; @@ -236,6 +244,7 @@ public class War3MapViewer extends AbstractMdxModelViewer { } this.commandErrorListener = errorListener; + this.mapConfig = mapConfig; } public void loadSLKs(final WorldEditStrings worldEditStrings) throws IOException { @@ -387,6 +396,17 @@ public class War3MapViewer extends AbstractMdxModelViewer { final War3MapW3i w3iFile = this.mapMpq.readMapInformation(); + if (ENABLE_WORLDEDIT_AS_GAMEPLAY_DATA_HACK) { + int playerIndex = 0; + for (final Player player : w3iFile.getPlayers()) { + final CBasePlayer cfgPlayer = this.mapConfig.getPlayer(playerIndex); + cfgPlayer.setName(player.getName()); + cfgPlayer.setRacePref(CRacePreference.VALUES[player.getRace()]); + cfgPlayer.setController(CMapControl.VALUES[player.getType()]); + playerIndex++; + } + } + tileset = w3iFile.getTileset(); DataSource tilesetSource; @@ -455,8 +475,8 @@ public class War3MapViewer extends AbstractMdxModelViewer { this.confirmationInstance.setScene(this.worldScene); this.allObjectData = this.mapMpq.readModifications(); - this.simulation = new CSimulation(this.miscData, this.allObjectData.getUnits(), this.allObjectData.getItems(), - this.allObjectData.getDestructibles(), this.allObjectData.getAbilities(), + this.simulation = new CSimulation(this.mapConfig, this.miscData, this.allObjectData.getUnits(), + this.allObjectData.getItems(), this.allObjectData.getDestructibles(), this.allObjectData.getAbilities(), new SimulationRenderController() { private final Map keyToCombatSound = new HashMap<>(); @@ -745,8 +765,7 @@ public class War3MapViewer extends AbstractMdxModelViewer { renderPeer.getZ()); } } - }, this.terrain.pathingGrid, this.terrain.getEntireMap(), this.seededRandom, w3iFile.getPlayers(), - this.commandErrorListener); + }, this.terrain.pathingGrid, this.terrain.getEntireMap(), this.seededRandom, this.commandErrorListener); this.walkableObjectsTree = new Quadtree<>(this.terrain.getEntireMap()); if (this.doodadsAndDestructiblesLoaded) { @@ -1853,4 +1872,7 @@ public class War3MapViewer extends AbstractMdxModelViewer { this.textTags.add(textTag); } + public War3MapConfig getMapConfig() { + return this.mapConfig; + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java index 2cba007..303fd7d 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java @@ -348,6 +348,22 @@ public class CGameplayConstants { return this.pawnItemRate; } + public float getFollowRange() { + return this.followRange; + } + + public float getStructureFollowRange() { + return this.structureFollowRange; + } + + public float getFollowItemRange() { + return this.followItemRange; + } + + public float getSpellCastRangeBuffer() { + return this.spellCastRangeBuffer; + } + private static int getTableValue(final int[] table, int level) { if (level <= 0) { return 0; 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 dc82645..24e23c3 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 @@ -5,12 +5,13 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Random; import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.parsers.w3x.w3i.Player; import com.etheller.warsmash.units.DataTable; import com.etheller.warsmash.units.manager.MutableObjectData; import com.etheller.warsmash.util.War3ID; @@ -24,20 +25,24 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUni import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CPlayerAPI; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfigStartLoc; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CAbilityData; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CDestructableData; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CItemData; 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.CMapControl; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimer; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; -public class CSimulation { +public class CSimulation implements CPlayerAPI { private final CAbilityData abilityData; private final CUnitData unitData; private final CDestructableData destructableData; @@ -63,13 +68,14 @@ public class CSimulation { private final Map handleIdToDestructable = new HashMap<>(); private final Map handleIdToItem = new HashMap<>(); private final Map handleIdToAbility = new HashMap<>(); + private final LinkedList activeTimers = new LinkedList<>(); private transient CommandErrorListener commandErrorListener; - public CSimulation(final DataTable miscData, final MutableObjectData parsedUnitData, + public CSimulation(final War3MapConfig config, final DataTable miscData, final MutableObjectData parsedUnitData, final MutableObjectData parsedItemData, final MutableObjectData parsedDestructableData, final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController, final PathingGrid pathingGrid, final Rectangle entireMapBounds, final Random seededRandom, - final List playerInfos, final CommandErrorListener commandErrorListener) { + final CommandErrorListener commandErrorListener) { this.gameplayConstants = new CGameplayConstants(miscData); this.simulationRenderController = simulationRenderController; this.pathingGrid = pathingGrid; @@ -94,27 +100,19 @@ public class CSimulation { } this.seededRandom = seededRandom; this.players = new ArrayList<>(); - for (int i = 0; i < (WarsmashConstants.MAX_PLAYERS - 4); i++) { - CPlayer newPlayer; - if (i < playerInfos.size()) { - final Player playerInfo = playerInfos.get(i); - newPlayer = new CPlayer(playerInfo.getId(), CMapControl.values()[playerInfo.getType()], - playerInfo.getName(), CRace.parseRace(playerInfo.getRace()), playerInfo.getStartLocation()); - } - else { - newPlayer = new CPlayer(i, CMapControl.NONE, "Default string", CRace.OTHER, new float[] { 0, 0 }); - } + for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { + final CBasePlayer configPlayer = config.getPlayer(i); + final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex()); + final CPlayer newPlayer = new CPlayer(CRace.OTHER, new float[] { startLoc.getX(), startLoc.getY() }, + configPlayer); this.players.add(newPlayer); } - this.players.add(new CPlayer(this.players.size(), CMapControl.NEUTRAL, - miscData.getLocalizedString("WESTRING_PLAYER_NA"), CRace.OTHER, new float[] { 0, 0 })); - this.players.add(new CPlayer(this.players.size(), CMapControl.NEUTRAL, - miscData.getLocalizedString("WESTRING_PLAYER_NV"), CRace.OTHER, new float[] { 0, 0 })); - this.players.add(new CPlayer(this.players.size(), CMapControl.NEUTRAL, - miscData.getLocalizedString("WESTRING_PLAYER_NE"), CRace.OTHER, new float[] { 0, 0 })); - final CPlayer neutralPassive = new CPlayer(this.players.size(), CMapControl.NEUTRAL, - miscData.getLocalizedString("WESTRING_PLAYER_NP"), CRace.OTHER, new float[] { 0, 0 }); - this.players.add(neutralPassive); + this.players.get(this.players.size() - 4).setName(miscData.getLocalizedString("WESTRING_PLAYER_NA")); + this.players.get(this.players.size() - 3).setName(miscData.getLocalizedString("WESTRING_PLAYER_NV")); + this.players.get(this.players.size() - 2).setName(miscData.getLocalizedString("WESTRING_PLAYER_NE")); + final CPlayer neutralPassive = this.players.get(this.players.size() - 1); + neutralPassive.setName(miscData.getLocalizedString("WESTRING_PLAYER_NP")); + for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { final CPlayer cPlayer = this.players.get(i); cPlayer.setAlliance(neutralPassive, CAllianceType.PASSIVE, true); @@ -133,6 +131,14 @@ public class CSimulation { return this.abilityData; } + public CDestructableData getDestructableData() { + return this.destructableData; + } + + public CItemData getItemData() { + return this.itemData; + } + public List getUnits() { return this.units; } @@ -141,6 +147,22 @@ public class CSimulation { return this.destructables; } + public void registerTimer(final CTimer timer) { + final ListIterator listIterator = this.activeTimers.listIterator(); + while (listIterator.hasNext()) { + final CTimer nextTimer = listIterator.next(); + if (nextTimer.getEngineFireTick() > timer.getEngineFireTick()) { + listIterator.previous(); + listIterator.add(timer); + } + } + this.activeTimers.add(timer); + } + + public void unregisterTimer(final CTimer time) { + this.activeTimers.remove(time); + } + public CUnit createUnit(final War3ID typeId, final int playerIndex, final float x, final float y, final float facing, final BufferedImage buildingPathingPixelMap, final RemovablePathingMapInstance pathingInstance) { @@ -247,6 +269,10 @@ public class CSimulation { this.gameTurnTick++; this.currentGameDayTimeElapsed = (this.currentGameDayTimeElapsed + WarsmashConstants.SIMULATION_STEP_TIME) % this.gameplayConstants.getGameDayLength(); + while (!this.activeTimers.isEmpty() && (this.activeTimers.peek().getEngineFireTick() <= this.gameTurnTick)) { + this.activeTimers.pop().fire(this); + } + } private void finishAddingNewUnits() { @@ -292,6 +318,7 @@ public class CSimulation { this.simulationRenderController.spawnUnitConstructionSound(constructingUnit, constructedStructure); } + @Override public CPlayer getPlayer(final int index) { return this.players.get(index); } 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 c64acc5..442321b 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 @@ -721,7 +721,7 @@ public class CUnit extends CWidget { } } if (!foundMatchingReturnFireAttack && this.unitType.isCanFlee() && !isMovementDisabled() - && (this.moveBehavior != null)) { + && (this.moveBehavior != null) && (this.playerIndex != source.getPlayerIndex())) { final double angleTo = source.angleTo(this); final int distanceToFlee = getSpeed(); this.currentBehavior = this.moveBehavior.reset(OrderIds.move, diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java index 9146721..50b27f9 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java @@ -20,6 +20,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPa */ public class CUnitType { private final String name; + private final String legacyName; + private final War3ID typeId; private final int life; private final int manaInitial; private final int manaMaximum; @@ -73,15 +75,16 @@ public class CUnitType { private final int properNamesCount; private final boolean canFlee; - public CUnitType(final String name, final int life, final int manaInitial, final int manaMaximum, final int speed, - final int defense, final String abilityList, final boolean isBldg, final MovementType movementType, - final float defaultFlyingHeight, final float collisionSize, - final EnumSet classifications, final List attacks, final String armorType, - final boolean raise, final boolean decay, final CDefenseType defenseType, final float impactZ, - final BufferedImage buildingPathingPixelMap, final float deathTime, final EnumSet targetedAs, - final float defaultAcquisitionRange, final float minimumAttackRange, final List structuresBuilt, - final List unitsTrained, final List researchesAvailable, final CUnitRace unitRace, - final int goldCost, final int lumberCost, final int foodUsed, final int foodMade, final int buildTime, + public CUnitType(final String name, final String legacyName, final War3ID typeId, final int life, + final int manaInitial, final int manaMaximum, final int speed, final int defense, final String abilityList, + final boolean isBldg, final MovementType movementType, final float defaultFlyingHeight, + final float collisionSize, final EnumSet classifications, + final List attacks, final String armorType, final boolean raise, final boolean decay, + final CDefenseType defenseType, final float impactZ, final BufferedImage buildingPathingPixelMap, + final float deathTime, final EnumSet targetedAs, final float defaultAcquisitionRange, + final float minimumAttackRange, final List structuresBuilt, final List unitsTrained, + final List researchesAvailable, final CUnitRace unitRace, final int goldCost, final int lumberCost, + final int foodUsed, final int foodMade, final int buildTime, final EnumSet preventedPathingTypes, final EnumSet requiredPathingTypes, final float propWindow, final float turnRate, final List requirements, final int level, final boolean hero, final int strength, @@ -90,6 +93,8 @@ public class CUnitType { final List heroAbilityList, final List heroProperNames, final int properNamesCount, final boolean canFlee) { this.name = name; + this.legacyName = legacyName; + this.typeId = typeId; this.life = life; this.manaInitial = manaInitial; this.manaMaximum = manaMaximum; @@ -145,6 +150,14 @@ public class CUnitType { return this.name; } + public String getLegacyName() { + return this.legacyName; + } + + public War3ID getTypeId() { + return this.typeId; + } + public int getLife() { return this.life; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java new file mode 100644 index 0000000..681f710 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java @@ -0,0 +1,9 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.ai; + +public enum AIDifficulty { + NEWBIE, + NORMAL, + INSANE; + + public static AIDifficulty[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java new file mode 100644 index 0000000..931d19a --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java @@ -0,0 +1,185 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; + +import java.util.EnumMap; +import java.util.EnumSet; + +import com.etheller.warsmash.util.WarsmashConstants; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerState; +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 { + private final int id; + private String name; + private int team; + private int startLocationIndex; + private int forcedStartLocationIndex = -1; + private int color; + private final EnumSet racePrefs; + private final EnumSet[] alliances; + private final EnumMap[] taxRates; + private boolean onScoreScreen; + private boolean raceSelectable; + private CMapControl mapControl = CMapControl.NEUTRAL; + private CPlayerSlotState slotState = CPlayerSlotState.EMPTY; + + public CBasePlayer(final CBasePlayer other) { + this.id = other.id; + this.name = other.name; + this.team = other.team; + this.startLocationIndex = other.startLocationIndex; + this.forcedStartLocationIndex = other.forcedStartLocationIndex; + this.color = other.color; + this.racePrefs = other.racePrefs; + this.alliances = other.alliances; + this.taxRates = other.taxRates; + this.onScoreScreen = other.onScoreScreen; + this.raceSelectable = other.raceSelectable; + this.mapControl = other.mapControl; + this.slotState = other.slotState; + } + + public CBasePlayer(final int id) { + this.id = id; + this.alliances = new EnumSet[WarsmashConstants.MAX_PLAYERS]; + this.taxRates = new EnumMap[WarsmashConstants.MAX_PLAYERS]; + this.racePrefs = EnumSet.noneOf(CRacePreference.class); + for (int i = 0; i < this.alliances.length; i++) { + if (i == id) { + // player is fully allied with self + this.alliances[i] = EnumSet.allOf(CAllianceType.class); + } + else { + this.alliances[i] = EnumSet.noneOf(CAllianceType.class); + } + this.taxRates[i] = new EnumMap<>(CPlayerState.class); + } + } + + public int getId() { + return this.id; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void setOnScoreScreen(final boolean onScoreScreen) { + this.onScoreScreen = onScoreScreen; + } + + public boolean isOnScoreScreen() { + return this.onScoreScreen; + } + + @Override + public void setRaceSelectable(final boolean raceSelectable) { + this.raceSelectable = raceSelectable; + } + + @Override + public void setTeam(final int team) { + this.team = team; + } + + @Override + public int getTeam() { + return this.team; + } + + @Override + public int getStartLocationIndex() { + return this.startLocationIndex; + } + + @Override + public void setStartLocationIndex(final int startLocationIndex) { + this.startLocationIndex = startLocationIndex; + } + + @Override + public void setColor(final int color) { + this.color = color; + } + + @Override + public int getColor() { + return this.color; + } + + @Override + public boolean isRacePrefSet(final CRacePreference racePref) { + return this.racePrefs.contains(racePref); + } + + @Override + public void setRacePref(final CRacePreference racePref) { + this.racePrefs.add(racePref); + } + + @Override + public void setAlliance(final int otherPlayerIndex, final CAllianceType allianceType, final boolean value) { + final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayerIndex]; + if (value) { + alliancesWithOtherPlayer.add(allianceType); + } + else { + alliancesWithOtherPlayer.remove(allianceType); + } + } + + public boolean hasAlliance(final int otherPlayerIndex, final CAllianceType allianceType) { + final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayerIndex]; + return alliancesWithOtherPlayer.contains(allianceType); + } + + @Override + public void forceStartLocation(final int startLocIndex) { + this.forcedStartLocationIndex = startLocIndex; + } + + @Override + public void setTaxRate(final int otherPlayerIndex, final CPlayerState whichResource, final int rate) { + this.taxRates[otherPlayerIndex].put(whichResource, rate); + } + + @Override + public void setController(final CMapControl mapControl) { + this.mapControl = mapControl; + + } + + @Override + public boolean isSelectable() { + return this.raceSelectable; + } + + @Override + public CMapControl getController() { + return this.mapControl; + } + + @Override + public CPlayerSlotState getSlotState() { + return this.slotState; + } + + @Override + public int getTaxRate(final int otherPlayerIndex, final CPlayerState whichResource) { + final Integer taxRate = this.taxRates[otherPlayerIndex].get(whichResource); + if (taxRate == null) { + return 0; + } + return taxRate; + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java new file mode 100644 index 0000000..61baa4f --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java @@ -0,0 +1,5 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; + +public interface CPlayerAPI { + CBasePlayer getPlayer(int index); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java new file mode 100644 index 0000000..dec0f41 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java @@ -0,0 +1,153 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; + +import java.util.EnumMap; + +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapFlag; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapPlacement; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameSpeed; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDensity; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDifficulty; + +public class War3MapConfig implements CPlayerAPI { + private String mapName; + private String mapDescription; + private int teamCount; + private int playerCount; + private final War3MapConfigStartLoc[] startLocations; + private final CBasePlayer[] players; + private final EnumMap gameTypeToSupported = new EnumMap<>(CGameType.class); + private final EnumMap mapFlagToEnabled = new EnumMap<>(CMapFlag.class); + private CMapPlacement placement; + private CGameSpeed gameSpeed; + private CMapDifficulty gameDifficulty; + private CMapDensity resourceDensity; + private CMapDensity creatureDensity; + private CGameType gameTypeSelected; + + public War3MapConfig(final int maxPlayers) { + this.startLocations = new War3MapConfigStartLoc[maxPlayers]; + this.players = new CBasePlayer[maxPlayers]; + for (int i = 0; i < maxPlayers; i++) { + this.startLocations[i] = new War3MapConfigStartLoc(); + this.players[i] = new CBasePlayer(i); + } + } + + public void setMapName(final String mapName) { + this.mapName = mapName; + } + + public void setMapDescription(final String mapDescription) { + this.mapDescription = mapDescription; + } + + public String getMapName() { + return this.mapName; + } + + public String getMapDescription() { + return this.mapDescription; + } + + public void setTeamCount(final int teamCount) { + this.teamCount = teamCount; + } + + public void setPlayerCount(final int playerCount) { + this.playerCount = playerCount; + } + + public void defineStartLocation(final int whichStartLoc, final float x, final float y) { + final War3MapConfigStartLoc startLoc = this.startLocations[whichStartLoc]; + startLoc.setX(x); + startLoc.setY(y); + } + + public War3MapConfigStartLoc getStartLoc(final int whichStartLoc) { + return this.startLocations[whichStartLoc]; + } + + public void setGameTypeSupported(final CGameType gameType, final boolean supported) { + this.gameTypeToSupported.put(gameType, supported); + } + + public void setMapFlag(final CMapFlag mapFlag, final boolean set) { + this.mapFlagToEnabled.put(mapFlag, set); + } + + public void setPlacement(final CMapPlacement placement) { + this.placement = placement; + } + + public void setGameSpeed(final CGameSpeed gameSpeed) { + this.gameSpeed = gameSpeed; + } + + public void setGameDifficulty(final CMapDifficulty gameDifficulty) { + this.gameDifficulty = gameDifficulty; + } + + public void setResourceDensity(final CMapDensity resourceDensity) { + this.resourceDensity = resourceDensity; + } + + public void setCreatureDensity(final CMapDensity creatureDensity) { + this.creatureDensity = creatureDensity; + } + + public int getTeamCount() { + return this.teamCount; + } + + public int getPlayerCount() { + return this.playerCount; + } + + public boolean isGameTypeSupported(final CGameType gameType) { + final Boolean supported = this.gameTypeToSupported.get(gameType); + return (supported != null) && supported; + } + + public CGameType getGameTypeSelected() { + return this.gameTypeSelected; + } + + public boolean isMapFlagSet(final CMapFlag mapFlag) { + final Boolean flag = this.mapFlagToEnabled.get(mapFlag); + return (flag != null) && flag; + } + + public CMapPlacement getPlacement() { + return this.placement; + } + + public CGameSpeed getGameSpeed() { + return this.gameSpeed; + } + + public CMapDifficulty getGameDifficulty() { + return this.gameDifficulty; + } + + public CMapDensity getResourceDensity() { + return this.resourceDensity; + } + + public CMapDensity getCreatureDensity() { + return this.creatureDensity; + } + + public float getStartLocationX(final int startLocIndex) { + return this.startLocations[startLocIndex].getX(); + } + + public float getStartLocationY(final int startLocIndex) { + return this.startLocations[startLocIndex].getY(); + } + + @Override + public CBasePlayer getPlayer(final int index) { + return this.players[index]; + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java new file mode 100644 index 0000000..281eb76 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java @@ -0,0 +1,44 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; + +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CStartLocPrio; + +public class War3MapConfigStartLoc { + private float x; + private float y; + private int[] otherStartIndices; + private CStartLocPrio[] otherStartLocPriorities; + + public void setX(final float x) { + this.x = x; + } + + public void setY(final float y) { + this.y = y; + } + + public float getX() { + return this.x; + } + + public float getY() { + return this.y; + } + + public int[] getOtherStartIndices() { + return this.otherStartIndices; + } + + public CStartLocPrio[] getOtherStartLocPriorities() { + return this.otherStartLocPriorities; + } + + public void setStartLocPrioCount(final int startLocPrioCount) { + this.otherStartIndices = new int[startLocPrioCount]; + this.otherStartLocPriorities = new CStartLocPrio[startLocPrioCount]; + } + + public void setStartLocPrio(final int prioSlotIndex, final int otherStartLocIndex, final CStartLocPrio priority) { + this.otherStartIndices[prioSlotIndex] = otherStartLocIndex; + this.otherStartLocPriorities[prioSlotIndex] = priority; + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java index bfc8305..24ea711 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java @@ -58,6 +58,14 @@ public class CItemData { return new CItem(handleId, x, y, itemTypeInstance.getHitPoints(), typeId, itemTypeInstance); } + public CItemType getItemType(final War3ID typeId) { + final MutableGameObject itemType = this.itemData.get(typeId); + if (itemType == null) { + return null; + } + return getItemTypeInstance(typeId, itemType); + } + private CItemType getItemTypeInstance(final War3ID typeId, final MutableGameObject itemType) { CItemType itemTypeInstance = this.itemIdToItemType.get(typeId); if (itemTypeInstance == null) { 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 283b160..7df7d6a 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 @@ -173,6 +173,7 @@ public class CUnitData { private final CGameplayConstants gameplayConstants; private final MutableObjectData unitData; private final Map unitIdToUnitType = new HashMap<>(); + private final Map jassLegacyNameToUnitId = new HashMap<>(); private final CAbilityData abilityData; private final SimulationRenderController simulationRenderController; @@ -266,6 +267,7 @@ public class CUnitData { final MutableGameObject unitType) { CUnitType unitTypeInstance = this.unitIdToUnitType.get(typeId); if (unitTypeInstance == null) { + final String legacyName = getLegacyName(unitType); 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); @@ -531,18 +533,33 @@ public class CUnitData { final List heroProperNames = Arrays.asList(properNames.split(",")); - unitTypeInstance = new CUnitType(unitName, life, manaInitial, manaMaximum, speed, defense, abilityList, - isBldg, movementType, moveHeight, collisionSize, classifications, attacks, armorType, raise, decay, - defenseType, impactZ, buildingPathingPixelMap, deathTime, targetedAs, acquisitionRange, - minimumAttackRange, structuresBuilt, unitsTrained, researchesAvailable, unitRace, goldCost, - lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, propWindow, - turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus, intelligence, intPlus, - primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, canFlee); + unitTypeInstance = new CUnitType(unitName, legacyName, typeId, life, manaInitial, manaMaximum, speed, + defense, abilityList, isBldg, movementType, moveHeight, collisionSize, classifications, attacks, + armorType, raise, decay, defenseType, impactZ, buildingPathingPixelMap, deathTime, targetedAs, + acquisitionRange, minimumAttackRange, structuresBuilt, unitsTrained, researchesAvailable, unitRace, + goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, + propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus, + intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, + canFlee); this.unitIdToUnitType.put(typeId, unitTypeInstance); + this.jassLegacyNameToUnitId.put(legacyName, typeId); } return unitTypeInstance; } + private String getLegacyName(final MutableGameObject unitType) { + String legacyName; + if (unitType.isCustom()) { + legacyName = "custom_" + unitType.getAlias(); + } + else { + // ?? this might be correct here, not sure, legacy name is mostly only used + // for spawning hidden units in campaign secrets + legacyName = unitType.readSLKTag("name"); + } + return legacyName; + } + private static int[] populateHeroStatTable(final int maxHeroLevel, final float statPerLevel) { final int[] table = new int[maxHeroLevel]; float sumBonusAtLevel = 0f; @@ -713,4 +730,22 @@ public class CUnitData { .getBuildingPathingPixelMap(rawcode); return getUnitTypeInstance(rawcode, buildingPathingPixelMap, unitType); } + + public CUnitType getUnitTypeByJassLegacyName(final String jassLegacyName) { + final War3ID typeId = this.jassLegacyNameToUnitId.get(jassLegacyName); + if (typeId == null) { + // VERY inefficient, but this is a crazy system anyway, they should not be using + // this! + System.err.println( + "We are doing a highly inefficient lookup for a non-cached unit type based on its legacy string ID that I am pretty sure is not used by modding community: " + + jassLegacyName); + for (final War3ID key : this.unitData.keySet()) { + final MutableGameObject mutableGameObject = this.unitData.get(key); + if (jassLegacyName.equals(getLegacyName(mutableGameObject))) { + return getUnitType(mutableGameObject.getAlias()); + } + } + } + return getUnitType(typeId); + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java new file mode 100644 index 0000000..bde3174 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java @@ -0,0 +1,15 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.item; + +public enum CItemTypeJass { + PERMANENT, + CHARGED, + POWERUP, + ARTIFACT, + PURCHASABLE, + CAMPAIGN, + MISCELLANEOUS, + UNKNOWN, + ANY; + + public static CItemTypeJass[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java new file mode 100644 index 0000000..90375e3 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java @@ -0,0 +1,38 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class OrderIdUtils { + private static Map orderIdToString = new HashMap<>(); + private static Map stringToOrderId = new HashMap<>(); + + static { + for (final Field field : OrderIds.class.getDeclaredFields()) { + final String name = field.getName(); + try { + final Object value = field.get(null); + if (value instanceof Integer) { + final Integer orderId = (Integer) value; + orderIdToString.put(orderId, name); + stringToOrderId.put(name, orderId); + } + } + catch (final IllegalArgumentException e) { + e.printStackTrace(); + } + catch (final IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + public static int getOrderId(final String orderIdString) { + return stringToOrderId.get(orderIdString); + } + + public static String getStringFromOrderId(final Integer orderId) { + return orderIdToString.get(orderId); + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java index 8587028..ea1f28a 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java @@ -11,4 +11,6 @@ public enum CAllianceType { SHARED_ADVANCED_CONTROL, RESCUABLE, SHARED_VISION_FORCED; + + public static CAllianceType[] VALUES = values(); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java index 0d7f4a1..423e458 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java @@ -7,4 +7,6 @@ public enum CMapControl { NEUTRAL, CREEP, NONE; + + public static CMapControl[] VALUES = values(); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java new file mode 100644 index 0000000..f001bc8 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java @@ -0,0 +1,44 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CMapFlag { + MAP_FOG_HIDE_TERRAIN, + MAP_FOG_MAP_EXPLORED, + MAP_FOG_ALWAYS_VISIBLE, + + MAP_USE_HANDICAPS, + MAP_OBSERVERS, + MAP_OBSERVERS_ON_DEATH, + + MAP_FIXED_COLORS, + + MAP_LOCK_RESOURCE_TRADING, + MAP_RESOURCE_TRADING_ALLIES_ONLY, + + MAP_LOCK_ALLIANCE_CHANGES, + MAP_ALLIANCE_CHANGES_HIDDEN, + + MAP_CHEATS, + MAP_CHEATS_HIDDEN, + + MAP_LOCK_SPEED, + MAP_LOCK_RANDOM_SEED, + MAP_SHARED_ADVANCED_CONTROL, + MAP_RANDOM_HERO, + MAP_RANDOM_RACES, + MAP_RELOADED; + + public static CMapFlag[] VALUES = values(); + + public static CMapFlag getById(final int id) { + for (final CMapFlag type : VALUES) { + if ((type.getId()) == id) { + return type; + } + } + return null; + } + + public int getId() { + return 1 << ordinal(); + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java new file mode 100644 index 0000000..29eb00e --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CMapPlacement { + RANDOM, + FIXED, + USE_MAP_SETTINGS, + TEAMS_TOGETHER; + + public static CMapPlacement[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java index e00070f..956a396 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java @@ -1,29 +1,22 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; -import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; 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; -public class CPlayer { - private final int id; - private int colorIndex; - private final CMapControl controlType; - private String name; +public class CPlayer extends CBasePlayer { private final CRace race; private final float[] startLocation; - private final EnumSet racePrefs; private int gold = 500; private int lumber = 150; private int foodCap; private int foodUsed; - private final EnumSet[] alliances = new EnumSet[WarsmashConstants.MAX_PLAYERS]; private final Map rawcodeToTechtreeUnlocked = new HashMap<>(); // if you use triggers for this then the transient tag here becomes really @@ -31,73 +24,20 @@ public class CPlayer { // which fields shouldn't be persisted if we do game state save later private transient CPlayerStateNotifier stateNotifier = new CPlayerStateNotifier(); - public CPlayer(final int id, final CMapControl controlType, final String name, final CRace race, - final float[] startLocation) { - this.id = id; - this.colorIndex = id; - this.controlType = controlType; - this.name = name; + public CPlayer(final CRace race, final float[] startLocation, final CBasePlayer configPlayer) { + super(configPlayer); this.race = race; this.startLocation = startLocation; - this.racePrefs = EnumSet.noneOf(CRacePreference.class); - for (int i = 0; i < this.alliances.length; i++) { - if (i == this.id) { - // player is fully allied with self - this.alliances[i] = EnumSet.allOf(CAllianceType.class); - } - else { - this.alliances[i] = EnumSet.noneOf(CAllianceType.class); - } - } } - public int getId() { - return this.id; - } - - public int getColorIndex() { - return this.colorIndex; - } - - public CMapControl getControlType() { - return this.controlType; - } - - public String getName() { - return this.name; - } - - public void setName(final String name) { - this.name = name; + public void setAlliance(final CPlayer other, final CAllianceType alliance, final boolean flag) { + setAlliance(other.getId(), alliance, flag); } public CRace getRace() { return this.race; } - public boolean isRacePrefSet(final CRacePreference racePref) { - return this.racePrefs.contains(racePref); - } - - public void setAlliance(final CPlayer otherPlayer, final CAllianceType allianceType, final boolean value) { - final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayer.getId()]; - if (value) { - alliancesWithOtherPlayer.add(allianceType); - } - else { - alliancesWithOtherPlayer.remove(allianceType); - } - } - - public boolean hasAlliance(final CPlayer otherPlayer, final CAllianceType allianceType) { - return hasAlliance(otherPlayer.getId(), allianceType); - } - - public boolean hasAlliance(final int otherPlayerIndex, final CAllianceType allianceType) { - final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayerIndex]; - return alliancesWithOtherPlayer.contains(allianceType); - } - public int getGold() { return this.gold; } @@ -138,10 +78,6 @@ public class CPlayer { this.stateNotifier.foodChanged(); } - public void setColorIndex(final int colorIndex) { - this.colorIndex = colorIndex; - } - public int getTechtreeUnlocked(final War3ID rawcode) { final Integer techtreeUnlocked = this.rawcodeToTechtreeUnlocked.get(rawcode); if (techtreeUnlocked == null) { diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java new file mode 100644 index 0000000..20cfcf6 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java @@ -0,0 +1,25 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CPlayerColor { + RED, + BLUE, + CYAN, + PURPLE, + YELLOW, + ORANGE, + GREEN, + PINK, + LIGHT_GRAY, + LIGHT_BLUE, + AQUA, + BROWN; + + public static CPlayerColor[] VALUES = values(); + + public static CPlayerColor getColorByIndex(final int index) { + if ((index >= 0) && (index < VALUES.length)) { + return VALUES[index]; + } + return null; + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java new file mode 100644 index 0000000..e713d5c --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CPlayerGameResult { + VICTORY, + DEFEAT, + TIE, + NEUTRAL; + + public static CPlayerGameResult[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java new file mode 100644 index 0000000..57cc14d --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java @@ -0,0 +1,47 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState; + +public interface CPlayerJass { + int getId(); + + void setTeam(int team); + + void setStartLocationIndex(int startLocIndex); + + void forceStartLocation(int startLocIndex); + + void setColor(int colorIndex); + + void setAlliance(int otherPlayerIndex, CAllianceType whichAllianceSetting, boolean value); + + void setTaxRate(int otherPlayerIndex, CPlayerState whichResource, int rate); + + void setRacePref(CRacePreference whichRacePreference); + + void setRaceSelectable(boolean selectable); + + void setController(CMapControl mapControl); + + void setName(String name); + + void setOnScoreScreen(boolean flag); + + int getTeam(); + + int getStartLocationIndex(); + + int getColor(); + + boolean isSelectable(); + + CMapControl getController(); + + CPlayerSlotState getSlotState(); + + int getTaxRate(int otherPlayerIndex, CPlayerState whichResource); + + boolean isRacePrefSet(CRacePreference pref); + + String getName(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java new file mode 100644 index 0000000..f0950d8 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java @@ -0,0 +1,31 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CPlayerScore { + UNITS_TRAINED, + UNITS_KILLED, + STRUCT_BUILT, + STRUCT_RAZED, + TECH_PERCENT, + FOOD_MAXPROD, + FOOD_MAXUSED, + HEROES_KILLED, + ITEMS_GAINED, + MERCS_HIRED, + GOLD_MINED_TOTAL, + GOLD_MINED_UPKEEP, + GOLD_LOST_UPKEEP, + GOLD_LOST_TAX, + GOLD_GIVEN, + GOLD_RECEIVED, + LUMBER_TOTAL, + LUMBER_LOST_UPKEEP, + LUMBER_LOST_TAX, + LUMBER_GIVEN, + LUMBER_RECEIVED, + UNIT_TOTAL, + HERO_TOTAL, + RESOURCE_TOTAL, + TOTAL; + + public static CPlayerScore[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java new file mode 100644 index 0000000..9965b4f --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java @@ -0,0 +1,42 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CPlayerState { + // current resource levels + // + RESOURCE_GOLD, + RESOURCE_LUMBER, + RESOURCE_HERO_TOKENS, + RESOURCE_FOOD_CAP, + RESOURCE_FOOD_USED, + FOOD_CAP_CEILING, + + GIVES_BOUNTY, + ALLIED_VICTORY, + PLACED, + OBSERVER_ON_DEATH, + OBSERVER, + UNFOLLOWABLE, + + // taxation rate for each resource + // + GOLD_UPKEEP_RATE, + LUMBER_UPKEEP_RATE, + + // cumulative resources collected by the player during the mission + // + GOLD_GATHERED, + LUMBER_GATHERED, + + UNKNOWN_STATE_17, + UNKNOWN_STATE_18, + UNKNOWN_STATE_19, + UNKNOWN_STATE_20, + UNKNOWN_STATE_21, + UNKNOWN_STATE_22, + UNKNOWN_STATE_23, + UNKNOWN_STATE_24, + + NO_CREEP_SLEEP; + + public static CPlayerState[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java index 96c2458..5620203 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java @@ -13,10 +13,13 @@ import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListene public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener { private final CSimulation game; + private final int playerIndex; private final CommandErrorListener errorListener; - public CPlayerUnitOrderExecutor(final CSimulation game, final CommandErrorListener errorListener) { + public CPlayerUnitOrderExecutor(final CSimulation game, final int playerIndex, + final CommandErrorListener errorListener) { this.game = game; + this.playerIndex = playerIndex; this.errorListener = errorListener; } @@ -24,50 +27,60 @@ public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener { public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final int targetHandleId, final boolean queue) { final CUnit unit = this.game.getUnit(unitHandleId); - unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId, queue), queue); + if (this.playerIndex == unit.getPlayerIndex()) { + unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId, queue), queue); + } } @Override public void issueDropItemAtPointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final int targetHandleId, final float x, final float y, final boolean queue) { final CUnit unit = this.game.getUnit(unitHandleId); - unit.order(this.game, new COrderDropItemAtPoint(abilityHandleId, orderId, targetHandleId, - new AbilityPointTarget(x, y), queue), queue); + if (this.playerIndex == unit.getPlayerIndex()) { + unit.order(this.game, new COrderDropItemAtPoint(abilityHandleId, orderId, targetHandleId, + new AbilityPointTarget(x, y), queue), queue); + } } @Override public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x, final float y, final boolean queue) { final CUnit unit = this.game.getUnit(unitHandleId); - unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new AbilityPointTarget(x, y), queue), - queue); + if (this.playerIndex == unit.getPlayerIndex()) { + unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new AbilityPointTarget(x, y), queue), + queue); + } } @Override public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final boolean queue) { final CUnit unit = this.game.getUnit(unitHandleId); - if (abilityHandleId == 0) { - if (orderId == OrderIds.stop) { - unit.order(this.game, null, queue); - } - else if (orderId == OrderIds.holdposition) { - unit.order(this.game, null, queue); - final CBehaviorHoldPosition holdPositionBehavior = unit.getHoldPositionBehavior(); - if (holdPositionBehavior != null) { - unit.setDefaultBehavior(holdPositionBehavior); + if (this.playerIndex == unit.getPlayerIndex()) { + if (abilityHandleId == 0) { + if (orderId == OrderIds.stop) { + unit.order(this.game, null, queue); + } + else if (orderId == OrderIds.holdposition) { + unit.order(this.game, null, queue); + final CBehaviorHoldPosition holdPositionBehavior = unit.getHoldPositionBehavior(); + if (holdPositionBehavior != null) { + unit.setDefaultBehavior(holdPositionBehavior); + } } } - } - else { - unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId, queue), queue); + else { + unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId, queue), queue); + } } } @Override public void unitCancelTrainingItem(final int unitHandleId, final int cancelIndex) { final CUnit unit = this.game.getUnit(unitHandleId); - unit.cancelBuildQueueItem(this.game, cancelIndex); + if (this.playerIndex == unit.getPlayerIndex()) { + unit.cancelBuildQueueItem(this.game, cancelIndex); + } } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java index 26bb76a..9043d91 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java @@ -14,6 +14,8 @@ public enum CRace { this.id = id; } + public static CRace[] VALUES = values(); + public int getId() { return this.id; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java index 7086929..24ff6ac 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java @@ -8,4 +8,19 @@ public enum CRacePreference { DEMON, RANDOM, USER_SELECTABLE; + + public static CRacePreference[] VALUES = values(); + + public static CRacePreference getById(final int id) { + for (final CRacePreference type : VALUES) { + if ((type.getId()) == id) { + return type; + } + } + return null; + } + + public int getId() { + return 1 << ordinal(); + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java new file mode 100644 index 0000000..99d7008 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java @@ -0,0 +1,9 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; + +public enum CStartLocPrio { + LOW, + HIGH, + NOT; + + public static CStartLocPrio[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java new file mode 100644 index 0000000..0cad618 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java @@ -0,0 +1,9 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.state; + +public enum CGameState { + DIVINE_INTERVENTION, + DISCONNECTED, + TIME_OF_DAY; + + public static CGameState[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java new file mode 100644 index 0000000..2272ad4 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.state; + +public enum CUnitState { + LIFE, + MAX_LIFE, + MANA, + MAX_MANA; + + public static CUnitState[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java new file mode 100644 index 0000000..917f44e --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java @@ -0,0 +1,89 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers; + +import com.etheller.warsmash.util.WarsmashConstants; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; + +public abstract class CTimer { + private int engineFireTick; + private int scheduleTick; + private float timeoutTime; + private float remainingTimeAfterPause; + private boolean running = false; + private boolean repeats; + + public void setTimeoutTime(final float timeoutTime) { + this.timeoutTime = timeoutTime; + } + + public boolean isRepeats() { + return this.repeats; + } + + public boolean isRunning() { + return this.running; + } + + public float getTimeoutTime() { + return this.timeoutTime; + } + + /** + * @param simulation + */ + public void start(final CSimulation simulation) { + this.running = true; + final int currentTick = simulation.getGameTurnTick(); + this.scheduleTick = currentTick; + innerStart(this.timeoutTime, simulation, currentTick); + } + + private void innerStart(final float timeoutTime, final CSimulation simulation, final int currentTick) { + final int ticks = (int) (timeoutTime / WarsmashConstants.SIMULATION_STEP_TIME); + this.engineFireTick = currentTick + ticks; + simulation.registerTimer(this); + } + + public void pause(final CSimulation simulation) { + this.remainingTimeAfterPause = getRemaining(simulation); + simulation.unregisterTimer(this); + } + + public void resume(final CSimulation simulation) { + if (this.remainingTimeAfterPause == 0) { + start(simulation); + } + final int currentTick = simulation.getGameTurnTick(); + innerStart(this.remainingTimeAfterPause, simulation, currentTick); + this.remainingTimeAfterPause = 0; + } + + public float getElapsed(final CSimulation simulation) { + final int currentTick = simulation.getGameTurnTick(); + final int elapsedTicks = currentTick - this.scheduleTick; + return Math.max(elapsedTicks * WarsmashConstants.SIMULATION_STEP_TIME, this.timeoutTime); + + } + + public float getRemaining(final CSimulation simulation) { + return this.timeoutTime - getElapsed(simulation); + } + + public void setRepeats(final boolean repeats) { + this.repeats = repeats; + } + + public int getEngineFireTick() { + return this.engineFireTick; + } + + public abstract void onFire(); + + public void fire(final CSimulation simulation) { + // its implied that we will have "unregisterTimer" happen automatically + // before this is called + this.running = false; + if (this.repeats) { + start(simulation); + } + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java new file mode 100644 index 0000000..33ba52e --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java @@ -0,0 +1,25 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers; + +import java.util.Collections; + +import com.etheller.interpreter.ast.function.JassFunction; +import com.etheller.interpreter.ast.scope.GlobalScope; +import com.etheller.interpreter.ast.scope.TriggerExecutionScope; + +public class CTimerJass extends CTimer { + private JassFunction handlerFunc; + private final GlobalScope jassGlobalScope; + + public CTimerJass(final GlobalScope jassGlobalScope) { + this.jassGlobalScope = jassGlobalScope; + } + + public void setHandlerFunc(final JassFunction handlerFunc) { + this.handlerFunc = handlerFunc; + } + + @Override + public void onFire() { + this.handlerFunc.call(Collections.emptyList(), this.jassGlobalScope, TriggerExecutionScope.EMPTY); + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java new file mode 100644 index 0000000..7d78f30 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java @@ -0,0 +1,248 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger; + +//=================================================== +//Game, Player and Unit Events +// +//When an event causes a trigger to fire these +//values allow the action code to determine which +//event was dispatched and therefore which set of +//native functions should be used to get information +//about the event. +// +//Do NOT change the order or value of these constants +//without insuring that the JASS_GAME_EVENTS_WAR3 enum +//is changed to match. +// +//=================================================== + +public enum JassGameEventsWar3 { + // =================================================== + // For use with TriggerRegisterGameEvent + // =================================================== + EVENT_GAME_VICTORY, + EVENT_GAME_END_LEVEL, + + EVENT_GAME_VARIABLE_LIMIT, + EVENT_GAME_STATE_LIMIT, + + EVENT_GAME_TIMER_EXPIRED, + + EVENT_GAME_ENTER_REGION, + EVENT_GAME_LEAVE_REGION, + + EVENT_GAME_TRACKABLE_HIT, + EVENT_GAME_TRACKABLE_TRACK, + + EVENT_GAME_SHOW_SKILL, + EVENT_GAME_BUILD_SUBMENU, + + // =================================================== + // For use with TriggerRegisterPlayerEvent + // =================================================== + EVENT_PLAYER_STATE_LIMIT, + EVENT_PLAYER_ALLIANCE_CHANGED, + + EVENT_PLAYER_DEFEAT, + EVENT_PLAYER_VICTORY, + EVENT_PLAYER_LEAVE, + EVENT_PLAYER_CHAT, + EVENT_PLAYER_END_CINEMATIC, + + // =================================================== + // For use with TriggerRegisterPlayerUnitEvent + // =================================================== + EVENT_PLAYER_UNIT_ATTACKED, + EVENT_PLAYER_UNIT_RESCUED, + + EVENT_PLAYER_UNIT_DEATH, + EVENT_PLAYER_UNIT_DECAY, + + EVENT_PLAYER_UNIT_DETECTED, + EVENT_PLAYER_UNIT_HIDDEN, + + EVENT_PLAYER_UNIT_SELECTED, + EVENT_PLAYER_UNIT_DESELECTED, + + EVENT_PLAYER_UNIT_CONSTRUCT_START, + EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, + EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, + + EVENT_PLAYER_UNIT_UPGRADE_START, + EVENT_PLAYER_UNIT_UPGRADE_CANCEL, + EVENT_PLAYER_UNIT_UPGRADE_FINISH, + + EVENT_PLAYER_UNIT_TRAIN_START, + EVENT_PLAYER_UNIT_TRAIN_CANCEL, + EVENT_PLAYER_UNIT_TRAIN_FINISH, + + EVENT_PLAYER_UNIT_RESEARCH_START, + EVENT_PLAYER_UNIT_RESEARCH_CANCEL, + EVENT_PLAYER_UNIT_RESEARCH_FINISH, + EVENT_PLAYER_UNIT_ISSUED_ORDER, + EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, + EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, + + EVENT_PLAYER_HERO_LEVEL, + EVENT_PLAYER_HERO_SKILL, + + EVENT_PLAYER_HERO_REVIVABLE, + + EVENT_PLAYER_HERO_REVIVE_START, + EVENT_PLAYER_HERO_REVIVE_CANCEL, + EVENT_PLAYER_HERO_REVIVE_FINISH, + EVENT_PLAYER_UNIT_SUMMON, + EVENT_PLAYER_UNIT_DROP_ITEM, + EVENT_PLAYER_UNIT_PICKUP_ITEM, + EVENT_PLAYER_UNIT_USE_ITEM, + EVENT_PLAYER_UNIT_LOADED, + + // =================================================== + // For use with TriggerRegisterUnitEvent + // =================================================== + + EVENT_UNIT_DAMAGED, + EVENT_UNIT_DEATH, + EVENT_UNIT_DECAY, + EVENT_UNIT_DETECTED, + EVENT_UNIT_HIDDEN, + EVENT_UNIT_SELECTED, + EVENT_UNIT_DESELECTED, + + EVENT_UNIT_STATE_LIMIT, + + // Events which may have a filter for the "other unit" + // + EVENT_UNIT_ACQUIRED_TARGET, + EVENT_UNIT_TARGET_IN_RANGE, + EVENT_UNIT_ATTACKED, + EVENT_UNIT_RESCUED, + + EVENT_UNIT_CONSTRUCT_CANCEL, + EVENT_UNIT_CONSTRUCT_FINISH, + + EVENT_UNIT_UPGRADE_START, + EVENT_UNIT_UPGRADE_CANCEL, + EVENT_UNIT_UPGRADE_FINISH, + +// Events which involve the specified unit performing +// training of other units +// + EVENT_UNIT_TRAIN_START, + EVENT_UNIT_TRAIN_CANCEL, + EVENT_UNIT_TRAIN_FINISH, + + EVENT_UNIT_RESEARCH_START, + EVENT_UNIT_RESEARCH_CANCEL, + EVENT_UNIT_RESEARCH_FINISH, + + EVENT_UNIT_ISSUED_ORDER, + EVENT_UNIT_ISSUED_POINT_ORDER, + EVENT_UNIT_ISSUED_TARGET_ORDER, + + EVENT_UNIT_HERO_LEVEL, + EVENT_UNIT_HERO_SKILL, + + EVENT_UNIT_HERO_REVIVABLE, + EVENT_UNIT_HERO_REVIVE_START, + EVENT_UNIT_HERO_REVIVE_CANCEL, + EVENT_UNIT_HERO_REVIVE_FINISH, + + EVENT_UNIT_SUMMON, + + EVENT_UNIT_DROP_ITEM, + EVENT_UNIT_PICKUP_ITEM, + EVENT_UNIT_USE_ITEM, + + EVENT_UNIT_LOADED, + + EVENT_WIDGET_DEATH, + + EVENT_DIALOG_BUTTON_CLICK, + EVENT_DIALOG_CLICK, + + // =================================================== + // Frozen Throne Expansion Events + // Need to be added here to preserve compat + // =================================================== + + // =================================================== + // For use with TriggerRegisterGameEvent + // =================================================== + + EVENT_GAME_LOADED, + EVENT_GAME_TOURNAMENT_FINISH_SOON, + EVENT_GAME_TOURNAMENT_FINISH_NOW, + EVENT_GAME_SAVE, + + EVENT_UNKNOWN_TFT_CODE_260, + + // =================================================== + // For use with TriggerRegisterPlayerEvent + // =================================================== + + EVENT_PLAYER_ARROW_LEFT_DOWN, + EVENT_PLAYER_ARROW_LEFT_UP, + EVENT_PLAYER_ARROW_RIGHT_DOWN, + EVENT_PLAYER_ARROW_RIGHT_UP, + EVENT_PLAYER_ARROW_DOWN_DOWN, + EVENT_PLAYER_ARROW_DOWN_UP, + EVENT_PLAYER_ARROW_UP_DOWN, + EVENT_PLAYER_ARROW_UP_UP, + + // =================================================== + // For use with TriggerRegisterPlayerUnitEvent + // =================================================== + + EVENT_PLAYER_UNIT_SELL, + EVENT_PLAYER_UNIT_CHANGE_OWNER, + EVENT_PLAYER_UNIT_SELL_ITEM, + EVENT_PLAYER_UNIT_SPELL_CHANNEL, + EVENT_PLAYER_UNIT_SPELL_CAST, + EVENT_PLAYER_UNIT_SPELL_EFFECT, + EVENT_PLAYER_UNIT_SPELL_FINISH, + EVENT_PLAYER_UNIT_SPELL_ENDCAST, + EVENT_PLAYER_UNIT_PAWN_ITEM, + + EVENT_UNKNOWN_TFT_CODE_278, + EVENT_UNKNOWN_TFT_CODE_279, + EVENT_UNKNOWN_TFT_CODE_280, + EVENT_UNKNOWN_TFT_CODE_281, + EVENT_UNKNOWN_TFT_CODE_282, + EVENT_UNKNOWN_TFT_CODE_283, + EVENT_UNKNOWN_TFT_CODE_284, + EVENT_UNKNOWN_TFT_CODE_285, + + // =================================================== + // For use with TriggerRegisterUnitEvent + // =================================================== + + EVENT_UNIT_SELL, + EVENT_UNIT_CHANGE_OWNER, + EVENT_UNIT_SELL_ITEM, + EVENT_UNIT_SPELL_CHANNEL, + EVENT_UNIT_SPELL_CAST, + EVENT_UNIT_SPELL_EFFECT, + EVENT_UNIT_SPELL_FINISH, + EVENT_UNIT_SPELL_ENDCAST, + EVENT_UNIT_PAWN_ITEM,; + + private static final int TFT_CUTOFF = EVENT_GAME_LOADED.ordinal(); + + public static JassGameEventsWar3[] VALUES; + static { + final JassGameEventsWar3[] localValuesArray = values(); + final JassGameEventsWar3 endValue = localValuesArray[localValuesArray.length]; + VALUES = new JassGameEventsWar3[endValue.getEventId() + 1]; + for (final JassGameEventsWar3 event : localValuesArray) { + VALUES[event.getEventId()] = event; + } + } + + public int getEventId() { + final int ordinal = ordinal(); + if (ordinal >= TFT_CUTOFF) { + return (ordinal - TFT_CUTOFF) + 256; + } + return ordinal; + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java new file mode 100644 index 0000000..8fbd348 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java @@ -0,0 +1,9 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; + +public enum CAttackTypeJass { + ; + public static CAttackType[] VALUES = { CAttackType.SPELLS, CAttackType.NORMAL, CAttackType.PIERCE, + CAttackType.SIEGE, CAttackType.MAGIC, CAttackType.CHAOS, CAttackType.HERO }; +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java new file mode 100644 index 0000000..8ea22de --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java @@ -0,0 +1,12 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CBlendMode { + NONE, + KEYALPHA, + BLEND, + ADDITIVE, + MODULATE, + MODULATE_2X; + + public static CBlendMode[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java new file mode 100644 index 0000000..b51f0a4 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java @@ -0,0 +1,13 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CCameraField { + TARGET_DISTANCE, + FARZ, + ANGLE_OF_ATTACK, + FIELD_OF_VIEW, + ROLL, + ROTATION, + ZOFFSET; + + public static CCameraField[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java new file mode 100644 index 0000000..2269db5 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java @@ -0,0 +1,32 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CDamageType { + UNKNOWN, + UNKNOWN_CODE_1, + UNKNOWN_CODE_2, + UNKNOWN_CODE_3, + NORMAL, + ENHANCED, + UNKNOWN_CODE_6, + UNKNOWN_CODE_7, + FIRE, + COLD, + LIGHTNING, + POISON, + DISEASE, + DIVINE, + MAGIC, + SONIC, + ACID, + FORCE, + DEATH, + MIND, + PLANT, + DEFENSIVE, + DEMOLITION, + SLOW_POISON, + SPIRIT_LINK, + SHADOW_STRIKE; + + public static CDamageType[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java new file mode 100644 index 0000000..1d02a97 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java @@ -0,0 +1,13 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CEffectType { + EFFECT, + TARGET, + CASTER, + SPECIAL, + AREA_EFFECT, + MISSILE, + LIGHTNING; + + public static CEffectType[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java new file mode 100644 index 0000000..4e849f1 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java @@ -0,0 +1,22 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CFogState { + MASKED, + FOGGED, + VISIBLE; + + public static CFogState[] VALUES = values(); + + public static CFogState getById(final int id) { + for (final CFogState type : VALUES) { + if ((type.getId()) == id) { + return type; + } + } + return null; + } + + public int getId() { + return 1 << ordinal(); + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java new file mode 100644 index 0000000..ee44d83 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java @@ -0,0 +1,11 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CGameSpeed { + SLOWEST, + SLOW, + NORMAL, + FAST, + FASTEST; + + public static CGameSpeed[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java new file mode 100644 index 0000000..6c068a3 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java @@ -0,0 +1,27 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CGameType { + MELEE, + FFA, + USE_MAP_SETTINGS, + BLIZ, + ONE_ON_ONE, + TWO_TEAM_PLAY, + THREE_TEAM_PLAY, + FOUR_TEAM_PLAY; + + public static CGameType[] VALUES = values(); + + public static CGameType getById(final int id) { + for (final CGameType type : VALUES) { + if ((type.getId()) == id) { + return type; + } + } + return null; + } + + public int getId() { + return 1 << ordinal(); + } +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CLimitOp.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CLimitOp.java new file mode 100644 index 0000000..1a36421 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CLimitOp.java @@ -0,0 +1,12 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CLimitOp { + LESS_THAN, + LESS_THAN_OR_EQUAL, + EQUAL, + GREATER_THAN_OR_EQUAL, + GREATER_THAN, + NOT_EQUAL; + + public static CLimitOp[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java new file mode 100644 index 0000000..0e27016 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CMapDensity { + NONE, + LIGHT, + MEDIUM, + HEAVY; + + public static CMapDensity[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java new file mode 100644 index 0000000..30b1e87 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CMapDifficulty { + EASY, + NORMAL, + HARD, + INSANE; + + public static CMapDifficulty[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java new file mode 100644 index 0000000..2e82cbe --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java @@ -0,0 +1,14 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CPathingTypeJass { + ANY, + WALKABILITY, + FLYABILITY, + BUILDABILITY, + PEONHARVESTPATHING, + BLIGHTPATHING, + FLOATABILITY, + AMPHIBIOUSPATHING; + + public static CPathingTypeJass[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java new file mode 100644 index 0000000..e8c219f --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java @@ -0,0 +1,9 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CPlayerSlotState { + EMPTY, + PLAYING, + LEFT; + + public static CPlayerSlotState[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java new file mode 100644 index 0000000..d67015d --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java @@ -0,0 +1,8 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CRarityControl { + FREQUENT, + RARE; + + public static CRarityControl[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java new file mode 100644 index 0000000..14db526 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java @@ -0,0 +1,8 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CSoundType { + EFFECT, + EFFECT_LOOPED; + + public static CSoundType[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java new file mode 100644 index 0000000..3f22881 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java @@ -0,0 +1,14 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CSoundVolumeGroup { + UNITMOVEMENT, + UNITSOUNDS, + COMBAT, + SPELLS, + UI, + MUSIC, + AMBIENTSOUNDS, + FIRE; + + public static CSoundVolumeGroup[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java new file mode 100644 index 0000000..10dee18 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java @@ -0,0 +1,10 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CTexMapFlags { + NONE, + WRAP_U, + WRAP_V, + WRAP_UV; + + public static CTexMapFlags[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java new file mode 100644 index 0000000..6e8cf22 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java @@ -0,0 +1,8 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CVersion { + REIGN_OF_CHAOS, + FROZEN_THRONE; + + public static CVersion[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java new file mode 100644 index 0000000..f3a6b8f --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java @@ -0,0 +1,40 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; + +public enum CWeaponSoundTypeJass { + WHOKNOWS(null), + METAL_LIGHT_CHOP("MetalLightChop"), + METAL_MEDIUM_CHOP("MetalMediumChop"), + METAL_HEAVY_CHOP("MetalHeavyChop"), + METAL_LIGHT_SLICE("MetalLightSlice"), + METAL_MEDIUM_SLICE("MetalMediumSlice"), + METAL_HEAVY_SLICE("MetalHeavySlice"), + METAL_MEDIUM_BASH("MetalMediumBash"), + METAL_HEAVY_BASH("MetalHeavyBash"), + METAL_MEDIUM_STAB("MetalMediumStab"), + METAL_HEAVY_STAB("MetalHeavyStab"), + WOOD_LIGHT_SLICE("WoodLightSlice"), + WOOD_MEDIUM_SLICE("WoodMediumSlice"), + WOOD_HEAVY_SLICE("WoodHeavySlice"), + WOOD_LIGHT_BASH("WoodLightBash"), + WOOD_MEDIUM_BASH("WoodMediumBash"), + WOOD_HEAVY_BASH("WoodHeavyBash"), + WOOD_LIGHT_STAB("WoodLightStab"), + WOOD_MEDIUM_STAB("WoodMediumStab"), + CLAW_LIGHT_SLICE("ClawLightSlice"), + CLAW_MEDIUM_SLICE("ClawMediumSlice"), + CLAW_HEAVY_SLICE("ClawHeavySlice"), + AXE_MEDIUM_CHOP("AxeMediumChop"), + ROCK_HEAVY_BASH("RockHeavyBash"); + + private final String soundKey; + + CWeaponSoundTypeJass(final String soundKey) { + this.soundKey = soundKey; + } + + public String getSoundKey() { + return this.soundKey; + } + + public static CWeaponSoundTypeJass[] VALUES = values(); +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java new file mode 100644 index 0000000..3092f37 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java @@ -0,0 +1,39 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.unit; + +public enum CUnitTypeJass { + HERO, + DEAD, + STRUCTURE, + + FLYING, + GROUND, + + ATTACKS_FLYING, + ATTACKS_GROUND, + + MELEE_ATTACKER, + RANGED_ATTACKER, + + GIANT, + SUMMONED, + STUNNED, + PLAGUED, + SNARED, + + UNDEAD, + MECHANICAL, + PEON, + SAPPER, + TOWNHALL, + ANCIENT, + + TAUREN, + POISONED, + POLYMORPHED, + SLEEPING, + RESISTANT, + ETHEREAL, + MAGIC_IMMUNE; + + public static CUnitTypeJass[] VALUES = values(); +} 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 290c4c9..20020e4 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 @@ -1163,7 +1163,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma MeleeUI.this.cursorModelInstance = (MdxComplexInstance) model.addInstance(); // MeleeUI.this.cursorModelInstance.setVertexColor(new float[] { 1, 1, 1, 0.5f }); final int playerColorIndex = viewer.simulation - .getPlayer(MeleeUI.this.activeCommandUnit.getSimulationUnit().getPlayerIndex()).getColorIndex(); + .getPlayer(MeleeUI.this.activeCommandUnit.getSimulationUnit().getPlayerIndex()).getColor(); MeleeUI.this.cursorModelInstance.setTeamColor(playerColorIndex); MeleeUI.this.cursorModelInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z, viewer.simulation.getGameplayConstants().getBuildingAngle())); @@ -1534,8 +1534,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma private void repositionRallyPoint(final CUnit simulationUnit) { final AbilityTarget rallyPoint = simulationUnit.getRallyPoint(); if (rallyPoint != null) { - this.rallyPointInstance.setTeamColor( - this.war3MapViewer.simulation.getPlayer(simulationUnit.getPlayerIndex()).getColorIndex()); + this.rallyPointInstance + .setTeamColor(this.war3MapViewer.simulation.getPlayer(simulationUnit.getPlayerIndex()).getColor()); this.rallyPointInstance.show(); this.rallyPointInstance.detach(); rallyPoint.visit(this.rallyPositioningVisitor.reset(this.rallyPointInstance)); @@ -1634,7 +1634,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma } repositionRallyPoint(simulationUnit); repositionWaypointFlags(simulationUnit); - if (simulationUnit.getBuildQueue()[0] != null) { + if ((simulationUnit.getBuildQueue()[0] != null) + && (simulationUnit.getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex())) { for (int i = 0; i < this.queueIconFrames.length; i++) { final QueueItemType queueItemType = simulationUnit.getBuildQueueTypes()[i]; if (queueItemType == null) { @@ -2063,24 +2064,27 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma private void clearAndRepopulateCommandCard() { clearCommandCard(); - final AbilityDataUI abilityDataUI = this.war3MapViewer.getAbilityDataUI(); - final int menuOrderId = getSubMenuOrderId(); - if ((this.activeCommand != null) && (this.draggingItem == null)) { - final IconUI cancelUI = abilityDataUI.getCancelUI(); - this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0, - menuOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, 0); - } - else { - if (menuOrderId != 0) { - final int exitOrderId = this.subMenuOrderIdStack.size() > 1 - ? this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 2) - : 0; + if (this.selectedUnit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { + final AbilityDataUI abilityDataUI = this.war3MapViewer.getAbilityDataUI(); + final int menuOrderId = getSubMenuOrderId(); + if ((this.activeCommand != null) && (this.draggingItem == null)) { final IconUI cancelUI = abilityDataUI.getCancelUI(); this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0, - exitOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, 0); + menuOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, 0); + } + else { + if (menuOrderId != 0) { + final int exitOrderId = this.subMenuOrderIdStack.size() > 1 + ? this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 2) + : 0; + final IconUI cancelUI = abilityDataUI.getCancelUI(); + this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), + 0, exitOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, + 0); + } + this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this.rootFrame, this, + abilityDataUI, menuOrderId); } - this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this.rootFrame, this, abilityDataUI, - menuOrderId); } } @@ -2224,7 +2228,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma } else { if (button == Input.Buttons.RIGHT) { - if (getSelectedUnit() != null) { + if ((getSelectedUnit() != null) && (getSelectedUnit().getSimulationUnit() + .getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex())) { final RenderWidget rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY); if ((rayPickUnit != null) && !rayPickUnit.getSimulationWidget().isDead()) { boolean ordered = false; @@ -2295,19 +2300,21 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma boolean ordered = false; boolean rallied = false; for (final RenderUnit unit : this.selectedUnits) { - for (final CAbility ability : unit.getSimulationUnit().getAbilities()) { - ability.checkCanUse(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, - BooleanAbilityActivationReceiver.INSTANCE); - if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { - ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, - clickLocationTemp2, PointAbilityTargetCheckReceiver.INSTANCE); - final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget(); - if (target != null) { - this.unitOrderListener.issuePointOrder(unit.getSimulationUnit().getHandleId(), - ability.getHandleId(), OrderIds.smart, clickLocationTemp2.x, clickLocationTemp2.y, - isShiftDown()); - rallied |= ability instanceof CAbilityRally; - ordered = true; + if (unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { + for (final CAbility ability : unit.getSimulationUnit().getAbilities()) { + ability.checkCanUse(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, + BooleanAbilityActivationReceiver.INSTANCE); + if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { + ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, + clickLocationTemp2, PointAbilityTargetCheckReceiver.INSTANCE); + final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget(); + if (target != null) { + this.unitOrderListener.issuePointOrder(unit.getSimulationUnit().getHandleId(), + ability.getHandleId(), OrderIds.smart, clickLocationTemp2.x, clickLocationTemp2.y, + isShiftDown()); + rallied |= ability instanceof CAbilityRally; + ordered = true; + } } } } @@ -2345,33 +2352,38 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma if (selectionChanged) { this.selectedSoundCount = 0; } - if (unit.soundset != null) { - UnitSound ackSoundToPlay = unit.soundset.what; - int soundIndex; - final int pissedSoundCount = unit.soundset.pissed.getSoundCount(); - if (unit.getSimulationUnit().isConstructing()) { - ackSoundToPlay = this.war3MapViewer.getUiSounds() - .getSound(this.rootFrame.getSkinField("ConstructingBuilding")); - soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount()); - } - else { - if ((this.selectedSoundCount >= 3) && (pissedSoundCount > 0)) { - soundIndex = this.selectedSoundCount - 3; - ackSoundToPlay = unit.soundset.pissed; - } - else { + if (unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { + if (unit.soundset != null) { + UnitSound ackSoundToPlay = unit.soundset.what; + int soundIndex; + final int pissedSoundCount = unit.soundset.pissed.getSoundCount(); + if (unit.getSimulationUnit().isConstructing()) { + ackSoundToPlay = this.war3MapViewer.getUiSounds() + .getSound(this.rootFrame.getSkinField("ConstructingBuilding")); soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount()); } - } - if ((ackSoundToPlay != null) && ackSoundToPlay - .playUnitResponse(this.war3MapViewer.worldScene.audioContext, unit, soundIndex)) { - this.selectedSoundCount++; - if ((this.selectedSoundCount - 3) >= pissedSoundCount) { - this.selectedSoundCount = 0; + else { + if ((this.selectedSoundCount >= 3) && (pissedSoundCount > 0)) { + soundIndex = this.selectedSoundCount - 3; + ackSoundToPlay = unit.soundset.pissed; + } + else { + soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount()); + } + } + if ((ackSoundToPlay != null) && ackSoundToPlay + .playUnitResponse(this.war3MapViewer.worldScene.audioContext, unit, soundIndex)) { + this.selectedSoundCount++; + if ((this.selectedSoundCount - 3) >= pissedSoundCount) { + this.selectedSoundCount = 0; + } + playedNewSound = true; } - playedNewSound = true; } } + else { + this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0, 0); + } if (selectionChanged) { selectUnit(unit); } diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java b/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java index ded54e9..e9799ed 100644 --- a/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java +++ b/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java @@ -3,6 +3,8 @@ package com.etheller.interpreter.ast.scope; import com.etheller.interpreter.ast.scope.trigger.Trigger; public class TriggerExecutionScope { + public static final TriggerExecutionScope EMPTY = new TriggerExecutionScope(null); + private final Trigger triggeringTrigger; public TriggerExecutionScope(final Trigger triggeringTrigger) { diff --git a/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java index d37c98f..9cbcbb8 100644 --- a/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java +++ b/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java @@ -3,12 +3,18 @@ package com.etheller.interpreter.ast.value; public class StringJassValue implements JassValue { private final String value; + public static StringJassValue of(final String value) { + // later this could do that dumb thing jass does with making sure we dont create + // duplicate instances, maybe + return new StringJassValue(value); + } + public StringJassValue(final String value) { this.value = value; } public String getValue() { - return value; + return this.value; } @Override