XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Hares
полупротосс
offline
Опыт: 6,966
Активность:
Ошибка с глобальными переменными
Делал спелл из темы "Заклинания на заказ". Сам спелл в принципе готов, однако при написании графики (а на неё я имел наполеоновские планы), я столкнулся со странной проблемой: Вар сбрасывает переменные, да ещё и пляс ко всему, делает это как ему вздумается.
» Заявка:
Dartek:
Название: Точка невозвращения
Способ исполнения: GUI, +CS если нужен будет
Цель: нет
Для героя: нет
MUI: не обязателен
Описание: При касте спелла вокруг юнита возникает круглая область диаметром 800, выйти из которой нельзя, как и войти в нее снаружи. Подробнее - можно свободно передвигаться внутри и вокруг указанной окружности, но нельзя пересечь эту черту. Эта окружность привязана к месту каста, и сам кастер тоже выйти не может. Длительность действия - 20 секунд.
По уровням: 1 уровень
Комментарий: Спелл нужен достаточно сильно.. Если кто-нибудь сделает - буду дико благодарен. С МУИ можно не забиваться, такой юнит будет всего один на карте.. И если не будет слишком сложно - хорошо бы еще сделать так, чтобы тем кто внутри не было видно ничего снаружи, и наоборот. Способ закрытия обзора - на ваше усмотрение.
» Код спелла
((код
define
{
int = integer;
bool = boolean;
void = nothing;
}
define
{
MDX = ".mdl";
PI = 3.1415926;

ABIL = 'MgWl';
COUNT = 100;
BLOCK = 'Blck';
RANGE = 300;
COUNTRUNES = 30;
RUNE = "Doodads\\Cityscape\\Props\\MagicRunes\\MagicRunes";
RUNEVARIATIONS = 3;
PERIODICRUNE = 0.5;
FIRE = "Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp";
FIREVARIATIONS = 1;
COUNTFIRES = 2;
PERIODICFIRE = 3;
}
globals
int Bound = -1;
int EBound = -1;
timer array Timers;
int array Index;
destructable array Block;
effect array Rune;
effect array Fire;
endglobals
void CreateRune()
{
BJDebugMsg("I want to create rune effect...");

string s = RUNE + I2S(GetRandomInt(1, RUNEVARIATIONS) - 1) + MDX;
string s = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl";

real Range = RANGE;

BJDebugMsg("Finding the timer...");

integer i = 0;
timer t = GetExpiredTimer();

BJDebugMsg(I2S(GetHandleId(t)));

BJDebugMsg(I2S(EBound));

whilenot(t == Timers[i] or i > EBound)
{BJDebugMsg(I2S(i) + ": " + I2S(GetHandleId(Timers[i]))); i++}

BJDebugMsg(I2S(i) + ": " + I2S(GetHandleId(Timers[i])));

BJDebugMsg("The timer is found.");

BJDebugMsg("Finding coordinates...");

location Loc = GetSpellTargetLoc();
real x = GetLocationX(Loc);
real y = GetLocationY(Loc);
RemoveLocation(Loc); Loc = null;

BJDebugMsg("Calculating coordinates...");

real Angle = 2*PI / COUNTRUNES * Index[i];
real x1 = x + Range * Cos(Angle);
real y1 = y + Range * Sin(Angle);

BJDebugMsg("Creating rune...");
Rune[COUNTRUNES * i + Index[i]] = AddSpecialEffect(s, x1, y1);
BJDebugMsg("Rune created.");

BJDebugMsg(I2S(i) + ": " + I2S(Index[i]));

Index[i]++

BJDebugMsg(I2S(i) + ": " + I2S(Index[i]));
BJDebugMsg(I2S(COUNTRUNES));

if Index[i] >= COUNTRUNES
{DestroyTimer(t)}

t = null;
}
void CreateFire()
{
string s = FIRE + I2S(GetRandomInt(1, FIREVARIATIONS) - 1) + MDX;

real Range = RANGE;

integer i = 0;
timer t = GetExpiredTimer();
whilenot(t == Timers[i])
{i++}

location Loc = GetSpellTargetLoc();
real x = GetLocationX(Loc);
real y = GetLocationY(Loc);
RemoveLocation(Loc); Loc = null;

real Angle = 2*PI / COUNTFIRES * Index[i];
real x1 = x + Range * Cos(Angle);
real y1 = y + Range * Sin(Angle);

Fire[COUNTFIRES * i + Index[i]] = AddSpecialEffect(s, x1, y1);
Index[i]++

if Index[i] >= COUNTRUNES
{DestroyTimer(t)}

t = null;
}
void CreateEffects()
{
BJDebugMsg("I want to create effects...");
EBound ++
int i = EBound;

timer t = CreateTimer();
Timers[i] = t;

BJDebugMsg(I2S(GetHandleId(t)));
BJDebugMsg(I2S(i) + ": " + I2S(GetHandleId(Timers[i])));

Index[i] = 0;

BJDebugMsg(I2S(Index[i]));

TimerStart(t, PERIODICRUNE, true, function CreateRune);

t = CreateTimer();
Timers[i] = t;
Index[i] = 0;
TimerStart(t, (PERIODICFIRE/COUNTRUNES*COUNTFIRES), true, function CreateFire);

EBound --
t = null;
}
bool Trig_Magic_Wall_Basic_cJass_Conditions()
{return GetSpellAbilityId() == ABIL}
void Trig_Magic_Wall_Basic_cJass_Actions()
{
Bound ++
integer b = Bound;

real Range = RANGE;

location Loc = GetSpellTargetLoc();
real x = GetLocationX(Loc);
real y = GetLocationY(Loc);
RemoveLocation(Loc); Loc = null;

real x1, y1;
real Angle;

integer i = 0;
integer a;

whilenot (i > COUNT - 1)
{
a = b * COUNT + i;

Angle = 2*PI / COUNT * i;
x1 = x + Range * Cos(Angle);
y1 = y + Range * Sin(Angle);

Block[a] = CreateDestructable(BLOCK, x1, y1, 2*PI - Angle, 1, 0);
i++
}
ExecuteFunc("CreateEffects");
CreateEffects();
TriggerSleepAction(20.00)

i = 0
whilenot (i > COUNT - 1)
{
a = b * COUNT + i;

KillDestructable(Block[a])
RemoveDestructable(Block[a])
i++
}

Bound--
}
===========================================================================
void InitTrig_Magic_Wall_cJass()
{
int i = 0;
whilenot(i == RUNEVARIATIONS)
{
Preload(RUNE + I2S(i) + MDX);
i++
}

i = 0;
whilenot(i == FIREVARIATIONS)
{
Preload(FIRE + I2S(i) + MDX);
i++
}
Preload("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl");

trigger t = CreateTrigger();

TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
TriggerAddCondition(t, Condition(function Trig_Magic_Wall_Basic_cJass_Conditions));
TriggerAddAction(t, function Trig_Magic_Wall_Basic_cJass_Actions);

gg_trg_Magic_Wall_cJass = t; t = null;
}
))
Барьеры создаются, удаляются, но со спецэффектами полнейший АДЪ. (Да, я знаю, что они не удаляются, до этого ещё не дошло). Также тут можно найти кучу тестовых фич (типа спецэффекта "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl", который выбран от балды).
А теперь о сути проблемы.
Как видно в коде, на экран регулярно выводятся хендлы. Вот что было установлено:
  1. При забивании в Timer[0] таймер ...8827 доставали ...8828. Известно, что ...8827 являлся последним созданным объектом, значит вар создаёт таймер, если используется глобалка типа timer. Более того, в редакторе переменных стартовым значением являлось "Создать таймер", что меня удивило.
  2. При каждом новом запуске EBound сбрасывалось на -1.
  3. А ещё не создавался (рисовался) спецэффект.
  4. Переменная Index[] сбивалась на 30. Связано ли это со значением дефайна COUNTRUNES, не известно.
Если надо, могу выложить карту. Скрины прилагаются.
Hares добавил:
Да, я знаю, что в заявке написано на GUI, я параллельно и так, и так делаю. Просто ведь надо разобраться, как ето реализовывается.
Hares добавил:
Более того, я знаю, все эти переменные можно было не брать в массив, ибо mui не обязательно. Более того, я легко бы и хеш-таблицами обошёлся. Но это просто не по Кодексу Истинного Программиста, а именно не является конечной продукцией.
Миниатюры
Кликните на картинку для увеличения
Название:  New Timer.JPG
Просмотров: 34
Размер:  26.3 Кбайт  Кликните на картинку для увеличения
Название:  Variables.JPG
Просмотров: 59
Размер:  221.4 Кбайт  
Старый 09.01.2012, 21:41
Clamp
Lost in space
offline
Опыт: 71,158
Активность:
код не смотрю@ответ пишу
используй хеш таблицу или, если совсем жмет кое-где, структуры, ибо так, как ты делаешь, слишком легко ошибиться.
Хеш спасает мир!
Старый 09.01.2012, 23:04
Hares
полупротосс
offline
Опыт: 6,966
Активность:
Clamp, Это не ответ на вопрос, а уход от него. Проблема остаётся проблемой, И ЕЁ РЕШЕНИЕ НЕОБХОДИМО. Поэтому решаем, друзья мои, решаем. Хотя если решение не найдётся, придётся хешать проблему.
Старый 09.01.2012, 23:23
Clamp
Lost in space
offline
Опыт: 71,158
Активность:
а ну да, ты же "истинный программист", есть проблема - делай так, чтобы не было видно, а что за ней куча других возникает и вообще подход наихреновейший - проблемы заказчика.
Тебе сказали самое верное решение проблемы - не создавать её.
Старый 09.01.2012, 23:33
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Hares
Код:
location Loc = GetSpellTargetLoc();
    real x = GetLocationX(Loc);
    real y = GetLocationY(Loc);
    RemoveLocation(Loc); Loc = null;


И нафиг этот индийский код?

Нафиг создаешь лишние переменные x1, y1?

Нафиг переменная range, юзай значение напрямую.

2*PI мог бы на калькуляторе просчитать и записать значение ._.

В общем ужс.
Старый 09.01.2012, 23:39
Hares
полупротосс
offline
Опыт: 6,966
Активность:
Faion:
И нафиг этот индийский код?
Я не нашёл ф-ий, возвращающий координаты каста, но помню, что они были... Локации я не люблю, вот и ухожу к координатам.
Faion:
Нафиг создаешь лишние переменные x1, y1?
Предыдущие могут использоваться ещё.
Faion:
Нафиг переменная range, юзай значение напрямую.
В конечной версии значение этой переменной будет изменено на ф-ию, и это сделано благоразумно вперёд.
Faion:
2*PI мог бы на калькуляторе просчитать и записать значение ._.
В некоторых случаях может потребоваться использование простого пи или его частей.
Старый 09.01.2012, 23:52
Clamp
Lost in space
offline
Опыт: 71,158
Активность:
GetSpellTargetX например...
И как же они могут использоваться?
И куда же в заказе влезает функция? Дефайн значения не катит?
Ну считай каждое, 2 кнопки, не сломаешься, а машине легче.
Старый 09.01.2012, 23:56
Hares
полупротосс
offline
Опыт: 6,966
Активность:
Clamp:
И куда же в заказе влезает функция? Дефайн значения не катит?
Конечный результат подразумевает, что у абилки может быть несколько лвлов, и тогда я использую загрузку пара из эффектов этой абилки, чтоб мододел мог использовать только РО, не залезать в РТ. Угу?
Clamp:
Ну считай каждое, 2 кнопки, не сломаешься, а машине легче.
Арифметика практически не замедляет процесс.
Hares добавил:
Clamp:
ты точно бредишь.
Я маразматик-фанатик-энтузиаст. Чего ты от меня хочешь?
Старый 10.01.2012, 00:00
Doc

offline
Опыт: 63,163
Активность:
Арифметика практически не замедляет процесс.
хеш тоже.
Старый 10.01.2012, 03:27
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 08:20.