Алгоритмы, Наработки и Способности
Способ реализации:
Zinc
Тип:
Наработка
Версия Warcraft:
1.26+

Орбитальная бомбардировка

MUI: да
Импорт: иконка, точка, снаряд, радар
Утечки: нет
Требования: JNGP
Описание: Герой сканирует указанное место и наносит урон в случайных точках.

Скриншот

Технические подробности

Перенос в свою карту
Спообности
  • 'AHob' Орбитальная бомбардировка (герой) "farsight"
Войска
  • 'hobd' Орбитальная бомбардировка (цель)
Заклинания/эффекты
  • 'XHob' Орбитальная бомбардировка (разведка)
Триггеры
  • SpellOrbitalBomb
Импорт
  • Effect\ArtilleryStrike.mdx
  • Effect\PointTarget.mdx
  • Effect\Radar.mdx
  • ReplaceableTextures\CommandButtons\BTNFireStrike.blp
  • ReplaceableTextures\CommandButtonsDisabled\DISBTNFireStrike.blp
Настройка
constant integer AbilityID = 'AHob'; // Равкод способности
constant real StrikeDelay = 2; // Задержка перед ударом

constant integer DummyPoint = 'hobd';
constant player DummyOwner = Player(PLAYER_NEUTRAL_PASSIVE);

hashtable HT = InitHashtable(); // Хэштаблица для таймера
// Можете вписать туда вашу таблицу, например:
// hashtable HT = udg_HashTable;

// Задержка перед взрывом
function getExplodeDelay(unit caster, integer level) -> real {
    return 2.0;
}

// Период появления взрывов
function getStrikePeriod(unit caster, integer level) -> real {
    return 0.25;
}  

// Количество 
function getStrikeCount(unit caster, integer level) -> integer {
    return 5*level;
}

// Радиус сканирования
function getScanRange(unit caster, integer level) -> integer {
    return 400;
}

function getDamageRange(unit caster, integer level) -> integer {
    return 150;
}

// Проверка целей
function checkTarget(unit caster, unit target) -> boolean {
    return (
        !IsUnitType(target, UNIT_TYPE_FLYING) // Не летающий
        &&
        !IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) // Восприимчив к магии
        &&
        IsPlayerEnemy(GetOwningPlayer(caster), GetOwningPlayer(target)) // Враг
    );
}

// Функция, вызываемая при нанесении урона
function onDamage(unit caster, unit target, integer level){
    real damage = level*50;
    UnitDamageTarget(caster, target, damage, false, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
}
Код заклинания
//! zinc
library SpellOrbitalBomb {
    constant integer AbilityID = 'AHob'; // Равкод способности
    constant real StrikeDelay = 2; // Задержка перед ударом

    constant integer DummyPoint = 'hobd';
    constant player DummyOwner = Player(PLAYER_NEUTRAL_PASSIVE);

    hashtable HT = InitHashtable(); // Хэштаблица для таймера
    // Можете вписать туда вашу таблицу, например:
    // hashtable HT = udg_HashTable;

    // Задержка перед взрывом
    function getExplodeDelay(unit caster, integer level) -> real {
        return 2.0;
    }

    // Период появления взрывов
    function getStrikePeriod(unit caster, integer level) -> real {
        return 0.25;
    }  

    // Количество 
    function getStrikeCount(unit caster, integer level) -> integer {
        return 5*level;
    }

    // Радиус сканирования
    function getScanRange(unit caster, integer level) -> integer {
        return 400;
    }

    function getDamageRange(unit caster, integer level) -> integer {
        return 150;
    }

    // Проверка целей
    function checkTarget(unit caster, unit target) -> boolean {
        return (
            !IsUnitType(target, UNIT_TYPE_FLYING) // Не летающий
            &&
            !IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) // Восприимчив к магии
            &&
            IsPlayerEnemy(GetOwningPlayer(caster), GetOwningPlayer(target)) // Враг
        );
    }

    // Функция, вызываемая при нанесении урона
    function onDamage(unit caster, unit target, integer level){
        real damage = level*50;
        UnitDamageTarget(caster, target, damage, false, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
    }
    
    //
    // Заклинание
    //
    function isUnitAlive(unit target) -> boolean {
        return GetWidgetLife(target) > 0.405;
    }
    
    function onInit(){
        integer i;
        trigger t;
        
        t = CreateTrigger();
        for (0 <= i < bj_MAX_PLAYER_SLOTS){
            TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null);
        }
        TriggerAddCondition(t, Filter(function() -> boolean {
            return GetSpellAbilityId() == AbilityID;
        }));
        TriggerAddAction(t, function(){
            unit caster = GetTriggerUnit();
            integer level = GetUnitAbilityLevel(caster, AbilityID);
            real r, range = I2R(getScanRange(caster, level));
            real xt = GetSpellTargetX();
            real yt = GetSpellTargetY();
            real x, y, angle;
            integer count = getStrikeCount(caster, level);
            timer t = CreateTimer();
            integer i, pk = GetHandleId(t);
            real period = getStrikePeriod(caster, level);
            real delay = getExplodeDelay(caster, level);
            
            SaveUnitHandle(HT, pk, 0, caster);
            SaveReal(HT, pk, 0, 0); // elapsed
            SaveReal(HT, pk, 1, period); // period
            SaveReal(HT, pk, 2, delay); // delay
            SaveReal(HT, pk, 3, getDamageRange(caster, level)); // damage range
            SaveInteger(HT, pk, 0, level);
            SaveInteger(HT, pk, 1, count);
            SaveInteger(HT, pk, 2, 0); // created
            SaveInteger(HT, pk, 3, 0); // exploaded
            for(0 <= i < count){
                angle = GetRandomReal(0, 360);
                r = GetRandomReal(0, range);
                x = xt + r * Cos(angle * bj_DEGTORAD);
                y = yt + r * Sin(angle * bj_DEGTORAD);
                SaveReal(HT, pk, 10 + i, x);
                SaveReal(HT, pk, 10 + i + count, y);                
            }
            
            TimerStart(t, period, true, function(){
                timer t = GetExpiredTimer();
                integer pk = GetHandleId(t);
                unit caster = LoadUnitHandle(HT, pk, 0);
                integer level = LoadInteger(HT, pk, 0);
                integer count = LoadInteger(HT, pk, 1);
                integer created = LoadInteger(HT, pk, 2); // created
                integer exploaded = LoadInteger(HT, pk, 3); // exploaded
                real elapsed = LoadReal(HT, pk, 0);
                real period = LoadReal(HT, pk, 1);
                real delay = LoadReal(HT, pk, 2);
                real x, y;
                group g = CreateGroup();
                unit u;
                
                SaveReal(HT, pk, 0, elapsed + period);
                
                if (created < count){
                    x = LoadReal(HT, pk, 10 + created);
                    y = LoadReal(HT, pk, 10 + created + count);
                    SaveUnitHandle(HT, pk, 10 + created, CreateUnit(DummyOwner, DummyPoint, x, y, GetRandomReal(0, 360)));
                    SaveInteger(HT, pk, 2, created + 1);
                }
                
                if (elapsed > delay && exploaded < count){
                    x = LoadReal(HT, pk, 10 + exploaded);
                    y = LoadReal(HT, pk, 10 + exploaded + count);
                    SaveInteger(HT, pk, 3, exploaded + 1);
                    RemoveUnit(LoadUnitHandle(HT, pk, 10 + exploaded));
                    DestroyEffect(AddSpecialEffect("Effect\\ArtilleryStrike.mdx", x, y));
                    GroupEnumUnitsInRange(g, x, y, LoadReal(HT, pk, 3), Filter(function() -> boolean {
                        return isUnitAlive(GetFilterUnit());
                    }));
                    while(true){
                        u = FirstOfGroup(g);
                        if (u == null) { break; }
                        if (checkTarget(caster, u)){
                            onDamage(caster, u, level);
                        }
                        GroupRemoveUnit(g, u);
                    }
                }
                
                if (created >= count && exploaded >= count){
                    PauseTimer(t);
                    DestroyTimer(t);
                    FlushChildHashtable(HT, pk);
                }
                
                DestroyGroup(g); g = null;
                u = null;
                caster = null;
                t = null;
            });
            
            t = null;
            caster = null;
        });
    }
}
//! endzinc
`
ОЖИДАНИЕ РЕКЛАМЫ...
2
26
5 лет назад
2
хорошее сочетание эффектов и реализации)
0
22
5 лет назад
Отредактирован PROSHELDOTU
0
У меня чёт не отображается эффект обстрела
Радар и цели есть
0
29
5 лет назад
0
У меня чёт не отображается эффект обстрела
Может нужно параметры графики на максимум выставить или компьютер перезагрузить.
0
22
5 лет назад
Отредактирован PROSHELDOTU
0
Может нужно параметры графики на максимум выставить или компьютер перезагрузить.
Графика вроде стояла на максимум
Я позже чекну с перезагрузкой
Если у кого тоже не показывается, скажите плз и как исправили, мне интересно в чём прикол
NazarPunk:
А у тебя не было такого что пропадает отображение выстрелов? в этой наработке
0
29
5 лет назад
0
А у тебя не было такого что пропадает отображение выстрелов?
Изображение нет, но вот звуки не все проигрываются из-за ограничений вара.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.