www.pudn.com > MobiCraft_src.rar > Battle.java
// style: tabs, tabsize=4, style=ANSI
//+----------------------------------------------------------------------+
// Copyright (c) 2006 Company Name
// Made by Andrew and Zahar
//+----------------------------------------------------------------------+
// Filename: Battle.java
//+----------------------------------------------------------------------+
// Comment: Battle module to take control over paint() and keyPressed().
//+----------------------------------------------------------------------+
package battle;
import app.Keys;
import app.MainCanvas;
import java.util.Vector;
import menu.Panel;
import fonts.FontManager;
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
class ActionTarget
{
public int Action;
public int Target;
}
public class Battle
{
public Force[] mForce;
public FontManager mFontManager;
public MainCanvas mMainCanvas; // Link to shared MainCanvas
// ------------------------------------
// Current state
public final static int STATE_LOADING= 0; // Здесь происходит загрузка картинок.
public final static int STATE_WORK= 1; // Все загружено, нормальная работа
public final static int STATE_CHOOSING_TARGET= 2; // Выбор цели для действия
public final static int STATE_PLAYING= 3; // Проигрывание событий
public final static int STATE_FINAL= 4; // Бой окончен
public int iState = STATE_LOADING;
public int mForceSelected = 0; // Сторона выбранного юнита (0,1)
public int mUnitSelected = 0; // Номер выбранного юнита (0..7)
public int mActionSelected = 0; // Номер выбранного действия (Для того чтобы это знала функция выбора цели
public int bAttackSelected = 0; // На какую форсу кидается действие (нужно при отрисовке целей)
public int mTargetSelected = -1; // Выбранная цель (-1 - нет целей вообще)
public int [] pValidTargets; // Массив доступных для выбранного действия целей (0 - недоступна, 1 - доступна)
public int [] pValidActions; // Массив доступных действий (нужен для корректной обработки SIEGE и BURROWED состояний)
public boolean bTargetsChecked; // Чтобы каждый кадр не проверять цели заново
public boolean bActionsChecked; // Чтобы каждый кадр не проверять действия заново
public ActionTarget [][] pActionTargets;
// ------------------------------------
// Background
Image mField;
public Sprite mZergActionIcon; // Иконки действий юнитов зергов
public Sprite mProtossActionIcon; // протоссов
public Sprite mTerranActionIcon; // терран
// ------------------------------------
// To have only one png animation loaded for identical types of units
public UnitAnimator mUnitAnimator;
// ------------------------------------
public BattleCalculator mBattleCalculator;
public Vector mBattleEvents;
public int iTime;
// ------------------------------------
public UnitAnimatorSprite mCursor;
public UnitAnimatorSprite mCursorRed;
// ------------------------------------
public Battle(MainCanvas m)
{
mMainCanvas = m;
}
public void Init()
{
mFontManager = mMainCanvas.mFontManager;
mFontManager.LoadFont(mFontManager.BIG);
mForce = new Force[2];
mForce[0] = new Force();
mForce[1] = new Force();
mForce[0].Init(true);//, this);
mForce[1].Init(false);//, this);
mUnitAnimator = null;
mUnitAnimator = new UnitAnimator();
mBattleCalculator = null;
mBattleCalculator = new BattleCalculator(mMainCanvas);
mBattleEvents = new Vector();
mMainCanvas.mLoader.Reset();
mMainCanvas.ResetTime();
iState = STATE_LOADING;
pValidTargets = new int[8];
pValidActions = new int[6];
bTargetsChecked = false;
bActionsChecked = false;
pActionTargets = new ActionTarget [2][8];
for (int i = 0; i < 2; i++)
{
for (int q = 0; q < 8; q++)
{
pActionTargets[i][q] = new ActionTarget();
pActionTargets[i][q].Action = -1;
}
}
}
public void Destroy()
{
mFontManager.UnLoadFont(mFontManager.BIG);
// Clear units memory ( mostly png animation ) -------------
mForce[0].Destroy();
mForce[1].Destroy();
mForce[0] = null;
mForce[1] = null;
mForce = null;
mField = null;
mUnitAnimator.UnLoadAll();
mUnitAnimator = null;
mBattleCalculator.Destroy();
mBattleCalculator = null;
mBattleEvents.removeAllElements();
mBattleEvents = null;
mZergActionIcon = null;
mProtossActionIcon = null;
mTerranActionIcon = null;
mCursor = null;
mCursorRed = null;
pValidActions = null;
pValidTargets = null;
mMainCanvas.ResetTime();
}
public void paint(Graphics g, long dt)
{
g.setColor(0x000000);
g.fillRect(0, 0, mMainCanvas.getWidth(), mMainCanvas.getHeight());
switch (iState)
{
case Battle.STATE_LOADING:
try
{
int unit_loading_part = 70; // Примерное кол-во процентов загрузки юнитов от всей загрузки по времени.
if (mMainCanvas.mLoader.TaskReady(0, "Units. Force 1", unit_loading_part/2, g) )
{
/*
mForce[0].mUnit[1].mType = Unit.UNIT_P_ZEALOT;
mForce[0].mUnit[2].mType = Unit.UNIT_P_DARK;
mForce[0].mUnit[3].mType = Unit.UNIT_P_DRAGOON;
mForce[0].mUnit[4].mType = Unit.UNIT_P_TEMPLAR;
mForce[0].mUnit[5].mType = Unit.UNIT_T_VESSEL;
mForce[0].mUnit[6].mType = Unit.UNIT_P_OBSERVER;
mForce[0].mUnit[7].mType = Unit.UNIT_P_REAVER;*/
/* mForce[0].mUnit[0].mType = Unit.UNIT_T_FIREBAT;
mForce[0].mUnit[1].mType = Unit.UNIT_T_GHOST;
mForce[0].mUnit[2].mType = Unit.UNIT_T_MARINE;
mForce[0].mUnit[3].mType = Unit.UNIT_T_MEDIC;
mForce[0].mUnit[4].mType = Unit.UNIT_T_SCV;
mForce[0].mUnit[5].mType = Unit.UNIT_T_TANK;
mForce[0].mUnit[6].mType = Unit.UNIT_T_VESSEL;
mForce[0].mUnit[7].mType = Unit.UNIT_T_GOLIATH; */
//Рандом
for (int i = 0; i < 8; i++)
{
mForce[0].mUnit[i].mType = mMainCanvas.mRandom.Rand(Unit.UNIT_TOTAL_NUMBER + 1) - 1;
mForce[0].mUnit[0].mType = Unit.UNIT_Z_LURKER;
mForce[0].mUnit[1].mType = Unit.UNIT_Z_QUEEN;
mForce[0].mUnit[2].mType = Unit.UNIT_T_TANK;
if (mForce[0].mUnit[i].mType == -1)
mForce[0].mUnit[i] = null;
}
for (int i=0; i<8; i++)
{
if ( mForce[0].mUnit[i] != null )
{
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_IDLE );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_IDLE2 );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_A1 );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_A2 );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_A3 );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_A4 );
mUnitAnimator.LoadAnim( mForce[0].mUnit[i].mType, UnitAnimator.ANIM_DEATH );
mForce[0].mUnit[i].InitDefaultParams(mForce[0].mUnit[i].mType, !mForce[0].bLeft);
mForce[0].mUnit[i].InitAnimationState(mForce[0].mUnit[i].mType, mUnitAnimator);
}
}
}
if (mMainCanvas.mLoader.TaskReady(1, "Units. Force 2", unit_loading_part, g) )
{
/* mForce[1].mUnit[0].mType = Unit.UNIT_Z_ZERGLING;
mForce[1].mUnit[1].mType = Unit.UNIT_Z_ULTRAL;
mForce[1].mUnit[2].mType = Unit.UNIT_Z_HYDRA;
mForce[1].mUnit[3].mType = Unit.UNIT_Z_OVERLORD;
mForce[1].mUnit[4].mType = Unit.UNIT_Z_QUEEN;
mForce[1].mUnit[5].mType = Unit.UNIT_Z_DRONE;
mForce[1].mUnit[6].mType = Unit.UNIT_Z_LURKER;
mForce[1].mUnit[7].mType = Unit.UNIT_Z_DEFILER;*/
//mForce[1].mUnit[0] = null;
/*mForce[1].mUnit[0].mType = Unit.UNIT_P_DRAGOON;
mForce[1].mUnit[1].mType = Unit.UNIT_P_ZEALOT;
mForce[1].mUnit[2].mType = Unit.UNIT_P_DARK;
mForce[1].mUnit[3].mType = Unit.UNIT_P_ARCHONT;
mForce[1].mUnit[4].mType = Unit.UNIT_P_DARKARCHONT;
mForce[1].mUnit[5].mType = Unit.UNIT_P_OBSERVER;
mForce[1].mUnit[6].mType = Unit.UNIT_P_TEMPLAR;
mForce[1].mUnit[7].mType = Unit.UNIT_P_REAVER; */
for (int i = 0; i < 8; i++)
{
if (mForce[0].mUnit[i] == null )
mForce[1].mUnit[i] = null;
else
mForce[1].mUnit[i].mType = mForce[0].mUnit[i].mType;
}
/*
//Рандом
for (int i = 0; i < 8; i++)
{
mForce[1].mUnit[i].mType = mMainCanvas.mRandom.Rand(Unit.UNIT_TOTAL_NUMBER + 1) - 1;
if (mForce[1].mUnit[i].mType == -1 )
mForce[1].mUnit[i] = null;
}
*/
for (int i=0; i<8; i++)
{
if ( mForce[1].mUnit[i] != null )
{
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_IDLE );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_IDLE2 );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_A1 );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_A2 );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_A3 );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_A4 );
mUnitAnimator.LoadAnim( mForce[1].mUnit[i].mType, UnitAnimator.ANIM_DEATH );
//20061221 Zahar Это надо после mUnitAnimator.LoadAnim() делать.
mForce[1].mUnit[i].InitDefaultParams(mForce[1].mUnit[i].mType, !mForce[1].bLeft);
mForce[1].mUnit[i].InitAnimationState(mForce[1].mUnit[i].mType, mUnitAnimator);
}
}
}
if (mMainCanvas.mLoader.TaskReady(2, "Battle Field", unit_loading_part, g) )
{
mField = Image.createImage("/battle/battle_field.png");
}
if (mMainCanvas.mLoader.TaskReady(3, "Icons", 90, g) )
{
mBattleCalculator.SetForces(mForce[0], mForce[1]);
mZergActionIcon = new Sprite(Image.createImage("/battle/icons_battle_zerg.png"),16,16); //20061122 Black
mProtossActionIcon = new Sprite(Image.createImage("/battle/icons_battle_protoss.png"),16,16); //20061122 Black
mTerranActionIcon = new Sprite(Image.createImage("/battle/icons_battle_terran.png"),16,16); //20061122 Black
mMainCanvas.mLoader.Reset();
mCursor = new UnitAnimatorSprite("/battle/cursor_select.png", 41, 25, -2, 14, 200, 7);
mCursorRed = new UnitAnimatorSprite("/battle/cursor_select_red.png", 41, 25, -2, 14, 200, 7);
mForceSelected = -1;
mUnitSelected = -1;
for (int i = 0; i < 16; i++)
if ( (mForce[i/8].mUnit[i%8] != null) && (mForceSelected == -1) )
{
mForceSelected = i/8;
mUnitSelected = i%8;
}
SetState(STATE_WORK);
}
mMainCanvas.mLoader.NextTaskIfDone();
}
catch(Throwable e)
{
mMainCanvas.mMIDlet.mErrorReporter.ShowError("Battle.paint()", e.toString());
}
break;
case Battle.STATE_WORK:
if (bActionsChecked == false)
{
bActionsChecked = true;
CheckValidActions();
}
if (CheckFinal())
SetState(STATE_FINAL);
iTime += dt;
mForce[0].DoTimeStep(dt);
mForce[1].DoTimeStep(dt);
mUnitAnimator.EffectsDoTimeStep(dt);
g.drawImage(mField, 0, 0, Graphics.LEFT | Graphics.TOP );
// Порядок отрисовки - панелька рисуется ПОСЛЕ юнитов
DrawSelection(g);
mUnitAnimator.EffectsDraw(g, true);
mForce[0].Draw( g, 0, 0 );
mForce[1].Draw( g, 176-80, 0 );
mUnitAnimator.EffectsDraw(g, false);
DrawPanelWithParams(g);
DrawUnitActions(g);
//DrawConditions(g);
if( mMainCanvas.mKeys.PressEvent(0) )
{
mMainCanvas.mKeyHelper.Show(mMainCanvas.mKeyHelper.HELP_Battle);
}
else if( mMainCanvas.mKeys.PressEvent(Keys.POUND) || mMainCanvas.mKeys.PressEvent(Keys.RSOFT) )
{
bActionsChecked = false;
if (mForceSelected == 0)
{
mForceSelected = -1;
for (int i = 0; i < 8; i++)
if ( (mForce[1].mUnit[i] != null) && (mForceSelected == -1) )
{
mForceSelected = 1;
mUnitSelected = i;
}
}
else
{
mBattleCalculator.Calculate(pActionTargets[0], pActionTargets[1], mBattleEvents, mUnitAnimator);
iTime = 0;
for (int i = 0; i < 16; i++)
{
pActionTargets[i / 8][i % 8].Action = -1;
pActionTargets[i / 8][i % 8].Target = -1;
}
mForceSelected = 0;
SetState(Battle.STATE_PLAYING);
}
}
else if (mMainCanvas.mKeys.PressEvent(Keys.FIRE))
{
if (pValidActions[0] == 1)
{
// Временно сделан аналог нажатия 4-ки
mActionSelected = 0;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(4))
{
if (pValidActions[0] == 1)
{
mActionSelected = 0;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(5))
{
if (pValidActions[1] == 1)
{
mActionSelected = 1;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(6))
{
if (pValidActions[2] == 1)
{
mActionSelected = 2;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(7))
{
if (pValidActions[3] == 1)
{
mActionSelected = 3;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(8))
{
if (pValidActions[4] == 1)
{
mActionSelected = 4;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && CheckEnergy() )
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(9))
{
if (pValidActions[5] == 1)
{
mActionSelected = 5;
if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected] != null) && (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_RETREAT) && CheckEnergy() ) //20070801 Black временно отрублено убегание
{
if ( NoTargetAction() )
{
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mUnitSelected + 8 * mForceSelected;
}
else
SetState(Battle.STATE_CHOOSING_TARGET);
}
}
}
else if (mMainCanvas.mKeys.PressEvent(Keys.STAR) || mMainCanvas.mKeys.PressEvent(Keys.LSOFT))
{
Destroy();
System.gc(); // Clear memory
mMainCanvas.iState = mMainCanvas.STATE_MENU;
}
else if (mMainCanvas.mKeys.PressEvent(Keys.UP))
{
do
{
if ((mUnitSelected == 0)||(mUnitSelected == 4)) {mUnitSelected+=3;} else {mUnitSelected--;}
}
while (mForce[mForceSelected].mUnit[mUnitSelected] == null);
bActionsChecked = false;
}
else if (mMainCanvas.mKeys.PressEvent(Keys.RIGHT))
{
mUnitSelected = HorizontalMove();
bActionsChecked = false;
}
else if (mMainCanvas.mKeys.PressEvent(Keys.DOWN))
{
do
{
if ((mUnitSelected == 3)||(mUnitSelected == 7)) {mUnitSelected-=3;} else {mUnitSelected++;}
}
while (mForce[mForceSelected].mUnit[mUnitSelected] == null);
bActionsChecked = false;
}
else if (mMainCanvas.mKeys.PressEvent(Keys.LEFT))
{
mUnitSelected = HorizontalMove();
bActionsChecked = false;
}
mTargetSelected = -1;
break;
case Battle.STATE_CHOOSING_TARGET:
iTime += dt;
// Проверка доступных для действия целей
if (bTargetsChecked == false)
{
bTargetsChecked = true;
CheckValidTargets();
}
if (mTargetSelected == -1)
{
mMainCanvas.mMessage.Send("No valid targets.");
bTargetsChecked = false;
SetState (STATE_WORK);
}
// Отрисовывается все то же, что и в STATE_WORK + Цели
mUnitAnimator.EffectsDraw(g, true);
mForce[0].DoTimeStep(dt);
mForce[1].DoTimeStep(dt);
mUnitAnimator.EffectsDoTimeStep(dt);
g.drawImage(mField, 0, 0, Graphics.LEFT | Graphics.TOP );
DrawSelection(g);
DrawTargets(g);
mForce[0].Draw( g, 0, 0 );
mForce[1].Draw( g, 176-80, 0 );
mUnitAnimator.EffectsDraw(g, false);
DrawPanelWithParams(g);
DrawUnitActions(g);
//DrawConditions(g);
if (mMainCanvas.mKeys.PressEvent(Keys.FIRE))
{
for (int i = 0; i < 8; i++)
pValidTargets[i] = 0;
bTargetsChecked = false;
ProcessAction(g);
}
else if (mMainCanvas.mKeys.PressEvent(Keys.STAR) || mMainCanvas.mKeys.PressEvent(Keys.LSOFT))
{
for (int i = 0; i < 8; i++)
pValidTargets[i] = 0;
mTargetSelected = -1;
mActionSelected = -1;
pActionTargets[mForceSelected][mUnitSelected].Action = -1;
pActionTargets[mForceSelected][mUnitSelected].Target = -1;
bTargetsChecked = false;
SetState(STATE_WORK);
}
else if (mMainCanvas.mKeys.PressEvent(Keys.UP))
{
do
{
if ((mTargetSelected == 0)||(mTargetSelected == 4))
{
mTargetSelected+=3;
}
else
{
mTargetSelected--;
}
}
while (pValidTargets[mTargetSelected] == 0);
}
else if (mMainCanvas.mKeys.PressEvent(Keys.DOWN))
{
do
{
if ((mTargetSelected == 3)||(mTargetSelected == 7)) {mTargetSelected-=3;} else {mTargetSelected++;}
}
while (pValidTargets[mTargetSelected] == 0);
}
else if (mMainCanvas.mKeys.PressEvent(Keys.RIGHT))
{
if (Math.abs(mForceSelected - bAttackSelected) == 1) // На правую форсу воздействие идет
{
if (mTargetSelected < 4)
{
if (pValidTargets[mTargetSelected + 4] != 0) // Есть юнит прямо справа
mTargetSelected += 4;
else
{
for (int i = 4; i < 8; i++)
{
if (pValidTargets[i] != 0)
{
mTargetSelected = i;
break;
}
}
}
}
}
else
{
if (mTargetSelected > 3)
{
if (pValidTargets[mTargetSelected - 4] != 0)
mTargetSelected -= 4;
else
{
for (int i = 0; i < 4; i++)
{
if (pValidTargets[i] != 0)
{
mTargetSelected = i;
break;
}
}
}
}
}
}
else if (mMainCanvas.mKeys.PressEvent(Keys.LEFT))
{
if (Math.abs(mForceSelected - bAttackSelected) == 0) // На левую форсу воздействие идет
{
if (mTargetSelected < 4)
{
if (pValidTargets[mTargetSelected + 4] != 0) // Есть юнит прямо cktdf
mTargetSelected += 4;
else
{
for (int i = 4; i < 8; i++)
{
if (pValidTargets[i] != 0)
{
mTargetSelected = i;
break;
}
}
}
}
}
else
{
if (mTargetSelected > 3)
{
if (pValidTargets[mTargetSelected - 4] != 0) // Есть юнит прямо справа
mTargetSelected -= 4;
else
{
for (int i = 0; i < 4; i++)
{
if (pValidTargets[i] != 0) // Есть юнит прямо справа
{
mTargetSelected = i;
break;
}
}
}
}
}
}
break;
case Battle.STATE_PLAYING: // отрисовываем события сгенеренный калькулятором
iTime += dt;
//20061213 Black Пробегаем по всем Event'ам и смотрим какие надо выполнить, после чего событие удаляем
for (int i = 0; i < mBattleEvents.size(); i++)
{
if (((Event)mBattleEvents.elementAt(i)).iTime <= iTime)
{
PlayEvent(i, g);
mBattleEvents.removeElementAt(i);
i--;
}
}
g.drawImage(mField, 0, 0, Graphics.LEFT | Graphics.TOP );
//DrawSelection(g);
mUnitAnimator.EffectsDraw(g, true);
mForce[0].Draw( g, 0, 0 );
mForce[1].Draw( g, 176-80, 0 );
mUnitAnimator.EffectsDraw(g, false);
mForce[0].DoTimeStep(dt);
mForce[1].DoTimeStep(dt);
mUnitAnimator.EffectsDoTimeStep(dt);
//DrawConditions(g);
DrawPanel(g);
DrawRoundTime(g);
if (mBattleEvents.isEmpty())
{
mForceSelected = -1;
mUnitSelected = -1;
for (int i = 0; i < 16; i++)
if ( (mForce[i/8].mUnit[i%8] != null) && (mForceSelected == -1) )
{
mForceSelected = i/8;
mUnitSelected = i%8;
}
SetState(Battle.STATE_WORK);
iTime = 0;
}
//DrawPanelWithParams(g);
//DrawUnitActions(g);
break;
case Battle.STATE_FINAL:
mMainCanvas.mMessage.Send("Battle has ended.");
mMainCanvas.iState = mMainCanvas.STATE_MENU;
/* if (mMainCanvas.mKeys.AnyKeyPressEvent())
{
Destroy();
System.gc(); // Clear memory
}*/
break;
default:
break; //ignore
}
}
// Отбработка нажатия кнопок влево/вправо на случай если там нету юнита возвращает mUnitSelected
public int HorizontalMove()
{
if (mForce[mForceSelected].mUnit[(mUnitSelected + 4)%8] != null)
return ((mUnitSelected + 4)%8);
else
{
if (mUnitSelected % 4 <= 1)
{
for (int i = 4 * (1 - mUnitSelected/4); i <= 3 + 4 * (1 - mUnitSelected / 4); i++)
{
if (mForce[mForceSelected].mUnit[i] != null)
return i;
}
}
else
{
for (int i = 3 + 4 * (1 - mUnitSelected / 4); i >= 4 * (1 - mUnitSelected/4); i--)
{
if (mForce[mForceSelected].mUnit[i] != null)
return i;
}
}
}
return mUnitSelected;
}
// Проверка доступных для действия целей
public void CheckValidTargets()
{
// switch на возможные типы атаки (melee, any single, splash ranged, lurker ranged, megasplash)
int bFirstRow = 1; // Переменная нужная чтобы понять есть ли у противника юниты в первом ряду
int mEnemyForce = 1 - mForceSelected;
switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType)
{
case UnitAction.ACTION_ATTACK_FIREBAT:
bAttackSelected = 1;
for (int i = mUnitSelected%4 - 1; i < mUnitSelected%4 +1; i++)
if ( (i >= 0) && (i <= 2) )
{
if ( ((mForce[1-mForceSelected].mUnit[i] != null) && (mForce[1-mForceSelected].mUnit[i].bAir == 0)) || ((mForce[1-mForceSelected].mUnit[i+1] != null) && (mForce[1-mForceSelected].mUnit[i+1].bAir == 0)) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
if (mTargetSelected == -1)
for (int i = mUnitSelected%4 - 1; i < mUnitSelected%4 +1; i++)
if ( (i >= 0) && (i <= 2) )
{
if ( ((mForce[1-mForceSelected].mUnit[i + 4] != null) && (mForce[1-mForceSelected].mUnit[i+4].bAir == 0)) || ((mForce[1-mForceSelected].mUnit[i+1+4] != null) && (mForce[1-mForceSelected].mUnit[i+1+4].bAir == 0)) )
{
pValidTargets[i+4] = 1;
if (mTargetSelected == -1)
mTargetSelected = i+4;
}
}
break;
case UnitAction.ACTION_ATTACK_MELEE:
bAttackSelected = 1;
for (int i = mUnitSelected%4 - 1; i <= mUnitSelected%4 +1; i++)
{
if ( (i >= 0) && (i <= 3) )
{
if ( (mForce[1 - mForceSelected].mUnit[i] == null) || (mForce[1 - mForceSelected].mUnit[i].bAir == 1) )
i += 4;
// Либо атакующий юнит стоит в первом ряду, либо в первом ряду пустое место напротив цели
if ( ((mUnitSelected < 4) || (mForce[mForceSelected].mUnit[i%4] == null) || (mForce[mForceSelected].mUnit[i%4].bAir == 1)) && (mForce[1-mForceSelected].mUnit[i] != null) && (mForce[1-mForceSelected].mUnit[i].bAir == 0 ))
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
if (i > 3)
i -= 4;
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_SHORT:
bAttackSelected = 1;
bFirstRow = 0;
// Может мочить всех юнитов противника если а) номер < 4 б) нет юнитов в первом ряду у себя в) нет юнитов в первом ряду у противника
if (mUnitSelected < 4)
bFirstRow = 1;
else
{
bFirstRow = 1;
for (int i = 0; i < 4; i++)
if (mForce[mForceSelected].mUnit[i] != null)
bFirstRow = 0;
if (bFirstRow == 0)
{
bFirstRow = 1;
for (int i = 0; i < 4; i++)
if (mForce[1 - mForceSelected].mUnit[i] != null)
bFirstRow = 0;
}
}
if (bFirstRow == 1)
for (int i = 0; i < 8; i++)
{
if (mForce[1 - mForceSelected].mUnit[i] != null)
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
else
for (int i = 0; i < 4; i++)
{
if (mForce[1 - mForceSelected].mUnit[i] != null)
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_GROUND:
bAttackSelected = 1;
bFirstRow = 0;
// Может мочить всех юнитов противника если а) номер < 4 б) нет юнитов в первом ряду у себя в) нет юнитов в первом ряду у противника
if (mUnitSelected < 4)
bFirstRow = 1;
else
{
bFirstRow = 1;
for (int i = 0; i < 4; i++)
if ( (mForce[mForceSelected].mUnit[i] != null) && ((mForce[mForceSelected].mUnit[i].bAir != 1)) )
bFirstRow = 0;
if (bFirstRow == 0)
{
bFirstRow = 1;
for (int i = 0; i < 4; i++)
if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].bAir != 1) )
bFirstRow = 0;
}
}
if (bFirstRow == 1)
for (int i = 0; i < 8; i++)
{
if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].bAir != 1) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
else
for (int i = 0; i < 4; i++)
{
if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].bAir != 1) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_LONG:
bAttackSelected = 1;
for (int i = 0; i < 8; i++)
{
if (mForce[mEnemyForce].mUnit[i] != null)
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
bFirstRow = 1;
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_LURKER:
bAttackSelected = 1;
for (int i = 0; i < 4; i++)
{
if ( (mForce[mEnemyForce].mUnit[i] != null && mForce[mEnemyForce].mUnit[i].bAir == 0 ) || (mForce[mEnemyForce].mUnit[i+4] != null && mForce[mEnemyForce].mUnit[i+4].bAir == 0 ) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_SPLASH:
bAttackSelected = 1;
for (int i = 0; i < 7; i++)
{
if (i % 4 == 3)
i++;
if ( (mForce[mEnemyForce].mUnit[i] != null && mForce[mEnemyForce].mUnit[i].bAir == 0) || (mForce[mEnemyForce].mUnit[i+1] != null && mForce[mEnemyForce].mUnit[i+1].bAir == 0) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
//20061204 Black Шторм или любая другая атака на 4 юнита (без проверки на воздушность)
case UnitAction.ACTION_EMP: //20061223 Black
// case UnitAction.ACTION_IRRADIATE: //20061223 Black
case UnitAction.ACTION_ENSNARE:
case UnitAction.ACTION_PLAGUE:
case UnitAction.ACTION_STORM:
bAttackSelected = 1;
for (int i = 0; i < 3; i++)
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
break;
case UnitAction.ACTION_HEAL:
bAttackSelected = 0;
for (int i = 0; i < 8; i++)
{
if ( (mForce[mForceSelected].mUnit[i] != null) && (mForce[mForceSelected].mUnit[i].mCurHealth != mForce[mForceSelected].mUnit[i].mMaxHealth) && (mForce[mForceSelected].mUnit[i].bOrganic == 1) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_LOCKDOWN:
bAttackSelected = 1;
for (int i = 0; i < 8; i++)
{
if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].bMechanic == 1) && (mForce[1 - mForceSelected].mUnit[i].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] == 0) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_DEFENCEMATRIX:
bAttackSelected = 0;
for (int i = 0; i < 8; i++)
{
if ( (mForce[mForceSelected].mUnit[i] != null) && (mForce[mForceSelected].mUnit[i].pConditions[Unit.UNIT_CONDITION_MATRIX] == 0) && ( i != mUnitSelected ) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
case UnitAction.ACTION_FEEDBACK:
bAttackSelected = 1;
for (int i = 0; i < 8; i++)
{
if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].mCurEnergy != 0) )
{
pValidTargets[i] = 1;
if (mTargetSelected == -1)
mTargetSelected = i;
}
}
break;
default:
break;
}
}
// Проверка доступных юниту действий, из его pActions[]
public void CheckValidActions()
{
// Базовое заполнение массива по null'евости действий
for (int i = 0; i < 6; i++)
{
if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[i] != null)
pValidActions[i] = 1;
else
pValidActions[i] = 0;
}
// Выбасываем действия недоступные по состоянию закопанности/разложенности
// Танк (отбрасываем одну из атак)
if (mForce[mForceSelected].mUnit[mUnitSelected].mType == Unit.UNIT_T_TANK)
{
if (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_SIEGE] == 1)
{
pValidActions[0] = 0;
pValidActions[5] = 0;
}
else
pValidActions[1] = 0;
}
// Закопанность (недоступно ничего кроме раскапывания)
if (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED] == 1)
{
for (int i = 0; i < 6; i++)
{
if ((mForce[mForceSelected].mUnit[mUnitSelected].pActions[i] != null) && (mForce[mForceSelected].mUnit[mUnitSelected].pActions[i].mType != UnitAction.ACTION_BURROW))
pValidActions[i] = 0;
}
}
// Люркер
if (mForce[mForceSelected].mUnit[mUnitSelected].mType == Unit.UNIT_Z_LURKER)
pValidActions[0] = mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED];
}
// Проверка на действия без целей (закапывани, убегание)
public boolean NoTargetAction()
{
switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType)
{
case UnitAction.ACTION_RETREAT:
case UnitAction.ACTION_BURROW:
case UnitAction.ACTION_SIEGE:
case UnitAction.ACTION_STIMPACK:
return true;
default:
return false;
}
}
// Проверка окончания боя (хотя бы в одной форсе нету юнитов)
public boolean CheckFinal()
{
boolean temp;
for (int i = 0; i<2; i++)
{
temp = true;
for (int q = 0; q < 7; q++)
{
if (mForce[i].mUnit[q] != null)
temp = false;
}
if (temp)
return true;
}
return false;
}
// Проверяет наличие достаточного, для совершения действия, количества энергии
public boolean CheckEnergy()
{
if ( mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_STIMPACK )
{
if ( mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost > mForce[mForceSelected].mUnit[mUnitSelected].mCurHealth)
{
mMainCanvas.mMessage.Send("Not enough health.");
return false;
}
else
return true;
}
else
{
if ( mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost > mForce[mForceSelected].mUnit[mUnitSelected].mCurEnergy)
{
mMainCanvas.mMessage.Send("Not enough energy.");
return false;
}
else
return true;
}
}
public void DrawSelection(Graphics g)
{
int x, y; // Нужны только для рисования эллипса, можно обойтись без них, но тогда в переборе нужно будет вместо их присваивания писать сразу вывод эллипса => куча кода. Хочешь передела, но ИМХО 8 байт - не деньги =)
if (mForceSelected == 0)
{
if (mUnitSelected < 4)
{
x = 40;
y = mUnitSelected*40;
}
else
{
x = 0;
y = (mUnitSelected-4)*40;
}
}
else
{
if (mUnitSelected < 4)
{
x = 176-80;
y = mUnitSelected*40;
}
else
{
x = 176-40;
y = (mUnitSelected-4)*40;
}
}
mCursor.setFrame( (iTime % (mCursor.mDelay * mCursor.mLength)) / mCursor.mDelay);
mCursor.Draw(g, x, y, false);
/* g.setColor(0x145c14);
// 20061114 Zahar сдвинул и по высоте сузил эллипс.
g.drawArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);// Рисуем эллипс под активным юнитом*/
}
public void DrawConditions(Graphics g)
{
int x, y;
//20061216 Black Отрисовка Lockdown, пока весьма условно =)
for (int i = 0; i < 16; i++)
{
if (mForce[i/8].mUnit[i%8] != null)
{
if (mForce[i / 8].mUnit[i % 8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] == 1)
{
if (i < 8)
{
if (i < 4)
{
x = 40;
y = i*40;
}
else
{
x = 0;
y = (i-4)*40;
}
}
else
{
if (i%8 < 4)
{
x = 176-80;
y = (i%8)*40;
}
else
{
x = 176-40;
y = (i%8-4)*40;
}
}
g.setColor(0x33ccff);
for (int q = 0; q < 4; q++)
{
g.drawArc(x + (40-10*(1+q))/2, y + (40-10*(1+q))/2, 10*(1+q), 10*(1+q), 0, 360);
}
}
if (mForce[i / 8].mUnit[i % 8].pConditions[Unit.UNIT_CONDITION_MATRIX] != 0)
{
if (i < 8)
{
if (i < 4)
{
x = 40;
y = i*40;
}
else
{
x = 0;
y = (i-4)*40;
}
}
else
{
if (i%8 < 4)
{
x = 176-80;
y = (i%8)*40;
}
else
{
x = 176-40;
y = (i%8-4)*40;
}
}
g.setColor(0x10e810);
for (int q = 0; q < 4; q++)
{
g.drawArc(x + (40-9*(1+q))/2, y + (40-9*(1+q))/2, 9*(1+q), 9*(1+q), 0, 360);
}
}
}
}
}
public void DrawTargets(Graphics g)
{
int x, y;
mCursorRed.setFrame( (iTime % (mCursor.mDelay * mCursor.mLength)) / mCursor.mDelay);
switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType )
{
case UnitAction.ACTION_ATTACK_MELEE:
case UnitAction.ACTION_ATTACK_RANGE_SHORT:
case UnitAction.ACTION_ATTACK_RANGE_LONG:
case UnitAction.ACTION_ATTACK_RANGE_GROUND:
case UnitAction.ACTION_CONSUME:
case UnitAction.ACTION_HEAL:
case UnitAction.ACTION_LOCKDOWN:
case UnitAction.ACTION_DEFENCEMATRIX:
case UnitAction.ACTION_FEEDBACK:
for (int i = 0; i < 8; i++)
{
if (pValidTargets[i] == 1)
{
x = mUnitAnimator.UnitToX(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
y = mUnitAnimator.UnitToY(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
g.setColor(0xffff00);
if (i == mTargetSelected)
{
mCursorRed.Draw(g, x, y, false);
/*g.setColor(0xff0000);
g.fillArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);*/
}
else
{
g.drawArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);// Рисуем эллипс под потенциальной целью
}
}
}
break;
case UnitAction.ACTION_ATTACK_RANGE_LURKER:
for (int i = 0; i < 8; i++)
{
if (pValidTargets[i%4] == 1 && mForce[1 - mForceSelected].mUnit[i].bAir == 0)
{
x = mUnitAnimator.UnitToX(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
y = mUnitAnimator.UnitToY(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
g.setColor(0xffff00);
if (i%4 == mTargetSelected)
{
mCursorRed.Draw(g, x, y, false);
/*g.setColor(0xff0000);
g.fillArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);*/
}
else
{
g.drawArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);// Рисуем эллипс под потенциальной целью
}
}
}
break;
case UnitAction.ACTION_ATTACK_FIREBAT:
case UnitAction.ACTION_ATTACK_RANGE_SPLASH:
for (int i = 0; i < 8; i++)
{
/*
if (i == 4)
i++;*/
x = mUnitAnimator.UnitToX(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
y = mUnitAnimator.UnitToY(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
g.setColor(0xffff00);
if ( ((i == mTargetSelected) || (i - 1 == mTargetSelected)) && (mForce[1-mForceSelected].mUnit[i] != null) && (mForce[1-mForceSelected].mUnit[i].bAir == 0) )
{
mCursorRed.Draw(g, x, y, false);
/*g.setColor(0xff0000);
g.fillArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);*/
}
else if ( ((pValidTargets[i] == 1) && (mForce[1-mForceSelected].mUnit[i] != null) && (mForce[1-mForceSelected].mUnit[i].bAir != 1)) || ( (i % 4 != 0) && (pValidTargets[i-1] == 1) && (mForce[1-mForceSelected].mUnit[i] != null) && (mForce[1-mForceSelected].mUnit[i].bAir != 1)) )
{
g.drawArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);// Рисуем эллипс под потенциальной целью
}
}
break;
case UnitAction.ACTION_STORM:
case UnitAction.ACTION_EMP:
case UnitAction.ACTION_PLAGUE:
case UnitAction.ACTION_ENSNARE:
for (int i = 0; i < 8; i++)
{
x = mUnitAnimator.UnitToX(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
y = mUnitAnimator.UnitToY(i + 8 * (Math.abs(mForceSelected - bAttackSelected)));
g.setColor(0xffff00);
if ( (i == mTargetSelected) || (i - 1 == mTargetSelected) || (i - 4 == mTargetSelected) || (i - 4 - 1 == mTargetSelected) )
{
mCursorRed.Draw(g, x, y, false);
/*g.setColor(0xff0000);
g.fillArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);*/
}
else
{
g.drawArc(x + (40-36)/2, y + (40-10)/2, 36, 20, 0, 360);// Рисуем эллипс под потенциальной целью
}
}
break;
}
}
public void DrawPanelWithParams(Graphics g)
{
// Устанавливает надписи для панельки.
// Пишем Хиты, Шилды и Ману выбранного юнита.
mMainCanvas.mPanel.s_1 = "&s" + mForce[mForceSelected].mUnit[mUnitSelected].mCurHealth + "/" + mForce[mForceSelected].mUnit[mUnitSelected].mMaxHealth;
if (mForce[mForceSelected].mUnit[mUnitSelected].mMaxShield != 0)
mMainCanvas.mPanel.s_2 = "&4" + mForce[mForceSelected].mUnit[mUnitSelected].mCurShield + "/" + mForce[mForceSelected].mUnit[mUnitSelected].mMaxShield;
else
mMainCanvas.mPanel.s_2 = null;
if (mForce[mForceSelected].mUnit[mUnitSelected].mMaxEnergy != 0)
mMainCanvas.mPanel.s_3 = "&0" + mForce[mForceSelected].mUnit[mUnitSelected].mCurEnergy + "/" + mForce[mForceSelected].mUnit[mUnitSelected].mMaxEnergy;
else
mMainCanvas.mPanel.s_3 = null;
mMainCanvas.mPanel.Draw(g);
}
public void DrawPanel(Graphics g)
{
mMainCanvas.mPanel.s_1 = "";
mMainCanvas.mPanel.s_2 = "";
mMainCanvas.mPanel.s_3 = "";
mMainCanvas.mPanel.Draw(g);
}
public void DrawRoundTime(Graphics g)
{
mFontManager.Print(mFontManager.BIG, g, "&s"+iTime, 176/2 - 3*8, 204 - 20);
}
// Функция отрисовки доступных юниту действий
// функция отрисовки иконки, принимает расу, действие и номер действия(отвечает за координаты)
public void DrawActionIcon(Graphics g, int mRace, int mAction, int iNumber)
{
Sprite mIcons = null;
switch (mRace)
{
case Unit.RACE_TERR: mIcons = new Sprite (mTerranActionIcon); break;
case Unit.RACE_TOSS: mIcons = new Sprite (mProtossActionIcon); break;
case Unit.RACE_ZERG: mIcons = new Sprite (mZergActionIcon); break;
default: break;
}
switch (mAction)
{
case UnitAction.ACTION_ATTACK_MELEE: //20061122 Black без точки с запятой!!!
case UnitAction.ACTION_ATTACK_RANGE_LONG:
case UnitAction.ACTION_ATTACK_RANGE_LURKER:
case UnitAction.ACTION_ATTACK_RANGE_SHORT:
case UnitAction.ACTION_ATTACK_FIREBAT:
case UnitAction.ACTION_ATTACK_RANGE_SPLASH: mIcons.setFrame(0); break;
case UnitAction.ACTION_BROODLING: mIcons.setFrame(1); break;
case UnitAction.ACTION_BURROW: mIcons.setFrame(2); break;
case UnitAction.ACTION_CLOACK: mIcons.setFrame(1); break;
case UnitAction.ACTION_CONSUME: mIcons.setFrame(3); break;
case UnitAction.ACTION_DEFENCEMATRIX: mIcons.setFrame(2); break;
case UnitAction.ACTION_EMP: mIcons.setFrame(3); break;
case UnitAction.ACTION_ENSNARE: mIcons.setFrame(5); break;
case UnitAction.ACTION_FEEDBACK: mIcons.setFrame(1); break;
case UnitAction.ACTION_HEAL: mIcons.setFrame(4); break;
case UnitAction.ACTION_IRRADIATE: mIcons.setFrame(5); break;
case UnitAction.ACTION_LOCKDOWN: mIcons.setFrame(6); break;
case UnitAction.ACTION_MAELSTORM: mIcons.setFrame(2); break;
case UnitAction.ACTION_MINDCONTROL: mIcons.setFrame(3); break;
case UnitAction.ACTION_PLAGUE: mIcons.setFrame(6); break;
case UnitAction.ACTION_RETREAT:
if (mRace == Unit.RACE_TOSS) {mIcons.setFrame(5);}
else {mIcons.setFrame(7);}
break;
case UnitAction.ACTION_SIEGE: mIcons.setFrame(9); break;
case UnitAction.ACTION_STIMPACK: mIcons.setFrame(8); break;
case UnitAction.ACTION_STORM: mIcons.setFrame(4); break;
case UnitAction.ACTION_SWARM: mIcons.setFrame(4); break;
default: break;
}
if (iNumber < 3)
{
mIcons.setPosition(176-4-3*16-2*4+iNumber*(16+4), 204-4-4-2*16+2);
}
else
{
mIcons.setPosition(176-4-3*16-2*4+(iNumber-3)*(16+4), 204-4-1*16+2);
}
mIcons.paint(g);
}
// Функция отрисовки доступных юниту действий
public void DrawUnitActions(Graphics g)
{
for (int i = 0; i < 6; i++)
{
if (pValidActions[i] == 1)
{
DrawActionIcon(g, mForce[mForceSelected].mUnit[mUnitSelected].mRace, mForce[mForceSelected].mUnit[mUnitSelected].pActions[i].mType, i);
}
}
}
public void ProcessAction(Graphics g)
{
int bAttackSelected = 0;
switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType)
{
case UnitAction.ACTION_ATTACK_MELEE:
case UnitAction.ACTION_ATTACK_RANGE_LONG:
case UnitAction.ACTION_ATTACK_RANGE_LURKER:
case UnitAction.ACTION_ATTACK_RANGE_GROUND:
case UnitAction.ACTION_ATTACK_RANGE_SHORT:
case UnitAction.ACTION_ATTACK_RANGE_SPLASH:
case UnitAction.ACTION_ATTACK_FIREBAT:
case UnitAction.ACTION_BROODLING:
case UnitAction.ACTION_EMP:
case UnitAction.ACTION_ENSNARE:
case UnitAction.ACTION_FEEDBACK:
case UnitAction.ACTION_IRRADIATE:
case UnitAction.ACTION_LOCKDOWN:
case UnitAction.ACTION_MAELSTORM:
case UnitAction.ACTION_MINDCONTROL:
case UnitAction.ACTION_PLAGUE:
case UnitAction.ACTION_STORM:
bAttackSelected = 1;
break;
default:
break;
}
/* if ( (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_RETREAT) )
{
mTargetSelected = mUnitSelected + 8 * mForceSelected;
pActionTargets[mForceSelected][mUnitSelected].Target = mTargetSelected;
}
else*/
{
pActionTargets[mForceSelected][mUnitSelected].Target = mTargetSelected; //20061207 Black
if ( bAttackSelected != mForceSelected )
pActionTargets[mForceSelected][mUnitSelected].Target += 8; //20061214 Black Все цели, кроме mTargetSelected, отныне 0..15
}
pActionTargets[mForceSelected][mUnitSelected].Action = mActionSelected; //20061207 Black
mTargetSelected = -1;
SetState (STATE_WORK);
}
// Функция проигрывания события
public void PlayEvent(int i, Graphics g)
{
int tX, tY, tvX, tvY, ttX, ttY; // Куча временных переменных, чтобы не писать строчки по 600 символов
switch (((Event)mBattleEvents.elementAt(i)).mType)
{
case Event.EVENT_TYPE_EFFECT_ADD:
switch (((Event)mBattleEvents.elementAt(i)).iParameter)
{
case UnitAnimator.EFFECT_BULLET_DRAGOON:
tX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iSource);
tY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iSource);
ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
tvX = (ttX - tX)*1000/mForce[((Event)mBattleEvents.elementAt(i)).iSource/8].mUnit[((Event)mBattleEvents.elementAt(i)).iSource%8].pActions[0].iInfluenceTime;
tvY = tvX * (ttY - tY)/(ttX - tX);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_BULLET_DRAGOON, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_BULLET_VULTURE:
tX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iSource);
tY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iSource);
ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
tvX = (ttX - tX)*1000/mForce[((Event)mBattleEvents.elementAt(i)).iSource/8].mUnit[((Event)mBattleEvents.elementAt(i)).iSource%8].pActions[0].iInfluenceTime;
tvY = tvX * (ttY - tY)/(ttX - tX);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_BULLET_VULTURE, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_LURKERHIT:
int temp = 1;
if ((((Event)mBattleEvents.elementAt(i)).iSource) > 7 )
temp = -1;
for (int j = 1; j < 5; j++)
{
Event tEvent = new Event(); // создадим по событию на каждый шип
tEvent.mType = Event.EVENT_TYPE_EFFECT_ADD;
tEvent.iParameter = UnitAnimator.EFFECT_LURKERHIT_ONE;
tEvent.iTarget = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iSource) + (UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget) + 20 * temp- UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iSource)) * j/4; // x координата
tEvent.iSource = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iSource) + (UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget) - UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iSource))* j/4; // y координата
tEvent.iTime = iTime + (j-1) * 120;
mBattleEvents.addElement(tEvent);
}
break;
case UnitAnimator.EFFECT_LURKERHIT_ONE:
tvX = tvY = 0;
tX = ttX = ((Event)mBattleEvents.elementAt(i)).iTarget;
tY = ttY = ((Event)mBattleEvents.elementAt(i)).iSource;
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_LURKERHIT_ONE, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_BULLET_REAVER:
tX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iSource);
tY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iSource);
ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
tvX = (ttX - tX)*1000/mForce[((Event)mBattleEvents.elementAt(i)).iSource/8].mUnit[((Event)mBattleEvents.elementAt(i)).iSource%8].pActions[0].iInfluenceTime;
tvY = tvX * (ttY - tY)/(ttX - tX);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_BULLET_REAVER, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_LOCKDOWN:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_LOCKDOWN, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_STORM:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_STORM, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_MATRIX:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_MATRIX, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_PLAGUE:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_PLAGUE, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_EMP:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_EMP, tX, tY, tvX, tvY, ttX, ttY, false);
// Создаем событие, коорое выключит ЕМП как только закончится анимация
Event mEvent = new Event();
mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE;
mEvent.iParameter = UnitAnimator.EFFECT_EMP;
mEvent.iSource = mUnitSelected + 8*mForceSelected;
mEvent.iTarget = ((Event)mBattleEvents.elementAt(i)).iTarget;
mEvent.iTime = iTime + mUnitAnimator.m_pEffectAnimation[UnitAnimator.EFFECT_EMP].mDelay * mUnitAnimator.m_pEffectAnimation[UnitAnimator.EFFECT_EMP].mLength;
mBattleEvents.addElement(mEvent);
break;
case UnitAnimator.EFFECT_ARCHONTHIT:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_ARCHONTHIT, tX, tY, tvX, tvY, ttX, ttY, false);
break;
case UnitAnimator.EFFECT_ENSNARE:
tvX = tvY = 0;
tX = ttX = UnitAnimator.UnitToX(((Event)mBattleEvents.elementAt(i)).iTarget);
tY = ttY = UnitAnimator.UnitToY(((Event)mBattleEvents.elementAt(i)).iTarget);
mUnitAnimator.AddEffect(UnitAnimator.EFFECT_ENSNARE, tX, tY, tvX, tvY, ttX, ttY, false);
break;
default:
break;
}
break;
case Event.EVENT_TYPE_EFFECT_DELETE:
mUnitAnimator.DeleteEffect(((Event)mBattleEvents.elementAt(i)).iParameter, ((Event)mBattleEvents.elementAt(i)).iTarget);
break;
case Event.EVENT_TYPE_NULL_UNIT:
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8] = null;
break;
case Event.EVENT_TYPE_CHANGE_HP:
if (mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8] != null)
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8].mCurHealth += ((Event)mBattleEvents.elementAt(i)).iParameter;
break;
case Event.EVENT_TYPE_CHANGE_SP:
if (mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8] != null)
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8].mCurShield += ((Event)mBattleEvents.elementAt(i)).iParameter;
break;
case Event.EVENT_TYPE_CHANGE_MP:
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8].mCurEnergy += ((Event)mBattleEvents.elementAt(i)).iParameter;
break;
case Event.EVENT_TYPE_CHANGE_CONDITION:
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8].pConditions[((Event)mBattleEvents.elementAt(i)).iParameter] = ((Event)mBattleEvents.elementAt(i)).iSource;
break;
case Event.EVENT_TYPE_PLAY_UNIT_ANIMATION:
Unit tunit = mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8];
mForce[((Event)mBattleEvents.elementAt(i)).iTarget / 8].mUnit[((Event)mBattleEvents.elementAt(i)).iTarget % 8].SetState(((Event)mBattleEvents.elementAt(i)).iParameter);
if ( ( (tunit.pConditions[Unit.UNIT_CONDITION_SIEGE] == 1) || (tunit.pConditions[Unit.UNIT_CONDITION_BURROWED] == 1) ) && (((Event)mBattleEvents.elementAt(i)).iParameter == UnitAnimator.ANIM_A4))
((UnitAnimatorState)mUnitAnimator.vStates.elementAt(tunit.iAnimationState)).bBackward = true;
else
((UnitAnimatorState)mUnitAnimator.vStates.elementAt(tunit.iAnimationState)).bBackward = false;
break;
default:
break;
}
}
public void SetState(int s)
{
mMainCanvas.ResetTime();
iState = s;
}
}