www.pudn.com > MobiCraft_src.rar > BattleCalculator.java


// style: tabs, tabsize=4, style=ANSI 
//+----------------------------------------------------------------------+ 
// Copyright (c) 2006 Company Name 
// Made by Andrew and Zahar 
//+----------------------------------------------------------------------+ 
// Filename: BattleCalculator.java 
//+----------------------------------------------------------------------+ 
// Comment: Module to calculate battle events. 
//+----------------------------------------------------------------------+ 
 
package battle; 
import java.io.IOException; 
import java.util.Vector; 
import java.util.Random; 
import app.MainCanvas; 
import app.MyRandom; 
import battle.Battle; 
import battle.UnitAnimator; 
 
class Order 
{ 
	public int mTime; 
	public int mType; 
	public int mPower; 
	public int mTarget; 
} 
 
public class BattleCalculator  
{ 
	// Типы отложенных приказов 
	public final static int ORDER_PLAGUE_ATTACK=0; 
	public final static int ORDER_PLAGUE_OFF=	1; 
	public final static int ORDER_ENSNARE_OFF=	2; 
	public final static int ORDER_SWARM_OFF=	3; 
	public final static int ORDER_MATRIX_OFF=	4; 
	public final static int ORDER_STIMPACK_OFF=	5; 
	 
	public final static int ROUND_TIME = 10000;	// 10 секунд на раунд 
	public final static int ENSNARE_TIME = 2 * ROUND_TIME;	 
	public final static int PLAGUE_TIME = 2 * ROUND_TIME;	 
	public final static int MATRIX_TIME = 2 * ROUND_TIME;	 
	public final static int STIMPACK_TIME = 2 * ROUND_TIME;	 
	 
	public int iTime; 
	public int [] mPretenders;	// Претенденты на ход в текущее время (16 - с боольшим запасом) 
	public int nPretendersNum = 0; 
	public int iPretenderSelected; 
	public int mForceSelected; 
	public int mUnitSelected; 
	public int mActionSelected; 
	public int mTargetSelected; 
	 
	public Event mEvent; 
	MainCanvas mMainCanvas; 
	 
	public Vector vDelayedOrders; 
	 
	public Force[] mForce; 
	public ActionTarget  [] [] pActionTargets; 
	 
	public BattleCalculator(MainCanvas m)  
	{ 
		mMainCanvas = m; 
		mEvent = new Event(); 
		mPretenders = new int[16];		 
		mForce = new Force[2]; 
		mForce[0] = new Force(); 
		mForce[1] = new Force(); 
		vDelayedOrders = new Vector(); 
		 
		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; 
				pActionTargets[i][q].Target = -1; 
			} 
		}	 
		 
	}	 
	public void Destroy() 
	{ 
		mEvent = null; 
		mPretenders = null; 
		mForce[0].Destroy(); 
		mForce[1].Destroy(); 
		mForce[0] = null; 
		mForce[1] = null; 
		mForce = null; 
		vDelayedOrders.removeAllElements(); 
		vDelayedOrders = null; 
 
		for (int i = 0; i < 2; i++) 
		{ 
			for (int q = 0; q < 8; q++) 
			{ 
				pActionTargets[i][q] = null; 
			} 
		}	 
		pActionTargets = null; 
		 
	}		 
	public void SetForces(Force mForce0, Force mForce1) // Сделано отдельной функцией ибо все изменения в форсе происходят от калькулятора и он про нее все знает 
	{ 
		//20061209 Black очень муторно копируем все что нужно из форсы и цели с действиями		 
		for (int i = 0; i < 8; i++) 
		{		 
			if (mForce0.mUnit[i] != null) 
			{ 
				mForce[0].mUnit[i].bAir				=	mForce0.mUnit[i].bAir; 
				mForce[0].mUnit[i].mCurEnergy		=	mForce0.mUnit[i].mCurEnergy; 
				mForce[0].mUnit[i].mCurHealth		=	mForce0.mUnit[i].mCurHealth; 
				mForce[0].mUnit[i].mCurShield		=	mForce0.mUnit[i].mCurShield; 
				mForce[0].mUnit[i].mMaxEnergy		=	mForce0.mUnit[i].mMaxEnergy; 
				mForce[0].mUnit[i].mMaxHealth		=	mForce0.mUnit[i].mMaxHealth; 
				mForce[0].mUnit[i].mMaxShield		=	mForce0.mUnit[i].mMaxShield; 
				mForce[0].mUnit[i].mNextActionTime	=	mForce0.mUnit[i].mStartTime; 
				mForce[0].mUnit[i].mRace			=	mForce0.mUnit[i].mRace; 
				mForce[0].mUnit[i].mSize			=	mForce0.mUnit[i].mSize; 
				mForce[0].mUnit[i].mStartTime		=	mForce0.mUnit[i].mStartTime; 
				mForce[0].mUnit[i].mType			=	mForce0.mUnit[i].mType; 
				//20061212 Black Копируем действия 
				for (int q = 0; q < 6; q++) 
				{ 
					if (mForce0.mUnit[i].pActions[q] != null) 
						mForce[0].mUnit[i].pActions[q]	= new UnitAction(mForce0.mUnit[i].pActions[q].mType, mForce0.mUnit[i].pActions[q].iPower, mForce0.mUnit[i].pActions[q].iCost, mForce0.mUnit[i].pActions[q].iDuration, mForce0.mUnit[i].pActions[q].iInfluenceTime);					 
				} 
			} 
			else  
				mForce[0].mUnit[i] = null; 
			if (mForce1.mUnit[i] != null) 
			{ 
				mForce[1].mUnit[i].bAir				=	mForce1.mUnit[i].bAir; 
				mForce[1].mUnit[i].mCurEnergy		=	mForce1.mUnit[i].mCurEnergy; 
				mForce[1].mUnit[i].mCurHealth		=	mForce1.mUnit[i].mCurHealth; 
				mForce[1].mUnit[i].mCurShield		=	mForce1.mUnit[i].mCurShield; 
				mForce[1].mUnit[i].mMaxEnergy		=	mForce1.mUnit[i].mMaxEnergy; 
				mForce[1].mUnit[i].mMaxHealth		=	mForce1.mUnit[i].mMaxHealth; 
				mForce[1].mUnit[i].mMaxShield		=	mForce1.mUnit[i].mMaxShield; 
				mForce[1].mUnit[i].mNextActionTime	=	mForce1.mUnit[i].mStartTime; 
				mForce[1].mUnit[i].mRace			=	mForce1.mUnit[i].mRace; 
				mForce[1].mUnit[i].mSize			=	mForce1.mUnit[i].mSize; 
				mForce[1].mUnit[i].mStartTime		=	mForce1.mUnit[i].mStartTime; 
				mForce[1].mUnit[i].mType			=	mForce1.mUnit[i].mType; 
				//20061212 Black Копируем действия 
				for (int q = 0; q < 6; q++) 
				{ 
					if (mForce1.mUnit[i].pActions[q] != null) 
						mForce[1].mUnit[i].pActions[q]	= new UnitAction(mForce1.mUnit[i].pActions[q].mType, mForce1.mUnit[i].pActions[q].iPower, mForce1.mUnit[i].pActions[q].iCost, mForce1.mUnit[i].pActions[q].iDuration, mForce1.mUnit[i].pActions[q].iInfluenceTime);					 
				}				 
			} 
			else  
				mForce[1].mUnit[i] = null; 
		}		 
	}		 
	public void Calculate(ActionTarget [] pActionTargets0, ActionTarget [] pActionTargets1, Vector mBattleEvents, UnitAnimator mUnitAnimator) 
	{ 
		// начинаем с копирования действий и целей 
		for (int i = 0; i < 8; i++) 
		{ 
			if (pActionTargets0[i].Action != -1) 
				pActionTargets[0][i].Action = pActionTargets0[i].Action; 
			if (pActionTargets0[i].Target != -1) 
				pActionTargets[0][i].Target = pActionTargets0[i].Target; 
			if (pActionTargets1[i].Action != -1) 
				pActionTargets[1][i].Action = pActionTargets1[i].Action; 
			if (pActionTargets1[i].Target != -1) 
				pActionTargets[1][i].Target = pActionTargets1[i].Target; 
		} 
		// Пускаем цикл с условием на время 
		do 
		{ 
			boolean bHaveOrders = false; 
			// "Зануляем" массив претендентов 
			for (int i = 0; i < 16; i++) 
				mPretenders[i] = -1; 
			// Ищем ближайшее время действия юнитов 
			iTime = BattleCalculator.ROUND_TIME; 
			for (int i = 0; i < 16; i++) 
			{ 
				if ( (mForce[i/8].mUnit[i%8] != null) && ( (pActionTargets[i/8][i%8].Action != -1) || (mForce[i/8].mUnit[i%8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] == 1) ) && (mForce[i/8].mUnit[i%8].mNextActionTime < iTime) ) 
					iTime = mForce[i/8].mUnit[i%8].mNextActionTime; 
			} 
			for (int i = 0; i < vDelayedOrders.size(); i++) 
			{ 
				if (((Order)vDelayedOrders.elementAt(i)).mTime <= iTime) 
				{ 
					iTime = ((Order)vDelayedOrders.elementAt(i)).mTime; 
					bHaveOrders = true; 
				} 
			} 
			 
			//20070130 Black Обрабатываем отложенные приказы 
			if (bHaveOrders) 
			{ 
				for (int i = 0; i < vDelayedOrders.size(); i++) 
				{ 
					if (((Order)vDelayedOrders.elementAt(i)).mTime == iTime) 
					{ 
						ProcessOrder(i, mBattleEvents, mUnitAnimator); 
						vDelayedOrders.removeElementAt(i); 
						i--; 
					} 
				}				 
			} 
			// ищем ближайшего претендента(-ов) на совершение действия 
			nPretendersNum = 0; 
			for (int i = 0; i < 16; i++) 
			{		 
				// Если юнит пора разлокдаунить, разлочим его и выключим анимацию 
				if ( (mForce[i / 8].mUnit[i % 8] != null) && (mForce[i / 8].mUnit[i % 8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] == 1) && (mForce[i / 8].mUnit[i % 8].mNextActionTime <= iTime) ) 
				{ 
					mForce[i / 8].mUnit[i % 8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] = 0; 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
					mEvent.iParameter = Unit.UNIT_CONDITION_LOCKDOWN; 
					mEvent.iSource = 0;	//20061216 Black Короче iSource - просто второй параметр теперь, переименовывать ломает =) 
					mEvent.iTarget = i; 
					mEvent.iTime = iTime;		 
					mBattleEvents.addElement(mEvent);							 
 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_LOCKDOWN; 
					mEvent.iSource = 0; 
					mEvent.iTarget = i; 
					mEvent.iTime = iTime;		 
					mBattleEvents.addElement(mEvent);		 
					 
				} 
				 
				// Пока не выставляется никаких дефолтных действий 
				if ( (mForce[i / 8].mUnit[i % 8] != null) && (pActionTargets[i / 8][i % 8].Action != -1) && (mForce[i / 8].mUnit[i % 8].mNextActionTime == iTime) ) 
				{ 
					mPretenders[nPretendersNum] = i; 
					nPretendersNum++;					 
				} 
			}			 
			if ( (nPretendersNum == 0) && (!bHaveOrders) ) //20061214 Black Если ни у кого нету валидных целей то покеда 
				iTime = BattleCalculator.ROUND_TIME; 
			// В случайном порядке проходим по претендентам и обрабатываем из действия 
			while (nPretendersNum > 0) 
			{ 
				int tNumber;	//20061209 Black Временная переменная, чтобы хранить номер ячейки с претендентом 
				// выбираем претендента, вычеркиваем его из списка претендентов, 
				// декрементируем число претендентов и переводим его номер в mForceSelected и mUnitSelected (чтобы было меньше мороки и чтобы можно было использовать уже написанную функцию =) 
				tNumber = mMainCanvas.mRandom.Rand(nPretendersNum); 
				iPretenderSelected = mPretenders[tNumber]; 
				mPretenders[tNumber] = mPretenders[nPretendersNum - 1];				 
				mPretenders[nPretendersNum - 1] = -1;	 
				nPretendersNum--; 
				mForceSelected = iPretenderSelected / 8; 
				mUnitSelected = iPretenderSelected % 8;				 
				if (mForce[mForceSelected].mUnit[mUnitSelected] != null)	//20061214 Black Юнита могли уже убить другие претенденты на ход 
				{ 
					mActionSelected = pActionTargets [mForceSelected] [mUnitSelected].Action; 
					mTargetSelected = pActionTargets [mForceSelected] [mUnitSelected].Target;				 
					//20061209 Обрабатываем его действие  
					if (mTargetSelected != -1) 
						ProcessAction(mBattleEvents, mUnitAnimator); 
				} 
			}			 
		} 
		while (iTime < ROUND_TIME); 
		// Времена следующих действий для всех юнитов снижаем на ROUND_TIME Только если цели и действия ненуллевые 
		for (int i = 0; i < 16; i++) 
			if ( (mForce[i/8].mUnit[i%8] != null) /*&& (pActionTargets[i/8][i%8].Action != -1)*/ ) 
			{ 
				mForce[i/8].mUnit[i%8].mNextActionTime -= ROUND_TIME; 
				if (mForce[i/8].mUnit[i%8].mNextActionTime < 0) 
					mForce[i/8].mUnit[i%8].mNextActionTime = 0; 
			} 
		// Так же снижаем время всех отложенных приказов 
		for (int i = 0; i < vDelayedOrders.size(); i++) 
			((Order)vDelayedOrders.elementAt(i)).mTime -= ROUND_TIME; 
	} 
    public void ProcessAction(Vector mBattleEvents, UnitAnimator mUnitAnimator) 
	{ 
		//20061214 Black Для начала проверка на ненуллевость цели, в противном случае ставится дефолтная цель 
		if ( (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8] == null)  
			&& (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_STORM)  
			&& (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_EMP)  
			&& (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_PLAGUE)  
			&& (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_ATTACK_FIREBAT)  
			&& (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_ATTACK_RANGE_LURKER) ) 
		{ 
			SetDefaultTarget(); 
		} 
		if (pActionTargets[mForceSelected][mUnitSelected].Target != -1) 
		{ 
			//20061210 Black Увеличиваем время следующего действия 
			mForce[mForceSelected].mUnit[mUnitSelected].mNextActionTime += mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iDuration; 
			if (mActionSelected < 4) 
			{ 
				//20061210 Black Создаем событие - анимация действия 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_PLAY_UNIT_ANIMATION; 
				switch (mActionSelected) 
				{ 
					case (0): mEvent.iParameter = UnitAnimator.ANIM_A1; break; 
					case (1): mEvent.iParameter = UnitAnimator.ANIM_A2; break; 
					case (2): mEvent.iParameter = UnitAnimator.ANIM_A3; break; 
					case (3): mEvent.iParameter = UnitAnimator.ANIM_A4; break; 
					default: break; 
				} 
				mEvent.iTime = iTime; 
				mEvent.iTarget = mUnitSelected + 8 * mForceSelected; 
				mBattleEvents.addElement(mEvent); 
			} 
			//20061210 Black Создаем событие - создать эффект 
			AddEventAnimAction(mBattleEvents); 
			 
			if ( mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost != 0 && mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_STIMPACK ) 
			{ 
				// Снимаем ману 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_CHANGE_MP; 
				mEvent.iParameter = -mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost; 
				mEvent.iTarget = 8 * mForceSelected + mUnitSelected; 
				mEvent.iTime = iTime; 
				mBattleEvents.addElement(mEvent); 
				mForce[mForceSelected].mUnit[mUnitSelected].mCurEnergy += mEvent.iParameter; 
			} 
			switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType)			 
			{ 
				case UnitAction.ACTION_ATTACK_MELEE: 
				case UnitAction.ACTION_ATTACK_RANGE_LONG: 
				case UnitAction.ACTION_ATTACK_RANGE_SHORT: 
				case UnitAction.ACTION_ATTACK_RANGE_GROUND: 
					AttackUnit(1-mForceSelected, mTargetSelected%8, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					break; 
				case UnitAction.ACTION_ATTACK_FIREBAT: 
				case UnitAction.ACTION_ATTACK_RANGE_SPLASH:					 
					if ( (mForce[1- mForceSelected].mUnit[mTargetSelected % 8] != null) && (mForce[1- mForceSelected].mUnit[mTargetSelected % 8].bAir == 0) ) 
						AttackUnit(1-mForceSelected, mTargetSelected%8, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					if ( (mForce[1- mForceSelected].mUnit[mTargetSelected % 8 + 1] != null) && (mForce[1- mForceSelected].mUnit[mTargetSelected % 8 + 1].bAir == 0) ) 
						AttackUnit(1-mForceSelected, mTargetSelected%8 + 1, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator);					 
					break; 
				case UnitAction.ACTION_ATTACK_RANGE_LURKER: 
					if ( (mForce[1- mForceSelected].mUnit[mTargetSelected % 8] != null) && (mForce[1- mForceSelected].mUnit[mTargetSelected % 8].bAir == 0) ) 
						AttackUnit(1-mForceSelected, mTargetSelected%8, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					if ( (mForce[1- mForceSelected].mUnit[(mTargetSelected + 4) % 8 ] != null) && (mForce[1- mForceSelected].mUnit[(mTargetSelected + 4) % 8 ].bAir == 0) ) 
						AttackUnit(1-mForceSelected, mTargetSelected%8 + 4, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator);					 
					break; 
				case UnitAction.ACTION_STORM: 
					if (mForce[1- mForceSelected].mUnit[mTargetSelected % 8] != null) 
						AttackUnit(1-mForceSelected, mTargetSelected%8, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					if (mForce[1- mForceSelected].mUnit[mTargetSelected % 8 + 1] != null) 
						AttackUnit(1-mForceSelected, mTargetSelected%8 + 1, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					if (mForce[1- mForceSelected].mUnit[mTargetSelected % 8 + 4] != null) 
						AttackUnit(1-mForceSelected, mTargetSelected%8 + 4, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					if (mForce[1- mForceSelected].mUnit[mTargetSelected % 8 + 1 + 4] != null) 
						AttackUnit(1-mForceSelected, mTargetSelected%8 + 1 + 4, mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					// Шторм бросается один раз на приказ - чтобы ману не проябывать и для соответствия Старику 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1;					 
					break; 
				case UnitAction.ACTION_STIMPACK: 
					if ( mForce[mForceSelected].mUnit[mUnitSelected].mCurHealth > mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost ) 
					{ 
						// Снимаем хиты 
						mEvent = new Event(); 
						mEvent.mType = Event.EVENT_TYPE_CHANGE_HP; 
						mEvent.iParameter = -mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost; 
						mEvent.iTarget = 8 * mForceSelected + mUnitSelected; 
						mEvent.iTime = iTime; 
						mBattleEvents.addElement(mEvent); 
						mForce[mForceSelected].mUnit[mUnitSelected].mCurHealth += mEvent.iParameter; 
						 
						//mForce[mForceSelected].mUnit[mUnitSelected].mCurHealth -= mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iCost; 
						mForce[mForceSelected].mUnit[mUnitSelected].pActions[0].iDuration /= 2; 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
						Order tOrder = new Order(); 
						tOrder.mPower = 0; 
						tOrder.mTarget = mTargetSelected ; 
						tOrder.mTime = iTime + STIMPACK_TIME; 
						tOrder.mType = ORDER_STIMPACK_OFF; 
						vDelayedOrders.addElement(tOrder);						 
					} 
					break; 
				case UnitAction.ACTION_ENSNARE: 
					int i = 0; //Временная переменная 
					while (i != -1) 
					{ 
						if ( (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i] != null) && (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].pConditions[Unit.UNIT_CONDITION_ENSNARE] == 0) ) 
						{	 
							for (int q = 0; q < 6; q++) 
							{ 
								if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].pActions[q] != null) 
								mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].pActions[q].iDuration *= 2; 
							} 
							 
							Order tOrder = new Order(); 
							tOrder.mPower = 0; 
							tOrder.mTarget = mTargetSelected + i; 
							tOrder.mTime = iTime + ENSNARE_TIME; 
							tOrder.mType = ORDER_ENSNARE_OFF; 
							vDelayedOrders.addElement(tOrder); 
							 
							mForce[(mTargetSelected + i) / 8].mUnit[(mTargetSelected + i) % 8].pConditions[Unit.UNIT_CONDITION_ENSNARE] = 1; 
						} 
						switch (i) 
						{ 
							case 0: i = 1; break; 
							case 1: i = 4; break; 
							case 4: i = 5; break; 
							case 5: i = -1; break; 
						}						 
					} 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1;					 
					break; 
				case UnitAction.ACTION_HEAL: 
					if (mForce[mForceSelected].mUnit[mTargetSelected % 8].mCurHealth == mForce[mForceSelected].mUnit[mTargetSelected % 8].mMaxHealth) 
					{ 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
					}					 
					else if (mForce[mForceSelected].mUnit[mTargetSelected % 8].mCurHealth != mForce[mForceSelected].mUnit[mTargetSelected % 8].mMaxHealth) 
					{ 
						mEvent = new Event(); 
						mEvent.mType = Event.EVENT_TYPE_CHANGE_HP; 
						mEvent.iParameter = Math.min(mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower, mForce[mForceSelected].mUnit[mTargetSelected % 8].mMaxHealth - mForce[mForceSelected].mUnit[mTargetSelected % 8].mCurHealth); 
						mEvent.iTarget = mTargetSelected; 
						mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime;		 
						mBattleEvents.addElement(mEvent); 
						mForce[mForceSelected].mUnit[mTargetSelected % 8].mCurHealth += mEvent.iParameter; 
					} 
					break; 
				case UnitAction.ACTION_LOCKDOWN: 
					if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] == 1) 
					{ 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1;		 
						return; 
					} 
					else 
					{ 
						mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] = 1; 
						mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8].mNextActionTime += mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower; 
						mEvent = new Event(); 
						mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
						mEvent.iParameter = Unit.UNIT_CONDITION_LOCKDOWN; 
						mEvent.iSource = 1;	//20061216 Black Короче iSource - просто второй параметр теперь, переименовывать ломает =) 
						mEvent.iTarget = mTargetSelected; 
						mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
						mBattleEvents.addElement(mEvent); 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1;						 
					} 
					break; 
				case UnitAction.ACTION_DEFENCEMATRIX: 
					if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8].pConditions[Unit.UNIT_CONDITION_MATRIX] != 0) 
					{ 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
						return; 
					} 
					else 
					{ 
						mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8].pConditions[Unit.UNIT_CONDITION_MATRIX] = mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower; 
						mEvent = new Event(); 
						mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
						mEvent.iParameter = Unit.UNIT_CONDITION_MATRIX; 
						mEvent.iSource = mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower; 
						mEvent.iTarget = mTargetSelected; 
						mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
						mBattleEvents.addElement(mEvent); 
						pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
						pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
						 
						Order tOrder = new Order(); 
						tOrder.mPower = 0; 
						tOrder.mTarget = mTargetSelected ; 
						tOrder.mTime = iTime + MATRIX_TIME; 
						tOrder.mType = ORDER_MATRIX_OFF; 
						vDelayedOrders.addElement(tOrder);						 
					} 
					break; 
				case UnitAction.ACTION_FEEDBACK: 
 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_MP; 
					mEvent.iParameter = -mForce[1 - mForceSelected].mUnit[mTargetSelected % 8].mCurEnergy; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent); 
					mForce[1 - mForceSelected].mUnit[mTargetSelected % 8].mCurEnergy = 0; 
					AttackUnit(1-mForceSelected, mTargetSelected%8, -mEvent.iParameter, iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime, mBattleEvents, mUnitAnimator); 
					 
					break; 
				case UnitAction.ACTION_EMP: 
					i = 0; //Временная переменная 
					while (i != -1) 
					{ 
						if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i] != null) 
						{ 
							if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurEnergy != 0) 
							{ 
								mEvent = new Event(); 
								mEvent.mType = Event.EVENT_TYPE_CHANGE_MP; 
								mEvent.iParameter = -mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurEnergy; 
								mEvent.iTarget = mTargetSelected + i; 
								mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
								mBattleEvents.addElement(mEvent); 
								mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurEnergy = 0; 
							} 
							if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurShield != 0) 
							{ 
								mEvent = new Event(); 
								mEvent.mType = Event.EVENT_TYPE_CHANGE_SP; 
								mEvent.iParameter = -mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurShield; 
								mEvent.iTarget = mTargetSelected + i; 
								mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
								mBattleEvents.addElement(mEvent); 
								mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i].mCurShield = 0; 
							}						 
						} 
						switch (i) 
						{ 
							case 0: i = 1; break; 
							case 1: i = 4; break; 
							case 4: i = 5; break; 
							case 5: i = -1; break; 
						}						 
					} 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1;					 
					break; 
				case UnitAction.ACTION_PLAGUE: 
					i = 0; //Временная переменная 
					while (i != -1) 
					{ 
						if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i] != null) 
						{ 
							for (int q = 0; q < 10; q++) 
							{ 
								Order tOrder = new Order(); 
								tOrder.mPower = mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iPower / 10; 
								tOrder.mTarget = pActionTargets[mForceSelected][mUnitSelected].Target + i; 
								tOrder.mTime = iTime + (q + 1) * (PLAGUE_TIME / 10); 
								tOrder.mType = ORDER_PLAGUE_ATTACK; 
								vDelayedOrders.addElement(tOrder); 
							} 
							Order tOrder = new Order(); 
							tOrder.mPower = 0; 
							tOrder.mTarget = mTargetSelected + i; 
							tOrder.mTime = iTime + PLAGUE_TIME; 
							tOrder.mType = ORDER_PLAGUE_OFF; 
							vDelayedOrders.addElement(tOrder); 
							 
							mForce[(mTargetSelected + i) / 8].mUnit[(mTargetSelected + i) % 8].pConditions[Unit.UNIT_CONDITION_PLAGUE] = 1; 
						} 
						switch (i) 
						{ 
							case 0: i = 1; break; 
							case 1: i = 4; break; 
							case 4: i = 5; break; 
							case 5: i = -1; break; 
						}						 
					} 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
					break; 
				case UnitAction.ACTION_SIEGE: 
					//20070310 Black Создаем событие - переход в IDLE2/IDLE 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_PLAY_UNIT_ANIMATION; 
					if (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_SIEGE] == 0) 
						mEvent.iParameter = UnitAnimator.ANIM_IDLE2; 
					else 
						mEvent.iParameter = UnitAnimator.ANIM_IDLE; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mEvent.iTarget = mUnitSelected + 8 * mForceSelected; 
					mBattleEvents.addElement(mEvent); 
					 
					mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_SIEGE] = (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_SIEGE] + 1) % 2; 
 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
					mEvent.iParameter = Unit.UNIT_CONDITION_SIEGE; 
					mEvent.iSource = mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_SIEGE]; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent); 
					 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1;					 
					break; 
				case UnitAction.ACTION_BURROW: 
					//20070310 Black Создаем событие - переход в IDLE2/IDLE 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_PLAY_UNIT_ANIMATION; 
					if (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED] == 0) 
						mEvent.iParameter = UnitAnimator.ANIM_IDLE2; 
					else 
						mEvent.iParameter = UnitAnimator.ANIM_IDLE; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mEvent.iTarget = mUnitSelected + 8 * mForceSelected; 
					mBattleEvents.addElement(mEvent); 
					 
					mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED] = (mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED] + 1) % 2; 
 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
					mEvent.iParameter = Unit.UNIT_CONDITION_BURROWED; 
					mEvent.iSource = mForce[mForceSelected].mUnit[mUnitSelected].pConditions[Unit.UNIT_CONDITION_BURROWED]; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent); 
					 
					pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
					pActionTargets[mForceSelected][mUnitSelected].Target = -1;					 
					break;					 
				default: 
					break; 
			} 
		} 
    } 
	public void AddEventAnimAction(Vector mBattleEvents) // Функция добавляет событие полета пули (если таковое возможно для этого юнита) 
	{ 
		switch (mForce[mForceSelected].mUnit[mUnitSelected].mType) 
		{ 
			case Unit.UNIT_P_DRAGOON: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_RETREAT) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_BULLET_DRAGOON; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent); 
				} 
				break; 
			case Unit.UNIT_P_REAVER: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_RETREAT) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_BULLET_REAVER; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent); 
				} 
				break;				 
			case Unit.UNIT_T_VULTURE: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType != UnitAction.ACTION_RETREAT) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_BULLET_VULTURE; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent); 
				} 
				break;				 
			case Unit.UNIT_T_GHOST: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_LOCKDOWN) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_LOCKDOWN; 
					mEvent.iSource = 0; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent);						 
				} 
				break; 
			case Unit.UNIT_P_TEMPLAR: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_STORM) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_STORM; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					if (1 - mForceSelected == 0) 
						mEvent.iTarget = mTargetSelected + 4; 
					else 
						mEvent.iTarget = mTargetSelected ; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);					 
								 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_STORM; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					if (1 - mForceSelected == 0) 
						mEvent.iTarget = mTargetSelected + 4; 
					else 
						mEvent.iTarget = mTargetSelected ; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent);					 
				} 
				break; 
			case Unit.UNIT_T_VESSEL: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_DEFENCEMATRIX) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_MATRIX; 
					mEvent.iSource = 0; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent);						 
				} 
				else if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_EMP) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_EMP; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					if (1 - mForceSelected == 0) 
						mEvent.iTarget = mTargetSelected + 4; 
					else 
						mEvent.iTarget = mTargetSelected ; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);					 
				} 
				break; 
			case Unit.UNIT_P_ARCHONT: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_ATTACK_MELEE) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_ARCHONTHIT; 
					mEvent.iSource = 0; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent); 
					// Создаем событие, коорое выключит Эффект по окончанию InfluenceTime 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_ARCHONTHIT; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent);					 
				} 
				break; 
			case Unit.UNIT_Z_LURKER: 
				if (mActionSelected == 0/*mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_ATTACK_MELEE*/) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
					mEvent.iParameter = UnitAnimator.EFFECT_LURKERHIT; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent); 
					// Создаем событие, коорое выключит Эффект по окончанию InfluenceTime 
					/*mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_LURKERHIT; 
					mEvent.iSource = mUnitSelected + 8*mForceSelected; 
					mEvent.iTarget = mTargetSelected; 
					mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
					mBattleEvents.addElement(mEvent);*/ 
				} 
				break; 
			case Unit.UNIT_Z_DEFILER: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_PLAGUE) 
				{ 
					int i = 0; //Временная переменная 
					while (i != -1) 
					{ 
						if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i] != null) 
						{ 
							mEvent = new Event(); 
							mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
							mEvent.iParameter = UnitAnimator.EFFECT_PLAGUE; 
							mEvent.iSource = 0; 
							mEvent.iTarget = mTargetSelected + i; 
							mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
							mBattleEvents.addElement(mEvent);						 
						} 
						switch (i) 
						{ 
							case 0: i = 1; break; 
							case 1: i = 4; break; 
							case 4: i = 5; break; 
							case 5: i = -1; break; 
						}						 
					}					 
				} 
				break; 
			case Unit.UNIT_Z_QUEEN: 
				if (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType == UnitAction.ACTION_ENSNARE) 
				{ 
					int i = 0; //Временная переменная 
					while (i != -1) 
					{ 
						if (mForce[mTargetSelected / 8].mUnit[mTargetSelected % 8 + i] != null) 
						{ 
							mEvent = new Event(); 
							mEvent.mType = Event.EVENT_TYPE_EFFECT_ADD; 
							mEvent.iParameter = UnitAnimator.EFFECT_ENSNARE; 
							mEvent.iSource = 0; 
							mEvent.iTarget = mTargetSelected + i; 
							mEvent.iTime = iTime + mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].iInfluenceTime; 
							mBattleEvents.addElement(mEvent);						 
						} 
						switch (i) 
						{ 
							case 0: i = 1; break; 
							case 1: i = 4; break; 
							case 4: i = 5; break; 
							case 5: i = -1; break; 
						}						 
					}					 
				} 
				break; 
			default: break; 
		} 
	} 
	public void AttackUnit(int iforce, int iunit, int ipower, int itime, Vector mBattleEvents, UnitAnimator mUnitAnimator)	//20061210 Black Создает по необходимости события снятия шилдов, хитов, поригрывания анимации смерти и занулления юнита 
	{ 
		int iPower = ipower;	// Переменная хранит значение атаки минус значение матрицы, в случае если матрица сносится на этом ходу 
		int iArmor = mForce[iforce].mUnit[iunit].mArmor; // Чтобы строчки были покороче 
		// Сначала идет проверка на Защитную матрицу и вносятся соответствующие корректировки 
		if (mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_MATRIX] != 0) 
		{ 
			iPower = Math.max(ipower - mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_MATRIX], 0);	// То есть если матрица сильнее атаки, то с нее снимется значение атаки и никаких событий создаваться не будет 
			mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_MATRIX] -= ipower - iPower; 
			// Если матрица занулилась, то создадим об этом событие 
			if (mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_MATRIX] == 0) 
			{ 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
				mEvent.iParameter = Unit.UNIT_CONDITION_MATRIX; 
				mEvent.iSource = 0; 
				mEvent.iTarget = iunit + 8*iforce; 
				mEvent.iTime = itime; 
				mBattleEvents.addElement(mEvent); 
				 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
				mEvent.iParameter = UnitAnimator.EFFECT_MATRIX; 
				mEvent.iSource = 0; 
				mEvent.iTarget = iunit + 8*iforce; 
				mEvent.iTime = itime; 
				mBattleEvents.addElement(mEvent); 
				 
				// Ищем приказы о снятии матрицы, относящиеся к данному юниту и убираем их 
				for (int i = 0; i < vDelayedOrders.size(); i++) 
				{ 
					if ( (((Order)vDelayedOrders.elementAt(i)).mTarget == (iforce*8 + iunit)) && (((Order)vDelayedOrders.elementAt(i)).mType == BattleCalculator.ORDER_MATRIX_OFF) ) 
					{ 
						vDelayedOrders.removeElementAt(i); 
						i--; 
					} 
				} 
				 
			} 
		} 
		if (iPower != 0)	// Матрица пробилась 
		{ 
			if (mForce[iforce].mUnit[iunit].mCurShield == 0)	// Только хиты снимаем 
			{ 
				// Снимаем хиты и создаем соответствующее событие 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_CHANGE_HP; 
				mEvent.iParameter = -Math.min(mForce[iforce].mUnit[iunit].mCurHealth, ipower - iArmor); 
				mEvent.iTarget = iunit + 8*iforce; 
				mEvent.iTime = itime;		 
				mBattleEvents.addElement(mEvent); 
				mForce[iforce].mUnit[iunit].mCurHealth += mEvent.iParameter;			 
			} 
			else  
			{					 
				if (mForce[iforce].mUnit[iunit].mCurShield >= ipower) // Только щит снимаем 
				{ 
					mForce[iforce].mUnit[iunit].mCurShield -= ipower; 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_SP; 
					mEvent.iParameter = -ipower; 
					mEvent.iTarget = iunit + 8*iforce; 
					mEvent.iTime = itime;	 
					mBattleEvents.addElement(mEvent); 
				} 
				else	// Снимаются целиком щиты, а потом и хиты 
				{ 
					// Создаем событие снятия щитов 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_SP; 
					mEvent.iParameter = -mForce[iforce].mUnit[iunit].mCurShield; 
					mEvent.iTarget = iunit + 8*iforce; 
					mEvent.iTime = itime;		 
					mBattleEvents.addElement(mEvent); 
					// Создаем событие снятия хитов 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_HP; 
					mEvent.iParameter = -Math.min( - mForce[iforce].mUnit[iunit].mCurShield + ipower - iArmor, mForce[iforce].mUnit[iunit].mCurHealth); 
					mEvent.iTarget = iunit + 8*iforce; 
					mEvent.iTime = itime;		 
					mBattleEvents.addElement(mEvent); 
					// Снимаем щит и хиты у юнита в внутренней форсе 
					mForce[iforce].mUnit[iunit].mCurHealth += mEvent.iParameter; 
					mForce[iforce].mUnit[iunit].mCurShield = 0;				 
				} 
			} 
			// Если юнит-цель умер создаем два события - анимация и занулление. + Снятие всех эффектов 
			if (mForce[iforce].mUnit[iunit].mCurHealth <= 0) 
			{ 
				// Создаем событие - анимировать смерть 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_PLAY_UNIT_ANIMATION; 
				mEvent.iParameter = UnitAnimator.ANIM_DEATH; 
				mEvent.iTime = itime; 
				mEvent.iTarget = iunit + 8 * iforce; 
				mBattleEvents.addElement(mEvent);			 
				// Создаем событие зануллить юнита 
				mEvent = new Event(); 
				mEvent.mType = Event.EVENT_TYPE_NULL_UNIT; 
				mEvent.iTime = itime; 
				if (mUnitAnimator.m_pUnitAnimation[mForce[iforce].mUnit[iunit].mType][UnitAnimator.ANIM_DEATH] != null) 
					mEvent.iTime += mUnitAnimator.m_pUnitAnimation[mForce[iforce].mUnit[iunit].mType][UnitAnimator.ANIM_DEATH].mDelay * mUnitAnimator.m_pUnitAnimation[mForce[iforce].mUnit[iunit].mType][UnitAnimator.ANIM_DEATH].mLength;	//20061210 Black Пиздец =) Это сдвиг по времени для того чтобы юнит зануллялся после проигрывания анимации 
				else 
					mEvent.iTime += 200;	//20061214 Black временная мера пока не для всех прорисованы анимации 
				mEvent.iTarget = iunit + 8 * iforce; 
				mBattleEvents.addElement(mEvent); 
				// Снимаем все эффекты 
				if (mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_LOCKDOWN] != 0) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_LOCKDOWN; 
					mEvent.iSource = 0; 
					mEvent.iTarget = iunit + 8 * iforce; 
					mEvent.iTime = itime;		 
					mBattleEvents.addElement(mEvent);							 
				} 
				if (mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_PLAGUE] != 0) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_PLAGUE; 
					mEvent.iSource = 0; 
					mEvent.iTarget = iunit + 8 * iforce; 
					mEvent.iTime = itime;		 
					mBattleEvents.addElement(mEvent);							 
				} 
				if (mForce[iforce].mUnit[iunit].pConditions[Unit.UNIT_CONDITION_IRRADIATE] != 0) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_IRRADIATE; 
					mEvent.iSource = 0; 
					mEvent.iTarget = iunit + 8 * iforce; 
					mEvent.iTime = itime;		 
					mBattleEvents.addElement(mEvent);							 
				} 
				mForce[iforce].mUnit[iunit] = null; 
			} 
		} 
	} 
	// тупо копия Battle.CheckValidTargets без лишнего выебонства (пока...) 
	public void SetDefaultTarget() 
	{ 
        //20061203 switch на возможные типы атаки (melee, any single, splash ranged, lurker ranged, megasplash) 
		pActionTargets[mForceSelected][mUnitSelected].Target = -1; 
        switch (mForce[mForceSelected].mUnit[mUnitSelected].pActions[mActionSelected].mType) 
		{ 
			case UnitAction.ACTION_ATTACK_MELEE: 
				for (int i = 0; i < 8; i++) 
					if ( (mForce[1 - mForceSelected].mUnit[i] != null) && (mForce[1 - mForceSelected].mUnit[i].bAir != 1) && (Math.abs(i%4 - mUnitSelected%4) <= 1)  && (pActionTargets[mForceSelected][mUnitSelected].Target == -1)) 
						pActionTargets[mForceSelected][mUnitSelected].Target = i + 8 * (1 - mForceSelected); 
				break; 
			case UnitAction.ACTION_ATTACK_RANGE_LONG: 
			case UnitAction.ACTION_ATTACK_RANGE_SHORT: 
				for (int i = 0; i < 8; i++)				 
					if ( (mForce[1 - mForceSelected].mUnit[i] != null) &&  (pActionTargets[mForceSelected][mUnitSelected].Target == -1)) 
						pActionTargets[mForceSelected][mUnitSelected].Target = i + 8 * (1 - mForceSelected); 
				break; 
			case UnitAction.ACTION_ATTACK_RANGE_GROUND: 
				for (int i = 0; i < 8; i++)				 
					if ( (mForce[1 - mForceSelected].mUnit[i] != null) &&  (pActionTargets[mForceSelected][mUnitSelected].Target == -1) && (mForce[1 - mForceSelected].mUnit[i].bAir != 1) ) 
						pActionTargets[mForceSelected][mUnitSelected].Target = i + 8 * (1 - mForceSelected);				 
/*			case UnitAction.ACTION_STORM: 
				for (int i = 0; i < 3; i++) 
					if ( ( (mForce[1 - mForceSelected].mUnit[i] != null) || (mForce[1 - mForceSelected].mUnit[i + 1] != null) || (mForce[1 - mForceSelected].mUnit[i + 4] != null) || (mForce[1 - mForceSelected].mUnit[i + 1 + 4] != null) )&& (pActionTargets[mForceSelected][mUnitSelected].Target == -1) ) 
						pActionTargets[mForceSelected][mUnitSelected].Target = i + 8 * (1 - mForceSelected); 
 */ 
			default: 
				break; 
		} 
		mTargetSelected = pActionTargets[mForceSelected][mUnitSelected].Target; 
		if (pActionTargets[mForceSelected][mUnitSelected].Target == -1) 
			pActionTargets[mForceSelected][mUnitSelected].Action = -1; 
	} 
	public void ProcessOrder(int i, Vector mBattleEvents, UnitAnimator mUnitAnimator) 
	{ 
		switch (((Order)vDelayedOrders.elementAt(i)).mType) 
		{ 
			case ORDER_PLAGUE_ATTACK: 
				int tForce = ((Order)vDelayedOrders.elementAt(i)).mTarget / 8; 
				int tUnit = ((Order)vDelayedOrders.elementAt(i)).mTarget % 8; 
				if (mForce[tForce].mUnit[tUnit] != null) 
				{ 
					int tPower = Math.min(((Order)vDelayedOrders.elementAt(i)).mPower, mForce[tForce].mUnit[tUnit].mCurHealth - 1); 
 
					// Создаем событие снятия хитов 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_HP; 
					mEvent.iParameter = -Math.min( tPower - mForce[tForce].mUnit[tUnit].mArmor, mForce[tForce].mUnit[tUnit].mCurHealth - 1); 
					mEvent.iTarget = tUnit + 8*tForce; 
					mEvent.iTime = iTime;		 
					mBattleEvents.addElement(mEvent); 
					// Снимаем хиты у юнита в внутренней форсе 
					mForce[tForce].mUnit[tUnit].mCurHealth += mEvent.iParameter; 
					 
					//AttackUnit(tForce, tUnit, tPower, iTime, mBattleEvents, mUnitAnimator); 
				} 
				break; 
			case ORDER_PLAGUE_OFF: 
				if (mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8] != null) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_PLAGUE; 
					mEvent.iSource = 0; 
					mEvent.iTarget = ((Order)vDelayedOrders.elementAt(i)).mTarget; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);	 
					mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pConditions[Unit.UNIT_CONDITION_PLAGUE] = 0; 
				} 
				break; 
			case ORDER_ENSNARE_OFF: 
				if (mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8] != null) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_ENSNARE;  
					mEvent.iSource = 0; 
					mEvent.iTarget = ((Order)vDelayedOrders.elementAt(i)).mTarget; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);	 
					mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pConditions[Unit.UNIT_CONDITION_ENSNARE] = 0; 
					for (int q = 0; q < 6; q++) 
						if (mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pActions[q] != null) 
							mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pActions[q].iDuration /= 2; 
				}				 
				break; 
			case ORDER_MATRIX_OFF: 
				if (mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8] != null) 
				{ 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_EFFECT_DELETE; 
					mEvent.iParameter = UnitAnimator.EFFECT_MATRIX; 
					mEvent.iSource = 0; 
					mEvent.iTarget = ((Order)vDelayedOrders.elementAt(i)).mTarget; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);	 
					 
					mEvent = new Event(); 
					mEvent.mType = Event.EVENT_TYPE_CHANGE_CONDITION; 
					mEvent.iParameter = Unit.UNIT_CONDITION_MATRIX; 
					mEvent.iSource = 0; 
					mEvent.iTarget = ((Order)vDelayedOrders.elementAt(i)).mTarget; 
					mEvent.iTime = iTime; 
					mBattleEvents.addElement(mEvent);	 
					 
					mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pConditions[Unit.UNIT_CONDITION_MATRIX] = 0; 
				} 
				break; 
			case ORDER_STIMPACK_OFF: 
				if (mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8] != null) 
					mForce[((Order)vDelayedOrders.elementAt(i)).mTarget / 8].mUnit[((Order)vDelayedOrders.elementAt(i)).mTarget % 8].pActions[0].iDuration *= 2; 
				break; 
			default: 
				break; 
		} 
	} 
}