offline
Опыт:
30,395
Активность:
|
Небольшой глюк препроцессора cjass
Есть следующая библиотека которую ток начал писать
» тык
library PandoraSpellCore
{
public unit SysTempUnit = null;
public group SysTempGroup = CreateGroup();
public constant int DUMMY_UNIT_ID = 'h004'
#define DummyCastToTarget(u,ut,a,l,o) =
{
unit dummyCaster = CreateUnit(GetOwningPlayer(u),PandoraSpellCore_DUMMY_UNIT_ID,GetUnitX(ut),GetUnitY(ut),0.0)
UnitAddAbility(dummyCaster,a)
SetUnitAbilityLevel(dummyCaster,a,l)
IssueTargetOrderById(dummyCaster,o,ut)
UnitApplyTimedLife(dummyCaster, 'BTLF',2.0)
dummyCaster = null
}
/// <summary>
/// Хз как даже эту функцию назвать
/// </summary>
/// <param name="caster">Кастер</param>
/// <param name="xStart">Координата Х начала обработки</param>
/// <param name="yStart">Координата Y начала обработки</param>
/// <param name="xEnd">Координата Х конца обработки</param>
/// <param name="yEnd">Координата Y конца обработки</param>
/// <param name="width">Ширина выборки</param>
/// <param name="forEach">код который исполнится для каждого юнита</param>
/// <param name="onPeroid">код который выполнится в конце каждого прохода</param>
/// <param name="onEnd">код который выполнится в после всех проходов</param>
#define LineAction(caster, xStart, yStart, xEnd, yEnd, width, forEach, onPeroid, onEnd) =
{
// "выгружаем" аргументы в локальные переменные, т.к. в виде аргументов могут быть переданы функции.
unit actionUnit = caster;
float curX = xStart;
float curY = yStart;
float xEn##d = xEnd;
float yEn##d = yEnd;
float widt##h = width;
// просчитываем дистанцию между указанными координатами
float dist = 57.295827 * Atan2(yEn##d-curY,xEn##d-curX);
// просчитываем угол между указанными координатами
float angle = SquareRoot(curX-xEn##d*curX-xEn##d+curY-yEn##d*curY-yEn##d);
// если не передано инструкций, то группа и тд нам не нужно формировать
#if (forEach != null)
// создаем группу для хранения сведений о используемых юнитах
group selectedUnitGroup = CreateGroup();
// объявляем переменную для хранения выбранного юнита
unit curUnit = null;
PandoraSpellCore_SysTempUnit = actionUnit;
#endif
// начинаем проход дистанции
for(int i = 0; i < 2*dist/widt##h; i++)
{
// выбираем юнитов в точке
// проверяем были ли указаны инструкции по обработке для юнитов
#if (forEach != null)
GroupEnumUnitsInRange(selectedUnitGroup, curX, curY, widt##h, Condition(lambda boolean ()
{
//фильтр юнитов
unit filteredUnit = GetFilterUnit();
if(!IsUnitInGroup(filteredUnit,PandoraSpellCore_SysTempGroup) &&
IsUnitEnemy(filteredUnit,GetOwningPlayer(PandoraSpellCore_SysTempUnit)) &&
GetUnitState(filteredUnit,UNIT_STATE_LIFE)>0. &&
GetUnitAbilityLevel(filteredUnit,'Avul')<=0 &&
!IsUnitType(filteredUnit,UNIT_TYPE_MAGIC_IMMUNE) &&
!IsUnitType(filteredUnit,UNIT_TYPE_STRUCTURE))
{
filteredUnit = null;
return true;
}
filteredUnit = null;
return false;
})));
// производим выбранных обработку юнитов
loop
{
// выбираем первого юнита из группы
curUnit = FirstOfGroup(selectedUnitGroup)
// если null, значит юнитов в группе нету, можно выйти из цикла
exitwhen curUnit==null
// добавляем юнита в темп группу, что бы не выполнять для него многократно какие либо действия
GroupAddUnit(SysTempGroup, curUnit)
// действие которое будет выплнено для каждого юнита
// доступные имена переменных (unit curUnit, float curX, float curY)
//===================================================
forEach
//===================================================
// удаляем юнита из группы, так как он более не нужен
GroupRemoveUnit(selectedUnitGroup, curUnit)
}
#endif
// просчитываем смещение
curX+=widt##h/2 * Cos(angle * 0.01745327)
curY+=widt##h/2 * Sin(angle * 0.01745327)
// действие которое будет выполненяться при каждом проходе цикла
// доступные имена переменных (float curX, float curY)
//===================================================
#if (onPeroid != null)
onPeroid
#endif
//===================================================
}
// финальное действие
// доступные имена переменных (float curX, float curY)
//===================================================
#if(onEnd != null)
onEnd
#endif
//===================================================
// очищаем мусор
#if (forEach != null)
PandoraSpellCore_SysTempUnit = null;
DestroyGroup(selectedUnitGroup);
GroupClear(PandoraSpellCore_SysTempGroup);
selectedUnitGroup = null;
curUnit = null;
#endif
actionUnit = null;
}
}
Юзается так:
#define private ForEach =
{
CauseDamageUnitX(SPELL_CASTER,curUnit,SPELL_DAMAGE,SPELL_TYPE);
}
#define private OnPeroid =
{
CreateOnPoint("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", curX, curY)
}
#define private OnEnd =
{
CreateOnPoint("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", curX, curY)
}
private void Action()
{
LineAction(SPELL_CASTER, GetUnitX(SPELL_CASTER), GetUnitY(SPELL_CASTER), GetSpellTargetX(), GetSpellTargetY(), 200., ForEach , OnPeroid , OnEnd)
}
Собсно проблема в том, что
#if (forEach != null)
Такая вот проверка стопорит парсер(он не падает, не зависает, а просто останавливается файнд'n'реплейс если значение является кодом. Если передано значение null, то все ок. Если совсем проверки эти убрать, то все ок.
Отредактировано Faion, 28.07.2012 в 18:31.
|