Lotus101, уберешь карту пути - можно будет перемещать как тебе хочется. Однако, в этом случае, реализовывать всю коллизию придется триггерно. Lotus101:
Даже если перемещать каждые 0.05 секунды?
Дело в функции перемещения SetUnitPosition(). Она чекает коллизию и сбивает приказ юниту(считай - отдает приказ "Stop").
В помощь тебе библиотеки(library) и базы данных.
Либы — для обращения по виду library_name.functionName(arguments)
Базы данных — для выделения юниту своих переменных.
С БД может быть момент не совсем понятным, поэтому скидываю пример:
Эта порнография разработана для личного пользования
У меня в коде есть иллюзия использования вжасса. Либа просто для доп табуляции и невостребованых манипуляций на случай импорта. При создании юнита ему присваивается ряд переменных, а номер этих переменных, относящихся к этому юниту, записывается в его(юнита) UnitUserData
library UnitDataBase
globals
constant integer UnitDBSize = 512
constant integer UnitDBHeroesStart = 0
constant integer UnitDBHeroesUnder = 49
constant integer UnitDBUnitsStart = 50//Includes illusions of heroes. Or Should include them at least :P
constant integer UnitDBUnitsUnder = 319
constant integer UnitDBSummonsStart = 320
constant integer UnitDBSummonsUnder = 511
integer UnitDBNextHero = 0
integer UnitDBNextUnit = 50
integer UnitDBNextSummon = 320
unit array UnitDBUnit[UnitDBSize]
real array UnitDBCurrentAnimationSpeed[UnitDBSize]
unit array UnitDBForceAttackTarget[UnitDBSize]
integer array UnitDBAffectedByStuns[UnitDBSize]
real array UnitDBMagicResistance[UnitDBSize]
real array UnitDBPhysResistance[UnitDBSize]
real array UnitDBCurrentArmor[UnitDBSize]//This armor does not include agility bonuses. Not used yet :>
real array UnitDBWhiteMovementSpeed[UnitDBSize]
real array UnitDBCurrentCustomSlow[UnitDBSize]
real array UnitDBMagicDamageAmplifier[UnitDBSize]
real array UnitDBPhysDamageAmplifier[UnitDBSize]
real array UnitDBAdditionalHealth[UnitDBSize]//AKA Shield. Healed whenever unit takes damage.
constant real GravityAcceleration = 14.//Azeroth, bitch!
real array UnitDBFlyingHeight[UnitDBSize]//Not used yet
real array UnitDBFallingSpeed[UnitDBSize]
integer array UnitDBItemUseVariable[UnitDBUnitsStart]//just don't ask
item array UnitDBLastUsedItem[UnitDBUnitsStart]
real array UnitDBCastPointX[UnitDBUnitsStart]
real array UnitDBCastPointY[UnitDBUnitsStart]
integer UnitDBPreviousHero//Used for exitwhen event. Its next minus two.
unit array UnitDBHeroHPBar[UnitDBUnitsStart]
unit array UnitDBHeroMPBar[UnitDBUnitsStart]
unit array UnitDBHeroSPBar[UnitDBUnitsStart]
endglobals
//Больно жирные для инлайна
function UnitDBFindNextFreeVariable takes integer i returns integer
local unit u
loop
set u = UnitDBUnit[i]
exitwhen u == null or GetUnitTypeId( u ) < 1
set i = i + 1
endloop
set u = null
return i
endfunction
function UnitDBAddHero takes unit u, real mdef, real armor returns nothing
local integer i = UnitDBNextHero
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call UnitMakeAbilityPermanent( u, true, 'A00B' )
set UnitDBUnit[i] = u
call SetUnitUserData( u, i )
call GroupAddUnit( UnitsInPlayableArea, u )
set UnitDBItemUseVariable[i] = 0
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( u )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.//Doesn't include point height.
set UnitDBAdditionalHealth[i] = 0.
/*if ( i == UnitDBHeroesUnder ) then
call BJDebugMsg("|c00ff6060Hero limit reached! More heroes can be created, but things can go wild.")
endif*/
set UnitDBNextHero = i + 1
set UnitDBPreviousHero = i - 1
set UnitDBHeroHPBar[i] = CreateUnit(BossPlayer1, 'hmil', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroHPBar[i], 100 )
set UnitDBHeroMPBar[i] = CreateUnit( BossPlayer1, 'hrtt', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroMPBar[i], 100 )
set UnitDBHeroSPBar[i] = CreateUnit( BossPlayer1, 'hwt2', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroSPBar[i], 0 )
set u = null
return
endfunction
function UnitDBAddUnit takes unit createdUnit, real mdef, real armor returns nothing
local integer i = UnitDBNextUnit
local unit u = UnitDBUnit[i]
if ( u == null ) then
set i = UnitDBFindNextFreeVariable( UnitDBSummonsStart )
endif
set UnitDBUnit[i] = createdUnit
call SetUnitUserData( createdUnit, i )
call GroupAddUnit( UnitsInPlayableArea, createdUnit )
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( createdUnit )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.
set UnitDBAdditionalHealth[i] = 0.
if ( i < UnitDBSummonsUnder) then
set UnitDBNextSummon = i + 1
else
set UnitDBNextSummon = UnitDBSummonsStart
endif
set u = null
set createdUnit = null
return
endfunction
function UnitDBAddSummon takes unit summonedUnit, real mdef, real armor returns nothing
local integer i = UnitDBNextSummon
local unit u = UnitDBUnit[i]
if ( u == null ) then
set i = UnitDBFindNextFreeVariable( UnitDBSummonsStart )
endif
set UnitDBUnit[i] = summonedUnit
call SetUnitUserData( summonedUnit, i )
call GroupAddUnit( UnitsInPlayableArea, summonedUnit )
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( summonedUnit )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.
set UnitDBAdditionalHealth[i] = 0.
if ( i < UnitDBSummonsUnder) then
set UnitDBNextSummon = i + 1
else
set UnitDBNextSummon = UnitDBSummonsStart
endif
set u = null
set summonedUnit = null
return
endfunction
//Система маг резиста была изменена на дефолтную, была введена аналогичная ей система физ урона.
//Необходимо протестить эти системы на низких значениях. (могучий float и его точность). В нынешних условиях низкие значения не достигаются. На тест положен болт. Есть нерешенные проблемы с точностью(при восстановлении, опять же, резисты съезжают). Необходимо учитывать при вычислениях лишь первые три цифры после запятой, например.
#define UnitDBIncreaseUnitMagicResistance( amount, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] * amount
}
#define UnitDBDecreaseUnitMagicResistance( amount, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] / amount
if ( UnitDBMagicResistance[userData] > 0.99997 and UnitDBMagicResistance[userData] < 1.00003 ) then
set UnitDBMagicResistance[userData] = 1.
endif
}
#define UnitDBIncreaseUnitPhysResistance( amount, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] * amount
}
#define UnitDBDecreaseUnitPhysResistance( amount, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] / amount
if ( UnitDBPhysResistance[userData] > 0.99997 and UnitDBPhysResistance[userData] < 1.00003 ) then
set UnitDBPhysResistance[userData] = 1.
endif
}
#define UnitDBReplaceUnitMagicResistance( before, after, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] / before * after
}
#define UnitDBReplaceUnitPhysResistance( before, after, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] / before * after
}
#define UnitDBIncreaseUnitMagicDamageAmplifier( amount, userData ) = {
set UnitDBMagicDamageAmplifier[userData] = UnitDBMagicDamageAmplifier[userData] + amount
}
#define UnitDBDecreaseUnitMagicDamageAmplifier( amount, userData ) = {
set UnitDBMagicDamageAmplifier[userData] = UnitDBMagicDamageAmplifier[userData] - amount
if ( UnitDBMagicDamageAmplifier[userData] > 0.99997 and UnitDBMagicDamageAmplifier[userData] < 1.00003 ) then
set UnitDBMagicDamageAmplifier[userData] = 1.
endif
}
#define UnitDBIncreaseUnitPhysDamageAmplifier( amount, userData ) = {
set UnitDBPhysDamageAmplifier[userData] = UnitDBPhysDamageAmplifier[userData] + amount
}
#define UnitDBDecreaseUnitPhysDamageAmplifier( amount, userData ) = {
set UnitDBPhysDamageAmplifier[userData] = UnitDBPhysDamageAmplifier[userData] - amount
if ( UnitDBPhysDamageAmplifier[userData] > 0.99997 and UnitDBPhysDamageAmplifier[userData] < 1.00003 ) then
set UnitDBPhysDamageAmplifier[userData] = 1.
endif
}
#define UnitDBIncreaseUnitShield( amount, userData ) = {
set UnitDBAdditionalHealth[userData] = UnitDBAdditionalHealth[userData] + amount
//redraw
}
#define UnitDBDecreaseUnitShield( amount, userData ) = {
set UnitDBAdditionalHealth[userData] = UnitDBAdditionalHealth[userData] - amount
if ( UnitDBAdditionalHealth[userData] < 0. ) then//Perhaps should be typed manually on every use. No need of that atm.
set UnitDBAdditionalHealth[userData] = 0.
endif
//redraw
}
function UnitDBAddUnitsCreatedOnInit takes nothing returns nothing
local unit u = GetEnumUnit()
if ( not IsUnitType( u, UNIT_TYPE_HERO ) ) then
call UnitDBAddUnit( u, 1., 0. )//!!! whatever
endif
set u = null
return
endfunction
endlibrary
Работает на всех, писали уже.
Верно понимаю, что GetMouseX, GetMouseY, GetMouseZ у разных игроков отлавливается по-разному и может вызвать десинк в сетевой при неправильном применении? То есть если я, например, по этим числам выведу координаты точки и использую ее для перемещения или создания объекта или определения направления - десинк, гг?
Скажу спасибо за образец кода, дающий возможность определить координаты мыши только для овнера определенного юнита без десинка в сетевой (ну чтоб там стрелять в направлении мыши, например).
Кажется, кто-то (на ксгм или на хайве) интересовался нашел ли кто где взять разрешение экрана, вероятно это связано с этим. Касательно стрельбы - вроде скорп ( ScorpioT1000) в свое время делал наработку по стрельбе от первого лица по нажатию ESC. Там единственная нерешенная проблема была, если не ошибаюсь, с движением камеры по XY. По Z она перемещалась свободно.
Мне кажется, я был не понят. Допустим ты заспавнил юнита с сотней маны. У него сгорело 10 маны, осталось 90. Ты морфишь его, триггер ловит каст и сохраняет его текущую ману(90), затем спустя 0 секунд юнит уже закончил морф и ты устанавливаешь его ману равной 90.
Любое ожидание через TriggerSleepAction(X) является ожиданием X + 0.1 сек. При этом, если не ошибаюсь, создается новый поток, в котором понятия применяющий юнит просто нет(считай вызвал функцию которая takes nothing returns nothing). Короче - ждать в данном случае вообще не нужно, а также стоит поставить другое событие (Приводит способность в действие).
Поскольку его не пугает наличие большого влияния промахов на геймплей - скорее всего он делает рпг. Имхо в рпг всегда клево смотрятся тексттаги полученного урона, для создания которых необходимы триггеры на отлов получения урона. А отлавливаемый урон - можно и прохилить.
Для прохила(и вообще всех манипуляций с задержкой в 0.00 сек) лично я юзаю такие костыли:
Либа здесь только для доп табуляции. Я за чистый жасс + дефайны.
library ZeroTimeEvent
globals
constant integer ZTEArraySize = 64//Even 32 is alot, 64 is too much! Exactly what I need!
timer Zero//Used for 0. sec uses
integer ZTECurrent = 0
unit array ZTEUnits[ZTEArraySize]
integer array ZTEIntegers[ZTEArraySize]
real array ZTEReals[ZTEArraySize]
trigger array ZTETriggers[ZTEArraySize]
endglobals
function ZeroTimeEvent takes nothing returns nothing
loop
set ZTECurrent = ZTECurrent - 1
call TriggerExecute( ZTETriggers[ZTECurrent] )
exitwhen ZTECurrent < 1
endloop
endfunction
#define ZTEAddUnit(u) = {
set ZTEUnits[ZTECurrent] = u
}
#define ZTEAddInteger(i) = {
set ZTEIntegers[ZTECurrent] = i
}
#define ZTEAddReal(r) = {
set ZTEReals[ZTECurrent] = r
}
#define ConfirmZTE(trig) = {
set ZTETriggers[ZTECurrent] = trig
set ZTECurrent = ZTECurrent + 1
call TimerStart( Zero, ZeroTime, false, function ZeroTimeEvent )
}
endlibrary
Ты просишь юзеров исправить косяки твоей системы, но ты просишь без уважения. Ты даже не соблюдаешь правила ксгм.
Оформи тему нормально. Ты даже не описал принципов работы системы. Например в пункте 1 ты говоришь про дебаффы. Какие дебаффы могут относиться к промахам? Вы знаете о чем здесь говорится? Я — нет.
А зачем тебе это вообще? Приказывать кастовать что-то в обход сайленса? Для этого есть руны.
Простой способ здесь — последовательно проверять все салящие баффы.
И да, в памяти полюбому есть количество сайленсов действующих на юнита (или на способность, я не знаю как там это сделано). Но я не в курсе конкретики.
Элсо — можешь проверить можно ли давать приказ на каст способности в сайленсе(отлавливается ли он). Через стан точно можно отловить приказ отмены щита пехотинца, например.
Из нововведений, теперь в редактор триггеров включен syntax cheker и можно проверять скрипт на ошибки не пересохраняя карту, очень нужное нововведение, только вот этак лет на 12 опоздало. Но халтурщики не сделали описание и внятную иконку новой кнопки.
Новых функций в common.j не обнаружены. В мак версии нету обфуксации game.dll что дает возможность по изучать движок игры всем желающим, вот пример кода спеллов:
Залил бы кто его на хостинг для юзверей винды. Любопытно потыкать палкой.
Дай юниту способность канал с строкой attack или smart (второе - ПКМ, первое - непосредственно атака). Не знаю, правда, работает ли с приказом attack(знаю лишь что кто-то мутил показательный пример на приказ smart). Однако, топик говорит об автоатаке, так что я предполагаю что это какая-то башня. В этом случае проще воспользоваться способностью сферы замедления, если, конечно, скилл таргетный.
Ну ты проверяешь типы предметов(кстати все условия будут проверяться так как они идут друг за другом а не в поле иначе (если оружие(п) то ... иначе если оружие(л) то ........)), а мог бы присвоить айдишники, например, с 'IC00' до 'ID00' (65536 или 65535 (много крч) значений) оружию в левой руке. Далее аналогично используешь айдишники 'AC00' до 'AD00' для способностей для этих предметов. Далее совершаешь арифметическую магию и определяешь какие скиллы нужно давать герою(что-то вроде определить модулус деления ID предмета на 256 и вычесть его из ID предмета (дабы IC07 было IC00), потом вычесть разницу между IC00 и AC00, в итоге мы имеем первый айдишник группы абилок для этих предметов). Какие конкретно абилки выдавать предмету - тут уж не знаю какой подход стоит применять. На что фантазии хватит. Если абилок меньше или равно 32 - можно сохранять какие абилки выданы в битах(потом просто прибавляем номер бита(1 бит - нулевой) к первому айди группы абилок и получаем нужную абилку) в ItemUserData
Т.е. сравнение по битам вроде:
Если ItemUserData >= 2^32, то выдаем AC00 + 0
Если ItemUserData >= 2^31, то выдаем AC00 + 1
...
Но такая архитектура не очень хорошо переносит правки, так что все нужно продумать изначально.
Две одинаковые абилки иметь нельзя -> из двух одинаковых способностей на предметах работает лишь одна (так как ты даешь их герою отдельно).
Например: 2 оружия в правую руку на +3 атаки каждое дают вместе +3 к атаке.
Есть способы обойти это, если не ошибаюсь, при помощи какого-то бага с мгновенным удалением предметов или что-то типа того(никогда не задавался этим вопросом так что не знаю), но да...
Элсо систему можно модернизировать колдуя над айдишниками предметов и абилок, что позволит избежать большинства сравнений.
Помню, что были где-то статьи, но интересно, нельзя ли именно без сильного напряга переделать все данные редактора объектов какой-либо карты в дефолтные данные варкрафта.
Нельзя. Как минимум нужно ПО, которое будет дополнять измененные картой данные дефолтными. Если оно вдруг существует - то можно и без напряга. Но даже азиаты такой фигней не заморачиваются.
Реализовать триггерно. Если это не очевидно - значит твои навыки не позволяют сделать этого. Однако спелл простой - поищи где-нибудь в заклинаниях на заказ или на хайве.
» WarCraft 3 / Движение декорации или альтернатива
Lotus101:
» WarCraft 3 / Муишность в vJass
Либы — для обращения по виду library_name.functionName(arguments)
Базы данных — для выделения юниту своих переменных.
С БД может быть момент не совсем понятным, поэтому скидываю пример:
» WarCraft 3 / Чит не работает, но почему???
» WarCraft 3 / "Десинхрон" и всё о нём!
» WarCraft 3 / Хак на память Warcraft3
» WarCraft 3 / Сохранить ману при морфе
Как вариант - устанавливает при морфе значение маны равном стартовому, согласно РО.
Ред. Diaboliko
» WarCraft 3 / Сохранить ману при морфе
» WarCraft 3 / Сохранить ману при морфе
Ред. Diaboliko
» WarCraft 3 / Способность не добавляется
» WarCraft 3 / Строка чата
» WarCraft 3 / Система точности у героев (+ не проходи мимо +)
Ред. Diaboliko
» WarCraft 3 / Система точности у героев (+ не проходи мимо +)
Для прохила(и вообще всех манипуляций с задержкой в 0.00 сек) лично я юзаю такие костыли:
» WarCraft 3 / Система точности у героев (+ не проходи мимо +)
Оформи тему нормально. Ты даже не описал принципов работы системы. Например в пункте 1 ты говоришь про дебаффы. Какие дебаффы могут относиться к промахам?
Вы знаете о чем здесь говорится? Я — нет.
Ред. Diaboliko
» WarCraft 3 / Как определить, под сайленсом юнит или нет?
Простой способ здесь — последовательно проверять все салящие баффы.
И да, в памяти полюбому есть количество сайленсов действующих на юнита (или на способность, я не знаю как там это сделано). Но я не в курсе конкретики.
Элсо — можешь проверить можно ли давать приказ на каст способности в сайленсе(отлавливается ли он). Через стан точно можно отловить приказ отмены щита пехотинца, например.
» WarCraft 3 / Патч 1.27б
» WarCraft 3 / Автоатака
» Peace, Death! / Контрабанда и взлом!
Ред. Diaboliko
» WarCraft 3 / Генератор предметов
Т.е. сравнение по битам вроде:
Если ItemUserData >= 2^32, то выдаем AC00 + 0
Если ItemUserData >= 2^31, то выдаем AC00 + 1
...
Но такая архитектура не очень хорошо переносит правки, так что все нужно продумать изначально.
» WarCraft 3 / Тип атаки
Ред. Diaboliko
» WarCraft 3 / Генератор предметов
Например: 2 оружия в правую руку на +3 атаки каждое дают вместе +3 к атаке.
» WarCraft 3 / Сделать данные по объекту из карты дефолтными для варкрафта
» WarCraft 3 / Порядок строк способности Перевоплощение.
» WarCraft 3 / Предметы, интересные баги и фитчи!
» WarCraft 3 / Как убрать channel'ing анимацию у скилла "Похищение маны"
» WarCraft 3 / Как убрать channel'ing анимацию у скилла "Похищение маны"