Hero skills tested with holy light, human build, other updates

This commit is contained in:
Retera 2022-01-21 18:32:04 -05:00
parent b4f67eb1e5
commit ba2291f572
161 changed files with 4544 additions and 815 deletions

View File

@ -39,6 +39,15 @@ allprojects {
}
}
project(":server") {
apply plugin: "java"
dependencies {
compile project(":shared")
}
}
project(":desktop") {
apply plugin: "java"
@ -62,6 +71,7 @@ project(":core") {
dependencies {
compile project(":shared")
compile project(":fdfparser")
compile project(":jassparser")
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
@ -75,6 +85,14 @@ project(":core") {
}
}
project(":shared") {
apply plugin: "java"
dependencies {
}
}
project(":fdfparser") {
apply plugin: "antlr"

View File

@ -2,4 +2,8 @@ package com.etheller.warsmash;
public interface SingleModelScreen {
void setModel(String path);
void alternateModelToBattlenet();
void unAlternateModelBackToNormal();
}

View File

@ -865,4 +865,16 @@ public class WarsmashGdxFDFTestRenderScreen implements InputProcessor, Screen, S
@Override
public void resume() {
}
@Override
public void alternateModelToBattlenet() {
System.err.println(
"alternateModelToBattlenet() on background not supported for FDF test render screen... TODO write better code here");
}
@Override
public void unAlternateModelBackToNormal() {
System.err.println(
"alternateModelToBattlenet() on background not supported for FDF test render screen... TODO write better code here");
}
}

View File

@ -193,7 +193,7 @@ public class WarsmashGdxMapScreen implements InputProcessor, Screen {
this.viewer.getCommandErrorListener().setDelegate(this.meleeUI);
final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "",
this.viewer.mapPathSolver, "").addInstance();
libgdxContentInstance.setLocation(0f, 0f, 0.5f);
libgdxContentInstance.setLocation(0f, 0f, -0.5f);
libgdxContentInstance.setScene(this.uiScene);
this.meleeUI.main();

View File

@ -5,11 +5,11 @@ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.EnumSet;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.OrthographicCamera;
@ -27,7 +27,6 @@ import com.etheller.warsmash.datasources.DataSource;
import com.etheller.warsmash.parsers.fdf.GameUI;
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
import com.etheller.warsmash.units.DataTable;
import com.etheller.warsmash.util.DataSourceFileHandle;
import com.etheller.warsmash.util.ImageUtils;
import com.etheller.warsmash.util.StringBundle;
import com.etheller.warsmash.util.WarsmashConstants;
@ -48,6 +47,8 @@ import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer;
import com.etheller.warsmash.viewer5.handlers.mdx.Sequence;
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag;
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
import com.etheller.warsmash.viewer5.handlers.w3x.ui.MenuUI;
@ -71,9 +72,9 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
private Texture solidGreenTexture;
private MenuUI menuUI;
private final WarsmashGdxMultiScreenGame game;
private Music currentMusic;
private boolean hasPlayedStandHack = false;
private boolean loaded = false;
private EnumSet<SecondaryTag> tags = SequenceUtils.EMPTY;
public WarsmashGdxMenuScreen(final DataTable warsmashIni, final WarsmashGdxMultiScreenGame game) {
this.warsmashIni = warsmashIni;
@ -196,25 +197,6 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
public void onCreate(final GameUI rootFrame) {
// WarsmashGdxMapGame.this.viewer.setGameUI(rootFrame);
if (WarsmashConstants.ENABLE_MUSIC) {
final String musicField = rootFrame
.getSkinField("GlueMusic_V" + WarsmashConstants.GAME_VERSION);
final String[] musics = musicField.split(";");
String musicPath = musics[(int) (Math.random() * musics.length)];
if (musicSLK.get(musicPath) != null) {
musicPath = musicSLK.get(musicPath).getField("FileNames");
}
final String[] moreSplitMusics = musicPath.split(",");
final String finalMusicPath = moreSplitMusics[(int) (Math.random()
* moreSplitMusics.length)];
final Music music = Gdx.audio.newMusic(new DataSourceFileHandle(
WarsmashGdxMenuScreen.this.viewer.dataSource, finalMusicPath));
// music.setVolume(0.2f);
music.setLooping(true);
music.play();
WarsmashGdxMenuScreen.this.currentMusic = music;
}
singleModelScene(WarsmashGdxMenuScreen.this.scene, War3MapViewer.mdx(rootFrame
.getSkinField("GlueSpriteLayerBackground_V" + WarsmashConstants.GAME_VERSION)),
"Stand");
@ -242,9 +224,7 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
}
Gdx.input.setInputProcessor(this);
if (this.currentMusic != null) {
this.currentMusic.play();
}
this.menuUI.show();
}
@ -369,6 +349,24 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
}
@Override
public void alternateModelToBattlenet() {
if (this.mainInstance != null) {
SequenceUtils.randomSequence(this.mainInstance, PrimaryTag.STAND, SequenceUtils.ALTERNATE, true);
this.tags = SequenceUtils.ALTERNATE;
this.hasPlayedStandHack = false;
}
}
@Override
public void unAlternateModelBackToNormal() {
if (this.mainInstance != null) {
SequenceUtils.randomSequence(this.mainInstance, PrimaryTag.MORPH, SequenceUtils.ALTERNATE, true);
this.tags = SequenceUtils.EMPTY;
this.hasPlayedStandHack = false;
}
}
private void acolytesHarvestingScene(final Scene scene) {
final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx",
@ -569,7 +567,7 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
if ((this.mainInstance != null) && this.mainInstance.sequenceEnded
&& (((this.mainModel.getSequences().get(this.mainInstance.sequence).getFlags() & 0x1) == 0)
|| !this.hasPlayedStandHack)) {
SequenceUtils.randomStandSequence(this.mainInstance);
SequenceUtils.randomSequence(this.mainInstance, PrimaryTag.STAND, this.tags, true);
this.hasPlayedStandHack = true;
}
this.viewer.updateAndRender();
@ -784,6 +782,7 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
private void renderLibGDXContent() {
Gdx.gl30.glClear(GL30.GL_DEPTH_BUFFER_BIT);
Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST);
Gdx.gl30.glDisable(GL30.GL_CULL_FACE);
@ -889,9 +888,6 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
@Override
public void hide() {
if (this.currentMusic != null) {
this.currentMusic.stop();
}
this.menuUI.hide();
}

View File

@ -9,11 +9,12 @@ import java.util.Map;
import java.util.Queue;
import com.badlogic.gdx.Gdx;
import com.etheller.warsmash.networking.udp.OrderedUdpClient;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderExecutor;
import net.warsmash.networking.udp.OrderedUdpClient;
public class WarsmashClient implements ServerToClientListener, GameTurnManager {
private final OrderedUdpClient udpClient;
private final War3MapViewer game;

View File

@ -2,7 +2,7 @@ package com.etheller.warsmash.networking;
import java.nio.ByteBuffer;
import com.etheller.warsmash.networking.udp.OrderedUdpClientListener;
import net.warsmash.networking.udp.OrderedUdpClientListener;
public class WarsmashClientParser implements OrderedUdpClientListener {
private final ServerToClientListener listener;

View File

@ -4,7 +4,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.etheller.warsmash.networking.udp.OrderedUdpClient;
import net.warsmash.networking.udp.OrderedUdpClient;
public class WarsmashClientWriter {
private final OrderedUdpClient client;

View File

@ -8,9 +8,10 @@ import java.util.List;
import java.util.Map;
import java.util.Scanner;
import com.etheller.warsmash.networking.udp.OrderedUdpServer;
import com.etheller.warsmash.util.WarsmashConstants;
import net.warsmash.networking.udp.OrderedUdpServer;
public class WarsmashServer implements ClientToServerListener {
private static final int MAGIC_DELAY_OFFSET = 4;
private final OrderedUdpServer udpServer;

View File

@ -4,7 +4,7 @@ import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import com.etheller.warsmash.networking.udp.OrderedUdpServerListener;
import net.warsmash.networking.udp.OrderedUdpServerListener;
public class WarsmashServerParser implements OrderedUdpServerListener {

View File

@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Set;
import com.etheller.warsmash.networking.udp.OrderedUdpServer;
import net.warsmash.networking.udp.OrderedUdpServer;
public class WarsmashServerWriter implements ServerToClientListener {
private final OrderedUdpServer server;

View File

@ -0,0 +1,8 @@
package com.etheller.warsmash.networking.uberserver;
import net.warsmash.nio.channels.WritableOutput;
import net.warsmash.uberserver.GamingNetworkServerToClientListener;
public interface GamingNetworkServerClientBuilder {
GamingNetworkServerToClientListener createClient(WritableOutput output);
}

View File

@ -0,0 +1,52 @@
package com.etheller.warsmash.networking.uberserver;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import net.warsmash.nio.channels.ChannelOpener;
import net.warsmash.nio.channels.SocketChannelCallback;
import net.warsmash.nio.channels.WritableOutput;
import net.warsmash.nio.channels.tcp.TCPClientParser;
import net.warsmash.nio.util.ExceptionListener;
import net.warsmash.uberserver.GamingNetwork;
public class TCPGamingNetworkServer {
private final ChannelOpener channelOpener;
public TCPGamingNetworkServer(final ChannelOpener channelOpener) {
this.channelOpener = channelOpener;
}
public void start() {
this.channelOpener.openTCPServerChannel(GamingNetwork.PORT, new SocketChannelCallback() {
@Override
public TCPClientParser onConnect(final WritableOutput writableOpenedChannel,
final SocketAddress remoteAddress) {
System.out.println("Received connection from " + remoteAddress);
return new TCPClientParser() {
@Override
public void parse(final ByteBuffer data) {
System.out.println("Got " + data.remaining() + " bytes from " + remoteAddress);
if (data.hasRemaining()) {
System.out.print("[");
System.out.print(data.get());
while (data.hasRemaining()) {
System.out.print(", ");
System.out.print(data.get());
}
System.out.println("]");
}
writableOpenedChannel.write(ByteBuffer.wrap("reply".getBytes()));
}
@Override
public void disconnected() {
System.out.println("Disconnected from " + remoteAddress);
}
};
}
}, ExceptionListener.THROW_RUNTIME, 8 * 1024 * 1024, ByteOrder.BIG_ENDIAN);
}
}

View File

@ -0,0 +1,76 @@
package com.etheller.warsmash.networking.uberserver;
import java.nio.ByteBuffer;
import com.etheller.warsmash.util.War3ID;
import net.warsmash.nio.channels.tcp.TCPClientParser;
import net.warsmash.uberserver.GamingNetworkClientToServerListener;
public class TCPGamingNetworkServerClientParser implements TCPClientParser {
private final GamingNetworkClientToServerListener listener;
public TCPGamingNetworkServerClientParser(final GamingNetworkClientToServerListener listener) {
this.listener = listener;
}
@Override
public void parse(final ByteBuffer data) {
while (data.remaining() > 8) {
final int protocolMessageId = data.getInt(data.position() + 0);
final int length = data.getInt(data.position() + 4);
if (data.remaining() >= length) {
data.position(data.position() + 8);
switch (protocolMessageId) {
case GamingNetworkClientToServerListener.Protocol.HANDSHAKE: {
final int gameIdInt = data.getInt();
final int gameVersion = data.getInt();
this.listener.handshake(new War3ID(gameIdInt).toString(), gameVersion);
break;
}
case GamingNetworkClientToServerListener.Protocol.CREATE_ACCOUNT: {
final String username = readString(64, data);
final String password = readString(1024, data);
this.listener.createAccount(username, password);
break;
}
case GamingNetworkClientToServerListener.Protocol.LOGIN: {
final String username = readString(64, data);
final String password = readString(1024, data);
this.listener.login(username, password);
break;
}
case GamingNetworkClientToServerListener.Protocol.JOIN_CHANNEL: {
final String channelName = readString(256, data);
this.listener.joinChannel(channelName);
break;
}
case GamingNetworkClientToServerListener.Protocol.CHAT_MESSAGE: {
final String text = readString(256, data);
this.listener.chatMessage(text);
break;
}
case GamingNetworkClientToServerListener.Protocol.EMOTE_MESSAGE: {
final String text = readString(256, data);
this.listener.emoteMessage(text);
break;
}
}
}
}
}
public String readString(final int maxLength, final ByteBuffer data) {
final int usernameStringLength = Math.min(maxLength, data.getInt());
final byte[] usernameStringBytes = new byte[usernameStringLength];
data.get(usernameStringBytes);
final String username = new String(usernameStringBytes);
return username;
}
@Override
public void disconnected() {
this.listener.disconnected();
}
}

View File

@ -0,0 +1,55 @@
package com.etheller.warsmash.networking.udp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import com.etheller.warsmash.util.WarsmashConstants;
import net.warsmash.networking.udp.UdpClient;
import net.warsmash.networking.udp.UdpClientListener;
public class UdpClientTestMain {
static UdpClient warsmashUdpClient;
public static void main(final String[] args) {
try {
warsmashUdpClient = new UdpClient(InetAddress.getLocalHost(), WarsmashConstants.PORT_NUMBER,
new UdpClientListener() {
@Override
public void parse(final ByteBuffer buffer) {
System.out.println("got " + buffer.remaining() + " bytes, pos=" + buffer.position()
+ ", lim=" + buffer.limit());
System.out.println("got from server: " + buffer.getInt());
}
});
new Thread(warsmashUdpClient).start();
final ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
for (int i = 0; i < 10; i++) {
sendBuffer.clear();
sendBuffer.put((byte) (1 + i));
sendBuffer.put((byte) 3);
sendBuffer.put((byte) 5);
sendBuffer.put((byte) 7);
sendBuffer.flip();
warsmashUdpClient.send(sendBuffer);
try {
Thread.sleep(1000);
}
catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
catch (final UnknownHostException e) {
e.printStackTrace();
}
catch (final IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,46 @@
package com.etheller.warsmash.networking.udp;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import com.etheller.warsmash.util.WarsmashConstants;
import net.warsmash.networking.udp.UdpServer;
import net.warsmash.networking.udp.UdpServerListener;
public class UdpServerTestMain {
static UdpServer warsmashGameServer;
public static void main(final String[] args) {
try {
warsmashGameServer = new UdpServer(WarsmashConstants.PORT_NUMBER, new UdpServerListener() {
int n = 0;
ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
@Override
public void parse(final SocketAddress sourceAddress, final ByteBuffer buffer) {
System.out.println("Got packet from: " + sourceAddress);
while (buffer.hasRemaining()) {
System.out.println("Received: " + buffer.get());
}
try {
this.sendBuffer.clear();
this.sendBuffer.putInt(this.n++);
this.sendBuffer.flip();
warsmashGameServer.send(sourceAddress, this.sendBuffer);
}
catch (final IOException e) {
e.printStackTrace();
}
}
});
new Thread(warsmashGameServer).start();
}
catch (final IOException e) {
e.printStackTrace();
}
}
}

View File

@ -27,6 +27,7 @@ import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition;
import com.etheller.warsmash.parsers.fdf.datamodel.BackdropCornerFlags;
import com.etheller.warsmash.parsers.fdf.datamodel.ControlStyle;
import com.etheller.warsmash.parsers.fdf.datamodel.FontDefinition;
import com.etheller.warsmash.parsers.fdf.datamodel.FontFlags;
import com.etheller.warsmash.parsers.fdf.datamodel.FrameClass;
import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition;
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
@ -65,6 +66,7 @@ import com.etheller.warsmash.units.Element;
import com.etheller.warsmash.units.custom.WTS;
import com.etheller.warsmash.util.ImageUtils;
import com.etheller.warsmash.util.StringBundle;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.Scene;
import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer;
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
@ -235,19 +237,37 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
}
public String getSkinField(String file) {
if ((file != null) && this.skin.hasField(file)) {
if (file == null) {
throw new NullPointerException("file is null");
}
if (this.skin.hasField(file)) {
file = this.skin.getField(file);
}
else {
throw new IllegalStateException("Decorated file name lookup not available: " + file);
final String fieldVersioned = file + "_V" + WarsmashConstants.GAME_VERSION;
if (this.skin.hasField(fieldVersioned)) {
file = this.skin.getField(fieldVersioned);
}
else {
throw new IllegalStateException("Decorated file name lookup not available: " + file);
}
}
return file;
}
public String trySkinField(String file) {
if ((file != null) && this.skin.hasField(file)) {
if (file == null) {
throw new NullPointerException("file is null");
}
if (this.skin.hasField(file)) {
file = this.skin.getField(file);
}
else {
final String fieldVersioned = file + "_V" + WarsmashConstants.GAME_VERSION;
if (this.skin.hasField(fieldVersioned)) {
file = this.skin.getField(fieldVersioned);
}
}
return file;
}
@ -447,6 +467,12 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
}
}
String fontFlagsString = frameDefinition.getString("FontFlags");
if (fontFlagsString == null) {
fontFlagsString = "";
}
final EnumSet<FontFlags> fontFlags = FontFlags.parseFontFlags(fontFlagsString);
Color fontColor;
final Vector4Definition fontColorDefinition = frameDefinition.getVector4("FontColor");
if (fontColorDefinition == null) {
@ -511,6 +537,9 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
}
final StringFrame stringFrame = new StringFrame(frameDefinition.getName(), parent, fontColor, justifyH,
justifyV, frameFont, textString, fontHighlightColor, fontDisabledColor);
if (fontFlags.contains(FontFlags.PASSWORDFIELD)) {
stringFrame.setPasswordField(true);
}
if (fontShadowColor != null) {
final Vector2Definition shadowOffset = frameDefinition.getVector2("FontShadowOffset");
stringFrame.setFontShadowColor(fontShadowColor);

View File

@ -358,6 +358,11 @@ public abstract class AbstractRenderableFrame implements UIFrame {
return this.parent;
}
@Override
public void setParent(final UIFrame parent) {
this.parent = parent;
}
@Override
public boolean isVisibleOnScreen() {
boolean visibleOnScreen = this.visible;

View File

@ -56,9 +56,10 @@ public class EditBoxFrame extends AbstractRenderableFrame implements FocusableFr
if ((time % 500) > 250) {
final BitmapFont frameFont = this.editTextFrame.getFrameFont();
frameFont.setColor(this.editCursorColor);
final int cursorRenderPosition = Math.min(this.cursorIndex, this.editTextFrame.getText().length());
final int cursorRenderPosition = Math.min(this.cursorIndex,
this.editTextFrame.getDisplayText().length());
this.cursorIndex = cursorRenderPosition;
glyphLayout.setText(frameFont, this.editTextFrame.getText().substring(0, cursorRenderPosition));
glyphLayout.setText(frameFont, this.editTextFrame.getDisplayText().substring(0, cursorRenderPosition));
final float cursorXOffset = glyphLayout.width;
glyphLayout.setText(frameFont, "|");
frameFont.draw(batch, "|",
@ -125,7 +126,7 @@ public class EditBoxFrame extends AbstractRenderableFrame implements FocusableFr
@Override
public boolean keyTyped(final char character) {
if (Character.isAlphabetic(character) || Character.isDigit(character)) {
if (Character.isAlphabetic(character) || Character.isDigit(character) || (character == ' ')) {
final String prevText = this.editTextFrame.getText();
final int prevTextLength = prevText.length();
final int cursorIndex = Math.min(this.cursorIndex, prevTextLength);

View File

@ -19,6 +19,7 @@ public class StringFrame extends AbstractRenderableFrame {
private final List<SingleStringFrame> internalFrames = new ArrayList<>();
private Color color;
private String text = "Default string";
private String displayText = this.text;
private final TextJustify justifyH;
private TextJustify justifyV;
private final BitmapFont frameFont;
@ -34,6 +35,7 @@ public class StringFrame extends AbstractRenderableFrame {
private final Color fontHighlightColor;
private final Color fontDisabledColor;
private final Color fontColor;
private boolean passwordField;
public StringFrame(final String name, final UIFrame parent, final Color color, final TextJustify justifyH,
final TextJustify justifyV, final BitmapFont frameFont, final String text, final Color fontHighlightColor,
@ -45,6 +47,7 @@ public class StringFrame extends AbstractRenderableFrame {
this.justifyV = justifyV;
this.frameFont = frameFont;
this.text = text;
this.displayText = text;
this.fontHighlightColor = fontHighlightColor;
this.fontDisabledColor = fontDisabledColor;
this.internalFramesContainer = new SimpleFrame(null, this);
@ -58,11 +61,25 @@ public class StringFrame extends AbstractRenderableFrame {
return this.text;
}
public String getDisplayText() {
return this.displayText;
}
public void setText(final String text, final GameUI gameUI, final Viewport viewport) {
if (text == null) {
throw new IllegalArgumentException();
}
this.text = text;
if (this.passwordField) {
final StringBuilder displayTextBuilder = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
displayTextBuilder.append('*');
}
this.displayText = displayTextBuilder.toString();
}
else {
this.displayText = text;
}
positionBounds(gameUI, viewport);
}
@ -162,20 +179,21 @@ public class StringFrame extends AbstractRenderableFrame {
final float startingBoundsWidth = getAssignedWidth();
final boolean firstInLine = false;
Color currentColor = this.color;
for (int i = 0; i < this.text.length(); i++) {
final char c = this.text.charAt(i);
final String displayTextToUse = this.displayText;
for (int i = 0; i < displayTextToUse.length(); i++) {
final char c = displayTextToUse.charAt(i);
switch (c) {
case '|': {
// special control character
if ((i + 1) < this.text.length()) {
final char escapedCharacter = this.text.charAt(i + 1);
if ((i + 1) < displayTextToUse.length()) {
final char escapedCharacter = displayTextToUse.charAt(i + 1);
switch (escapedCharacter) {
case 'c':
case 'C':
if ((i + 9) < this.text.length()) {
if ((i + 9) < displayTextToUse.length()) {
int colorInt;
try {
final String upperCase = this.text.substring(i + 2, i + 10).toUpperCase();
final String upperCase = displayTextToUse.substring(i + 2, i + 10).toUpperCase();
colorInt = (int) Long.parseLong(upperCase, 16);
}
catch (final NumberFormatException exc) {
@ -507,4 +525,8 @@ public class StringFrame extends AbstractRenderableFrame {
public BitmapFont getFrameFont() {
return this.frameFont;
}
public void setPasswordField(final boolean passwordField) {
this.passwordField = passwordField;
}
}

View File

@ -41,6 +41,8 @@ public interface UIFrame {
UIFrame getParent();
void setParent(UIFrame parent);
boolean isVisible();
boolean isVisibleOnScreen();

View File

@ -2342,22 +2342,7 @@ public class Jass2 {
final boolean random = arguments.get(1).visit(BooleanJassValueVisitor.getInstance());
final int index = arguments.get(2).visit(IntegerJassValueVisitor.getInstance());
String musicField;
if (!CommonEnvironment.this.gameUI.hasSkinField(musicName)) {
// TODO this versioning system should probably be more general case than this,
// maybe at the level
// of skin field lookup???
final String versionedMusic = "Music_V" + WarsmashConstants.GAME_VERSION;
if (!CommonEnvironment.this.gameUI.hasSkinField(versionedMusic)) {
musicField = musicName;
}
else {
musicField = CommonEnvironment.this.gameUI.getSkinField(versionedMusic);
}
}
else {
musicField = CommonEnvironment.this.gameUI.getSkinField(musicName);
}
final String musicField = CommonEnvironment.this.gameUI.trySkinField(musicName);
meleeUI.playMusic(musicField, random, index);
return null;
}
@ -2368,22 +2353,7 @@ public class Jass2 {
final TriggerExecutionScope triggerScope) {
final String musicName = arguments.get(0).visit(StringJassValueVisitor.getInstance());
String musicField;
if (!CommonEnvironment.this.gameUI.hasSkinField(musicName)) {
// TODO this versioning system should probably be more general case than this,
// maybe at the level
// of skin field lookup???
final String versionedMusic = "Music_V" + WarsmashConstants.GAME_VERSION;
if (!CommonEnvironment.this.gameUI.hasSkinField(versionedMusic)) {
musicField = musicName;
}
else {
musicField = CommonEnvironment.this.gameUI.getSkinField(versionedMusic);
}
}
else {
musicField = CommonEnvironment.this.gameUI.getSkinField(musicName);
}
final String musicField = CommonEnvironment.this.gameUI.trySkinField(musicName);
meleeUI.playMusic(musicField, true, 0);
return null;
}
@ -2489,8 +2459,9 @@ public class Jass2 {
final double x = arguments.get(2).visit(RealJassValueVisitor.getInstance());
final double y = arguments.get(3).visit(RealJassValueVisitor.getInstance());
final double facing = arguments.get(4).visit(RealJassValueVisitor.getInstance());
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(new War3ID(rawcode),
player.getId(), (float) x, (float) y, (float) facing);
final War3ID rawcodeId = new War3ID(rawcode);
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(rawcodeId, player.getId(),
(float) x, (float) y, (float) facing);
final CUnitType newUnitType = newUnit.getUnitType();
final int foodUsed = newUnitType.getFoodUsed();
newUnit.setFoodUsed(foodUsed);
@ -2498,6 +2469,7 @@ public class Jass2 {
if (newUnitType.getFoodMade() != 0) {
player.setFoodCap(player.getFoodCap() + newUnitType.getFoodMade());
}
player.addTechtreeUnlocked(rawcodeId);
// nudge unit
newUnit.setPointAndCheckUnstuck((float) x, (float) y, CommonEnvironment.this.simulation);
return new HandleJassValue(unitType, newUnit);
@ -2513,8 +2485,9 @@ public class Jass2 {
final double y = arguments.get(3).visit(RealJassValueVisitor.getInstance());
final double facing = arguments.get(4).visit(RealJassValueVisitor.getInstance());
final int skinId = arguments.get(5).visit(IntegerJassValueVisitor.getInstance());
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(new War3ID(rawcode),
player.getId(), (float) x, (float) y, (float) facing);
final War3ID rawcodeId = new War3ID(rawcode);
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(rawcodeId, player.getId(),
(float) x, (float) y, (float) facing);
final CUnitType newUnitType = newUnit.getUnitType();
final int foodUsed = newUnitType.getFoodUsed();
newUnit.setFoodUsed(foodUsed);
@ -2522,6 +2495,7 @@ public class Jass2 {
if (newUnitType.getFoodMade() != 0) {
player.setFoodCap(player.getFoodCap() + newUnitType.getFoodMade());
}
player.addTechtreeUnlocked(rawcodeId);
// nudge unit
newUnit.setPointAndCheckUnstuck((float) x, (float) y, CommonEnvironment.this.simulation);
if (skinId != rawcode) {
@ -2540,8 +2514,9 @@ public class Jass2 {
final int rawcode = arguments.get(1).visit(IntegerJassValueVisitor.getInstance());
final Point2D.Double whichLocation = arguments.get(2).visit(ObjectJassValueVisitor.getInstance());
final float facing = arguments.get(3).visit(RealJassValueVisitor.getInstance()).floatValue();
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(new War3ID(rawcode),
player.getId(), (float) whichLocation.x, (float) whichLocation.y, facing);
final War3ID rawcodeId = new War3ID(rawcode);
final CUnit newUnit = CommonEnvironment.this.simulation.createUnit(rawcodeId, player.getId(),
(float) whichLocation.x, (float) whichLocation.y, facing);
final CUnitType newUnitType = newUnit.getUnitType();
final int foodUsed = newUnitType.getFoodUsed();
newUnit.setFoodUsed(foodUsed);
@ -2549,6 +2524,7 @@ public class Jass2 {
if (newUnitType.getFoodMade() != 0) {
player.setFoodCap(player.getFoodCap() + newUnitType.getFoodMade());
}
player.addTechtreeUnlocked(rawcodeId);
// nudge unit
newUnit.setPointAndCheckUnstuck((float) whichLocation.x, (float) whichLocation.y,
CommonEnvironment.this.simulation);
@ -2560,12 +2536,14 @@ public class Jass2 {
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
// TODO this needs to setup a non-blighted mine underneath!!!
final CPlayerJass player = arguments.get(0).visit(ObjectJassValueVisitor.getInstance());
final CPlayer player = arguments.get(0).visit(ObjectJassValueVisitor.getInstance());
final double x = arguments.get(1).visit(RealJassValueVisitor.getInstance());
final double y = arguments.get(2).visit(RealJassValueVisitor.getInstance());
final double facing = arguments.get(3).visit(RealJassValueVisitor.getInstance());
return new HandleJassValue(unitType, CommonEnvironment.this.simulation.createUnit(
War3ID.fromString("ugol"), player.getId(), (float) x, (float) y, (float) facing));
final War3ID blightedMineRawcode = War3ID.fromString("ugol");
player.addTechtreeUnlocked(blightedMineRawcode);
return new HandleJassValue(unitType, CommonEnvironment.this.simulation
.createUnit(blightedMineRawcode, player.getId(), (float) x, (float) y, (float) facing));
}
});
jassProgramVisitor.getJassNativeManager().createNative("SetUnitColor", new JassFunction() {
@ -3796,7 +3774,10 @@ public class Jass2 {
for (final CUnit unit : units) {
if (unit.getPlayerIndex() == whichPlayer.getId()) {
if (legacySystemUnitTypeName.equals(unit.getUnitType().getLegacyName())) {
if (includeIncomplete || !unit.isConstructing()) {
if ((includeIncomplete || !unit.isConstructing())
&& (includeUpgrades || !unit.isUpgrading())) {
// TODO this might not actually be what includeUpgrades means, it probably means
// to include higher tier of hall when asked for lower tier type ID
count++;
}
}
@ -4724,6 +4705,18 @@ public class Jass2 {
return null;
}
});
jassProgramVisitor.getJassNativeManager().createNative("GetPlayerAlliance", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
final TriggerExecutionScope triggerScope) {
final CPlayerJass player = arguments.get(0).visit(ObjectJassValueVisitor.<CPlayerJass>getInstance());
final CPlayerJass otherPlayer = arguments.get(1)
.visit(ObjectJassValueVisitor.<CPlayerJass>getInstance());
final CAllianceType whichAllianceSetting = arguments.get(2)
.visit(ObjectJassValueVisitor.<CAllianceType>getInstance());
return BooleanJassValue.of(player.hasAlliance(otherPlayer.getId(), whichAllianceSetting));
}
});
jassProgramVisitor.getJassNativeManager().createNative("SetPlayerTaxRate", new JassFunction() {
@Override
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,

View File

@ -183,6 +183,11 @@ public class Element extends HashedGameObject {
return name;
}
@Override
public String getLegacyName() {
return null;
}
public void addParent(final String parentId) {
String parentField = getField("Parents");
if (!parentField.contains(parentId)) {

View File

@ -30,6 +30,8 @@ public interface GameObject {
public String getName();
public String getLegacyName();
public Set<String> keySet();
GameObject EMPTY = new GameObject() {
@ -96,6 +98,11 @@ public interface GameObject {
public String getField(final String field) {
return "";
}
@Override
public String getLegacyName() {
return "custom_0000";
}
};
}

View File

@ -562,6 +562,21 @@ public class StandardObjectData {
return this.dataSource;
}
@Override
public String getLegacyName() {
final DataTable dataTable = this.dataSource.tableMap.get(new StringKey("UnitUI"));
if (dataTable != null) {
final Element element = dataTable.get(this.id);
if (element != null) {
return element.getField("name");
}
else {
return null;
}
}
return null;
}
// @Override
// public String getName() {
// return dataSource.profile.get(id).getName();

View File

@ -745,6 +745,16 @@ public final class MutableObjectData {
return name;
}
public String getLegacyName() {
if (!isCustom()) {
final String legacyNameIfAvailable = this.parentWC3Object.getLegacyName();
if (legacyNameIfAvailable != null) {
return legacyNameIfAvailable;
}
}
return "custom_" + getAlias().toString();
}
private String getFieldStringFromSLKs(final War3ID field, final int level) {
final GameObject metaData = MutableObjectData.this.sourceSLKMetaData.get(field.asStringValue());
if (metaData == null) {

View File

@ -0,0 +1,7 @@
package com.etheller.warsmash.util;
public class Test3 {
public static void main(final String[] args) {
System.out.println(new War3ID(1786017909));
}
}

View File

@ -25,9 +25,9 @@ public class WarsmashConstants {
// find it yet so I used this
public static final String DEFAULT_STRING = "Default string";
public static final boolean CATCH_CURSOR = false;
public static final boolean VERBOSE_LOGGING = true;
public static final boolean ENABLE_DEBUG = true;
public static final boolean CATCH_CURSOR = true;
public static final boolean VERBOSE_LOGGING = false;
public static final boolean ENABLE_DEBUG = false;
public static final char SPECIAL_ESCAPE_KEYCODE = 0x7E;
// My tileset loader is "always on top", even for local files. This is different
@ -36,7 +36,7 @@ public class WarsmashConstants {
// workaround to fix it if you need the local files
// to take priority over built-ins for tilesets.
public static final boolean FIX_FLAT_FILES_TILESET_LOADING = false;
public static final boolean ENABLE_MUSIC = false;
public static final boolean ENABLE_MUSIC = true;
public static final boolean LOAD_UNITS_FROM_WORLDEDIT_DATA = false;
public static final boolean CRASH_ON_INCOMPATIBLE_132_FEATURES = false;
public static final boolean FIRE_DEATH_EVENTS_ON_REMOVEUNIT = false;

View File

@ -316,19 +316,7 @@ public abstract class ModelViewer {
public void render() {
for (final Scene scene : this.scenes) {
scene.startFrame();
}
this.renderOpaque();
this.renderTranslucent();
}
private void renderOpaque() {
for (final Scene scene : this.scenes) {
scene.renderOpaque();
}
}
private void renderTranslucent() {
for (final Scene scene : this.scenes) {
scene.renderTranslucent();
}
}

View File

@ -240,6 +240,9 @@ public abstract class Scene {
gl.glDepthMask(true);
gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
}
else {
Gdx.gl30.glClear(GL30.GL_DEPTH_BUFFER_BIT);
}
this.lightManager.update();
}

View File

@ -21,6 +21,7 @@ public class SequenceUtils {
public static final EnumSet<SecondaryTag> SPELL = EnumSet.of(SecondaryTag.SPELL);
public static final EnumSet<SecondaryTag> WORK = EnumSet.of(SecondaryTag.WORK);
public static final EnumSet<SecondaryTag> FAST = EnumSet.of(SecondaryTag.FAST);
public static final EnumSet<SecondaryTag> ALTERNATE = EnumSet.of(SecondaryTag.ALTERNATE);
private static final StandSequenceComparator STAND_SEQUENCE_COMPARATOR = new StandSequenceComparator();
private static final SecondaryTagSequenceComparator SECONDARY_TAG_SEQUENCE_COMPARATOR = new SecondaryTagSequenceComparator(

View File

@ -80,6 +80,7 @@ import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
import com.etheller.warsmash.viewer5.handlers.mdx.MdxNode;
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
import com.etheller.warsmash.viewer5.handlers.tga.TgaFile;
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag;
import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover;
import com.etheller.warsmash.viewer5.handlers.w3x.environment.BuildingShadow;
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance;
@ -643,6 +644,70 @@ public class War3MapViewer extends AbstractMdxModelViewer {
}
}
@Override
public void unitUpgradingEvent(final CUnit unit, final War3ID upgradeIdType) {
// final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(unit);
final MutableGameObject upgrade = War3MapViewer.this.allObjectData.getUnits()
.get(upgradeIdType);
// TODO this should be behind some auto lookup so it isn't copied from
// RenderUnit class:
final String originalRequiredAnimationNames = War3MapViewer.this.allObjectData.getUnits()
.get(unit.getTypeId()).getFieldAsString(RenderUnit.ANIM_PROPS, 0);
TokenLoop: for (final String animationName : originalRequiredAnimationNames.split(",")) {
final String upperCaseToken = animationName.toUpperCase();
for (final SecondaryTag secondaryTag : SecondaryTag.values()) {
if (upperCaseToken.equals(secondaryTag.name())) {
unit.getUnitAnimationListener().removeSecondaryTag(secondaryTag);
continue TokenLoop;
}
}
}
// TODO this should be behind some auto lookup so it isn't copied from
// RenderUnit class:
final String requiredAnimationNames = upgrade.getFieldAsString(RenderUnit.ANIM_PROPS, 0);
TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) {
final String upperCaseToken = animationName.toUpperCase();
for (final SecondaryTag secondaryTag : SecondaryTag.values()) {
if (upperCaseToken.equals(secondaryTag.name())) {
unit.getUnitAnimationListener().addSecondaryTag(secondaryTag);
continue TokenLoop;
}
}
}
}
@Override
public void unitCancelUpgradingEvent(final CUnit unit, final War3ID upgradeIdType) {
final MutableGameObject upgrade = War3MapViewer.this.allObjectData.getUnits()
.get(upgradeIdType);
// TODO this should be behind some auto lookup so it isn't copied from
// RenderUnit class:
final String requiredAnimationNames = upgrade.getFieldAsString(RenderUnit.ANIM_PROPS, 0);
TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) {
final String upperCaseToken = animationName.toUpperCase();
for (final SecondaryTag secondaryTag : SecondaryTag.values()) {
if (upperCaseToken.equals(secondaryTag.name())) {
unit.getUnitAnimationListener().removeSecondaryTag(secondaryTag);
continue TokenLoop;
}
}
}
final String originalRequiredAnimationNames = War3MapViewer.this.allObjectData.getUnits()
.get(unit.getTypeId()).getFieldAsString(RenderUnit.ANIM_PROPS, 0);
TokenLoop: for (final String animationName : originalRequiredAnimationNames.split(",")) {
final String upperCaseToken = animationName.toUpperCase();
for (final SecondaryTag secondaryTag : SecondaryTag.values()) {
if (upperCaseToken.equals(secondaryTag.name())) {
unit.getUnitAnimationListener().addSecondaryTag(secondaryTag);
continue TokenLoop;
}
}
}
}
@Override
public void removeUnit(final CUnit unit) {
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.remove(unit);
@ -1665,7 +1730,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
final float rawDeltaTime = Gdx.graphics.getRawDeltaTime();
this.updateTime += rawDeltaTime;
while (this.updateTime >= WarsmashConstants.SIMULATION_STEP_TIME) {
while (this.updateTime >= (WarsmashConstants.SIMULATION_STEP_TIME)) {
if (this.gameTurnManager.getLatestCompletedTurn() >= this.simulation.getGameTurnTick()) {
this.updateTime -= WarsmashConstants.SIMULATION_STEP_TIME;
this.simulation.update();

View File

@ -35,7 +35,7 @@ public class RenderUnit implements RenderWidget {
private static final War3ID BLUE = War3ID.fromString("uclb");
private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh");
private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori");
private static final War3ID ANIM_PROPS = War3ID.fromString("uani");
public static final War3ID ANIM_PROPS = War3ID.fromString("uani");
private static final War3ID BLEND_TIME = War3ID.fromString("uble");
private static final War3ID BUILD_SOUND_LABEL = War3ID.fromString("ubsl");
private static final War3ID UNIT_SELECT_HEIGHT = War3ID.fromString("uslz");
@ -409,7 +409,7 @@ public class RenderUnit implements RenderWidget {
selectionCircleHeight + map.imageWalkableZOffset);
}
this.unitAnimationListenerImpl.update();
if (!dead && this.simulationUnit.isConstructing()) {
if (!dead && this.simulationUnit.isConstructingOrUpgrading()) {
this.instance.setFrameByRatio(
this.simulationUnit.getConstructionProgress() / this.simulationUnit.getUnitType().getBuildTime());
}

View File

@ -36,5 +36,6 @@ public interface CommandButtonListener {
// int getOrderId();
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId,
int autoCastOrderId, boolean active, boolean autoCastActive, boolean menuButton, String tip, String uberTip,
char hotkey, int goldCost, int lumberCost, int foodCost);
char hotkey, int goldCost, int lumberCost, int foodCost, int manaCost, float cooldownRemaining,
float cooldownMax, int numberOverlay);
}

View File

@ -11,7 +11,7 @@ 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.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGenericDoNothing;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.AbstractCAbilityBuild;
@ -25,6 +25,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAb
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally;
@ -107,10 +108,10 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
}
@Override
public Void accept(final CAbilityGeneric ability) {
public Void accept(final CAbilityGenericDoNothing ability) {
if (ENABLE_PLACEHOLDERS) {
if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) {
final AbilityUI abilityUI = this.abilityDataUI.getUI(ability.getRawcode());
final AbilityUI abilityUI = this.abilityDataUI.getUI(ability.getAlias());
if (abilityUI != null) {
addCommandButton(ability, abilityUI.getOnIconUI(), ability.getHandleId(), 0, 0, false, false);
}
@ -129,7 +130,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
final AbilityUI ui = this.abilityDataUI.getUI(ability.getAlias());
addCommandButton(ability, ability.isToggleOn() ? ui.getOffIconUI() : ui.getOnIconUI(),
ability.getHandleId(), ability.getBaseOrderId(), 0, false, false, ability.getUIGoldCost(),
ability.getUILumberCost(), 0);
ability.getUILumberCost(), 0, ability.getUIManaCost(), -1);
}
return null;
}
@ -139,6 +140,11 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
return null;
}
@Override
public Void accept(final CAbilityReturnResources ability) {
return null;
}
@Override
public Void accept(final CAbilityRally ability) {
if (this.menuBaseOrderId == 0) {
@ -159,7 +165,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
else {
autoCastId = OrderIds.uncoldarrows;
}
final IconUI onIconUI = this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI();
final IconUI onIconUI = this.abilityDataUI.getUI(ability.getAlias()).getOnIconUI();
addCommandButton(ability, onIconUI, ability.getHandleId(), OrderIds.coldarrowstarg, autoCastId,
autoCastActive, false);
}
@ -210,7 +216,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
final CUnitType simulationUnitType = this.game.getUnitData().getUnitType(unitType);
addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false,
simulationUnitType.getGoldCost(), simulationUnitType.getLumberCost(),
simulationUnitType.getFoodUsed());
simulationUnitType.getFoodUsed(), 0, -1);
}
}
}
@ -224,25 +230,29 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton) {
addCommandButton(ability, iconUI, handleId, orderId, autoCastOrderId, autoCastActive, menuButton, 0, 0, 0);
addCommandButton(ability, iconUI, handleId, orderId, autoCastOrderId, autoCastActive, menuButton, 0, 0, 0, 0,
-1);
}
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, final int goldCost,
final int lumberCost, final int foodCost) {
final int lumberCost, final int foodCost, final int manaCost, final int numberOverlay) {
addCommandButton(ability, iconUI, iconUI.getToolTip(), iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
handleId, orderId, autoCastOrderId, autoCastActive, menuButton, goldCost, lumberCost, foodCost);
handleId, orderId, autoCastOrderId, autoCastActive, menuButton, goldCost, lumberCost, foodCost,
manaCost, numberOverlay);
}
private void addCommandButton(final CAbility ability, final IconUI iconUI, final String toolTip,
final int buttonPosX, final int buttonPosY, final int handleId, final int orderId,
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, int goldCost,
int lumberCost, int foodCost) {
int lumberCost, int foodCost, final int manaCost, final int numberOverlay) {
ability.checkCanUse(this.game, this.unit, orderId, this.previewCallback.reset());
if (!this.previewCallback.techtreeMaxReached) {
final boolean active = ((this.unit.getCurrentBehavior() != null)
&& (orderId == this.unit.getCurrentBehavior().getHighlightOrderId()));
final boolean disabled = ((ability != null) && ability.isDisabled()) || this.previewCallback.disabled;
final float cooldownRemaining = this.previewCallback.cooldownRemaining;
final float cooldownMax = this.previewCallback.cooldownMax;
String uberTip = iconUI.getUberTip();
if (disabled) {
// dont show these on disabled
@ -256,7 +266,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
this.commandButtonListener.commandButton(buttonPosX, buttonPosY,
disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId,
autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, iconUI.getHotkey(), goldCost,
lumberCost, foodCost);
lumberCost, foodCost, manaCost, cooldownRemaining, cooldownMax, numberOverlay);
}
}
@ -287,7 +297,8 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
.getHeroReviveLumberCost(simulationUnitType.getLumberCost(), heroData.getHeroLevel());
addCommandButton(ability, unitUI, unitUI.getReviveTip() + " - " + heroData.getProperName(),
heroIndex++, 0, ability.getHandleId(), playerHero.getHandleId(), 0, false, false,
goldCost, lumberCost, simulationUnitType.getFoodUsed());
goldCost, lumberCost, simulationUnitType.getFoodUsed(), 0,
playerHero.getHeroData().getHeroLevel());
}
}
}
@ -309,9 +320,18 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
final IconUI unitUI = this.abilityDataUI.getUnitUI(unitType);
if (unitUI != null) {
final CUnitType simulationUnitType = this.game.getUnitData().getUnitType(unitType);
int goldCost, lumberCost;
if (simulationUnitType.isHero()
&& (this.game.getPlayer(this.unit.getPlayerIndex()).getHeroTokens() > 0)) {
goldCost = 0;
lumberCost = 0;
}
else {
goldCost = simulationUnitType.getGoldCost();
lumberCost = simulationUnitType.getLumberCost();
}
addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false,
simulationUnitType.getGoldCost(), simulationUnitType.getLumberCost(),
simulationUnitType.getFoodUsed());
goldCost, lumberCost, simulationUnitType.getFoodUsed(), 0, -1);
}
}
if (ENABLE_PLACEHOLDERS) {
@ -341,10 +361,22 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
for (final War3ID unitType : ability.getUpgradesTo()) {
final IconUI unitUI = this.abilityDataUI.getUnitUI(unitType);
if (unitUI != null) {
int relativeOffsetGold;
int relativeOffsetLumber;
final CUnitType existingUnitType = this.unit.getUnitType();
if (this.game.getGameplayConstants().isRelativeUpgradeCosts()) {
relativeOffsetGold = existingUnitType.getGoldCost();
relativeOffsetLumber = existingUnitType.getLumberCost();
}
else {
relativeOffsetGold = 0;
relativeOffsetLumber = 0;
}
final CUnitType simulationUnitType = this.game.getUnitData().getUnitType(unitType);
addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false,
simulationUnitType.getGoldCost(), simulationUnitType.getLumberCost(),
simulationUnitType.getFoodUsed());
simulationUnitType.getGoldCost() - relativeOffsetGold,
simulationUnitType.getLumberCost() - relativeOffsetLumber,
simulationUnitType.getFoodUsed() - existingUnitType.getFoodUsed(), 0, -1);
}
}
if (this.unit.getBuildQueueTypes()[0] != null) {
@ -361,11 +393,15 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
private final class CommandCardActivationReceiverPreviewCallback implements AbilityActivationReceiver {
private boolean disabled;
private boolean techtreeMaxReached;
private boolean notEnoughMana;
private final StringBuilder requirementsTextBuilder = new StringBuilder();
private float cooldownRemaining;
private float cooldownMax;
public CommandCardActivationReceiverPreviewCallback reset() {
this.disabled = false;
this.techtreeMaxReached = false;
this.cooldownRemaining = 0;
this.requirementsTextBuilder.setLength(0);
return this;
}
@ -377,7 +413,9 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
@Override
public void notEnoughResources(final ResourceType resource) {
if (resource == ResourceType.MANA) {
this.notEnoughMana = true;
}
}
@Override
@ -402,6 +440,27 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
this.requirementsTextBuilder.append("|n");
}
@Override
public void missingHeroLevelRequirement(final int level) {
this.disabled = true;
if (this.requirementsTextBuilder.length() == 0) {
this.requirementsTextBuilder.append(CommandCardPopulatingAbilityVisitor.this.gameUI.getTemplates()
.getDecoratedString("REQUIRESTOOLTIP"));
this.requirementsTextBuilder.append("|n - ");
}
else {
this.requirementsTextBuilder.append(" - ");
}
this.requirementsTextBuilder.append(String.format(CommandCardPopulatingAbilityVisitor.this.gameUI
.getTemplates().getDecoratedString("INFOPANEL_LEVEL").replace("%u", "%d"), level));
this.requirementsTextBuilder.append("|n");
}
@Override
public void noHeroSkillPointsAvailable() {
this.disabled = true;
}
@Override
public void techtreeMaximumReached() {
this.techtreeMaxReached = true;
@ -421,6 +480,13 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
this.disabled = true;
}
@Override
public void cooldownNotYetReady(final float cooldownRemaining, final float cooldownMax) {
this.cooldownRemaining = cooldownRemaining;
this.cooldownMax = cooldownMax;
}
public boolean isShowingRequirements() {
return this.requirementsTextBuilder.length() != 0;
}
@ -432,7 +498,24 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
@Override
public Void accept(final CAbilityHero ability) {
// TODO
if ((this.menuBaseOrderId == OrderIds.skillmenu) && ability.isIconShowing()) {
for (final War3ID unitType : ability.getSkillsAvailable()) {
final AbilityUI abilityUI = this.abilityDataUI.getUI(unitType);
if (abilityUI != null) {
final int nextLevel = this.unit.getAbilityLevel(unitType) + 1;
addCommandButton(ability, abilityUI.getLearnIconUI(), ability.getHandleId(), unitType.getValue(), 0,
false, false, 0, 0, 0, 0, nextLevel);
}
}
}
else {
if (this.multiSelect) {
return null;
}
final int skillPoints = ability.getSkillPoints();
addCommandButton(ability, this.abilityDataUI.getSelectSkillUI(), ability.getHandleId(), OrderIds.skillmenu,
0, false, true, 0, 0, 0, 0, skillPoints != 0 ? skillPoints : -1);
}
return null;
}
}

View File

@ -105,6 +105,8 @@ public class CGameplayConstants {
private final float followItemRange;
private final float spellCastRangeBuffer;
private final boolean relativeUpgradeCosts;
public CGameplayConstants(final DataTable parsedDataTable) {
final Element miscData = parsedDataTable.get("Misc");
// TODO use radians for half angle
@ -236,6 +238,8 @@ public class CGameplayConstants {
this.followItemRange = miscData.getFieldFloatValue("FollowItemRange");
this.spellCastRangeBuffer = miscData.getFieldFloatValue("SpellCastRangeBuffer");
this.relativeUpgradeCosts = miscData.getFieldValue("RelativeUpgradeCost") == 0;
}
public float getAttackHalfAngle() {
@ -455,6 +459,10 @@ public class CGameplayConstants {
return this.heroReviveManaStart;
}
public boolean isRelativeUpgradeCosts() {
return this.relativeUpgradeCosts;
}
private static int getTableValue(final int[] table, int level) {
if (level <= 0) {
return 0;

View File

@ -437,6 +437,14 @@ public class CSimulation implements CPlayerAPI {
this.simulationRenderController.spawnUnitConstructionSound(constructingUnit, constructedStructure);
}
public void unitUpgradingEvent(final CUnit cUnit, final War3ID upgradeIdType) {
this.simulationRenderController.unitUpgradingEvent(cUnit, upgradeIdType);
}
public void unitCancelUpgradingEvent(final CUnit cUnit, final War3ID upgradeIdType) {
this.simulationRenderController.unitCancelUpgradingEvent(cUnit, upgradeIdType);
}
@Override
public CPlayer getPlayer(final int index) {
return this.players.get(index);

View File

@ -22,13 +22,17 @@ import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.Remova
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener.CUnitStateNotifier;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.GetAbilityByRawcodeVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.upgrade.CAbilityUpgrade;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener;
@ -38,6 +42,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorStop;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.AbilityDisableWhileUnderConstructionVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CRegenType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
@ -67,9 +72,12 @@ public class CUnit extends CWidget {
private float facing; // degrees
private float mana;
private int maximumLife;
private final float lifeRegen;
private float lifeRegen;
private float lifeRegenStrengthBonus;
private float lifeRegenBonus;
private float manaRegen;
private float manaRegenIntelligenceBonus;
private float manaRegenBonus;
private int maximumMana;
private int speed;
private int agilityDefensePermanentBonus;
@ -81,6 +89,7 @@ public class CUnit extends CWidget {
private int currentDefenseDisplay;
private float currentDefense;
private float currentLifeRegenPerTick;
private float currentManaRegenPerTick;
private int cooldownEndTime = 0;
private float flyHeight;
@ -90,7 +99,7 @@ public class CUnit extends CWidget {
private CBehavior currentBehavior;
private final Queue<COrder> orderQueue = new LinkedList<>();
private final CUnitType unitType;
private CUnitType unitType;
private Rectangle collisionRectangle;
private RemovablePathingMapInstance pathingInstance;
@ -119,6 +128,8 @@ public class CUnit extends CWidget {
private transient CBehaviorStop stopBehavior;
private transient CBehaviorHoldPosition holdPositionBehavior;
private boolean constructing = false;
private boolean constructingPaused = false;
private War3ID upgradeIdType = null;
private float constructionProgress;
private boolean hidden = false;
private boolean paused = false;
@ -152,6 +163,7 @@ public class CUnit extends CWidget {
this.mana = mana;
this.maximumLife = maximumLife;
this.lifeRegen = lifeRegen;
this.manaRegen = unitType.getManaRegen();
this.maximumMana = maximumMana;
this.speed = speed;
this.pathingInstance = pathingInstance;
@ -171,6 +183,7 @@ public class CUnit extends CWidget {
public void setLifeRegenStrengthBonus(final float lifeRegenStrengthBonus) {
this.lifeRegenStrengthBonus = lifeRegenStrengthBonus;
computeDerivedFields();
}
private void computeDerivedFields() {
@ -180,6 +193,13 @@ public class CUnit extends CWidget {
this.currentDefense = this.currentDefenseDisplay + this.totalTemporaryDefenseBonus;
this.currentLifeRegenPerTick = (this.lifeRegen + this.lifeRegenBonus + this.lifeRegenStrengthBonus)
* WarsmashConstants.SIMULATION_STEP_TIME;
this.currentManaRegenPerTick = (this.manaRegen + this.manaRegenBonus + this.manaRegenIntelligenceBonus)
* WarsmashConstants.SIMULATION_STEP_TIME;
}
public void setManaRegenIntelligenceBonus(final float manaRegenIntelligenceBonus) {
this.manaRegenIntelligenceBonus = manaRegenIntelligenceBonus;
computeDerivedFields();
}
public void setLifeRegenBonus(final float lifeRegenBonus) {
@ -187,6 +207,11 @@ public class CUnit extends CWidget {
computeDerivedFields();
}
public void setManaRegenBonus(final float manaRegenBonus) {
this.manaRegenBonus = manaRegenBonus;
computeDerivedFields();
}
public void setAgilityDefensePermanentBonus(final int agilityDefensePermanentBonus) {
this.agilityDefensePermanentBonus = agilityDefensePermanentBonus;
computeDerivedFields();
@ -263,8 +288,40 @@ public class CUnit extends CWidget {
return this.maximumLife;
}
public void setTypeId(final War3ID typeId) {
public void setTypeId(final CSimulation game, final War3ID typeId) {
this.typeId = typeId;
final float lifeRatio = this.maximumLife == 0 ? 1 : (this.life / this.maximumLife);
final float manaRatio = this.maximumMana == 0 ? Float.NaN : (this.mana / this.maximumMana);
this.unitType = game.getUnitData().getUnitType(typeId);
if (Float.isNaN(manaRatio)) {
this.mana = this.unitType.getManaInitial();
}
else {
this.maximumMana = this.unitType.getManaMaximum();
this.mana = manaRatio * this.maximumMana;
}
this.maximumLife = this.unitType.getMaxLife();
this.life = lifeRatio * this.maximumLife;
this.lifeRegen = this.unitType.getLifeRegen();
this.manaRegen = this.unitType.getManaRegen();
this.flyHeight = this.unitType.getDefaultFlyingHeight();
this.classifications.clear();
this.classifications.addAll(this.unitType.getClassifications());
this.acquisitionRange = this.unitType.getDefaultAcquisitionRange();
for (final CAbility ability : this.abilities) {
if (ability instanceof CAbilityQueue) {
((CAbilityQueue) ability).onSetUnitType(this.unitType);
}
else if (ability instanceof CAbilityUpgrade) {
((CAbilityUpgrade) ability).onSetUnitType(this.unitType);
}
else {
// refresh abilities...
ability.onRemove(game, this);
ability.onAdd(game, this);
}
}
computeDerivedFields();
}
public void setFacing(final float facing) {
@ -363,13 +420,25 @@ public class CUnit extends CWidget {
setRallyPoint(this);
}
if (this.constructing) {
this.constructionProgress += WarsmashConstants.SIMULATION_STEP_TIME;
final int buildTime = this.unitType.getBuildTime();
final float healthGain = (WarsmashConstants.SIMULATION_STEP_TIME / buildTime)
* (this.maximumLife * (1.0f - WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE));
setLife(game, Math.min(this.life + healthGain, this.maximumLife));
if (!this.constructingPaused) {
this.constructionProgress += WarsmashConstants.SIMULATION_STEP_TIME;
}
final int buildTime;
final boolean upgrading = isUpgrading();
if (!upgrading) {
buildTime = this.unitType.getBuildTime();
if (!this.constructingPaused) {
final float healthGain = (WarsmashConstants.SIMULATION_STEP_TIME / buildTime)
* (this.maximumLife * (1.0f - WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE));
setLife(game, Math.min(this.life + healthGain, this.maximumLife));
}
}
else {
buildTime = game.getUnitData().getUnitType(this.upgradeIdType).getBuildTime();
}
if (this.constructionProgress >= buildTime) {
this.constructing = false;
this.constructingPaused = false;
this.constructionProgress = 0;
popoutWorker(game);
final Iterator<CAbility> abilityIterator = this.abilities.iterator();
@ -384,12 +453,24 @@ public class CUnit extends CWidget {
}
}
final CPlayer player = game.getPlayer(this.playerIndex);
if (upgrading) {
if (this.unitType.getFoodMade() != 0) {
player.setFoodCap(player.getFoodCap() - this.unitType.getFoodMade());
}
setTypeId(game, this.upgradeIdType);
this.upgradeIdType = null;
}
if (this.unitType.getFoodMade() != 0) {
player.setFoodCap(player.getFoodCap() + this.unitType.getFoodMade());
}
player.removeTechtreeInProgress(this.unitType.getTypeId());
player.addTechtreeUnlocked(this.unitType.getTypeId());
game.unitConstructFinishEvent(this);
if (upgrading) {
// TODO shouldnt need to play stand here, probably
getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f,
true);
}
this.stateNotifier.ordersChanged();
}
}
@ -543,6 +624,14 @@ public class CUnit extends CWidget {
this.stateNotifier.lifeChanged();
}
}
if (this.mana < this.maximumMana) {
float manaPlusRegen = this.mana + this.currentManaRegenPerTick;
if (manaPlusRegen > this.maximumMana) {
manaPlusRegen = this.maximumMana;
}
this.mana = manaPlusRegen;
this.stateNotifier.manaChanged();
}
for (final CAbility ability : this.abilities) {
ability.onTick(game, this);
}
@ -964,7 +1053,14 @@ public class CUnit extends CWidget {
damageRatioFromDefense = 2f - (float) StrictMath.pow(0.94, -defense);
}
final float trueDamage = damageRatioFromArmorClass * damageRatioFromDefense * damage;
final boolean wasAboveMax = this.life > this.maximumLife;
this.life -= trueDamage;
if ((damage < 0) && !wasAboveMax && (this.life > this.maximumLife)) {
// NOTE wasAboveMax is for that weird life drain power to drain above max... to
// be honest that's a crazy mechanic anyway so I didn't test whether it works
// yet
this.life = this.maximumLife;
}
this.stateNotifier.lifeChanged();
}
simulation.unitDamageEvent(this, weaponType, this.unitType.getArmorType());
@ -1221,6 +1317,10 @@ public class CUnit extends CWidget {
@Override
public boolean canBeTargetedBy(final CSimulation simulation, final CUnit source,
final EnumSet<CTargetType> targetsAllowed) {
if ((this == source) && targetsAllowed.contains(CTargetType.NOTSELF)
&& !targetsAllowed.contains(CTargetType.SELF)) {
return false;
}
if (targetsAllowed.containsAll(this.unitType.getTargetedAs()) || (!targetsAllowed.contains(CTargetType.GROUND)
&& (!targetsAllowed.contains(CTargetType.STRUCTURE) && !targetsAllowed.contains(CTargetType.AIR)))) {
final int sourcePlayerIndex = source.getPlayerIndex();
@ -1376,11 +1476,27 @@ public class CUnit extends CWidget {
}
}
public void setConstructingPaused(final boolean constructingPaused) {
this.constructingPaused = constructingPaused;
}
public void setConstructionProgress(final float constructionProgress) {
this.constructionProgress = constructionProgress;
}
public boolean isConstructing() {
return this.constructing && (this.upgradeIdType == null);
}
public boolean isUpgrading() {
return this.constructing && (this.upgradeIdType != null);
}
public War3ID getUpgradeIdType() {
return this.upgradeIdType;
}
public boolean isConstructingOrUpgrading() {
return this.constructing;
}
@ -1579,7 +1695,13 @@ public class CUnit extends CWidget {
if (queue(game, rawcode, QueueItemType.UNIT)) {
final CPlayer player = game.getPlayer(this.playerIndex);
final CUnitType unitType = game.getUnitData().getUnitType(rawcode);
player.chargeFor(unitType);
final boolean isHeroType = unitType.isHero();
if (isHeroType && (player.getHeroTokens() > 0)) {
player.setHeroTokens(player.getHeroTokens() - 1);
}
else {
player.chargeFor(unitType);
}
}
}
@ -1886,11 +2008,65 @@ public class CUnit extends CWidget {
}
public void cancelUpgrade(final CSimulation game) {
throw new RuntimeException("NYI");
final CPlayer player = game.getPlayer(this.playerIndex);
player.setUnitFoodUsed(this, this.unitType.getFoodUsed());
int goldCost, lumberCost;
final CUnitType newUpgradeUnitType = game.getUnitData().getUnitType(this.upgradeIdType);
if (game.getGameplayConstants().isRelativeUpgradeCosts()) {
goldCost = newUpgradeUnitType.getGoldCost() - this.unitType.getGoldCost();
lumberCost = newUpgradeUnitType.getLumberCost() - this.unitType.getLumberCost();
}
else {
goldCost = newUpgradeUnitType.getGoldCost();
lumberCost = newUpgradeUnitType.getLumberCost();
}
player.refund(goldCost, lumberCost);
final Iterator<CAbility> abilityIterator = this.abilities.iterator();
while (abilityIterator.hasNext()) {
final CAbility ability = abilityIterator.next();
if (ability instanceof CAbilityBuildInProgress) {
abilityIterator.remove();
}
else {
ability.setDisabled(false);
ability.setIconShowing(true);
}
}
game.unitCancelUpgradingEvent(this, this.upgradeIdType);
this.upgradeIdType = null;
this.constructing = false;
this.constructionProgress = 0;
this.unitAnimationListener.playAnimation(true, PrimaryTag.STAND, SequenceUtils.EMPTY, 0.0f, true);
}
public void beginUpgrade(final CSimulation game, final War3ID rawcode) {
this.upgradeIdType = rawcode;
this.constructing = true;
this.constructionProgress = 0;
final CPlayer player = game.getPlayer(this.playerIndex);
final CUnitType newUpgradeUnitType = game.getUnitData().getUnitType(rawcode);
player.setUnitFoodUsed(this, newUpgradeUnitType.getFoodUsed());
int goldCost, lumberCost;
if (game.getGameplayConstants().isRelativeUpgradeCosts()) {
goldCost = newUpgradeUnitType.getGoldCost() - this.unitType.getGoldCost();
lumberCost = newUpgradeUnitType.getLumberCost() - this.unitType.getLumberCost();
}
else {
goldCost = newUpgradeUnitType.getGoldCost();
lumberCost = newUpgradeUnitType.getLumberCost();
}
player.charge(goldCost, lumberCost);
add(game, new CAbilityBuildInProgress(game.getHandleIdAllocator().createId()));
for (final CAbility ability : getAbilities()) {
ability.visit(AbilityDisableWhileUnderConstructionVisitor.INSTANCE);
}
player.addTechtreeInProgress(rawcode);
game.unitUpgradingEvent(this, rawcode);
this.unitAnimationListener.playAnimation(true, PrimaryTag.BIRTH, SequenceUtils.EMPTY, 0.0f, true);
}
public void setUnitState(final CSimulation game, final CUnitState whichUnitState, final float value) {
@ -2036,4 +2212,18 @@ public class CUnit extends CWidget {
}
return unit.getUnitType().getName();
}
public void fireCooldownsChangedEvent() {
this.stateNotifier.ordersChanged();
}
public int getAbilityLevel(final War3ID abilityId) {
final CLevelingAbility ability = getAbility(GetAbilityByRawcodeVisitor.getInstance().reset(abilityId));
if (ability == null) {
return 0;
}
else {
return ability.getLevel();
}
}
}

View File

@ -5,6 +5,8 @@ import com.etheller.warsmash.util.SubscriberSetNotifier;
public interface CUnitStateListener {
void lifeChanged(); // hp (current) changes
void manaChanged();
void ordersChanged();
void queueChanged();
@ -26,6 +28,13 @@ public interface CUnitStateListener {
}
}
@Override
public void manaChanged() {
for (final CUnitStateListener listener : set) {
listener.manaChanged();
}
}
@Override
public void ordersChanged() {
for (final CUnitStateListener listener : set) {

View File

@ -1,6 +1,7 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
@ -25,6 +26,7 @@ public class CUnitType {
private final War3ID typeId;
private final int maxLife;
private final float lifeRegen;
private final float manaRegen;
private final CRegenType lifeRegenType;
private final int manaInitial;
private final int manaMaximum;
@ -81,10 +83,13 @@ public class CUnitType {
private final int priority;
private final boolean revivesHeroes;
private final int pointValue;
private final List<List<CUnitTypeRequirement>> requirementTiers;
private final float castBackswingPoint;
private final float castPoint;
public CUnitType(final String name, final String legacyName, final War3ID typeId, final int maxLife,
final float lifeRegen, final CRegenType lifeRegenType, final int manaInitial, final int manaMaximum,
final int speed, final int defense, final String abilityList, final boolean isBldg,
final float lifeRegen, final float manaRegen, final CRegenType lifeRegenType, 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<CUnitClassification> classifications, final List<CUnitAttack> attacks, final String armorType,
final boolean raise, final boolean decay, final CDefenseType defenseType, final float impactZ,
@ -94,16 +99,18 @@ public class CUnitType {
final CUnitRace unitRace, final int goldCost, final int lumberCost, final int foodUsed, final int foodMade,
final int buildTime, final EnumSet<CBuildingPathingType> preventedPathingTypes,
final EnumSet<CBuildingPathingType> requiredPathingTypes, final float propWindow, final float turnRate,
final List<CUnitTypeRequirement> requirements, final int level, final boolean hero, final int strength,
final float strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence,
final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute,
final List<War3ID> heroAbilityList, final List<String> heroProperNames, final int properNamesCount,
final boolean canFlee, final int priority, final boolean revivesHeroes, final int pointValue) {
final List<CUnitTypeRequirement> requirements, final List<List<CUnitTypeRequirement>> requirementTiers,
final int level, final boolean hero, final int strength, final float strengthPerLevel, final int agility,
final float agilityPerLevel, final int intelligence, final float intelligencePerLevel,
final CPrimaryAttribute primaryAttribute, final List<War3ID> heroAbilityList,
final List<String> heroProperNames, final int properNamesCount, final boolean canFlee, final int priority,
final boolean revivesHeroes, final int pointValue, final float castBackswingPoint, final float castPoint) {
this.name = name;
this.legacyName = legacyName;
this.typeId = typeId;
this.maxLife = maxLife;
this.lifeRegen = lifeRegen;
this.manaRegen = manaRegen;
this.lifeRegenType = lifeRegenType;
this.manaInitial = manaInitial;
this.manaMaximum = manaMaximum;
@ -141,6 +148,7 @@ public class CUnitType {
this.propWindow = propWindow;
this.turnRate = turnRate;
this.requirements = requirements;
this.requirementTiers = requirementTiers;
this.level = level;
this.hero = hero;
this.startingStrength = strength;
@ -157,6 +165,8 @@ public class CUnitType {
this.priority = priority;
this.revivesHeroes = revivesHeroes;
this.pointValue = pointValue;
this.castBackswingPoint = castBackswingPoint;
this.castPoint = castPoint;
}
public String getName() {
@ -179,6 +189,10 @@ public class CUnitType {
return this.lifeRegen;
}
public float getManaRegen() {
return this.manaRegen;
}
public CRegenType getLifeRegenType() {
return this.lifeRegenType;
}
@ -327,6 +341,16 @@ public class CUnitType {
return this.requirements;
}
public List<CUnitTypeRequirement> getRequirementsTier(final int tier) {
final int index = tier - 1;
if ((index >= 0) && (index < this.requirementTiers.size())) {
return this.requirementTiers.get(index);
}
else {
return Collections.emptyList();
}
}
public int getLevel() {
return this.level;
}
@ -390,4 +414,12 @@ public class CUnitType {
public int getPointValue() {
return this.pointValue;
}
public float getCastBackswingPoint() {
return this.castBackswingPoint;
}
public float getCastPoint() {
return this.castPoint;
}
}

View File

@ -4,6 +4,7 @@ import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericAliasedAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
@ -13,16 +14,10 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
/**
* Represents an ability from the object data
*/
public class CAbilityGeneric extends AbstractCAbility {
private final War3ID rawcode;
public class CAbilityGenericDoNothing extends AbstractGenericAliasedAbility {
public CAbilityGeneric(final War3ID rawcode, final int handleId) {
super(handleId);
this.rawcode = rawcode;
}
public War3ID getRawcode() {
return this.rawcode;
public CAbilityGenericDoNothing(final War3ID rawcode, final int handleId) {
super(handleId, rawcode);
}
@Override
@ -67,7 +62,8 @@ public class CAbilityGeneric extends AbstractCAbility {
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) {
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return false;
}
@ -90,4 +86,5 @@ public class CAbilityGeneric extends AbstractCAbility {
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
}

View File

@ -10,6 +10,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAb
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally;
@ -37,7 +38,7 @@ public interface CAbilityVisitor<T> {
T accept(CAbilityNightElfBuild ability);
T accept(CAbilityGeneric ability);
T accept(CAbilityGenericDoNothing ability);
T accept(CAbilityColdArrows ability);
@ -53,6 +54,8 @@ public interface CAbilityVisitor<T> {
T accept(CAbilityReviveHero ability);
T accept(CAbilityReturnResources ability);
T accept(GenericSingleIconActiveAbility ability);
T accept(CAbilityRally ability);

View File

@ -9,15 +9,17 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAb
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.upgrade.CAbilityUpgrade;
public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CAbility> {
public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CLevelingAbility> {
private static final GetAbilityByRawcodeVisitor INSTANCE = new GetAbilityByRawcodeVisitor();
public static GetAbilityByRawcodeVisitor getInstance() {
@ -33,83 +35,37 @@ public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CAbility> {
}
@Override
public CAbility accept(final CAbilityAttack ability) {
public CLevelingAbility accept(final CAbilityAttack ability) {
return null;
}
@Override
public CAbility accept(final CAbilityMove ability) {
public CLevelingAbility accept(final CAbilityMove ability) {
return null;
}
@Override
public CAbility accept(final CAbilityOrcBuild ability) {
public CLevelingAbility accept(final CAbilityOrcBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityHumanBuild ability) {
public CLevelingAbility accept(final CAbilityHumanBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityUndeadBuild ability) {
public CLevelingAbility accept(final CAbilityUndeadBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityNightElfBuild ability) {
public CLevelingAbility accept(final CAbilityNightElfBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityGeneric ability) {
if (this.rawcode.equals(ability.getRawcode())) {
return ability;
}
return null;
}
@Override
public CAbility accept(final CAbilityColdArrows ability) {
if (this.rawcode.equals(ability.getRawcode())) {
return ability;
}
return null;
}
@Override
public CAbility accept(final CAbilityNagaBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityNeutralBuild ability) {
return null;
}
@Override
public CAbility accept(final CAbilityBuildInProgress ability) {
return null;
}
@Override
public CAbility accept(final CAbilityQueue ability) {
return null;
}
@Override
public CAbility accept(final CAbilityUpgrade ability) {
return null;
}
@Override
public CAbility accept(final CAbilityReviveHero ability) {
return null;
}
@Override
public CAbility accept(final GenericSingleIconActiveAbility ability) {
public CLevelingAbility accept(final CAbilityGenericDoNothing ability) {
if (this.rawcode.equals(ability.getAlias())) {
return ability;
}
@ -117,7 +73,53 @@ public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CAbility> {
}
@Override
public CAbility accept(final CAbilityRally ability) {
public CLevelingAbility accept(final CAbilityColdArrows ability) {
if (this.rawcode.equals(ability.getAlias())) {
return ability;
}
return null;
}
@Override
public CLevelingAbility accept(final CAbilityNagaBuild ability) {
return null;
}
@Override
public CLevelingAbility accept(final CAbilityNeutralBuild ability) {
return null;
}
@Override
public CLevelingAbility accept(final CAbilityBuildInProgress ability) {
return null;
}
@Override
public CLevelingAbility accept(final CAbilityQueue ability) {
return null;
}
@Override
public CLevelingAbility accept(final CAbilityUpgrade ability) {
return null;
}
@Override
public CLevelingAbility accept(final CAbilityReviveHero ability) {
return null;
}
@Override
public CLevelingAbility accept(final GenericSingleIconActiveAbility ability) {
if (this.rawcode.equals(ability.getAlias())) {
return ability;
}
return null;
}
@Override
public CLevelingAbility accept(final CAbilityRally ability) {
if (this.rawcode.equals(RALLY_RAWCODE)) {
return ability;
}
@ -125,7 +127,7 @@ public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CAbility> {
}
@Override
public CAbility accept(final GenericNoIconAbility ability) {
public CLevelingAbility accept(final GenericNoIconAbility ability) {
if (this.rawcode.equals(ability.getAlias())) {
return ability;
}
@ -133,7 +135,15 @@ public class GetAbilityByRawcodeVisitor implements CAbilityVisitor<CAbility> {
}
@Override
public CAbility accept(final CAbilityHero ability) {
public CLevelingAbility accept(final CAbilityReturnResources ability) {
if (this.rawcode.equals(ability.getAlias())) {
return ability;
}
return null;
}
@Override
public CLevelingAbility accept(final CAbilityHero ability) {
return null;
}

View File

@ -50,8 +50,8 @@ public abstract class AbstractCAbilityBuild extends AbstractCAbility implements
}
}
if (requirementsMet) {
if (player.getGold() >= unitType.getGoldCost()) {
if (player.getLumber() >= unitType.getLumberCost()) {
if ((player.getGold() >= unitType.getGoldCost())) {
if ((player.getLumber() >= unitType.getLumberCost())) {
if ((unitType.getFoodUsed() == 0)
|| ((player.getFoodUsed() + unitType.getFoodUsed()) <= player.getFoodCap())) {

View File

@ -38,10 +38,16 @@ public class CAbilityBuildInProgress extends AbstractCAbility {
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
final CPlayer player = game.getPlayer(caster.getPlayerIndex());
final CUnitType unitType = caster.getUnitType();
player.refundFor(unitType);
player.removeTechtreeInProgress(unitType.getTypeId());
caster.setLife(game, 0);
if (caster.isUpgrading()) {
player.removeTechtreeInProgress(caster.getUpgradeIdType());
caster.cancelUpgrade(game);
}
else {
final CUnitType unitType = caster.getUnitType();
player.refundFor(unitType);
player.removeTechtreeInProgress(unitType.getTypeId());
caster.setLife(game, 0);
}
return false;
}

View File

@ -1,21 +1,26 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
import java.awt.image.BufferedImage;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
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.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorHumanBuild;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
public class CAbilityHumanBuild extends AbstractCAbilityBuild {
private CBehaviorHumanBuild buildBehavior;
public CAbilityHumanBuild(final int handleId, final List<War3ID> structuresBuilt) {
super(handleId, structuresBuilt);
// TODO Auto-generated constructor stub
}
@Override
@ -25,33 +30,45 @@ public class CAbilityHumanBuild extends AbstractCAbilityBuild {
@Override
public void onAdd(final CSimulation game, final CUnit unit) {
// TODO Auto-generated method stub
this.buildBehavior = new CBehaviorHumanBuild(unit);
}
@Override
public void onRemove(final CSimulation game, final CUnit unit) {
// TODO Auto-generated method stub
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
// TODO Auto-generated method stub
return null;
return caster.pollNextOrderBehavior(game);
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
final AbilityPointTarget point) {
// caster.getMoveBehavior().reset(point.x, point.y, )
return null;
final War3ID orderIdAsRawtype = new War3ID(orderId);
final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype);
final BufferedImage buildingPathingPixelMap = unitType.getBuildingPathingPixelMap();
if (buildingPathingPixelMap != null) {
point.x = (float) Math.floor(point.x / 64f) * 64f;
point.y = (float) Math.floor(point.y / 64f) * 64f;
if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) {
point.x += 32f;
}
if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) {
point.y += 32f;
}
}
final CPlayer player = game.getPlayer(caster.getPlayerIndex());
player.chargeFor(unitType);
if (unitType.getFoodUsed() != 0) {
player.setFoodUsed(player.getFoodUsed() + unitType.getFoodUsed());
}
return this.buildBehavior.reset(point, orderId, getBaseOrderId());
}
@Override
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
// TODO Auto-generated method stub
return null;
return caster.pollNextOrderBehavior(game);
}
@Override
@ -59,10 +76,4 @@ public class CAbilityHumanBuild extends AbstractCAbilityBuild {
return visitor.accept(this);
}
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
// TODO Auto-generated method stub
}
}

View File

@ -1,5 +1,7 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
import java.util.EnumSet;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
@ -13,123 +15,150 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
import java.util.EnumSet;
public class CAbilityHumanRepair extends AbstractGenericSingleIconActiveAbility {
private EnumSet<CTargetType> targetsAllowed;
private final float navalRangeBonus;
private final float repairCostRatio;
private final float repairTimeRatio;
private final float castRange;
private CBehaviorHumanRepair behaviorRepair;
private EnumSet<CTargetType> targetsAllowed;
private float navalRangeBonus;
private float repairCostRatio;
private float repairTimeRatio;
private float castRange;
private CBehaviorHumanRepair behaviorRepair;
public CAbilityHumanRepair(int handleId, War3ID alias, EnumSet<CTargetType> targetsAllowed,
float navalRangeBonus, float repairCostRatio, float repairTimeRatio,
float castRange) {
super(handleId, alias);
this.targetsAllowed = targetsAllowed;
this.navalRangeBonus = navalRangeBonus;
this.repairCostRatio = repairCostRatio;
this.repairTimeRatio = repairTimeRatio;
this.castRange = castRange;
}
public CAbilityHumanRepair(final int handleId, final War3ID alias, final EnumSet<CTargetType> targetsAllowed,
final float navalRangeBonus, final float repairCostRatio, final float repairTimeRatio,
final float castRange) {
super(handleId, alias);
this.targetsAllowed = targetsAllowed;
this.navalRangeBonus = navalRangeBonus;
this.repairCostRatio = repairCostRatio;
this.repairTimeRatio = repairTimeRatio;
this.castRange = castRange;
}
@Override
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver<CWidget> receiver) {
if(target.canBeTargetedBy(game, unit, targetsAllowed) && target.getLife() < target.getMaxLife()) {
receiver.targetOk(target);
} else {
receiver.orderIdNotAccepted();
}
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
if (target.canBeTargetedBy(game, unit, this.targetsAllowed) && (target.getLife() < target.getMaxLife())) {
receiver.targetOk(target);
}
else {
receiver.orderIdNotAccepted();
}
}
@Override
protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver<CWidget> receiver) {
innerCheckCanTarget(game, unit, orderId, target, receiver);
}
@Override
protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId,
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
innerCheckCanTarget(game, unit, orderId, target, receiver);
}
@Override
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.mustTargetType(AbilityTargetCheckReceiver.TargetType.UNIT);
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.mustTargetType(AbilityTargetCheckReceiver.TargetType.UNIT);
}
@Override
protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
innerCheckCanTarget(game, unit, orderId, target, receiver);
}
@Override
protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
innerCheckCanTarget(game, unit, orderId, target, receiver);
}
@Override
protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver<Void> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver) {
receiver.useOk();
}
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
receiver.useOk();
}
@Override
public void onAdd(CSimulation game, CUnit unit) {
behaviorRepair = new CBehaviorHumanRepair(unit, this);
}
@Override
public void onAdd(final CSimulation game, final CUnit unit) {
this.behaviorRepair = new CBehaviorHumanRepair(unit, this);
}
@Override
public void onRemove(CSimulation game, CUnit unit) {
@Override
public void onRemove(final CSimulation game, final CUnit unit) {
}
}
@Override
public void onTick(CSimulation game, CUnit unit) {
@Override
public void onTick(final CSimulation game, final CUnit unit) {
}
}
@Override
public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) {
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
}
@Override
public CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target) {
return behaviorRepair.reset(target);
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
return this.behaviorRepair.reset(target);
}
@Override
public CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point) {
return null;
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
final AbilityPointTarget point) {
return null;
}
@Override
public CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId) {
return null;
}
@Override
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
return null;
}
@Override
public int getBaseOrderId() {
return OrderIds.repair;
}
@Override
public int getBaseOrderId() {
return OrderIds.repair;
}
@Override
public boolean isToggleOn() {
return false;
}
@Override
public boolean isToggleOn() {
return false;
}
public EnumSet<CTargetType> getTargetsAllowed() {
return targetsAllowed;
}
public EnumSet<CTargetType> getTargetsAllowed() {
return this.targetsAllowed;
}
public float getNavalRangeBonus() {
return navalRangeBonus;
}
public float getNavalRangeBonus() {
return this.navalRangeBonus;
}
public float getRepairCostRatio() {
return repairCostRatio;
}
public float getRepairCostRatio() {
return this.repairCostRatio;
}
public float getRepairTimeRatio() {
return repairTimeRatio;
}
public float getRepairTimeRatio() {
return this.repairTimeRatio;
}
public float getCastRange() {
return this.castRange;
}
public void setTargetsAllowed(final EnumSet<CTargetType> targetsAllowed) {
this.targetsAllowed = targetsAllowed;
}
public void setNavalRangeBonus(final float navalRangeBonus) {
this.navalRangeBonus = navalRangeBonus;
}
public void setRepairCostRatio(final float repairCostRatio) {
this.repairCostRatio = repairCostRatio;
}
public void setRepairTimeRatio(final float repairTimeRatio) {
this.repairTimeRatio = repairTimeRatio;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public float getCastRange() {
return castRange;
}
}

View File

@ -4,8 +4,8 @@ import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericAliasedAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
@ -18,13 +18,11 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
/**
* Represents an ability from the object data
*/
public class CAbilityColdArrows extends AbstractCAbility {
private final War3ID rawcode;
public class CAbilityColdArrows extends AbstractGenericAliasedAbility {
private boolean autoCastActive;
public CAbilityColdArrows(final War3ID rawcode, final int handleId) {
super(handleId);
this.rawcode = rawcode;
super(handleId, rawcode);
}
@Override
@ -66,10 +64,6 @@ public class CAbilityColdArrows extends AbstractCAbility {
}
}
public War3ID getRawcode() {
return this.rawcode;
}
public boolean isAutoCastActive() {
return this.autoCastActive;
}
@ -92,7 +86,8 @@ public class CAbilityColdArrows extends AbstractCAbility {
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) {
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
switch (orderId) {
case OrderIds.coldarrows:
case OrderIds.uncoldarrows:

View File

@ -0,0 +1,37 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
public abstract class AbstractGenericAliasedAbility extends AbstractCAbility implements CLevelingAbility {
private final War3ID alias;
private int level = 1;
public AbstractGenericAliasedAbility(final int handleId, final War3ID alias) {
super(handleId);
this.alias = alias;
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return true;
}
public War3ID getAlias() {
return this.alias;
}
@Override
public final int getLevel() {
return this.level;
}
@Override
public void setLevel(final int level) {
this.level = level;
}
}

View File

@ -1,24 +1,13 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
public abstract class AbstractGenericNoIconAbility extends AbstractCAbility implements GenericNoIconAbility {
private final War3ID alias;
public abstract class AbstractGenericNoIconAbility extends AbstractGenericAliasedAbility
implements GenericNoIconAbility {
public AbstractGenericNoIconAbility(final int handleId, final War3ID alias) {
super(handleId);
this.alias = alias;
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return true;
super(handleId, alias);
}
@Override
@ -26,9 +15,4 @@ public abstract class AbstractGenericNoIconAbility extends AbstractCAbility impl
return visitor.accept(this);
}
@Override
public War3ID getAlias() {
return this.alias;
}
}

View File

@ -4,20 +4,17 @@ import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
public abstract class AbstractGenericSingleIconActiveAbility extends AbstractCAbility
public abstract class AbstractGenericSingleIconActiveAbility extends AbstractGenericAliasedAbility
implements GenericSingleIconActiveAbility {
private final War3ID alias;
public AbstractGenericSingleIconActiveAbility(final int handleId, final War3ID alias) {
super(handleId);
this.alias = alias;
super(handleId, alias);
}
@Override
@ -85,11 +82,6 @@ public abstract class AbstractGenericSingleIconActiveAbility extends AbstractCAb
return visitor.accept(this);
}
@Override
public War3ID getAlias() {
return this.alias;
}
@Override
public int getUIGoldCost() {
return 0;
@ -100,4 +92,9 @@ public abstract class AbstractGenericSingleIconActiveAbility extends AbstractCAb
return 0;
}
@Override
public int getUIManaCost() {
return 0;
}
}

View File

@ -0,0 +1,9 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
public interface CLevelingAbility extends CAbility {
int getLevel();
void setLevel(int level);
}

View File

@ -1,8 +1,7 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
public interface GenericNoIconAbility extends CAbility {
public interface GenericNoIconAbility extends CLevelingAbility {
War3ID getAlias();
}

View File

@ -1,9 +1,8 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
public interface GenericSingleIconActiveAbility extends CAbility {
public interface GenericSingleIconActiveAbility extends CLevelingAbility {
War3ID getAlias();
int getBaseOrderId();
@ -13,4 +12,6 @@ public interface GenericSingleIconActiveAbility extends CAbility {
int getUIGoldCost();
int getUILumberCost();
int getUIManaCost();
}

View File

@ -27,11 +27,11 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
public class CAbilityHarvest extends AbstractGenericSingleIconActiveAbility {
private final int damageToTree;
private final int goldCapacity;
private final int lumberCapacity;
private final float castRange;
private final float duration;
private int damageToTree;
private int goldCapacity;
private int lumberCapacity;
private float castRange;
private float duration;
private CBehaviorHarvest behaviorHarvest;
private CBehaviorReturnResources behaviorReturnResources;
private int carriedResourceAmount;
@ -233,4 +233,23 @@ public class CAbilityHarvest extends AbstractGenericSingleIconActiveAbility {
return this.behaviorTreeAttack;
}
public void setDamageToTree(final int damageToTree) {
this.damageToTree = damageToTree;
}
public void setGoldCapacity(final int goldCapacity) {
this.goldCapacity = goldCapacity;
}
public void setLumberCapacity(final int lumberCapacity) {
this.lumberCapacity = lumberCapacity;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public void setDuration(final float duration) {
this.duration = duration;
}
}

View File

@ -6,7 +6,8 @@ import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericAliasedAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
@ -16,8 +17,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
/**
* Was probably named CAbilityReturn in 2002, idk
*/
public class CAbilityReturnResources extends AbstractGenericNoIconAbility {
private final EnumSet<ResourceType> acceptedResourceTypes;
public class CAbilityReturnResources extends AbstractGenericAliasedAbility {
private EnumSet<ResourceType> acceptedResourceTypes;
public CAbilityReturnResources(final int handleId, final War3ID alias,
final EnumSet<ResourceType> acceptedResourceTypes) {
@ -25,6 +26,11 @@ public class CAbilityReturnResources extends AbstractGenericNoIconAbility {
this.acceptedResourceTypes = acceptedResourceTypes;
}
@Override
public <T> T visit(final CAbilityVisitor<T> visitor) {
return visitor.accept(this);
}
@Override
public void onAdd(final CSimulation game, final CUnit unit) {
@ -89,4 +95,8 @@ public class CAbilityReturnResources extends AbstractGenericNoIconAbility {
}
return this.acceptedResourceTypes.contains(resourceType);
}
public void setAcceptedResourceTypes(final EnumSet<ResourceType> acceptedResourceTypes) {
this.acceptedResourceTypes = acceptedResourceTypes;
}
}

View File

@ -1,5 +1,7 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest;
import java.util.EnumSet;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
@ -15,8 +17,6 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
import java.util.EnumSet;
public class CAbilityWispHarvest extends AbstractGenericSingleIconActiveAbility {
public static final EnumSet<CTargetType> TREE_ALIVE_TYPE_ONLY = EnumSet.of(CTargetType.TREE, CTargetType.ALIVE);
@ -27,15 +27,14 @@ public class CAbilityWispHarvest extends AbstractGenericSingleIconActiveAbility
private int periodicIntervalLengthTicks;
private CBehaviorWispHarvest behaviorWispHarvest;
public CAbilityWispHarvest(final int handleId, final War3ID alias, final int lumberPerInterval, float artAttachmentHeight,
float castRange, final float periodicIntervalLength) {
public CAbilityWispHarvest(final int handleId, final War3ID alias, final int lumberPerInterval,
final float artAttachmentHeight, final float castRange, final float periodicIntervalLength) {
super(handleId, alias);
this.lumberPerInterval = lumberPerInterval;
this.artAttachmentHeight = artAttachmentHeight;
this.castRange = castRange;
this.periodicIntervalLength = periodicIntervalLength;
this.periodicIntervalLengthTicks = (int)(periodicIntervalLength / WarsmashConstants.SIMULATION_STEP_TIME);
this.periodicIntervalLengthTicks = (int) (periodicIntervalLength / WarsmashConstants.SIMULATION_STEP_TIME);
}
@Override
@ -129,27 +128,44 @@ public class CAbilityWispHarvest extends AbstractGenericSingleIconActiveAbility
}
public float getArtAttachmentHeight() {
return artAttachmentHeight;
return this.artAttachmentHeight;
}
public float getPeriodicIntervalLength() {
return periodicIntervalLength;
return this.periodicIntervalLength;
}
public int getPeriodicIntervalLengthTicks() {
return periodicIntervalLengthTicks;
return this.periodicIntervalLengthTicks;
}
public int getLumberPerInterval() {
return lumberPerInterval;
return this.lumberPerInterval;
}
public float getCastRange() {
return castRange;
return this.castRange;
}
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
public void setLumberPerInterval(final int lumberPerInterval) {
this.lumberPerInterval = lumberPerInterval;
}
public void setArtAttachmentHeight(final float artAttachmentHeight) {
this.artAttachmentHeight = artAttachmentHeight;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public void setPeriodicIntervalLength(final float periodicIntervalLength) {
this.periodicIntervalLength = periodicIntervalLength;
this.periodicIntervalLengthTicks = (int) (periodicIntervalLength / WarsmashConstants.SIMULATION_STEP_TIME);
}
}

View File

@ -1,6 +1,8 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.util.WarsmashConstants;
@ -10,19 +12,24 @@ 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.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.GetAbilityByRawcodeVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CAbilityData;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
public class CAbilityHero extends AbstractCAbility {
private final List<War3ID> skillsAvailable;
private final Set<War3ID> skillsAvailable;
private int xp;
private int heroLevel;
private int skillPoints;
private int skillPoints = 1;
private HeroStatValue strength;
private HeroStatValue agility;
@ -33,7 +40,7 @@ public class CAbilityHero extends AbstractCAbility {
public CAbilityHero(final int handleId, final List<War3ID> skillsAvailable) {
super(handleId);
this.skillsAvailable = skillsAvailable;
this.skillsAvailable = new LinkedHashSet<>(skillsAvailable);
}
@Override
@ -83,7 +90,25 @@ public class CAbilityHero extends AbstractCAbility {
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return true;
final War3ID orderIdAsRawtype = new War3ID(orderId);
final CAbilityType<?> abilityType = game.getAbilityData().getAbilityType(orderIdAsRawtype);
if (abilityType != null) {
this.skillPoints--;
final CLevelingAbility existingAbility = caster
.getAbility(GetAbilityByRawcodeVisitor.getInstance().reset(orderIdAsRawtype));
if (existingAbility == null) {
final CAbility newAbility = abilityType.createAbility(game.getHandleIdAllocator().createId());
caster.add(game, newAbility);
}
else {
abilityType.setLevel(game, existingAbility, existingAbility.getLevel() + 1);
}
}
else {
game.getCommandErrorListener().showCommandError(caster.getPlayerIndex(),
"NOTEXTERN: Ability is not yet programmed, unable to learn!");
}
return false;
}
@Override
@ -117,7 +142,13 @@ public class CAbilityHero extends AbstractCAbility {
@Override
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) {
receiver.orderIdNotAccepted();
final War3ID orderIdAsRawtype = new War3ID(orderId);
if (this.skillsAvailable.contains(orderIdAsRawtype)) {
receiver.targetOk(null);
}
else {
receiver.orderIdNotAccepted();
}
}
@Override
@ -128,7 +159,28 @@ public class CAbilityHero extends AbstractCAbility {
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
receiver.useOk();
final War3ID orderIdAsRawtype = new War3ID(orderId);
if (this.skillsAvailable.contains(orderIdAsRawtype)) {
if (this.skillPoints > 0) {
final CAbilityData abilityData = game.getAbilityData();
final int priorLevel = unit.getAbilityLevel(orderIdAsRawtype);
final int heroRequiredLevel = abilityData.getHeroRequiredLevel(game, orderIdAsRawtype, priorLevel);
final CAbilityType<?> abilityType = abilityData.getAbilityType(orderIdAsRawtype);
// TODO check abilityType.getRequiredLevel() which api doesn't currently offer!!
if (this.heroLevel >= heroRequiredLevel) {
receiver.useOk();
}
else {
receiver.missingHeroLevelRequirement(heroRequiredLevel);
}
}
else {
receiver.noHeroSkillPointsAvailable();
}
}
else {
receiver.useOk();
}
}
public int getSkillPoints() {
@ -252,7 +304,8 @@ public class CAbilityHero extends AbstractCAbility {
this.intelligence.calculate(this.heroLevel);
final int currentStrength = this.strength.getCurrent();
final int deltaStrength = currentStrength - prevStrength;
final int deltaIntelligence = this.intelligence.getCurrent() - prevIntelligence;
final int currentIntelligence = this.intelligence.getCurrent();
final int deltaIntelligence = currentIntelligence - prevIntelligence;
final int currentAgilityBase = this.agility.getBase();
final int currentAgilityBonus = this.agility.getBonus();
@ -287,6 +340,7 @@ public class CAbilityHero extends AbstractCAbility {
unit.setAgilityDefensePermanentBonus(agilityDefenseBonus);
unit.setAgilityDefenseTemporaryBonus(gameplayConstants.getAgiDefenseBonus() * currentAgilityBonus);
unit.setLifeRegenStrengthBonus(currentStrength * gameplayConstants.getStrRegenBonus());
unit.setManaRegenIntelligenceBonus(currentIntelligence * gameplayConstants.getIntRegenBonus());
}
public static final class HeroStatValue {
@ -339,4 +393,8 @@ public class CAbilityHero extends AbstractCAbility {
return text;
}
}
public Set<War3ID> getSkillsAvailable() {
return this.skillsAvailable;
}
}

View File

@ -13,89 +13,96 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivat
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
public class CAbilityItemHeal extends AbstractGenericSingleIconNoSmartActiveAbility {
private final int lifeToRegain;
private final int lifeToRegain;
public CAbilityItemHeal(int handleId, War3ID alias, int lifeToRegain) {
super(handleId, alias);
this.lifeToRegain = lifeToRegain;
}
public CAbilityItemHeal(final int handleId, final War3ID alias, final int lifeToRegain) {
super(handleId, alias);
this.lifeToRegain = lifeToRegain;
}
@Override
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver<CWidget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver<Void> receiver) {
if(orderId == getBaseOrderId()) {
receiver.targetOk(null);
} else {
receiver.orderIdNotAccepted();
}
}
@Override
protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) {
if (orderId == getBaseOrderId()) {
receiver.targetOk(null);
}
else {
receiver.orderIdNotAccepted();
}
}
@Override
protected void innerCheckCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver) {
receiver.useOk();
}
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
receiver.useOk();
}
@Override
public int getBaseOrderId() {
return OrderIds.heal;
}
@Override
public int getBaseOrderId() {
return OrderIds.heal;
}
@Override
public boolean isToggleOn() {
return false;
}
@Override
public boolean isToggleOn() {
return false;
}
@Override
public void onAdd(CSimulation game, CUnit unit) {
@Override
public void onAdd(final CSimulation game, final CUnit unit) {
}
}
@Override
public void onRemove(CSimulation game, CUnit unit) {
@Override
public void onRemove(final CSimulation game, final CUnit unit) {
}
}
@Override
public void onTick(CSimulation game, CUnit unit) {
@Override
public void onTick(final CSimulation game, final CUnit unit) {
}
}
@Override
public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) {
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
}
@Override
public boolean checkBeforeQueue(CSimulation game, CUnit caster, int orderId, AbilityTarget target) {
if(target == null && orderId == getBaseOrderId()) {
caster.heal(game, lifeToRegain);
game.createSpellEffectOnUnit(caster, getAlias());
return false;
}
return super.checkBeforeQueue(game, caster, orderId, target);
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
if ((target == null) && (orderId == getBaseOrderId())) {
caster.heal(game, this.lifeToRegain);
game.createSpellEffectOnUnit(caster, getAlias());
return false;
}
return super.checkBeforeQueue(game, caster, orderId, target);
}
@Override
public CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target) {
return null;
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
return null;
}
@Override
public CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point) {
return null;
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
final AbilityPointTarget point) {
return null;
}
@Override
public CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId) {
return null;
}
@Override
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
return null;
}
}

View File

@ -17,8 +17,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
public class CAbilityGoldMine extends AbstractGenericNoIconAbility {
private int gold;
private final float miningDuration;
private final int miningCapacity;
private float miningDuration;
private int miningCapacity;
private final List<CBehaviorHarvest> activeMiners;
private boolean wasEmpty;
@ -137,4 +137,11 @@ public class CAbilityGoldMine extends AbstractGenericNoIconAbility {
return this.miningDuration;
}
public void setMiningCapacity(final int miningCapacity) {
this.miningCapacity = miningCapacity;
}
public void setMiningDuration(final float miningDuration) {
this.miningDuration = miningDuration;
}
}

View File

@ -55,9 +55,20 @@ public final class CAbilityQueue extends AbstractCAbility {
requirementsMet = false;
}
}
final boolean isHeroType = unitType.isHero();
if (isHeroType) {
final int heroCount = player.getHeroCount(game, true);
final List<CUnitTypeRequirement> requirementsTier = unitType.getRequirementsTier(heroCount);
for (final CUnitTypeRequirement requirement : requirementsTier) {
if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement.getRequiredLevel()) {
requirementsMet = false;
}
}
}
final boolean skipGoldLumberCost = isHeroType && (player.getHeroTokens() > 0);
if (requirementsMet) {
if (player.getGold() >= unitType.getGoldCost()) {
if (player.getLumber() >= unitType.getLumberCost()) {
if ((player.getGold() >= unitType.getGoldCost()) || skipGoldLumberCost) {
if ((player.getLumber() >= unitType.getLumberCost()) || skipGoldLumberCost) {
if ((unitType.getFoodUsed() == 0)
|| ((player.getFoodUsed() + unitType.getFoodUsed()) <= player.getFoodCap())) {
receiver.useOk();
@ -79,6 +90,17 @@ public final class CAbilityQueue extends AbstractCAbility {
for (final CUnitTypeRequirement requirement : requirements) {
receiver.missingRequirement(requirement.getRequirement(), requirement.getRequiredLevel());
}
if (isHeroType) {
final int heroCount = player.getHeroCount(game, true);
final List<CUnitTypeRequirement> requirementsTier = unitType.getRequirementsTier(heroCount);
for (final CUnitTypeRequirement requirement : requirementsTier) {
if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement
.getRequiredLevel()) {
receiver.missingRequirement(requirement.getRequirement(),
requirement.getRequiredLevel());
}
}
}
}
else {
receiver.techtreeMaximumReached();
@ -177,4 +199,11 @@ public final class CAbilityQueue extends AbstractCAbility {
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
public void onSetUnitType(final CUnitType unitType) {
this.unitsTrained.clear();
this.researchesAvailable.clear();
this.unitsTrained.addAll(unitType.getUnitsTrained());
this.researchesAvailable.addAll(unitType.getResearchesAvailable());
}
}

View File

@ -5,6 +5,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
@ -12,7 +13,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
public class CAbilityRally extends AbstractCAbility {
public class CAbilityRally extends AbstractCAbility implements CLevelingAbility {
public CAbilityRally(final int handleId) {
super(handleId);
@ -73,7 +74,8 @@ public class CAbilityRally extends AbstractCAbility {
}
@Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) {
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return true;
}
@ -108,4 +110,13 @@ public class CAbilityRally extends AbstractCAbility {
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
@Override
public int getLevel() {
return 1; // TODO maybe less hacky solution
}
@Override
public void setLevel(final int level) {
}
}

View File

@ -0,0 +1,200 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.skills.human.paladin;
import java.util.EnumSet;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconNoSmartActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.skills.human.paladin.CBehaviorHolyLight;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver.TargetType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
public class CAbilityHolyLight extends AbstractGenericSingleIconNoSmartActiveAbility {
private int manaCost;
private int healAmount;
private float castRange;
private float cooldown;
private EnumSet<CTargetType> targetsAllowed;
private float cooldownRemaining;
private CBehaviorHolyLight behaviorHolyLight;
public CAbilityHolyLight(final int handleId, final War3ID alias, final int manaCost, final int healAmount,
final float castRange, final float cooldown, final EnumSet<CTargetType> targetsAllowed) {
super(handleId, alias);
this.manaCost = manaCost;
this.healAmount = healAmount;
this.castRange = castRange;
this.cooldown = cooldown;
this.targetsAllowed = targetsAllowed;
}
@Override
public int getBaseOrderId() {
return OrderIds.holybolt;
}
@Override
public boolean isToggleOn() {
return false;
}
@Override
public void onAdd(final CSimulation game, final CUnit unit) {
this.behaviorHolyLight = new CBehaviorHolyLight(unit, this);
}
@Override
public void onRemove(final CSimulation game, final CUnit unit) {
}
@Override
public void onTick(final CSimulation game, final CUnit unit) {
if (this.cooldownRemaining > 0) {
this.cooldownRemaining -= WarsmashConstants.SIMULATION_STEP_TIME;
}
}
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
return this.behaviorHolyLight.reset(target);
}
@Override
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
final AbilityPointTarget point) {
return null;
}
@Override
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
return null;
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
if ((target instanceof CUnit) && target.canBeTargetedBy(game, unit, this.targetsAllowed)) {
if (!unit.isMovementDisabled() || unit.canReach(target, this.castRange)) {
final CUnit targetUnit = (CUnit) target;
final CPlayer player = game.getPlayer(unit.getPlayerIndex());
final boolean undead = targetUnit.getClassifications().contains(CUnitClassification.UNDEAD);
final boolean ally = player.hasAlliance(targetUnit.getPlayerIndex(), CAllianceType.PASSIVE);
if (undead != ally) {
if (ally && (targetUnit.getLife() >= targetUnit.getMaximumLife())) {
receiver.alreadyFullHealth();
}
else {
receiver.targetOk(targetUnit);
}
}
else {
receiver.notHolyBoltTarget();
}
}
else {
receiver.targetOutsideRange();
}
}
else {
receiver.mustTargetType(TargetType.UNIT);
}
}
@Override
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
if (this.cooldownRemaining > 0) {
receiver.cooldownNotYetReady(this.cooldownRemaining, this.cooldown);
}
else if (unit.getMana() < this.manaCost) {
receiver.notEnoughResources(ResourceType.MANA);
}
else {
receiver.useOk();
}
}
public void setManaCost(final int manaCost) {
this.manaCost = manaCost;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public void setCooldown(final float cooldown) {
this.cooldown = cooldown;
}
public void setHealAmount(final int healAmount) {
this.healAmount = healAmount;
}
public void setTargetsAllowed(final EnumSet<CTargetType> targetsAllowed) {
this.targetsAllowed = targetsAllowed;
}
public void setCooldownRemaining(final float cooldownRemaining) {
this.cooldownRemaining = cooldownRemaining;
}
public int getManaCost() {
return this.manaCost;
}
@Override
public int getUIManaCost() {
return getManaCost();
}
public int getHealAmount() {
return this.healAmount;
}
public float getCastRange() {
return this.castRange;
}
public float getCooldown() {
return this.cooldown;
}
public EnumSet<CTargetType> getTargetsAllowed() {
return this.targetsAllowed;
}
public float getCooldownRemaining() {
return this.cooldownRemaining;
}
}

View File

@ -17,8 +17,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
public class CAbilityCarrionSwarmDummy extends AbstractGenericSingleIconNoSmartActiveAbility {
private final float castRange;
private final EnumSet<CTargetType> targetsAllowed;
private float castRange;
private EnumSet<CTargetType> targetsAllowed;
private CBehaviorCarrionSwarmDummy behaviorCarrionSwarmDummy;
public CAbilityCarrionSwarmDummy(final int handleId, final War3ID alias, final float castRange,
@ -115,4 +115,12 @@ public class CAbilityCarrionSwarmDummy extends AbstractGenericSingleIconNoSmartA
public EnumSet<CTargetType> getTargetsAllowed() {
return this.targetsAllowed;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public void setTargetsAllowed(final EnumSet<CTargetType> targetsAllowed) {
this.targetsAllowed = targetsAllowed;
}
}

View File

@ -14,7 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetC
public class CAbilityChannelTest extends AbstractGenericSingleIconNoSmartActiveAbility {
private CBehaviorChannelTest behaviorChannelTest;
private final float artDuration;
private float artDuration;
public CAbilityChannelTest(final int handleId, final War3ID alias, final float artDuration) {
super(handleId, alias);
@ -88,4 +88,7 @@ public class CAbilityChannelTest extends AbstractGenericSingleIconNoSmartActiveA
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
public void setArtDuration(final float artDuration) {
this.artDuration = artDuration;
}
}

View File

@ -23,15 +23,15 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
public class CAbilityCoupleInstant extends AbstractGenericSingleIconNoSmartActiveAbility {
private final War3ID resultingUnitType;
private final War3ID partnerUnitType;
private final boolean moveToPartner;
private final float castRange;
private final float area;
private final EnumSet<CTargetType> targetsAllowed;
private War3ID resultingUnitType;
private War3ID partnerUnitType;
private boolean moveToPartner;
private float castRange;
private float area;
private EnumSet<CTargetType> targetsAllowed;
private CBehaviorCoupleInstant behaviorCoupleInstant;
private final int goldCost;
private final int lumberCost;
private int goldCost;
private int lumberCost;
public CAbilityCoupleInstant(final int handleId, final War3ID alias, final War3ID resultingUnitType,
final War3ID partnerUnitType, final boolean moveToPartner, final float castRange, final float area,
@ -210,4 +210,36 @@ public class CAbilityCoupleInstant extends AbstractGenericSingleIconNoSmartActiv
public int getUILumberCost() {
return this.lumberCost;
}
public void setResultingUnitType(final War3ID resultingUnitType) {
this.resultingUnitType = resultingUnitType;
}
public void setPartnerUnitType(final War3ID partnerUnitType) {
this.partnerUnitType = partnerUnitType;
}
public void setMoveToPartner(final boolean moveToPartner) {
this.moveToPartner = moveToPartner;
}
public void setCastRange(final float castRange) {
this.castRange = castRange;
}
public void setArea(final float area) {
this.area = area;
}
public void setTargetsAllowed(final EnumSet<CTargetType> targetsAllowed) {
this.targetsAllowed = targetsAllowed;
}
public void setGoldCost(final int goldCost) {
this.goldCost = goldCost;
}
public void setLumberCost(final int lumberCost) {
this.lumberCost = lumberCost;
}
}

View File

@ -4,7 +4,9 @@ import java.util.EnumSet;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
public abstract class CAbilityType<TYPE_LEVEL_DATA extends CAbilityTypeLevelData> {
@ -39,4 +41,6 @@ public abstract class CAbilityType<TYPE_LEVEL_DATA extends CAbilityTypeLevelData
public abstract CAbility createAbility(int handleId);
public abstract void setLevel(CSimulation game, CLevelingAbility existingAbility, int level);
}

View File

@ -16,6 +16,8 @@ public abstract class AbstractCAbilityTypeDefinition<TYPE_LEVEL_DATA extends CAb
protected static final War3ID CAST_RANGE = War3ID.fromString("aran");
protected static final War3ID DURATION = War3ID.fromString("adur");
protected static final War3ID AREA = War3ID.fromString("aare");
protected static final War3ID MANA_COST = War3ID.fromString("amcs");
protected static final War3ID COOLDOWN = War3ID.fromString("acdn");
@Override
public CAbilityType<?> createAbilityType(final War3ID alias, final MutableGameObject abilityEditorData) {

View File

@ -0,0 +1,36 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl;
import java.util.EnumSet;
import java.util.List;
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHolyLight;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHolyLightLevelData;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
public class CAbilityTypeDefinitionHolyLight extends AbstractCAbilityTypeDefinition<CAbilityTypeHolyLightLevelData>
implements CAbilityTypeDefinition {
private static final War3ID HEAL_AMOUNT = War3ID.fromString("Hhb1");
@Override
protected CAbilityTypeHolyLightLevelData createLevelData(final MutableGameObject abilityEditorData,
final int level) {
final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level);
final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level);
final int healAmount = (int) abilityEditorData.getFieldAsFloat(HEAL_AMOUNT, level);
final float cooldown = abilityEditorData.getFieldAsFloat(COOLDOWN, level);
final int manaCost = abilityEditorData.getFieldAsInteger(MANA_COST, level);
final EnumSet<CTargetType> targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString);
return new CAbilityTypeHolyLightLevelData(targetsAllowedAtLevel, castRange, cooldown, healAmount, manaCost);
}
@Override
protected CAbilityType<?> innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData,
final List<CAbilityTypeHolyLightLevelData> levelData) {
return new CAbilityTypeHolyLight(alias, abilityEditorData.getCode(), levelData);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityCarrionSwarmDummy;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -21,4 +23,13 @@ public class CAbilityTypeCarrionSwarmDummy extends CAbilityType<CAbilityTypeCarr
levelData.getTargetsAllowed());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeCarrionSwarmDummyLevelData levelData = getLevelData(level - 1);
final CAbilityCarrionSwarmDummy heroAbility = ((CAbilityCarrionSwarmDummy) existingAbility);
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setTargetsAllowed(levelData.getTargetsAllowed());
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityChannelTest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -20,4 +22,12 @@ public class CAbilityTypeChannelTest extends CAbilityType<CAbilityTypeChannelTes
return new CAbilityChannelTest(handleId, getAlias(), levelData.getArtDuration());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeChannelTestLevelData levelData = getLevelData(level - 1);
final CAbilityChannelTest heroAbility = ((CAbilityChannelTest) existingAbility);
heroAbility.setArtDuration(levelData.getArtDuration());
heroAbility.setLevel(level);
}
}

View File

@ -3,8 +3,10 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
public class CAbilityTypeColdArrows extends CAbilityType<CAbilityTypeColdArrowsLevelData> {
@ -19,4 +21,11 @@ public class CAbilityTypeColdArrows extends CAbilityType<CAbilityTypeColdArrowsL
return new CAbilityColdArrows(getAlias(), handleId);
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeColdArrowsLevelData levelData = getLevelData(level - 1);
final CAbilityColdArrows heroAbility = ((CAbilityColdArrows) existingAbility);
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityCoupleInstant;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -22,4 +24,21 @@ public class CAbilityTypeCoupleInstant extends CAbilityType<CAbilityTypeCoupleIn
levelData.getArea(), levelData.getTargetsAllowed(), levelData.getGoldCost(), levelData.getLumberCost());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeCoupleInstantLevelData levelData = getLevelData(level - 1);
final CAbilityCoupleInstant heroAbility = ((CAbilityCoupleInstant) existingAbility);
heroAbility.setResultingUnitType(levelData.getResultingUnitTypeId());
heroAbility.setPartnerUnitType(levelData.getPartnerUnitTypeId());
heroAbility.setMoveToPartner(levelData.isMoveToPartner());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setArea(levelData.getArea());
heroAbility.setTargetsAllowed(levelData.getTargetsAllowed());
heroAbility.setGoldCost(levelData.getGoldCost());
heroAbility.setLumberCost(levelData.getLumberCost());
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -21,4 +23,14 @@ public class CAbilityTypeGoldMine extends CAbilityType<CAbilityTypeGoldMineLevel
levelData.getMiningCapacity());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeGoldMineLevelData levelData = getLevelData(level - 1);
final CAbilityGoldMine heroAbility = ((CAbilityGoldMine) existingAbility);
heroAbility.setMiningCapacity(levelData.getMiningCapacity());
heroAbility.setMiningDuration(levelData.getMiningDuration());
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -21,4 +23,17 @@ public class CAbilityTypeHarvest extends CAbilityType<CAbilityTypeHarvestLevelDa
levelData.getLumberCapacity(), levelData.getCastRange(), levelData.getDuration());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeHarvestLevelData levelData = getLevelData(level - 1);
final CAbilityHarvest heroAbility = ((CAbilityHarvest) existingAbility);
heroAbility.setDamageToTree(levelData.getDamageToTree());
heroAbility.setGoldCapacity(levelData.getGoldCapacity());
heroAbility.setLumberCapacity(levelData.getLumberCapacity());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setDuration(levelData.getDuration());
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -21,4 +23,16 @@ public class CAbilityTypeHarvestLumber extends CAbilityType<CAbilityTypeHarvestL
levelData.getCastRange(), levelData.getDuration());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeHarvestLumberLevelData levelData = getLevelData(level - 1);
final CAbilityHarvest heroAbility = ((CAbilityHarvest) existingAbility);
heroAbility.setDamageToTree(levelData.getDamageToTree());
heroAbility.setLumberCapacity(levelData.getLumberCapacity());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setDuration(levelData.getDuration());
heroAbility.setLevel(level);
}
}

View File

@ -0,0 +1,42 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.skills.human.paladin.CAbilityHolyLight;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
public class CAbilityTypeHolyLight extends CAbilityType<CAbilityTypeHolyLightLevelData> {
public CAbilityTypeHolyLight(final War3ID alias, final War3ID code,
final List<CAbilityTypeHolyLightLevelData> levelData) {
super(alias, code, levelData);
}
@Override
public CAbility createAbility(final int handleId) {
final CAbilityTypeHolyLightLevelData levelData = getLevelData(0);
return new CAbilityHolyLight(handleId, getAlias(), levelData.getManaCost(), levelData.getHealAmount(),
levelData.getCastRange(), levelData.getCooldown(), levelData.getTargetsAllowed());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeHolyLightLevelData levelData = getLevelData(level - 1);
final CAbilityHolyLight heroAbility = ((CAbilityHolyLight) existingAbility);
heroAbility.setManaCost(levelData.getManaCost());
heroAbility.setHealAmount(levelData.getHealAmount());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setCooldown(levelData.getCooldown());
heroAbility.setTargetsAllowed(levelData.getTargetsAllowed());
heroAbility.setLevel(level);
}
}

View File

@ -0,0 +1,39 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
import java.util.EnumSet;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
public class CAbilityTypeHolyLightLevelData extends CAbilityTypeLevelData {
private final float castRange;
private final float cooldown;
private final int healAmount;
private final int manaCost;
public CAbilityTypeHolyLightLevelData(final EnumSet<CTargetType> targetsAllowed, final float castRange,
final float cooldown, final int healAmount, final int manaCost) {
super(targetsAllowed);
this.castRange = castRange;
this.cooldown = cooldown;
this.healAmount = healAmount;
this.manaCost = manaCost;
}
public float getCastRange() {
return this.castRange;
}
public float getCooldown() {
return this.cooldown;
}
public int getHealAmount() {
return this.healAmount;
}
public int getManaCost() {
return this.manaCost;
}
}

View File

@ -1,16 +1,18 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import java.util.List;
public class CAbilityTypeHumanRepair extends CAbilityType<CAbilityTypeHumanRepairLevelData> {
public CAbilityTypeHumanRepair(final War3ID alias, final War3ID code,
final List<CAbilityTypeHumanRepairLevelData> levelData) {
final List<CAbilityTypeHumanRepairLevelData> levelData) {
super(alias, code, levelData);
}
@ -22,4 +24,20 @@ public class CAbilityTypeHumanRepair extends CAbilityType<CAbilityTypeHumanRepai
levelData.getCastRange());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeHumanRepairLevelData levelData = getLevelData(level - 1);
final CAbilityHumanRepair heroAbility = ((CAbilityHumanRepair) existingAbility);
heroAbility.setTargetsAllowed(levelData.getTargetsAllowed());
heroAbility.setNavalRangeBonus(levelData.getNavalRangeBonus());
heroAbility.setRepairCostRatio(levelData.getRepairCostRatio());
heroAbility.setRepairTimeRatio(levelData.getRepairTimeRatio());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setLevel(level);
}
}

View File

@ -3,7 +3,9 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
@ -21,4 +23,16 @@ public class CAbilityTypeInventory extends CAbilityType<CAbilityTypeInventoryLev
levelData.isCanUseItems(), levelData.isDropItemsOnDeath(), levelData.getItemCapacity());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeInventoryLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,8 +3,10 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityInvulnerable;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
@ -21,4 +23,15 @@ public class CAbilityTypeInvulnerable extends CAbilityType<CAbilityTypeLevelData
return new CAbilityInvulnerable(handleId, getAlias());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,9 +3,12 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemAttackBonus;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemAttackBonus extends CAbilityType<CAbilityTypeItemAttackBonusLevelData> {
@ -20,4 +23,15 @@ public class CAbilityTypeItemAttackBonus extends CAbilityType<CAbilityTypeItemAt
return new CAbilityItemAttackBonus(handleId, getAlias(), levelData.getDamageBonus());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,9 +3,12 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemDefenseBonus;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemDefenseBonus extends CAbilityType<CAbilityTypeItemDefenseBonusLevelData> {
@ -20,4 +23,15 @@ public class CAbilityTypeItemDefenseBonus extends CAbilityType<CAbilityTypeItemD
return new CAbilityItemDefenseBonus(handleId, getAlias(), levelData.getDefenseBonus());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -1,17 +1,19 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemHeal;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityChannelTest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemHeal;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemHeal extends CAbilityType<CAbilityTypeItemHealLevelData> {
public CAbilityTypeItemHeal(final War3ID alias, final War3ID code,
final List<CAbilityTypeItemHealLevelData> levelData) {
final List<CAbilityTypeItemHealLevelData> levelData) {
super(alias, code, levelData);
}
@ -21,4 +23,15 @@ public class CAbilityTypeItemHeal extends CAbilityType<CAbilityTypeItemHealLevel
return new CAbilityItemHeal(handleId, getAlias(), levelData.getLifeToRegain());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,9 +3,12 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemLifeBonus;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemLifeBonus extends CAbilityType<CAbilityTypeItemLifeBonusLevelData> {
@ -20,4 +23,15 @@ public class CAbilityTypeItemLifeBonus extends CAbilityType<CAbilityTypeItemLife
return new CAbilityItemLifeBonus(handleId, getAlias(), levelData.getLifeBonus());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,9 +3,12 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemPermanentStatGain;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemPermanentStatGain extends CAbilityType<CAbilityTypeItemStatBonusLevelData> {
@ -21,4 +24,15 @@ public class CAbilityTypeItemPermanentStatGain extends CAbilityType<CAbilityType
levelData.getIntelligence());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -3,9 +3,12 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.im
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemStatBonus;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
public class CAbilityTypeItemStatBonus extends CAbilityType<CAbilityTypeItemStatBonusLevelData> {
@ -21,4 +24,15 @@ public class CAbilityTypeItemStatBonus extends CAbilityType<CAbilityTypeItemStat
levelData.getIntelligence());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeLevelData levelData = getLevelData(level - 1);
final CLevelingAbility heroAbility = (existingAbility);
// TODO ignores fields
heroAbility.setLevel(level);
}
}

View File

@ -4,7 +4,9 @@ import java.util.EnumSet;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
@ -29,4 +31,22 @@ public class CAbilityTypeReturnResources extends CAbilityType<CAbilityTypeReturn
return new CAbilityReturnResources(handleId, getAlias(), acceptedResourceTypes);
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeReturnResourcesLevelData levelData = getLevelData(level - 1);
final CAbilityReturnResources heroAbility = (CAbilityReturnResources) existingAbility;
final EnumSet<ResourceType> acceptedResourceTypes = EnumSet.noneOf(ResourceType.class);
if (levelData.isAcceptsGold()) {
acceptedResourceTypes.add(ResourceType.GOLD);
}
if (levelData.isAcceptsLumber()) {
acceptedResourceTypes.add(ResourceType.LUMBER);
}
heroAbility.setAcceptedResourceTypes(acceptedResourceTypes);
heroAbility.setLevel(level);
}
}

View File

@ -1,25 +1,38 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
import java.util.List;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityWispHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import java.util.List;
public class CAbilityTypeWispHarvest extends CAbilityType<CAbilityTypeWispHarvestLevelData> {
public CAbilityTypeWispHarvest(final War3ID alias, final War3ID code,
final List<CAbilityTypeWispHarvestLevelData> levelData) {
final List<CAbilityTypeWispHarvestLevelData> levelData) {
super(alias, code, levelData);
}
@Override
public CAbility createAbility(final int handleId) {
final CAbilityTypeWispHarvestLevelData levelData = getLevelData(0);
return new CAbilityWispHarvest(handleId, getAlias(), levelData.getLumberPerInterval(), levelData.getArtAttachmentHeight(),
levelData.getCastRange(), levelData.getDuration());
return new CAbilityWispHarvest(handleId, getAlias(), levelData.getLumberPerInterval(),
levelData.getArtAttachmentHeight(), levelData.getCastRange(), levelData.getDuration());
}
@Override
public void setLevel(final CSimulation game, final CLevelingAbility existingAbility, final int level) {
final CAbilityTypeWispHarvestLevelData levelData = getLevelData(level - 1);
final CAbilityWispHarvest heroAbility = ((CAbilityWispHarvest) existingAbility);
heroAbility.setLumberPerInterval(levelData.getLumberPerInterval());
heroAbility.setArtAttachmentHeight(levelData.getArtAttachmentHeight());
heroAbility.setCastRange(levelData.getCastRange());
heroAbility.setPeriodicIntervalLength(levelData.getDuration());
heroAbility.setLevel(level);
}
}

View File

@ -36,6 +36,10 @@ public final class CAbilityUpgrade extends AbstractCAbility {
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
if (unit.getBuildQueueTypes()[0] != null) {
receiver.disabled();
return;
}
final War3ID orderIdAsRawtype = new War3ID(orderId);
if (this.upgradesTo.contains(orderIdAsRawtype) && (unit.getBuildQueue()[0] == null)) {
final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype);
@ -50,10 +54,21 @@ public final class CAbilityUpgrade extends AbstractCAbility {
}
}
if (requirementsMet) {
if (player.getGold() >= unitType.getGoldCost()) {
if (player.getLumber() >= unitType.getLumberCost()) {
if ((unitType.getFoodUsed() == 0)
|| ((player.getFoodUsed() + unitType.getFoodUsed()) <= player.getFoodCap())) {
int relativeOffsetGold;
int relativeOffsetLumber;
final CUnitType existingUnitType = unit.getUnitType();
if (game.getGameplayConstants().isRelativeUpgradeCosts()) {
relativeOffsetGold = existingUnitType.getGoldCost();
relativeOffsetLumber = existingUnitType.getLumberCost();
}
else {
relativeOffsetGold = 0;
relativeOffsetLumber = 0;
}
if ((player.getGold() + relativeOffsetGold) >= unitType.getGoldCost()) {
if ((player.getLumber() + relativeOffsetLumber) >= unitType.getLumberCost()) {
final int foodNeeded = unitType.getFoodUsed() - existingUnitType.getFoodUsed();
if ((foodNeeded == 0) || ((player.getFoodUsed() + foodNeeded) <= player.getFoodCap())) {
receiver.useOk();
}
else {
@ -168,4 +183,9 @@ public final class CAbilityUpgrade extends AbstractCAbility {
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
public void onSetUnitType(final CUnitType unitType) {
this.upgradesTo.clear();
this.upgradesTo.addAll(unitType.getUpgradesTo());
}
}

View File

@ -1,7 +1,7 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGenericDoNothing;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress;
@ -14,6 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAb
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally;
@ -66,7 +67,7 @@ public class AbilityDisableWhileUnderConstructionVisitor implements CAbilityVisi
}
@Override
public Void accept(final CAbilityGeneric ability) {
public Void accept(final CAbilityGenericDoNothing ability) {
ability.setDisabled(true);
ability.setIconShowing(false);
return null;
@ -142,6 +143,11 @@ public class AbilityDisableWhileUnderConstructionVisitor implements CAbilityVisi
return null;
}
@Override
public Void accept(final CAbilityReturnResources ability) {
return null;
}
@Override
public Void accept(final CAbilityHero ability) {
ability.setDisabled(true);

View File

@ -0,0 +1,160 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build;
import java.awt.image.BufferedImage;
import java.util.EnumSet;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
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.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityTargetCheckReceiver;
public class CBehaviorHumanBuild extends CAbstractRangedBehavior {
private int highlightOrderId;
private War3ID orderId;
private boolean unitCreated = false;
public CBehaviorHumanBuild(final CUnit unit) {
super(unit);
}
public CBehavior reset(final AbilityPointTarget target, final int orderId, final int highlightOrderId) {
this.highlightOrderId = highlightOrderId;
this.orderId = new War3ID(orderId);
this.unitCreated = false;
return innerReset(target);
}
@Override
public boolean isWithinRange(final CSimulation simulation) {
final CUnitType unitType = simulation.getUnitData().getUnitType(this.orderId);
return this.unit.canReachToPathing(0, simulation.getGameplayConstants().getBuildingAngle(),
unitType.getBuildingPathingPixelMap(), this.target.getX(), this.target.getY());
}
@Override
public int getHighlightOrderId() {
return this.highlightOrderId;
}
@Override
protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) {
if (!this.unitCreated) {
this.unitCreated = true;
final CUnitType unitTypeToCreate = simulation.getUnitData().getUnitType(this.orderId);
final BufferedImage buildingPathingPixelMap = unitTypeToCreate.getBuildingPathingPixelMap();
boolean buildLocationObstructed = false;
if (buildingPathingPixelMap != null) {
final EnumSet<CBuildingPathingType> preventedPathingTypes = unitTypeToCreate.getPreventedPathingTypes();
final EnumSet<CBuildingPathingType> requiredPathingTypes = unitTypeToCreate.getRequiredPathingTypes();
if (!simulation.getPathingGrid().checkPathingTexture(this.target.getX(), this.target.getY(),
(int) simulation.getGameplayConstants().getBuildingAngle(), buildingPathingPixelMap,
preventedPathingTypes, requiredPathingTypes, simulation.getWorldCollision(), this.unit)) {
buildLocationObstructed = true;
}
}
final int playerIndex = this.unit.getPlayerIndex();
if (!buildLocationObstructed) {
final CUnit constructedStructure = simulation.createUnit(this.orderId, playerIndex, this.target.getX(),
this.target.getY(), simulation.getGameplayConstants().getBuildingAngle());
constructedStructure.setConstructing(true);
constructedStructure.setConstructingPaused(true);
constructedStructure.setLife(simulation,
constructedStructure.getMaximumLife() * WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE);
constructedStructure.setFoodUsed(unitTypeToCreate.getFoodUsed());
constructedStructure.add(simulation,
new CAbilityBuildInProgress(simulation.getHandleIdAllocator().createId()));
for (final CAbility ability : constructedStructure.getAbilities()) {
ability.visit(AbilityDisableWhileUnderConstructionVisitor.INSTANCE);
}
final float deltaX = this.unit.getX() - this.target.getX();
final float deltaY = this.unit.getY() - this.target.getY();
final float delta = (float) Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
this.unit.setPointAndCheckUnstuck(
this.target.getX() + ((deltaX / delta) * unitTypeToCreate.getCollisionSize()),
this.target.getY() + ((deltaY / delta) * unitTypeToCreate.getCollisionSize()), simulation);
simulation.unitRepositioned(this.unit);
simulation.getPlayer(playerIndex).addTechtreeInProgress(this.orderId);
simulation.unitConstructedEvent(this.unit, constructedStructure);
for (final CAbility ability : this.unit.getAbilities()) {
if (ability instanceof CAbilityHumanRepair) {
final int baseOrderId = ((CAbilityHumanRepair) ability).getBaseOrderId();
ability.checkCanUse(simulation, this.unit, baseOrderId,
BooleanAbilityActivationReceiver.INSTANCE);
if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) {
final BooleanAbilityTargetCheckReceiver<CWidget> targetCheckReceiver = BooleanAbilityTargetCheckReceiver
.getInstance();
ability.checkCanTarget(simulation, this.unit, baseOrderId, constructedStructure,
targetCheckReceiver.reset());
if (targetCheckReceiver.isTargetable()) {
return ability.begin(simulation, this.unit, baseOrderId, constructedStructure);
}
}
}
}
}
else {
final CPlayer player = simulation.getPlayer(playerIndex);
refund(player, unitTypeToCreate);
simulation.getCommandErrorListener().showCantPlaceError(playerIndex);
}
}
return this.unit.pollNextOrderBehavior(simulation);
}
@Override
protected boolean checkTargetStillValid(final CSimulation simulation) {
return true;
}
@Override
protected CBehavior updateOnInvalidTarget(final CSimulation simulation) {
return this.unit.pollNextOrderBehavior(simulation);
}
@Override
protected void resetBeforeMoving(final CSimulation simulation) {
}
@Override
public void begin(final CSimulation game) {
}
@Override
public void end(final CSimulation game, final boolean interrupted) {
if (!this.unitCreated && interrupted) {
final CPlayer player = game.getPlayer(this.unit.getPlayerIndex());
final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId);
refund(player, unitTypeToCreate);
}
}
private void refund(final CPlayer player, final CUnitType unitTypeToCreate) {
player.setFoodUsed(player.getFoodUsed() - unitTypeToCreate.getFoodUsed());
player.refundFor(unitTypeToCreate);
}
@Override
public void endMove(final CSimulation game, final boolean interrupted) {
if (!this.unitCreated && interrupted) {
final CPlayer player = game.getPlayer(this.unit.getPlayerIndex());
final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId);
refund(player, unitTypeToCreate);
}
}
}

View File

@ -1,88 +1,107 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens;
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.*;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveAndTargetableVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
public class CBehaviorHumanRepair extends CAbstractRangedBehavior {
private final CAbilityHumanRepair ability;
private AbilityTargetStillAliveAndTargetableVisitor stillAliveVisitor;
private final CAbilityHumanRepair ability;
private final AbilityTargetStillAliveAndTargetableVisitor stillAliveVisitor;
public CBehaviorHumanRepair(CUnit unit, CAbilityHumanRepair ability) {
super(unit);
this.ability = ability;
stillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor();
}
public CBehaviorHumanRepair(final CUnit unit, final CAbilityHumanRepair ability) {
super(unit);
this.ability = ability;
this.stillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor();
}
public CBehaviorHumanRepair reset(final CWidget target) {
innerReset(target, false);
return this;
}
public CBehaviorHumanRepair reset(final CWidget target) {
innerReset(target, false);
return this;
}
@Override
public boolean isWithinRange(CSimulation simulation) {
float castRange = ability.getCastRange();
if(target instanceof CUnit) {
CUnit unitTarget = (CUnit)target;
if(unitTarget.getUnitType().getMovementType() == PathingGrid.MovementType.FLOAT) {
castRange += ability.getNavalRangeBonus();
}
}
return unit.canReach(target, castRange);
}
@Override
public boolean isWithinRange(final CSimulation simulation) {
float castRange = this.ability.getCastRange();
if (this.target instanceof CUnit) {
final CUnit unitTarget = (CUnit) this.target;
if (unitTarget.getUnitType().getMovementType() == PathingGrid.MovementType.FLOAT) {
castRange += this.ability.getNavalRangeBonus();
}
}
return this.unit.canReach(this.target, castRange);
}
@Override
protected CBehavior update(CSimulation simulation, boolean withinFacingWindow) {
unit.getUnitAnimationListener().playAnimation(false, AnimationTokens.PrimaryTag.STAND,
SequenceUtils.WORK, 1.0f, true);
if(this.target instanceof CWidget) {
CWidget targetWidget = (CWidget) this.target;
float newLifeValue = targetWidget.getLife() + 1;
boolean done = newLifeValue > targetWidget.getMaxLife();
if(done) {
newLifeValue = targetWidget.getMaxLife();
}
targetWidget.setLife(simulation, newLifeValue);
if(done) {
return unit.pollNextOrderBehavior(simulation);
}
}
return this;
}
@Override
protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) {
this.unit.getUnitAnimationListener().playAnimation(false, AnimationTokens.PrimaryTag.STAND, SequenceUtils.WORK,
1.0f, true);
if (this.target instanceof CWidget) {
final CWidget targetWidget = (CWidget) this.target;
if ((targetWidget instanceof CUnit) && ((CUnit) targetWidget).isConstructing()) {
final CUnit targetUnit = (CUnit) targetWidget;
targetUnit.setConstructionProgress(
targetUnit.getConstructionProgress() + WarsmashConstants.SIMULATION_STEP_TIME);
final int buildTime = targetUnit.getUnitType().getBuildTime();
final float healthGain = (WarsmashConstants.SIMULATION_STEP_TIME / buildTime)
* (targetUnit.getMaximumLife() * (1.0f - WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE));
targetUnit.setLife(simulation,
Math.min(targetUnit.getLife() + healthGain, targetUnit.getMaximumLife()));
if (targetUnit.getConstructionProgress() >= buildTime) {
return this.unit.pollNextOrderBehavior(simulation);
}
}
else {
float newLifeValue = targetWidget.getLife() + 1;
final boolean done = newLifeValue > targetWidget.getMaxLife();
if (done) {
newLifeValue = targetWidget.getMaxLife();
}
targetWidget.setLife(simulation, newLifeValue);
if (done) {
return this.unit.pollNextOrderBehavior(simulation);
}
}
}
return this;
}
@Override
protected CBehavior updateOnInvalidTarget(CSimulation simulation) {
return unit.pollNextOrderBehavior(simulation);
}
@Override
protected CBehavior updateOnInvalidTarget(final CSimulation simulation) {
return this.unit.pollNextOrderBehavior(simulation);
}
@Override
protected boolean checkTargetStillValid(CSimulation simulation) {
return target.visit(stillAliveVisitor.reset(simulation, unit, ability.getTargetsAllowed()));
}
@Override
protected boolean checkTargetStillValid(final CSimulation simulation) {
return this.target.visit(this.stillAliveVisitor.reset(simulation, this.unit, this.ability.getTargetsAllowed()));
}
@Override
protected void resetBeforeMoving(CSimulation simulation) {}
@Override
protected void resetBeforeMoving(final CSimulation simulation) {
}
@Override
public void begin(CSimulation game) {}
@Override
public void begin(final CSimulation game) {
}
@Override
public void end(CSimulation game, boolean interrupted) {}
@Override
public void end(final CSimulation game, final boolean interrupted) {
}
@Override
public void endMove(CSimulation game, boolean interrupted) {}
@Override
public void endMove(final CSimulation game, final boolean interrupted) {
}
@Override
public int getHighlightOrderId() {
return OrderIds.repair;
}
@Override
public int getHighlightOrderId() {
return OrderIds.repair;
}
}

View File

@ -78,6 +78,7 @@ public class CBehaviorOrcBuild extends CAbstractRangedBehavior {
this.unit.setHidden(true);
this.unit.setPaused(true);
this.unit.setInvulnerable(true);
simulation.getPlayer(playerIndex).addTechtreeInProgress(this.orderId);
simulation.unitConstructedEvent(this.unit, constructedStructure);
}
else {

View File

@ -94,10 +94,11 @@ public class CBehaviorUndeadBuild extends CAbstractRangedBehavior {
final float deltaX = this.unit.getX() - this.target.getX();
final float deltaY = this.unit.getY() - this.target.getY();
final float delta = (float) Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
this.unit.setPoint(this.target.getX() + ((deltaX / delta) * unitTypeToCreate.getCollisionSize()),
this.target.getY() + ((deltaY / delta) * unitTypeToCreate.getCollisionSize()),
simulation.getWorldCollision(), simulation.getRegionManager());
this.unit.setPointAndCheckUnstuck(
this.target.getX() + ((deltaX / delta) * unitTypeToCreate.getCollisionSize()),
this.target.getY() + ((deltaY / delta) * unitTypeToCreate.getCollisionSize()), simulation);
simulation.unitRepositioned(this.unit);
simulation.getPlayer(playerIndex).addTechtreeInProgress(this.orderId);
simulation.unitConstructedEvent(this.unit, constructedStructure);
this.doneTick = simulation.getGameTurnTick() + delayAnimationTicks;
}

View File

@ -0,0 +1,117 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.skills.human.paladin;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.skills.human.paladin.CAbilityHolyLight;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveAndTargetableVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CWeaponSoundTypeJass;
public class CBehaviorHolyLight extends CAbstractRangedBehavior {
private final CAbilityHolyLight ability;
private final AbilityTargetStillAliveAndTargetableVisitor stillAliveVisitor;
private int castStartTick = 0;
private boolean doneEffect = false;
public CBehaviorHolyLight(final CUnit unit, final CAbilityHolyLight ability) {
super(unit);
this.ability = ability;
this.stillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor();
}
public CBehaviorHolyLight reset(final CWidget target) {
innerReset(target, false);
this.castStartTick = 0;
this.doneEffect = false;
return this;
}
@Override
public boolean isWithinRange(final CSimulation simulation) {
final float castRange = this.ability.getCastRange();
return this.unit.canReach(this.target, castRange);
}
@Override
protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) {
this.unit.getUnitAnimationListener().playAnimation(false, null, SequenceUtils.SPELL, 1.0f, true);
if (this.castStartTick == 0) {
this.castStartTick = simulation.getGameTurnTick();
}
final int ticksSinceCast = simulation.getGameTurnTick() - this.castStartTick;
final int castPointTicks = (int) (this.unit.getUnitType().getCastPoint()
/ WarsmashConstants.SIMULATION_STEP_TIME);
final int backswingTicks = (int) (this.unit.getUnitType().getCastBackswingPoint()
/ WarsmashConstants.SIMULATION_STEP_TIME);
if (!this.doneEffect && ((ticksSinceCast >= castPointTicks) || (ticksSinceCast >= backswingTicks))) {
this.doneEffect = true;
if (this.unit.getMana() >= this.ability.getManaCost()) {
this.unit.setMana(this.unit.getMana() - this.ability.getManaCost());
}
else {
simulation.getCommandErrorListener().showNoManaError(this.unit.getPlayerIndex());
return this.unit.pollNextOrderBehavior(simulation);
}
if (this.target instanceof CUnit) {
final CUnit targetUnit = (CUnit) this.target;
final boolean undead = targetUnit.getClassifications().contains(CUnitClassification.UNDEAD);
if (undead) {
targetUnit.damage(simulation, this.unit, CAttackType.SPELLS, CWeaponSoundTypeJass.WHOKNOWS.name(),
this.ability.getHealAmount() / 2);
}
else {
float newLifeValue = targetUnit.getLife() + this.ability.getHealAmount();
if (newLifeValue > targetUnit.getMaxLife()) {
newLifeValue = targetUnit.getMaxLife();
}
targetUnit.setLife(simulation, newLifeValue);
}
this.ability.setCooldownRemaining(this.ability.getCooldown());
this.unit.fireCooldownsChangedEvent();
simulation.createSpellEffectOnUnit(targetUnit, this.ability.getAlias());
}
}
if (ticksSinceCast >= backswingTicks) {
return this.unit.pollNextOrderBehavior(simulation);
}
return this;
}
@Override
protected CBehavior updateOnInvalidTarget(final CSimulation simulation) {
return this.unit.pollNextOrderBehavior(simulation);
}
@Override
protected boolean checkTargetStillValid(final CSimulation simulation) {
return this.target.visit(this.stillAliveVisitor.reset(simulation, this.unit, this.ability.getTargetsAllowed()));
}
@Override
protected void resetBeforeMoving(final CSimulation simulation) {
}
@Override
public void begin(final CSimulation game) {
}
@Override
public void end(final CSimulation game, final boolean interrupted) {
}
@Override
public void endMove(final CSimulation game, final boolean interrupted) {
}
@Override
public int getHighlightOrderId() {
return OrderIds.repair;
}
}

View File

@ -6,8 +6,9 @@ import java.util.Map;
import com.etheller.warsmash.units.manager.MutableObjectData;
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGenericDoNothing;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionCarrionSwarmDummy;
@ -17,6 +18,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.def
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionGoldMine;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvestLumber;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHolyLight;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHumanRepair;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInventory;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable;
@ -30,6 +32,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.def
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionWispHarvest;
public class CAbilityData {
private static final War3ID REQUIRED_LEVEL = War3ID.fromString("arlv");
private static final War3ID REQUIRED_LEVEL_SKIP = War3ID.fromString("alsk");
private final MutableObjectData abilityData;
private Map<War3ID, CAbilityType<?>> aliasToAbilityType = new HashMap<>();
@ -42,7 +46,11 @@ public class CAbilityData {
}
private void registerCodes() {
this.codeToAbilityTypeDefinition.put(War3ID.fromString("ACcw"), new CAbilityTypeDefinitionColdArrows());
// ----Human----
// Paladin:
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AHhb"), new CAbilityTypeDefinitionHolyLight());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AHca"), new CAbilityTypeDefinitionColdArrows());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest());
@ -87,12 +95,26 @@ public class CAbilityData {
return abilityType;
}
public int getHeroRequiredLevel(final CSimulation game, final War3ID alias, final int currentLevelOfAbility) {
// TODO maybe use CAbilityType for this to avoid hashtable lookups and just do
// fast symbol table resolution.
// (i.e. like all other fields of CAbilityType). For now I didn't bother because
// I wanted to just have this working.
final MutableGameObject mutableGameObject = this.abilityData.get(alias);
int levelSkip = mutableGameObject.getFieldAsInteger(REQUIRED_LEVEL_SKIP, 0);
if (levelSkip == 0) {
levelSkip = game.getGameplayConstants().getHeroAbilityLevelSkip();
}
final int baseRequiredLevel = mutableGameObject.getFieldAsInteger(REQUIRED_LEVEL, 0);
return baseRequiredLevel + (currentLevelOfAbility * levelSkip);
}
public CAbility createAbility(final String ability, final int handleId) {
final War3ID war3Id = War3ID.fromString(ability.trim());
final CAbilityType<?> abilityType = getAbilityType(war3Id);
if (abilityType != null) {
return abilityType.createAbility(handleId);
}
return new CAbilityGeneric(war3Id, handleId);
return new CAbilityGenericDoNothing(war3Id, handleId);
}
}

View File

@ -53,6 +53,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRend
public class CUnitData {
private static final War3ID MANA_INITIAL_AMOUNT = War3ID.fromString("umpi");
private static final War3ID MANA_MAXIMUM = War3ID.fromString("umpm");
private static final War3ID MANA_REGEN = War3ID.fromString("umpr");
private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("uhpm");
private static final War3ID HIT_POINT_REGEN = War3ID.fromString("uhpr");
private static final War3ID HIT_POINT_REGEN_TYPE = War3ID.fromString("uhrt");
@ -125,6 +126,9 @@ public class CUnitData {
private static final War3ID ATTACK2_WEAPON_SOUND = War3ID.fromString("ucs2");
private static final War3ID ATTACK2_WEAPON_TYPE = War3ID.fromString("ua2w");
private static final War3ID CAST_BACKSWING_POINT = War3ID.fromString("ucbs");
private static final War3ID CAST_POINT = War3ID.fromString("ucpt");
private static final War3ID ACQUISITION_RANGE = War3ID.fromString("uacq");
private static final War3ID MINIMUM_ATTACK_RANGE = War3ID.fromString("uamn");
@ -153,7 +157,11 @@ public class CUnitData {
private static final War3ID UNIT_RACE = War3ID.fromString("urac");
private static final War3ID REQUIRES = War3ID.fromString("ureq");
private static final War3ID REQUIRES_AMOUNT = War3ID.fromString("urqc");
private static final War3ID REQUIRES_AMOUNT = War3ID.fromString("urqa");
private static final War3ID REQUIRES_TIER_COUNT = War3ID.fromString("urqc");
private static final War3ID[] REQUIRES_TIER_X = { War3ID.fromString("urq1"), War3ID.fromString("urq2"),
War3ID.fromString("urq3"), War3ID.fromString("urq4"), War3ID.fromString("urq5"), War3ID.fromString("urq6"),
War3ID.fromString("urq7"), War3ID.fromString("urq8"), War3ID.fromString("urq9") };
private static final War3ID GOLD_COST = War3ID.fromString("ugol");
private static final War3ID LUMBER_COST = War3ID.fromString("ulum");
@ -291,6 +299,7 @@ public class CUnitData {
.parseRegenType(unitType.getFieldAsString(HIT_POINT_REGEN_TYPE, 0));
final int manaInitial = unitType.getFieldAsInteger(MANA_INITIAL_AMOUNT, 0);
final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0);
final float manaRegen = unitType.getFieldAsFloat(MANA_REGEN, 0);
final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0);
final int defense = unitType.getFieldAsInteger(DEFENSE, 0);
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
@ -472,6 +481,9 @@ public class CUnitData {
final int foodUsed = unitType.getFieldAsInteger(FOOD_USED, 0);
final int foodMade = unitType.getFieldAsInteger(FOOD_MADE, 0);
final float castBackswingPoint = unitType.getFieldAsFloat(CAST_BACKSWING_POINT, 0);
final float castPoint = unitType.getFieldAsFloat(CAST_POINT, 0);
final int pointValue = unitType.getFieldAsInteger(POINT_VALUE, 0);
final boolean revivesHeroes = unitType.getFieldAsBoolean(REVIVES_HEROES, 0);
@ -522,36 +534,14 @@ public class CUnitData {
final String requirementsString = unitType.getFieldAsString(REQUIRES, 0);
final String requirementsLevelsString = unitType.getFieldAsString(REQUIRES_AMOUNT, 0);
final String[] requirementsStringItems = requirementsString.split(",");
final String[] requirementsLevelsStringItems = requirementsLevelsString.split(",");
final List<CUnitTypeRequirement> requirements = new ArrayList<>();
for (int i = 0; i < requirementsStringItems.length; i++) {
final String item = requirementsStringItems[i];
if (!item.isEmpty() && (item.length() == 4)) {
int level;
if (i < requirementsLevelsStringItems.length) {
if (requirementsLevelsStringItems[i].isEmpty()) {
level = 1;
}
else {
level = Integer.parseInt(requirementsLevelsStringItems[i]);
}
}
else if (requirementsLevelsStringItems.length > 0) {
final String requirementLevel = requirementsLevelsStringItems[requirementsLevelsStringItems.length
- 1];
if (requirementLevel.isEmpty()) {
level = 1;
}
else {
level = Integer.parseInt(requirementLevel);
}
}
else {
level = 1;
}
requirements.add(new CUnitTypeRequirement(War3ID.fromString(item), level));
}
final List<CUnitTypeRequirement> requirements = parseRequirements(requirementsString,
requirementsLevelsString);
final int requirementsTiersCount = unitType.getFieldAsInteger(REQUIRES_TIER_COUNT, 0);
final List<List<CUnitTypeRequirement>> requirementTiers = new ArrayList<>();
for (int i = 1; i <= requirementsTiersCount; i++) {
final String requirementsTierString = unitType.getFieldAsString(REQUIRES_TIER_X[i - 1], 0);
final List<CUnitTypeRequirement> tierRequirements = parseRequirements(requirementsTierString, "");
requirementTiers.add(tierRequirements);
}
final EnumSet<CBuildingPathingType> preventedPathingTypes = CBuildingPathingType
@ -566,31 +556,59 @@ public class CUnitData {
final List<String> heroProperNames = Arrays.asList(properNames.split(","));
unitTypeInstance = new CUnitType(unitName, legacyName, typeId, life, lifeRegen, lifeRegenType, manaInitial,
manaMaximum, speed, defense, abilityList, isBldg, movementType, moveHeight, collisionSize,
classifications, attacks, armorType, raise, decay, defenseType, impactZ, buildingPathingPixelMap,
deathTime, targetedAs, acquisitionRange, minimumAttackRange, structuresBuilt, unitsTrained,
researchesAvailable, upgradesTo, unitRace, goldCost, lumberCost, foodUsed, foodMade, buildTime,
preventedPathingTypes, requiredPathingTypes, propWindow, turnRate, requirements, unitLevel, hero,
strength, strPlus, agility, agiPlus, intelligence, intPlus, primaryAttribute, heroAbilityList,
heroProperNames, properNamesCount, canFlee, priority, revivesHeroes, pointValue);
unitTypeInstance = new CUnitType(unitName, legacyName, typeId, life, lifeRegen, manaRegen, lifeRegenType,
manaInitial, manaMaximum, speed, defense, abilityList, isBldg, movementType, moveHeight,
collisionSize, classifications, attacks, armorType, raise, decay, defenseType, impactZ,
buildingPathingPixelMap, deathTime, targetedAs, acquisitionRange, minimumAttackRange,
structuresBuilt, unitsTrained, researchesAvailable, upgradesTo, unitRace, goldCost, lumberCost,
foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, propWindow, turnRate,
requirements, requirementTiers, unitLevel, hero, strength, strPlus, agility, agiPlus, intelligence,
intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, canFlee, priority,
revivesHeroes, pointValue, castBackswingPoint, castPoint);
this.unitIdToUnitType.put(typeId, unitTypeInstance);
this.jassLegacyNameToUnitId.put(legacyName, typeId);
}
return unitTypeInstance;
}
public List<CUnitTypeRequirement> parseRequirements(final String requirementsString,
final String requirementsLevelsString) {
final String[] requirementsStringItems = requirementsString.split(",");
final String[] requirementsLevelsStringItems = requirementsLevelsString.split(",");
final List<CUnitTypeRequirement> requirements = new ArrayList<>();
for (int i = 0; i < requirementsStringItems.length; i++) {
final String item = requirementsStringItems[i];
if (!item.isEmpty() && (item.length() == 4)) {
int level;
if (i < requirementsLevelsStringItems.length) {
if (requirementsLevelsStringItems[i].isEmpty()) {
level = 1;
}
else {
level = Integer.parseInt(requirementsLevelsStringItems[i]);
}
}
else if (requirementsLevelsStringItems.length > 0) {
final String requirementLevel = requirementsLevelsStringItems[requirementsLevelsStringItems.length
- 1];
if (requirementLevel.isEmpty()) {
level = 1;
}
else {
level = Integer.parseInt(requirementLevel);
}
}
else {
level = 1;
}
requirements.add(new CUnitTypeRequirement(War3ID.fromString(item), level));
}
}
return requirements;
}
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;
return unitType.getLegacyName();
}
private static int[] populateHeroStatTable(final int maxHeroLevel, final float statPerLevel) {

View File

@ -391,13 +391,16 @@ public class CPathfindingProcessor {
}
}
if (stepsBackward > this.pathingGridCellCount) {
throw new IllegalStateException(
new IllegalStateException(
"PATHING SYSTEM ERROR: The path finding algorithm hit an infinite cycle at or near pt: "
+ current.cameFrom.point
+ ".\nThis means the A* search algorithm heuristic 'admissable' constraint was probably violated.\n\nUnit1:"
+ CUnit.maybeMeaningfulName(job.ignoreIntersectionsWithThisUnit)
+ "\nUnit2:"
+ CUnit.maybeMeaningfulName(job.ignoreIntersectionsWithThisSecondUnit));
+ CUnit.maybeMeaningfulName(job.ignoreIntersectionsWithThisSecondUnit))
.printStackTrace();
totalPath.clear();
break;
}
stepsBackward++;
}

View File

@ -273,6 +273,21 @@ public class CPlayer extends CBasePlayer {
return this.heroes;
}
public int getHeroCount(final CSimulation game, final boolean includeInProgress) {
if (!includeInProgress) {
return this.heroes.size();
}
else {
int heroInProgressCount = 0;
for (final Map.Entry<War3ID, Integer> entry : this.rawcodeToTechtreeInProgress.entrySet()) {
if (game.getUnitData().getUnitType(entry.getKey()).isHero()) {
heroInProgressCount += entry.getValue();
}
}
return this.heroes.size() + heroInProgressCount;
}
}
public void fireHeroLevelEvents(final CUnit hero) {
firePlayerUnitEvents(hero, CommonTriggerExecutionScope::playerHeroRevivableScope,
JassGameEventsWar3.EVENT_PLAYER_HERO_LEVEL);

Some files were not shown because too many files have changed in this diff Show More