找回密码
 点一下
查看: 18547|回复: 144

位面消隐——异步显示单位方面Demo

[复制链接]
发表于 2009-7-31 22:28:15 | 显示全部楼层 |阅读模式
如题。
仅仅解决了不同步显示单位的问题。
而且非常不完美。
远程单位攻击前摇必须为0。
单位的大部分魔兽自带的技能需要模拟。
所有添加【非单位附加】的模型必须模拟。
由于本人还没学抛物线,所以远程单位的射弹是没有弧度的。
由于单位的碰撞改动(自然,单位的碰撞也必须小心使用)会出现AI寻路上的很不方便。
不同步的单位和同步的单位(至少两个)叠在一起,会出现推人(模拟碰撞)的现象。
对于隐形的技能等东西绝对不要碰了。
单位的碰撞体积不要设得太大(只是建议而已)

演示中按Esc切换两个世界。

注意,这只是个Demo而已,地形装饰物等其余东东的位面消隐技术还未开始制作。等到做完之后,会把正式版和所有的研究文献发上来。

PS:如果发现楼下什么也没有,请告诉我,代码显示有问题……

感谢:
thewisp
老狼
咨询了关于不同步的一些问题~
头目~(其实只是回答了一个小问题……)

某幕后黑手:
疯人~~
经常在XX上讨论思路及其他核心问题~~~
虽然是我发帖~但其实这玩意在最初还是他告诉我的~
称他为幕后黑手一点都不过分~~
还是阴影下的木偶师好呢?~~

System_Demo.w3x

96 KB, 下载次数: 106

 楼主| 发表于 2009-7-31 22:28:41 | 显示全部楼层
//***************************************************************************
//*
//*  Custom Script Code
//*
//***************************************************************************
globals
    gamecache                                   DataGC                          = null
    constant real                               InitTime_Type                   = 0.1
    constant real                               InitTime_World                  = 0.2
    constant real                               InitTime_Unit                   = 0.3
endglobals

constant function H2I takes handle h returns integer
    return h
    return 0
endfunction
//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************

//===========================================================================
// Trigger: Common Functions
//===========================================================================
function PointsAngle takes real fromx, real fromy, real tox, real toy returns real
    return bj_RADTODEG * Atan2( toy - fromy, tox - fromx )
endfunction

function PointsDistance takes real x1, real y1, real x2, real y2 returns real
    local real dx = x2 - x1
    local real dy = y2 - y1
    return SquareRoot( dx * dx + dy * dy )
endfunction
//math function

function GetUnitUnit takes unit u returns Unit
    return GetUnitUserData( u )
endfunction

function IsUsableUnit takes unit u returns boolean
    return GetUnitUnit( u ) == 0
endfunction

function IsUsableUnit_Type takes unit u returns boolean
    return GetStoredBoolean( DataGC, I2S( GetUnitTypeId( u ) ), "IsUsableUnit" )
endfunction
//condition

function GetUser takes player p returns User
    return GetPlayerId( p )
endfunction

function IsUnitsInSameWorld takes unit u1, unit u2 returns boolean
    local User U1 = GetUser( GetOwningPlayer( u1 ) )
    local User U2 = GetUser( GetOwningPlayer( u2 ) )
    return U1.Place == U2.Place
endfunction

function Trig_Struct_Unit_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_Common_Functions takes nothing returns nothing
    set gg_trg_Common_Functions = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Common_Functions, function Trig_Struct_Unit_Actions )
endfunction

//===========================================================================
// Trigger: Collision
//===========================================================================
globals
    constant real                               Const_MaxCollision                      = 100.0
    constant real                               Const_TimerInterval                     = 0.03
    constant real                               Const_SafeDistance                      = 40.0
    constant real                               Const_CheckMoveDistance                 = 0.0
    group                                       CollisionTempDifferentWorldGroup        = null
    group                                       CollisionTempSameWorldGroup             = null
    group                                       CollisionTempGroup                      = null
    unit                                        CollisionTempUnit                       = null
    real                                        CollisionTempX                          = 0.0
    real                                        CollisionTempY                          = 0.0
    real                                        CollisionTempDistance                   = 0.0
    boolexpr                                    CollisionConstCond                      = null
endglobals

function Collision_Trigger_Condition takes unit u_in, unit u_origin returns boolean
    if IsUsableUnit_Type( u_in ) then
        return false
    endif
    //if not( IsUnitsInSameWorld( u_in, u_origin ) ) then
    //    return false
    //endif
    return true
endfunction

function CollisionTimerCondition takes nothing returns boolean
    if IsUsableUnit_Type( GetFilterUnit() ) then
        return false
    endif
    //if not( IsUnitsInSameWorld( GetFilterUnit(), CollisionTempUnit ) ) then
    //    return false
    //endif
    return true
endfunction

//function CollisionTimer_CollectUnit takes nothing returns nothing
//    if IsUnitsInSameWorld( GetEnumUnit(), CollisionTempUnit ) then
//        call GroupAddUnit( CollisionTempSameWorldGroup, GetEnumUnit() )
//        call GroupRemoveUnit( CollisionTempGroup, GetEnumUnit() )
//    endif
//endfunction

function CollisionTimer_Push takes nothing returns nothing
    local unit u = GetEnumUnit()
    local Unit U = GetUnitUnit( u )
    local real ux = GetUnitX( u )
    local real uy = GetUnitY( u )
    local real distance = PointsDistance( CollisionTempX, CollisionTempY, ux, uy )
    local real check = CollisionTempDistance + U.CollisionRemoveDistance - Const_MaxCollision
    local real angle = 0.0
    local real tox = 0.0
    local real toy = 0.0
    if distance < check then
        //if IsUnitsInSameWorld( CollisionTempUnit, u ) then
            if GetUnitMoveSpeed( u ) > GetUnitMoveSpeed( CollisionTempUnit ) then
                //set angle = PointsAngle( CollisionTempX, CollisionTempY, ux, uy )
                set angle = PointsAngle( ux, uy, CollisionTempX, CollisionTempY )
                set tox = ux + check * Cos( angle * bj_DEGTORAD )
                set toy = uy + check * Sin( angle * bj_DEGTORAD )
                call SetUnitX( CollisionTempUnit, tox )
                call SetUnitY( CollisionTempUnit, toy )
            else
                //set angle = PointsAngle( ux, uy, CollisionTempX, CollisionTempY )
                set angle = PointsAngle( CollisionTempX, CollisionTempY, ux, uy )
                set tox = CollisionTempX + check * Cos( angle * bj_DEGTORAD )
                set toy = CollisionTempY + check * Sin( angle * bj_DEGTORAD )
                call SetUnitX( u, tox )
                call SetUnitY( u, toy )            
            endif
        //else
            //call BJDebugMsg( GetUnitName( u ) )
            //call BJDebugMsg( GetUnitName( CollisionTempUnit ) )
        //endif
    endif
    set u = null
endfunction

function CollisionTimerRun takes nothing returns nothing
    call ForGroup( CollisionTempSameWorldGroup, function CollisionTimer_Push )
endfunction

function CollisionTimer_CheckUnit_SameWorld takes nothing returns nothing
    local unit u = GetEnumUnit()
    local Unit U = GetUnitUnit( u )
    local real ux = GetUnitX( u )
    local real uy = GetUnitY( u )
    local real distance = PointsDistance( CollisionTempX, CollisionTempY, ux, uy )
    local real check = CollisionTempDistance + U.CollisionRemoveDistance - Const_MaxCollision
    if distance - Const_CheckMoveDistance < check then
        call GroupAddUnit( CollisionTempSameWorldGroup, u )
    elseif distance > Const_MaxCollision + CollisionTempDistance + Const_SafeDistance then
        call GroupRemoveUnit( CollisionTempGroup, u )
    endif
    set u = null     
endfunction

function CollisionTimer_CheckUnit_DifferentWorld takes nothing returns nothing
    local unit u = GetEnumUnit()
    local Unit U = GetUnitUnit( u )
    local real ux = GetUnitX( u )
    local real uy = GetUnitY( u )
    local real distance = PointsDistance( CollisionTempX, CollisionTempY, ux, uy )
    local real check = CollisionTempDistance + U.CollisionRemoveDistance - Const_MaxCollision
    if distance - Const_CheckMoveDistance < check then
        call GroupAddUnit( CollisionTempDifferentWorldGroup, u )
    elseif distance > Const_MaxCollision + CollisionTempDistance + Const_SafeDistance then
        call GroupRemoveUnit( CollisionTempGroup, u )
    endif
    set u = null     
endfunction

function CollisionReOrder takes unit u, Unit U returns nothing
    if not U.reordering then
        if GetUnitCurrentOrder( u ) == U.order then
            call DisableTrigger( gg_trg_Unit_ReOrder )
            if U.target != null then
                call IssueTargetOrderById( u, U.order, U.target )
            else
                call IssuePointOrderById( u, U.order, U.targetx, U.targety )
            endif
            call EnableTrigger( gg_trg_Unit_ReOrder )
            set U.reordering = true
        else
            set U.order = 0
            set U.target = null
            set U.targetx = 0.0
            set U.targety = 0.0
        endif
    endif
endfunction

function CollisionTimerAction takes nothing returns nothing
    local Unit OU = H2I( GetExpiredTimer() ) - Unit.CollisionTimerMinHandle
    local unit origin = OU.U
    local real x = GetUnitX( origin )
    local real y = GetUnitY( origin )
    set CollisionTempUnit = origin
    set CollisionTempDistance = OU.CollisionRemoveDistance - Const_MaxCollision
    set CollisionTempX = x
    set CollisionTempY = y
    set CollisionTempGroup = OU.CollisionSameWorldGroup
    call ForGroup( CollisionTempGroup, function CollisionTimer_CheckUnit_SameWorld )
    set CollisionTempGroup = OU.CollisionDifferentWorldGroup
    call ForGroup( CollisionTempGroup, function CollisionTimer_CheckUnit_DifferentWorld )
    set CollisionTempGroup = null
    if FirstOfGroup( CollisionTempDifferentWorldGroup ) != null then
        if OU.CollisionPathing == true then
            call SetUnitPathing( origin, false )
            set OU.CollisionPathing = false
            call CollisionReOrder( origin, OU )
        endif
        if FirstOfGroup( CollisionTempSameWorldGroup ) != null then
            call CollisionTimerRun()
        endif
    else
        if OU.CollisionPathing == false and FirstOfGroup( CollisionTempSameWorldGroup ) != null then
            call SetUnitPathing( origin, true )
            set OU.CollisionPathing = true
        endif
        if FirstOfGroup( OU.CollisionSameWorldGroup ) == null and FirstOfGroup( OU.CollisionDifferentWorldGroup ) == null then
            call PauseTimer( GetExpiredTimer() )
            set OU.CollisionTimerRuning = false
            call SetUnitPathing( origin, true )
            set OU.CollisionPathing = true
        endif
    endif
    call GroupClear( CollisionTempDifferentWorldGroup )
    call GroupClear( CollisionTempSameWorldGroup )
    set CollisionTempUnit = null
    set CollisionTempDistance = 0.0
    set CollisionTempX = 0.0
    set CollisionTempY = 0.0
    set origin = null
endfunction

function Collision_Trigger_Run takes unit origin, Unit U returns nothing
    local timer t = U.CollisionTimer
    if not( U.CollisionTimerRuning ) then
        set U.CollisionTimerRuning = true
        call TimerStart( t, Const_TimerInterval, true, function CollisionTimerAction )
    endif
    set t = null
endfunction

function Collision_Trigger_Action takes nothing returns boolean
    local Hash_T HT = Hash_T.Get( GetTriggeringTrigger() )
    local Unit U = GetUnitUnit( HT.U )
    if Collision_Trigger_Condition( GetTriggerUnit(), HT.U ) then
        if IsUnitsInSameWorld( GetTriggerUnit(), HT.U ) then
            call GroupAddUnit( U.CollisionSameWorldGroup, GetTriggerUnit() )
            //if GetOwningPlayer( HT.U ) == Player(0) then
            //call BJDebugMsg( GetUnitName( GetTriggerUnit() ) )
            //call BJDebugMsg( I2S( GetUnitUnit( HT.U ).Owner ) )
            //call BJDebugMsg( GetPlayerName( GetOwningPlayer( HT.U ) ) )
            //call BJDebugMsg( I2S( GetUnitUnit( GetTriggerUnit() ).Owner ) )
            //call BJDebugMsg( GetPlayerName( GetOwningPlayer( GetTriggerUnit() ) ) )
            //endif
            //call Collision_Trigger_Run( HT.U, U )
        else
            call GroupAddUnit( U.CollisionDifferentWorldGroup, GetTriggerUnit() )
            call Collision_Trigger_Run( HT.U, U )
        endif
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Collision takes nothing returns nothing
    set CollisionTempDifferentWorldGroup = CreateGroup()
    set CollisionTempSameWorldGroup = CreateGroup()
    set CollisionTempGroup = CreateGroup()
    set CollisionConstCond = Condition( function CollisionTimerCondition )
endfunction

//===========================================================================
// Trigger: Struct Unit
//===========================================================================
globals
    constant integer                            Const_TempItemSlotAbility                       = 'A005'
    boolexpr                                    Const_UnitTriggerAction                         = null
endglobals

struct Hash_T
    Hash_T                       head
    Hash_T                       before
    Hash_T                       next
   
    trigger                      T
    triggercondition             TC
    unit                         U
   
    static method Hash takes integer i returns integer
        return i - i / 8191 * 8191
    endmethod
   
    static method create takes trigger t, triggercondition tc, unit u returns Hash_T
        local Hash_T HT = Hash_T.allocate()
        local Hash_T index = Hash_T.Hash( H2I( t ) )
        local Hash_T head = index.head
        set HT.T = t
        if head == 0 then
            set HT.next = 0
        else
            set HT.next = head
            set head.before = HT
        endif
        set index.head = HT
        set HT.before = 0
        set HT.T = t
        set HT.TC = tc
        set HT.U = u
        return HT
    endmethod

    static method Get takes trigger t returns Hash_T
        local Hash_T index = Hash_T.Hash( H2I( t ) )
        local Hash_T now = index.head
        local Hash_T next = now.next  
        loop
            exitwhen now == 0 or now.T == t
            set now = next
            set next = now.next
        endloop
        return now
    endmethod
   
    method Destroy takes nothing returns nothing
        local Hash_T index = Hash_T.Hash( H2I( this.T ) )
        local Hash_T head = index.head
        local Hash_T before = this.before
        local Hash_T next = this.next
        if before != 0 then
            set before.next = next
        else
            set index.head = next
        endif
        if next != 0 then
            set next.before = before
        endif
        call TriggerRemoveCondition( this.T, this.TC )
        call DestroyTrigger( this.T )
        set this.U = null
        call this.destroy()
    endmethod
   
endstruct

struct Unit
   
    static integer               CollisionTimerMinHandle                                = 0
    static integer               CollisionTimerMaxNumber                                = 2000

    timer                        CollisionTimer
    boolean                      CollisionTimerRuning
    real                         CollisionRemoveDistance
    group                        CollisionSameWorldGroup
    group                        CollisionDifferentWorldGroup
    trigger                      CollisionTrigger
    Hash_T                       CollisionTriggerHashIndex
    boolean                      CollisionPathing
    string                       MissileArt
    real                         MissileSpeed
    real                         MissileHeight
    boolean                      MissileHoming
    real                         MissileAttackedHeight
   
    unit                         U
   
    User                         Owner
   
    unit                         Seer
   
    real                         targetx
    real                         targety
    widget                       target
    integer                      order
    boolean                      reordering
   
    static method InitUnit takes unit u returns nothing
        local string Id = I2S( GetUnitTypeId( u ) )
        call UnitAddAbility( u, GetStoredInteger( DataGC, Id, "Id01" ) )
        call UnitAddItemByIdSwapped( GetStoredInteger( DataGC, Id, "Id02Item" ), u )
        call UnitRemoveAbility( u, Const_TempItemSlotAbility )
        set Id = null   
    endmethod
   
    static method create takes unit u returns Unit
        local Unit new = Unit.allocate()
        local integer id = GetUnitTypeId( u )
        local string Id = I2S( id )
        local triggercondition tc = null
        set new.CollisionTrigger = CreateTrigger()
        set new.CollisionRemoveDistance = GetStoredReal( DataGC, Id, "Collision" ) + Const_MaxCollision
        call TriggerRegisterUnitInRange( new.CollisionTrigger, u, new.CollisionRemoveDistance, null )
        set tc = TriggerAddCondition( new.CollisionTrigger, Const_UnitTriggerAction )
        set new.CollisionTriggerHashIndex = Hash_T.create( new.CollisionTrigger, tc, u )
        set new.MissileArt = GetStoredString( DataGC, Id, "MissileArt" )
        set new.MissileSpeed = GetStoredReal( DataGC, Id, "MissileSpeed" )
        set new.MissileHeight = GetStoredReal( DataGC, Id, "MissileAttackHeight" )
        set new.MissileAttackedHeight = GetStoredReal( DataGC, Id, "MissileAttackedHeight" )
        set new.MissileHoming = GetStoredBoolean( DataGC, Id, "MissileHoming" )
        set new.Owner = GetUser( GetOwningPlayer( u ) )
        set new.CollisionSameWorldGroup = CreateGroup()
        set new.CollisionDifferentWorldGroup = CreateGroup()
        call SetUnitUserData( u, new )
        call Unit.InitUnit( u )
        //call SetUnitPathing( u, false )
        set new.CollisionPathing = true
        call GroupAddUnit( new.Owner.Units, u )
        set new.U = u
        set tc = null
        set Id = null
        return new
    endmethod
   
    method Destroy takes nothing returns nothing
        call GroupRemoveUnit( this.Owner.Units, this.U )
        call PauseTimer( this.CollisionTimer )
        set this.CollisionTimerRuning = false
        set this.CollisionRemoveDistance = 0.0
        call this.CollisionTriggerHashIndex.Destroy()
        set this.CollisionTrigger = null
        set this.MissileArt = null
        set this.MissileSpeed = 0.0
        set this.MissileHeight = 0.0
        set this.MissileAttackedHeight = 0.0
        set this.MissileHoming = false
        set this.U = null
        set this.Owner = 0
        set this.CollisionPathing = false
        set this.targetx = 0.0
        set this.targety = 0.0
        set this.target = null
        set this.order = 0
        set this.reordering = false
        call DestroyGroup( this.CollisionSameWorldGroup )
        set this.CollisionSameWorldGroup = null
        call DestroyGroup( this.CollisionDifferentWorldGroup )
        set this.CollisionDifferentWorldGroup = null
        if this.Seer != null then
            call RemoveUnit( this.Seer )
            set this.Seer = null
        endif
        call this.destroy()
    endmethod
   
    method GetPlace takes nothing returns World
        return this.Owner.Place
    endmethod
   
endstruct

function Trig_Struct_Units_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_Struct_Unit takes nothing returns nothing
    set Const_UnitTriggerAction = Condition( function Collision_Trigger_Action )
    set gg_trg_Struct_Unit = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Struct_Unit, function Trig_Struct_Units_Actions )
endfunction

//===========================================================================
// Trigger: Unit ReOrder
//===========================================================================
function Trig_Unit_ReOrder_Condition takes unit u returns boolean
    if IsUsableUnit( u ) then
        return false
    endif
    return true
endfunction

function Trig_Unit_ReOrder_Run takes unit u returns nothing
    local Unit U = GetUnitUnit( u )
    if GetOrderTarget() != null then
        set U.target = GetOrderTarget()
        set U.targetx = 0.0
        set U.targety = 0.0
    else
        set U.target = null
        set U.targetx = GetOrderPointX()
        set U.targety = GetOrderPointY()
    endif
    set U.order = GetIssuedOrderId()
    set U.reordering = false
endfunction

function Trig_Unit_ReOrder_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    if Trig_Unit_ReOrder_Condition( u ) then
        call Trig_Unit_ReOrder_Run( u )
    endif
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_Unit_ReOrder takes nothing returns nothing
    set gg_trg_Unit_ReOrder = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Unit_ReOrder, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Unit_ReOrder, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddCondition( gg_trg_Unit_ReOrder, Condition( function Trig_Unit_ReOrder_Actions ) )
endfunction

//===========================================================================
// Trigger: Unit Missile
//===========================================================================
globals
    constant integer                      Const_MissileUnitId                           = 'h000'
    constant integer                      Const_MissileTimeId                           = 'BHwe'
    constant string                       Const_MissilePoint                            = "origin"
    constant real                         Const_MissileInterval                         = 0.03
    constant real                         Const_MissileDeathTime                        = 3.0
    constant integer                      Const_MissileLocust                           = 'Aloc'
endglobals

struct Missile
    static integer                        MinTimerHandleAddress                         = 0
    static integer                        MaxTimerNumber                                = 2000
    timer                                 Timer
    unit                                  M
    unit                                  target
    real                                  x
    real                                  y
    real                                  speed
    effect                                e
    real                                  targetheight
   
    static method create takes unit u, unit from, unit target, real x, real y, real speed, string art, real height returns Missile
        local Missile new = Missile.allocate()
        set new.M = u
        set new.target = target
        set new.x = x
        set new.y = y
        set new.speed = speed
        set new.e = AddSpecialEffectTarget( art, new.M, Const_MissilePoint )
        call UnitAddAbility( u, Const_MissileLocust )
        call SetUnitFlyHeight( u, height + GetUnitFlyHeight( from ), 0.0 )
        set new.targetheight = GetUnitUnit( target ).MissileAttackedHeight + GetUnitFlyHeight( target )
        return new
    endmethod
   
    method Destroy takes nothing returns nothing
        call PauseTimer( this.Timer )
        call DestroyEffect( this.e )
        set this.e = null
        call UnitApplyTimedLife( this.M, Const_MissileTimeId, Const_MissileDeathTime )
        set this.M = null
        set this.target = null
        set this.x = 0.0
        set this.y = 0.0
        set this.speed = 0.0
        set this.targetheight = 0.0
        call this.destroy()
    endmethod
   
    static method Get takes timer t returns Missile
        return H2I( t ) - Missile.MinTimerHandleAddress
    endmethod

    static method TimerAction takes nothing returns nothing
        local Missile m = Missile.Get( GetExpiredTimer() )
        local real x = GetUnitX( m.M )
        local real y = GetUnitY( m.M )
        local real tx = 0.0
        local real ty = 0.0
        local real distance = 0.0
        local real angle = 0.0
        local real tox = 0.0
        local real toy = 0.0
        local real i = 0.0
        local real height = 0.0
        if GetUnitState( m.target, UNIT_STATE_LIFE ) <= 0.0 then
            set tx = m.x
            set ty = m.y
        else
            set tx = GetUnitX( m.target )
            set ty = GetUnitY( m.target )
            set m.x = tx
            set m.y = ty
        endif
        set distance = PointsDistance( x, y, tx, ty )
        set angle = PointsAngle( x, y, tx, ty )
        if distance > m.speed then
            set tox = x + m.speed * Cos( angle * bj_DEGTORAD )
            set toy = y + m.speed * Sin( angle * bj_DEGTORAD )
            call SetUnitX( m.M, tox )
            call SetUnitY( m.M, toy )
            call SetUnitFacing( m.M, angle )
            set i = distance / m.speed
            set height = GetUnitFlyHeight( m.M ) - m.targetheight
            set height = height / i
            set height = GetUnitFlyHeight( m.M ) - height
            call SetUnitFlyHeight( m.M, height, 0.0 )
        else
            call m.Destroy()
        endif
    endmethod
   
    method Start takes nothing returns nothing
        call TimerStart( this.Timer, Const_MissileInterval, true, function Missile.TimerAction )
    endmethod
   
endstruct

function Trig_Unit_Missile_Condition takes unit u, unit atter returns boolean
    if IsUsableUnit( atter ) or IsUsableUnit( u ) then
        return false
    endif
    if IsUnitType( atter, UNIT_TYPE_RANGED_ATTACKER) == false then
        return false
    endif
    return true
endfunction

function Trig_Unit_Missile_Run takes unit u, unit atter returns nothing
    local Unit AU = GetUnitUnit( atter )
    local string art = AU.MissileArt
    local real speed = AU.MissileSpeed
    local real height = AU.MissileHeight
    local real ax = GetUnitX( atter )
    local real ay = GetUnitY( atter )
    local real tx = GetUnitX( u )
    local real ty = GetUnitY( u )
    local real angle = PointsAngle( ax, ay, tx, ty )
    local unit missile = null
    local Missile m = 0
    if art != null then
        set missile = CreateUnit( GetOwningPlayer(atter), Const_MissileUnitId, ax, ay, angle )
        call Unit.InitUnit( missile )
        if AU.MissileHoming then
            set m = Missile.create( missile, atter, u, tx, ty, speed * Const_MissileInterval, art, height )
        else
            set m = Missile.create( missile, atter, null, tx, ty, speed * Const_MissileInterval, art, height )
        endif
        call m.Start()
    endif
    set art = null
    set missile = null
endfunction

function Trig_Unit_Missile_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local unit atter = GetAttacker()
    if Trig_Unit_Missile_Condition( u, atter ) then
        call Trig_Unit_Missile_Run( u, atter )
    endif
    set u = null
    set atter = null
    return false
endfunction

//===========================================================================
function InitTrig_Unit_Missile takes nothing returns nothing
    set gg_trg_Unit_Missile = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Unit_Missile, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_Unit_Missile, Condition( function Trig_Unit_Missile_Actions ) )
endfunction

//===========================================================================
// Trigger: Unit Seer
//===========================================================================
globals
    constant integer                            Const_SeerOrder                               = 851990
endglobals

function GetUnitSeerId takes integer id returns integer
    return GetStoredInteger( DataGC, I2S( id ), "SeerId" )
endfunction

function CreateSeer takes unit target returns nothing
    local Unit U = GetUnitUnit( target )
    local integer id = GetUnitSeerId( GetUnitTypeId( target ) )
    local User Us = GetUser( GetOwningPlayer( target ) )
    local unit use = CreateUnit( Us.SeerOwner, id, GetUnitX( target ), GetUnitY( target ), GetUnitFacing( target ) )
    call Unit.InitUnit( use )
    set U.Seer = use
    //call SetUnitPathing( use, false )
    call UnitAddAbility( use, Const_MissileLocust )
    if IssueTargetOrderById( use, Const_SeerOrder, target ) == false then
        call BJDebugMsg( "bug" )
    endif
    set use = null
endfunction

function Trig_Unit_Seer_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_Unit_Seer takes nothing returns nothing
    set gg_trg_Unit_Seer = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Unit_Seer, function Trig_Unit_Seer_Actions )
endfunction

//===========================================================================
// Trigger: Struct Player User
//===========================================================================
globals
    player                              User_Temp                               = null
    Unit                                Unit_Change_Temp                        = 0
    group                               Unit_Change_Group                       = null
endglobals

struct User
    group                               Units
    World                               Place
    player                              SeerOwner
    //unit                                DeathSpellUnit
   
    static method SharedVision takes User u1, User u2, boolean flag returns nothing
        if flag then
            call SetPlayerAlliance( u1.SeerOwner, Player(u2), ALLIANCE_SHARED_VISION, true )
            call SetPlayerAlliance( u2.SeerOwner, Player(u1), ALLIANCE_SHARED_VISION, true )
        else
            call SetPlayerAlliance( u1.SeerOwner, Player(u2), ALLIANCE_SHARED_VISION, false )
            call SetPlayerAlliance( u2.SeerOwner, Player(u1), ALLIANCE_SHARED_VISION, false )            
        endif
    endmethod
   
    static method SetSee takes nothing returns nothing
        if User_Temp != GetEnumPlayer() then
            call SetPlayerAlliance( User_Temp, GetEnumPlayer(), ALLIANCE_SHARED_VISION, true )
            call SetPlayerAlliance( GetEnumPlayer(), User_Temp, ALLIANCE_SHARED_VISION, true )
            call User.SharedVision( GetUser( User_Temp ), GetUser( GetEnumPlayer() ), IsPlayerAlly( User_Temp, GetEnumPlayer() ) )
        endif
    endmethod
   
    static method FlushSee takes nothing returns nothing
        if User_Temp != GetEnumPlayer() then
            call SetPlayerAlliance( User_Temp, GetEnumPlayer(), ALLIANCE_SHARED_VISION, false )
            call SetPlayerAlliance( GetEnumPlayer(), User_Temp, ALLIANCE_SHARED_VISION, false )
            call User.SharedVision( GetUser( User_Temp ), GetUser( GetEnumPlayer() ), false )
        endif   
    endmethod
   
    method initseerowner takes player seerowner returns nothing
        set this.SeerOwner = seerowner
    endmethod
   
    method init takes World P returns nothing
        set this.Place = P
        set User_Temp = Player(this)
        call ForForce( this.Place.Users, function User.SetSee )
        //call ForceAddPlayer( this.Place.Users, User_Temp )
        //set this.DeathSpellUnit = CreateUnit( User_Temp, Const_DeathSpellUnitId, 0.0, 0.0, 0.0 )
        //call UnitAddAbility( this.DeathSpellUnit, Const_DeathSpellAbilityId )
        //call UnitAddAbility( this.DeathSpellUnit, Const_MissileLocust )
        set this.Units = CreateGroup()
        call SetPlayerAlliance( this.SeerOwner, User_Temp, ALLIANCE_PASSIVE, true )
        call SetPlayerAlliance( User_Temp, this.SeerOwner, ALLIANCE_PASSIVE, true )
        call SetPlayerAlliance( User_Temp, this.SeerOwner, ALLIANCE_SHARED_VISION, true )
        call SetPlayerAlliance( this.SeerOwner, User_Temp, ALLIANCE_SHARED_VISION, true )
        set User_Temp = null
    endmethod
   
    static method ChangeUnits_Same takes nothing returns nothing
        local unit u = GetEnumUnit()
        local Unit U = GetUnitUnit( u )
        if not(IsUnitsInSameWorld( u, Unit_Change_Temp.U )) then
            call GroupRemoveUnit( Unit_Change_Temp.CollisionSameWorldGroup, u )
            call GroupAddUnit( Unit_Change_Temp.CollisionDifferentWorldGroup, u )
            call GroupRemoveUnit( U.CollisionSameWorldGroup, Unit_Change_Temp.U )
            call GroupAddUnit( U.CollisionDifferentWorldGroup, Unit_Change_Temp.U )
        endif
        set u = null
    endmethod

    static method ChangeUnits_Different takes nothing returns nothing
        local unit u = GetEnumUnit()
        local Unit U = GetUnitUnit( u )
        if IsUnitsInSameWorld( u, Unit_Change_Temp.U ) then
            call GroupRemoveUnit( Unit_Change_Temp.CollisionDifferentWorldGroup, u )
            call GroupAddUnit( Unit_Change_Temp.CollisionSameWorldGroup, u )
            call GroupRemoveUnit( U.CollisionDifferentWorldGroup, Unit_Change_Temp.U )
            call GroupAddUnit( U.CollisionSameWorldGroup, Unit_Change_Temp.U )
        endif
        set u = null
    endmethod
   
    static method ChangeUnits_All takes nothing returns nothing
        local unit u = GetEnumUnit()
        local Unit U = GetUnitUnit( u )
        if IsUnitsInSameWorld( u, Unit_Change_Temp.U ) then
            call GroupRemoveUnit( Unit_Change_Temp.CollisionDifferentWorldGroup, u )
            call GroupAddUnit( Unit_Change_Temp.CollisionSameWorldGroup, u )
            call GroupRemoveUnit( U.CollisionDifferentWorldGroup, Unit_Change_Temp.U )
            call GroupAddUnit( U.CollisionSameWorldGroup, Unit_Change_Temp.U )
        else
            call GroupRemoveUnit( Unit_Change_Temp.CollisionSameWorldGroup, u )
            call GroupAddUnit( Unit_Change_Temp.CollisionDifferentWorldGroup, u )
            call GroupRemoveUnit( U.CollisionSameWorldGroup, Unit_Change_Temp.U )
            call GroupAddUnit( U.CollisionDifferentWorldGroup, Unit_Change_Temp.U )            
        endif
        set u = null   
    endmethod
   
    static method ChangeUnits takes nothing returns nothing
        local unit u = GetEnumUnit()
        local Unit U = GetUnitUnit( u )
        set Unit_Change_Temp = U
        call GroupEnumUnitsInRange( Unit_Change_Group, GetUnitX( u ), GetUnitY( u ), Const_MaxCollision * 2.0 + Const_SafeDistance, CollisionConstCond )
        call GroupRemoveUnit( Unit_Change_Group, u )
        call ForGroup( Unit_Change_Group, function User.ChangeUnits_All )
        call GroupClear( Unit_Change_Group )
        //call ForGroup( U.CollisionSameWorldGroup, function User.ChangeUnits_Same )
        //call ForGroup( U.CollisionDifferentWorldGroup, function User.ChangeUnits_Different )
        set Unit_Change_Temp = 0
        set u = null
    endmethod
   
    method change takes World newP returns nothing
        if newP != this.Place then
            set User_Temp = Player(this)
            if this.Place != 0 then
                call ForceRemovePlayer( this.Place.Users, User_Temp )
                call ForForce( this.Place.Users, function User.FlushSee )
            endif
            set this.Place = newP
            call ForForce( this.Place.Users, function User.SetSee )
            call ForceAddPlayer( this.Place.Users, User_Temp )
            call ForGroup( this.Units, function User.ChangeUnits )
            set User_Temp = null
            //call BJDebugMsg( "|cffff0000===============|r" )
        endif            
    endmethod
   
    method Destroy takes nothing returns nothing
        call DestroyGroup( this.Units )
        set this.Units = null
        set User_Temp = Player(this)
        call ForceRemovePlayer( this.Place.Users, User_Temp )
        call ForForce( this.Place.Users, function User.FlushSee )
        set this.Place = 0
        set this.SeerOwner = null
        //call RemoveUnit( this.DeathSpellUnit )
        //set this.DeathSpellUnit = null
    endmethod
   
endstruct

function Trig_Struct_Player_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_Struct_Player_User takes nothing returns nothing
    set Unit_Change_Group = CreateGroup()
    set gg_trg_Struct_Player_User = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Struct_Player_User, function Trig_Struct_Player_Actions )
endfunction

//===========================================================================
// Trigger: Struct World
//===========================================================================
globals
    force                               Users_Temp                                      = null
    player array                        Users_SeeTemp
    integer                             Users_SeeTemp_Num                               = 0
    World                               Users_World_Temp                                = 0
    constant integer                    Const_SeerPlayerMove                            = 6
endglobals

struct World
    force                               Users
    //force                               GMs
   
    static method GMEnum takes nothing returns nothing
        local User U = GetUser( GetEnumPlayer() )
        call ForceAddPlayer( Users_Temp, GetEnumPlayer() )
        call U.initseerowner( Player( U + 5 ) )
        set Users_SeeTemp[Users_SeeTemp_Num] = GetEnumPlayer()
        set Users_SeeTemp_Num = Users_SeeTemp_Num + 1
    endmethod
   
    static method GMinit takes nothing returns nothing
        local User U = GetUser( GetEnumPlayer() )
        call U.init( Users_World_Temp )
    endmethod
   
    static method create takes force GM returns World
        local World new = World.allocate()
        local integer i = 0
        local integer j = 0
        set new.Users = CreateForce()
        set Users_Temp = new.Users
        set Users_World_Temp = new
        call ForForce( GM, function World.GMEnum )
        call ForForce( GM, function World.GMinit )
        set Users_World_Temp = 0
        set Users_Temp = null
        loop
            exitwhen i >= Users_SeeTemp_Num
            set j = 0
            loop
                exitwhen j >= Users_SeeTemp_Num
                if i != j then
                    call SetPlayerAlliance( Users_SeeTemp【i】, Users_SeeTemp[j], ALLIANCE_SHARED_VISION, true )
                    call SetPlayerAlliance( Users_SeeTemp[j], Users_SeeTemp【i】, ALLIANCE_SHARED_VISION, true )
                endif
                set j = j + 1
            endloop
            set i = i + 1
        endloop
        loop
            exitwhen Users_SeeTemp_Num <= 0
            set Users_SeeTemp_Num = Users_SeeTemp_Num - 1
            set Users_SeeTemp[Users_SeeTemp_Num] = null
        endloop
        //set new.GMs = GM
        return new
    endmethod
   
    method Destroy takes nothing returns nothing
        call DestroyForce( this.Users )
        set this.Users = null
        //call DestroyForce( this.GMs )
        //set this.GMs = null
        call this.destroy()
    endmethod
   
endstruct

function Trig_Struct_World_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_Struct_World takes nothing returns nothing
    set gg_trg_Struct_World = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Struct_World, function Trig_Struct_World_Actions )
endfunction

//===========================================================================
// Trigger: AllUnitDeath
//===========================================================================
globals
    constant integer                            Const_UnitDeath_TimedId                       = 'BHwe'
    constant real                               Const_UnitDeath_DecayTime                     = 100.0
    constant real                               Const_UnitDeath_DeathTime                     = 5.0
    constant integer                            Const_DeathMoveAbility                        = 'Amov'
    constant integer                            Const_DeathAttackAbility                      = 'Abun'
endglobals

function UnitDeath_Condition takes unit u returns boolean
    if IsUsableUnit( u ) then
        return false
    endif
    return true
endfunction

function AllUnitDeath_Flesh takes unit d returns nothing
    local player p = GetOwningPlayer(d)
    //local User U = GetUser( p )
    local string Id = I2S( GetUnitTypeId( d ) )
    local unit u = CreateUnit( p, GetStoredInteger( DataGC, Id, "DeadBodyId" ), GetUnitX(d), GetUnitY(d), GetUnitFacing(d) )
    call Unit.InitUnit( u )
    call SetUnitTimeScale( u, 1.0 )
    call SetUnitAnimation( u, "Death" )
    if GetStoredBoolean( DataGC, Id, "HaveDecay" ) then
        call QueueUnitAnimation( u, "Decay Flesh" )
        call QueueUnitAnimation( u, "Decay Bone" )
        call UnitApplyTimedLife( u, Const_UnitDeath_TimedId, Const_UnitDeath_DecayTime )
    else
        call UnitApplyTimedLife( u, Const_UnitDeath_TimedId, Const_UnitDeath_DeathTime )
    endif
    call UnitAddAbility( u, Const_MissileLocust )
    call UnitRemoveAbility( u, Const_DeathMoveAbility )
    call UnitAddAbility( u, Const_DeathAttackAbility )
    set u = null
    set p = null
    set Id = null
endfunction

function Trig_AllUnitDeath_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local Unit U = 0
    if UnitDeath_Condition( u ) then
        if IsUnitType( u, UNIT_TYPE_HERO ) == false then
            set U = GetUnitUnit( u )
            call U.Destroy()
            call AllUnitDeath_Flesh( u )
        endif
    //elseif IsUsableUnit( u ) then
        //call RemoveUnit( u )
    endif
    call RemoveUnit( u )
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_AllUnitDeath takes nothing returns nothing
    set gg_trg_AllUnitDeath = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AllUnitDeath, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_AllUnitDeath, Condition( function Trig_AllUnitDeath_Actions ) )
endfunction

//===========================================================================
// Trigger: RegisterUnitData
//===========================================================================
function RegisterUnit_EnumCondition takes nothing returns boolean
    if IsUsableUnit_Type( GetFilterUnit() ) then
        return false
    endif
    return true
endfunction

function RegisterUnit takes unit u returns nothing
    call Unit.create( u )
    call CreateSeer( u )
endfunction

function Register_UnitIn takes nothing returns boolean
    if not( IsUsableUnit_Type( GetTriggerUnit() ) ) then
        call RegisterUnit( GetTriggerUnit() )
    endif
    return false
endfunction

function Register_UnitSummon takes nothing returns boolean
    if not( IsUsableUnit_Type( GetSummonedUnit() ) ) then
        call RegisterUnit( GetSummonedUnit() )
    endif
    return false
endfunction

function RegisterUnitData_TriggerInit takes nothing returns nothing
    local trigger t = CreateTrigger()
    local rect r = GetWorldBounds()
    local boolexpr cond = Condition( function Register_UnitIn )
    call TriggerRegisterEnterRectSimple( t, r )
    call TriggerAddCondition( t, cond )
    call DestroyBoolExpr( cond )
    set cond = null   
    call RemoveRect( r )
    set r = null
    set t = null
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SUMMON )
    set cond = Condition( function Register_UnitSummon )
    call TriggerAddCondition( t, cond )
    call DestroyBoolExpr( cond )
    set cond = null
    set t = null
endfunction

function Trig_RegisterUnitData_Actions takes nothing returns nothing
    local group g = CreateGroup()
    local boolexpr cond = Condition( function RegisterUnit_EnumCondition )
    local unit u = null
    local rect r = GetWorldBounds()
    call GroupEnumUnitsInRect( g, r, cond )
    loop
        set u = FirstOfGroup( g )
        exitwhen u == null
        call GroupRemoveUnit( g, u )
        call RegisterUnit( u )
    endloop
    call DestroyBoolExpr( cond )
    set cond = null
    call DestroyGroup( g )
    set g = null
    call RemoveRect( r )
    set r = null
    set u = null
    call RegisterUnitData_TriggerInit()
endfunction

//===========================================================================
function InitTrig_RegisterUnitData takes nothing returns nothing
    set gg_trg_RegisterUnitData = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_RegisterUnitData, InitTime_Unit, false )
    call TriggerAddAction( gg_trg_RegisterUnitData, function Trig_RegisterUnitData_Actions )
endfunction

//===========================================================================
// Trigger: RegisterTypeData
//===========================================================================
function RegisterUnitTypeData_Missile takes integer id, string missileart, real missilespeed, boolean missileHoming returns nothing
    local string Id = I2S( id )
    call StoreString( DataGC, Id, "MissileArt", missileart )
    call StoreReal( DataGC, Id, "MissileSpeed", missilespeed )
    call StoreBoolean( DataGC, Id, "MissileHoming", missileHoming )
    set Id = null
endfunction

function RegisterUnitTypeData_MissileHeight takes integer id, real attack, real attacked returns nothing
    local string Id = I2S( id )
    call StoreReal( DataGC, Id, "MissileAttackHeight", attack )
    call StoreReal( DataGC, Id, "MissileAttackedHeight", attacked )
    set Id = null
endfunction

function RegisterUnitTypeData_Usable takes integer id returns nothing
    local string Id = I2S( id )
    call StoreBoolean( DataGC, Id, "IsUsableUnit", true )
    set Id = null
endfunction

function RegisterUnitTypeData_SeerId takes integer id, integer seerid returns nothing
    local string Id = I2S( id )
    call StoreInteger( DataGC, Id, "SeerId", seerid )
    call RegisterUnitTypeData_Usable( seerid )
    set Id = null
endfunction

function RegisterUnitTypeData_Burrow takes integer id, integer id_01, integer id_02_it returns nothing
    local string Id = I2S( id )
    call StoreInteger( DataGC, Id, "Id01", id_01 )
    call StoreInteger( DataGC, Id, "Id02Item", id_02_it )
    set Id = null
endfunction

function RegisterUnitTypeData_DeadBody takes integer id, integer db_id, boolean havedecay returns nothing
    local string Id = I2S( id )
    call StoreInteger( DataGC, Id, "DeadBodyId", db_id )
    call RegisterUnitTypeData_Usable( db_id )
    call StoreBoolean( DataGC, Id, "HaveDecay", havedecay )
    set Id = null
endfunction

function RegisterUnitTypeData_Collision takes integer id, real collision returns nothing
    local string Id = I2S( id )
    call StoreReal( DataGC, Id, "Collision", collision * 2 )
    set Id = null
endfunction

function Trig_RegisterTypeData_Actions takes nothing returns nothing
    call RegisterUnitTypeData_Burrow( 'hfoo', 'A00A', 'I000' )
    call RegisterUnitTypeData_MissileHeight( 'hfoo', 0.0, 60.0 )
    call RegisterUnitTypeData_SeerId( 'hfoo', 'h001' )
    call RegisterUnitTypeData_DeadBody( 'hfoo', 'h003', true )
    call RegisterUnitTypeData_Burrow( 'h003', 'A00I', 'I006' )
    call RegisterUnitTypeData_Collision( 'hfoo', 48.0 )
    //hfoo
    call RegisterUnitTypeData_Burrow( 'hmpr', 'A009', 'I001' )
    call RegisterUnitTypeData_Missile( 'hmpr', "Abilities\\\\Weapons\\\\PriestMissile\\\\PriestMissile.mdl", 900.0, true )
    call RegisterUnitTypeData_MissileHeight( 'hmpr', 60.0, 60.0 )
    call RegisterUnitTypeData_SeerId( 'hmpr', 'h001' )
    call RegisterUnitTypeData_DeadBody( 'hmpr', 'h004', true )
    call RegisterUnitTypeData_Burrow( 'h004', 'A00J', 'I007' )
    call RegisterUnitTypeData_Collision( 'hmpr', 16.0 )
    //hmpr
    call RegisterUnitTypeData_Burrow( 'hwt2', 'A00C', 'I002' )
    call RegisterUnitTypeData_Missile( 'hwt2', "Abilities\\\\Weapons\\\\WaterElementalMissile\\\\WaterElementalMissile.mdl", 1300.0, true )
    call RegisterUnitTypeData_MissileHeight( 'hwt2', 120.0, 60.0 )
    call RegisterUnitTypeData_SeerId( 'hwt2', 'h002' )
    call RegisterUnitTypeData_DeadBody( 'hwt2', 'h005', false )
    call RegisterUnitTypeData_Burrow( 'h005', 'A00K', 'I008' )
    call RegisterUnitTypeData_Collision( 'hwt2', 32.0 )
    //hwt2
    call RegisterUnitTypeData_Usable( Const_MissileUnitId )
    call RegisterUnitTypeData_Burrow( 'h000', 'A00D', 'I003' )
    //Usable h000
    call RegisterUnitTypeData_Burrow( 'h001', 'A00E', 'I004' )
    //Usable h001
    call RegisterUnitTypeData_Burrow( 'h002', 'A00B', 'I005' )
    //Usable h002
endfunction

//===========================================================================
function InitTrig_RegisterTypeData takes nothing returns nothing
    set gg_trg_RegisterTypeData = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_RegisterTypeData, InitTime_Type, false )
    call TriggerAddAction( gg_trg_RegisterTypeData, function Trig_RegisterTypeData_Actions )
endfunction

//===========================================================================
// Trigger: Init
//===========================================================================
function Init_Actions5 takes nothing returns nothing
    call FlushGameCache( InitGameCache( "DataGC.w3v" ) )
    set DataGC = InitGameCache( "DataGC.w3v" )
endfunction

function Init_Actions1 takes nothing returns nothing
    local Unit i = 0
    local Missile i2 = 0
    loop
        exitwhen i >= Unit.CollisionTimerMaxNumber
        set i.CollisionTimer = CreateTimer()
        set i = i + 1
    endloop
    set i = 0
    set Unit.CollisionTimerMinHandle = H2I( i.CollisionTimer )
    loop
        exitwhen i2 >= Missile.MaxTimerNumber
        set i2.Timer = CreateTimer()
        set i2 = i2 + 1
    endloop
    set i2 = 0
    set Missile.MinTimerHandleAddress = H2I( i2.Timer )
    call TimerStart( GetExpiredTimer(), 0.01, false, function Init_Actions5 )
endfunction

//===========================================================================
function InitTrig_Init takes nothing returns nothing
    call TimerStart( CreateTimer(), 0.01, false, function Init_Actions1 )
endfunction

//===========================================================================
// Trigger: Test
//===========================================================================
function Trig_Test_Actions takes nothing returns nothing
    local force f1 = CreateForce()
    local force f2 = CreateForce()
    local World W1 = 0
    local World W2 = 0
    call ForceAddPlayer( f1, Player(0) )
    call ForceAddPlayer( f1, Player(3) )
    call SetPlayerAlliance( Player(0), Player(3), ALLIANCE_PASSIVE, true )
    call SetPlayerAlliance( Player(3), Player(0), ALLIANCE_PASSIVE, true )
    call ForceAddPlayer( f2, Player(1) )
    call ForceAddPlayer( f2, Player(2) )
    set W1 = World.create( f1 )
    set W2 = World.create( f2 )
    set f1 = null
    set f2 = null
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Test, InitTime_World )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction

//===========================================================================
// Trigger: Esc
//===========================================================================
function Trig____________________002_Actions takes nothing returns nothing
    local User U = 0
    if udg_Test_Bool then
        call U.change( 1 )
        set udg_Test_Bool = false
    else
        call U.change( 2 )
        set udg_Test_Bool = true
    endif
endfunction

//===========================================================================
function InitTrig_Esc takes nothing returns nothing
    set gg_trg_Esc = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Esc, Player(0) )
    call TriggerAddAction( gg_trg_Esc, function Trig____________________002_Actions )
endfunction
回复

使用道具 举报

发表于 2009-7-31 22:45:48 | 显示全部楼层
等解决了这些问题~就加精罢
我明天去找下抛物线的算法给你
回复

使用道具 举报

 楼主| 发表于 2009-8-1 06:45:04 | 显示全部楼层
算了吧…………抛物线就先不用了………………不想做……
回复

使用道具 举报

发表于 2009-8-1 08:34:45 | 显示全部楼层
PS
小血用了VJ
所以不懂vj的人就放弃吧
回复

使用道具 举报

发表于 2009-8-1 08:40:31 | 显示全部楼层
连J都木有学好,竟然还是VJ……
快速放弃完毕。
回复

使用道具 举报

发表于 2009-8-1 08:41:07 | 显示全部楼层
2楼什么也没有!
/////////////////////////////////////////////////

单位的大部分魔兽自带的技能需要模拟。

非单位附加】的模型必须模拟
...
                  
这个有什么实用之处呢?做风景图么还是做电影图

还是用vjass写的。。。纯欣赏,纯支持了。。。

哦,我能听到另外一个位面打架的声音....
回复

使用道具 举报

发表于 2009-8-1 08:50:06 | 显示全部楼层
如果有精力和想法,我们可以做出一个前所未有的经典的图。
小血~什么时候出个完善版的,去别处宣传下我们星球的力量
回复

使用道具 举报

 楼主| 发表于 2009-8-1 12:02:40 | 显示全部楼层
为什么啊!!!
呜呜……………………
代码只要使用
[codes=jass]
[/codes]
[jass]
[/jass]
立马就会消失不见…………
只好不加语法高亮了…………
因为太长了?
回复

使用道具 举报

 楼主| 发表于 2009-8-1 12:04:45 | 显示全部楼层
突然发现自己不知不觉就编到1000+行了………………
这还是因为vj的struct方便的缘故……
看来也只能欣赏了~
回复

使用道具 举报

发表于 2009-8-1 12:11:42 | 显示全部楼层
这个系统虽然很麻烦,但是很美阿。
回复

使用道具 举报

 楼主| 发表于 2009-8-1 12:13:55 | 显示全部楼层
…………貌似有人说听到了声音………………
哎…………这个我再看看吧…………(99.9%不能解决)
回复

使用道具 举报

发表于 2009-8-1 12:35:30 | 显示全部楼层
远程的抛物线是永远无法解决的,因为那口胡的SetUnitLookAt()没用,已经放弃了N次了........
回复

使用道具 举报

 楼主| 发表于 2009-8-1 12:38:04 | 显示全部楼层
远程抛物线怎么不能解决?
timer+SetUnitFlyHeight就可以。
只是我不会抛物线罢了。
回复

使用道具 举报

发表于 2009-8-1 13:03:11 | 显示全部楼层
声音是可以异步播放的
把攻击音效取消
然后播放吧
回复

使用道具 举报

 楼主| 发表于 2009-8-1 13:20:42 | 显示全部楼层
恩好像可以~~
稍微改一下就行了………………
不过应该播放什么音效啊………………
3d音效?
回复

使用道具 举报

发表于 2009-8-1 14:50:18 | 显示全部楼层
看着一大串头晕 血魔能讲解下思路不
回复

使用道具 举报

 楼主| 发表于 2009-8-1 14:55:33 | 显示全部楼层
…………这只是个演示,而且光是代码你也看不懂。
主要还是有一些纯WE技术在里面…………所以真要讲思路还是等正式版吧……
PS:单位声音真不想隐藏……太麻烦了……………………
回复

使用道具 举报

发表于 2009-8-1 15:01:58 | 显示全部楼层
线是能画出来,但是你会看见所有的投射物都是平放的……
回复

使用道具 举报

 楼主| 发表于 2009-8-1 15:03:59 | 显示全部楼层
嗯。不过也没办法了。
毕竟没有什么好的方法调整单位的水平角度。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-24 04:40 , Processed in 0.221423 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表