Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Наработка
Версия Warcraft:
1.26 (UjAPI)

Система турели

Демонстрация

Просто кликните юнитом на турель, чтобы посадить его внутрь, и расстреливайте осколки моих разбитых надежд и мечт монстров с помощью движения мышкой и ЛКМ
Чтобы выйти из турели можно сдохнуть (не ирл, позязь, кто ж лайки ставить то будет), либо нажать ESC
+ Мультиплеерное
+ Управление камерой с помощью мыши и стрельба с помощью ЛКМ
+ Пушку не могут занять несколько юнитов одновременно
+ Игрок не может занять больше одной пушки
+ Количество урона, скорости полёта снаряда, дистанция полёта снаряда и скорострельность настраиваются в редакторе объектов
+ Курсор прячется при стрельбе
- Корректная работа только при полноэкранном режиме (версия UjAPI 1.1.20.244)
- Модель пушки криво порезана (источники свечения лень было поправлять), так что есть необходимость обратиться в Нужна Модель? Вам сюда!
- Отсутствует звук погрузки юнита в турель и выгрузки из неё
- Нет прицела

Инструкция по импорту

  • Работает исключительно на UjAPI, поэтому вам необходимо установить лаунчер
Скопировать папку Initialization и закинуть в свою карту вместе со всем импортом
В триггере Turret указать на 420, 460, 523, 500-502 строках равкоды основного юнита турели и его составляющих (полные турели будут заменены на разрезанные и возвращены обратно при смерти), на строке 335 указать радиус снаряда, на строках 218-220 указать разброс снарядов. Всё остальное требует минимальных знаний джасса
Триггер Untitled Trigger 001 можно удалять, он тестовый
если что-то не понятно - комменты

Код

AllGlobals
library AllGlobalsLib initializer OnInit
globals
    constant hashtable H = InitHashtable( )
    
    real array PlayerMouseScreenX
    real array PlayerMouseScreenY
    
    real MaxX
    real MinX
    real MaxY
    real MinY
    
    framehandle CURSOR_FRAME
endglobals

native UnitAlive takes unit id returns boolean

function AngleDifference takes real a, real a1 returns real
	set a = RAbsBJ( a - a1 )
	
	if a > 180.00 then
		set a = 360.00 - a
	endif

	return a
endfunction

function GetCorX takes real x returns real
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    
    return x
endfunction

function GetCorY takes real y returns real
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    
    return y
endfunction

function CreateUnitEx takes player id, integer unitid, real x, real y, real face returns unit
    set bj_lastCreatedUnit = CreateUnit( id, unitid, x, y, face )
    
    call SetUnitX( bj_lastCreatedUnit, GetCorX( x ) )
    call SetUnitY( bj_lastCreatedUnit, GetCorY( y ) )
    
    return bj_lastCreatedUnit
endfunction

function TrackMouseScreenXY takes nothing returns nothing
    local integer i = GetPlayerId( GetTriggerPlayer( ) )
    
    set PlayerMouseScreenX[i] = GetTriggerPlayerMouseScreenX( )
    set PlayerMouseScreenY[i] = GetTriggerPlayerMouseScreenY( )
endfunction

private function OnInit takes nothing returns nothing
    local integer i = 0
    local rect r = GetWorldBounds( )
    
    
    set gg_trg_AllGlobals = CreateTrigger(  )
    
    loop
        call TriggerRegisterPlayerEvent( gg_trg_AllGlobals, Player( i ), EVENT_PLAYER_MOUSE_MOVE )
        
        set i = i + 1
        exitwhen i >= bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( gg_trg_AllGlobals, function TrackMouseScreenXY )
    
    set MaxX = GetRectMaxX( r )
    set MinX = GetRectMinX( r )
    set MaxY = GetRectMaxY( r )
    set MinY = GetRectMinY( r )
    
    call RemoveRect( r )
    
    set r = null
    
    call TriggerSleepAction( 0.00 )
    
    set CURSOR_FRAME = GetOriginFrame( ORIGIN_FRAME_CURSOR_FRAME, 0 )
endfunction
endlibrary

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //
//endfunction

Turret
library TurretLib
globals
    private constant group TempGroup = CreateGroup( )
    private constant real TimerPeriodic = 0.0225
    
    private boolean array TurretOpen
    private boolean array BUTTON_PRESSED[195][12]
    private boolean array BUTTON_PRESSED_ESCAPE
    
    private real array ReloadTime
    
    constant key TurretStructKey
    constant key UnitDFTKey
endglobals

private struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

private struct TurretS
    vector v
    
    timer t
    integer playerID
    
    unit caster
    unit foundation
    unit cockpit
    unit weapon
    unit main
    
    real time
    real speed
    real yaw
    real pitch
    
    method close takes nothing returns nothing
        call RemoveSavedInteger( H, GetHandleId( caster ), TurretStructKey )
        call ShowUnit( caster, true )
        
        call PauseTimer( t )
        
        if GetLocalPlayer( ) == Player( playerID ) then
            call EnableSelect( true, true )
            call EnablePreSelect( true, true )
            call EnableDragSelect( true, true )
            
            call ClearSelection( )
            call SelectUnit( caster, true )
            
            call CameraSetSmoothingFactor( 0.00 )
            call ResetToGameCamera( 0.00 )
            call SetUnitVertexColor( cockpit, 255, 255, 255, 255 )
            call SetFrameSpriteAlpha( CURSOR_FRAME, 255 )
        endif
        
        set caster = null
    endmethod
endstruct

private struct bulletS
    vector v
    vector p
    
    real speed
    real damage
    real radius
    real distance
    effect bullet
    effect bullet1
    player pl
    timer t
    unit caster
    
    method Destroy takes nothing returns nothing
        if t != null then
            call PauseTimer( t )
            call FlushChildHashtable( H, GetHandleId( t ) )
            call DestroyTimer( t )
        
            set t = null
        endif
        
        if bullet != null then
            call DestroyEffect( bullet )
            
            set bullet = null
        endif
        
        if bullet1 != null then
            call DestroyEffect( bullet1 )
            
            set bullet1 = null
        endif
        
        call p.destroy( )
        call v.destroy( )
        call destroy( )
    endmethod
    
    static method move takes nothing returns nothing
        local thistype this = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
        local unit u
        
        if this.distance < this.speed then
            set this.speed = this.distance
        endif
        
        set this.p.x = GetCorX( this.p.x + this.speed * this.v.x )
        set this.p.y = GetCorY( this.p.y + this.speed * this.v.y )
        set this.p.z = this.p.z + this.speed * this.v.z
        set this.distance = this.distance - this.speed
        
        call SetSpecialEffectPositionWithZ( this.bullet, this.p.x, this.p.y, this.p.z )
        call SetSpecialEffectPositionWithZ( this.bullet1, this.p.x, this.p.y, this.p.z )
        
        call GroupEnumUnitsInRange( TempGroup, this.p.x, this.p.y, this.radius + 200.00, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, this.p.x, this.p.y, this.radius ) then
                if IsUnitAlive( u ) and IsUnitEnemy( u, this.pl ) then
                    if RAbsBJ( GetUnitZ( u ) - this.p.z ) <= this.radius + GetUnitRealField( u, UNIT_RF_COLLISION_SIZE ) * 2.00 then
                        call GroupClear( TempGroup )
                        set this.distance = 0.00
                    endif
                endif
            endif
        endloop
        
        if this.distance <= 0.00 or this.p.z <= GetAxisZ( this.p.x, this.p.y ) then
            call GroupEnumUnitsInRange( TempGroup, this.p.x, this.p.y, this.radius * 2.00 + 200.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitInRangeXY( u, this.p.x, this.p.y, this.radius * 2.00 ) then
                    if IsUnitAlive( u ) and IsUnitEnemy( u, this.pl ) then
                        if RAbsBJ( GetUnitZ( u ) - this.p.z ) <= this.radius + GetUnitRealField( u, UNIT_RF_COLLISION_SIZE ) * 2.00 then
                            call UnitDamageTarget( this.caster, u, this.damage, false, false, null, null, null )
                        endif
                    endif
                endif
            endloop
                        
            set bj_lastCreatedEffect = AddSpecialEffect( "war3mapImported\\AncientExplode.mdx", this.p.x, this.p.y )
            call SetSpecialEffectZ( bj_lastCreatedEffect, this.p.z )
            call SetSpecialEffectScale( bj_lastCreatedEffect, 0.30 )
            call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 7.00 )
            call SetSpecialEffectOrientation( bj_lastCreatedEffect, GetRandomReal( 0.00, 360.00 ), GetRandomReal( -90.00, 90.00 ), GetRandomReal( -90.00, 90.00 ) )
            call DestroyEffect( bj_lastCreatedEffect )
            
            call this.Destroy( )
        endif
    endmethod
    
    method launch takes nothing returns nothing
        set t = CreateTimer( )
        
        call SaveInteger( H, GetHandleId( t ), 0, this )
        call TimerStart( t, TimerPeriodic, true, function thistype.move )
    endmethod
endstruct

private function CreateBullets takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local integer c = LoadInteger( H, i, 1 ) - 1
    local bulletS A = LoadInteger( H, i, 0 )
    local bulletS S = bulletS.create( )
    local real a = Atan2( A.v.y, A.v.x )
    
    if c == 3 then
        set S.p = vector.create( A.p.x + 75.00 * Cos( a - 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.y + 75.00 * Sin( a - 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.z + 25.00 - 10.00 )
    elseif c == 2 then
        set S.p = vector.create( A.p.x + 75.00 * Cos( a - 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.y + 75.00 * Sin( a - 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.z - 25.00 - 10.00 )
    elseif c == 1 then
        set S.p = vector.create( A.p.x + 75.00 * Cos( a + 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.y + 75.00 * Sin( a + 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.z + 25.00 - 10.00 )
    else
        set S.p = vector.create( A.p.x + 75.00 * Cos( a + 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.y + 75.00 * Sin( a + 45.00 * bj_DEGTORAD ) * Cos( A.v.z ), A.p.z - 25.00 - 10.00 )
    endif
    
    set S.v = vector.create( A.v.x, A.v.y, A.v.z )
    
    set S.v.x = S.v.x + GetRandomReal( -0.01, 0.01 )
    set S.v.y = S.v.y + GetRandomReal( -0.01, 0.01 )
    set S.v.z = S.v.z + GetRandomReal( -0.005, 0.005 )
    
    set S.pl = A.pl
    set S.bullet = AddSpecialEffect( "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl", S.p.x, S.p.y )
    set S.bullet1 =  AddSpecialEffect( "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", S.p.x, S.p.y )
    
    call SetSpecialEffectScale( S.bullet1, 0.50 )
    
    call SetSpecialEffectZ( S.bullet, S.p.z )
    call SetSpecialEffectOrientation( S.bullet, Atan2( S.v.y, S.v.x ) * bj_RADTODEG, Atan2( S.v.z, S.v.length( ) ) * bj_RADTODEG, 0.00 )
    
    call SetSpecialEffectZ( S.bullet1, S.p.z )
    call SetSpecialEffectOrientation( S.bullet1, Atan2( S.v.y, S.v.x ) * bj_RADTODEG, Atan2( S.v.z, S.v.length( ) ) * bj_RADTODEG, 0.00 )
    
    set S.speed = A.speed
    set S.damage = A.damage
    set S.radius = A.radius
    set S.distance = A.distance
    set S.caster = A.caster
    
    call S.launch( )
    
    if c <= 0 then
        call FlushChildHashtable( H, i )
        call DestroyTimer( t )
        
        call A.Destroy( )
    else
        call SaveInteger( H, i, 1, c )
        call TimerStart( t, 0.10, false, function CreateBullets )
    endif
endfunction

private function Check takes nothing returns nothing
    local timer t
    local real x
    local real y
    local TurretS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local bulletS S
    
    if BUTTON_PRESSED_ESCAPE[A.playerID] then
        call A.close( )
    else
        if A.time <= 0.10 and ( PlayerMouseScreenX[A.playerID] - 0.50 != 0.00 or PlayerMouseScreenY[A.playerID] - 0.50 != 0.00 ) then
            set A.time = 0.20
            
            set A.v.x = PlayerMouseScreenX[A.playerID] - 0.50
            set A.v.y = PlayerMouseScreenY[A.playerID] - 0.50
            
            set A.speed = SquareRoot( A.v.x * A.v.x + A.v.y * A.v.y )
            
            if A.speed == 0.00 then
                set A.speed = 1.00
            endif
            
            set A.v.x = A.v.x / A.speed
            set A.v.y = A.v.y / A.speed
            
            if GetLocalPlayer( ) == Player( A.playerID ) then
                if IsWindowActive( ) then
                    call SetMouseScreenPosition( 0.50, 0.50 )
                endif
            endif
            
            set PlayerMouseScreenX[A.playerID] = 0.50
            set PlayerMouseScreenY[A.playerID] = 0.50
        elseif A.time > 0.00 then
            set A.time = A.time - 0.01
            
            set A.yaw = A.yaw - A.speed * A.v.x
            set A.pitch = A.pitch + A.speed * A.v.y
            
            if A.pitch < -20.00 then
                set A.pitch = -20.00
            elseif A.pitch > 20.00 then
                set A.pitch = 20.00
            endif
        endif
        
        call SetUnitFacing( A.cockpit, A.yaw )
        call SetUnitOrientation( A.weapon, A.yaw, A.pitch, 0.00 )
        
        if GetLocalPlayer( ) == Player( A.playerID ) then
            if IsWindowActive( ) then
                call SetCameraField( CAMERA_FIELD_ROTATION, A.yaw, 0.01 )
                call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, A.pitch, 0.01 )
                call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, 150.00, 0.00 )
                call SetCameraField( CAMERA_FIELD_ZOFFSET, GetUnitZ( A.weapon ), 0.00 )
                call SetFrameSpriteAlpha( CURSOR_FRAME, 0 )
            endif
        endif
        
        if ReloadTime[A.playerID] > 0.00 then
            set ReloadTime[A.playerID] = ReloadTime[A.playerID] - 0.01
        elseif BUTTON_PRESSED[ GetHandleId( OSKEY_LBUTTON ) ][A.playerID] then
            set ReloadTime[A.playerID] = GetUnitWeaponRealField( A.foundation, UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN, 0 ) - 0.10
            
            call SetUnitAnimation( A.weapon, "attack" )
            call QueueUnitAnimation( A.weapon, "ready" )
            call QueueUnitAnimation( A.weapon, "stand" )
            
            set t = CreateTimer( )
            set S = bulletS.create( )
            
            set S.p = vector.create( GetUnitX( A.weapon ), GetUnitY( A.weapon ), GetUnitZ( A.weapon ) )
            
            set S.v = vector.create( MathCosDeg( A.yaw ) * MathCosDeg( A.pitch ), MathSinDeg( A.yaw ) * MathCosDeg( A.pitch ), A.pitch * bj_DEGTORAD )
            
            set S.pl = Player( A.playerID )
            set S.caster = A.caster
            
            call S.v.normalize( )
            
            set S.speed = GetUnitWeaponRealField( A.foundation, UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED, 0 ) * TimerPeriodic
            set S.damage = GetRandomInt( GetUnitWeaponIntegerField( A.foundation, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MINIMUM, 0 ), GetUnitWeaponIntegerField( A.foundation, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MAXIMUM, 0 ) ) + GetUnitWeaponIntegerField( A.foundation, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 )
            set S.radius = 48.00
            set S.distance = GetUnitWeaponRealField( A.foundation, UNIT_WEAPON_RF_ATTACK_RANGE, 0 )
            
            call SaveInteger( H, GetHandleId( t ), 0, S )
            call SaveInteger( H, GetHandleId( t ), 1, 4 )
            
            call TimerStart( t, 0.00, false, function CreateBullets )
            
            set t = null
        endif
    endif
endfunction

private function CheckDistanceForTurret takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local unit caster = LoadUnitHandle( H, GetHandleId( t ), 0 )
    local unit target = LoadUnitHandle( H, GetHandleId( t ), 1 )
    local integer i
    local TurretS A
    local boolean a = not UnitAlive( caster )
    local boolean b = not UnitAlive( target )
    
    if a or b or MathDistanceBetweenPoints( GetUnitX( caster ), GetUnitY( caster ), GetUnitX( target ), GetUnitY( target ) ) <= GetUnitRealField( caster, UNIT_RF_COLLISION_SIZE ) + GetUnitRealField( target, UNIT_RF_COLLISION_SIZE ) + 128.00 then
        if not ( a or b ) then
            set i = GetPlayerId( GetOwningPlayer( caster ) )
            
            if not TurretOpen[i] then
                set A = LoadInteger( H, GetHandleId( target ), TurretStructKey )
                
                if A.caster == null then
                    set A.caster = caster
                    set A.playerID = i
                    
                    call SaveInteger( H, GetHandleId( caster ), TurretStructKey, A )
                    call ShowUnit( caster, false )
                    
                    set PlayerMouseScreenX[i] = 0.50
                    set PlayerMouseScreenY[i] = 0.50
                    set BUTTON_PRESSED_ESCAPE[i] = false
                    
                    if GetLocalPlayer( ) == Player( i ) then
                        call SetUnitVertexColor( A.cockpit, 255, 255, 255, 0 )
                        
                        call ClearSelection( )
                        call SelectUnit( A.foundation, true )
                        
                        call EnableSelect( false, false )
                        call EnablePreSelect( false, false )
                        call EnableDragSelect( false, false )
                        
                        call SetCameraTargetController( A.foundation, 0.00, 0.00, false )
                        call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, A.pitch, 0.00 )
                        call SetCameraField( CAMERA_FIELD_ROTATION, A.yaw, 0.00 )
                        call SetCameraField( CAMERA_FIELD_ZOFFSET, GetUnitZ( A.weapon ), 0.00 )
                        call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, 150.00, 0.00 )
                        call SetCameraField( CAMERA_FIELD_FARZ, 6000.00, 0.10 )
                        call SetCameraField( CAMERA_FIELD_NEARZ, 1.00, 0.10 )
                        
                        call CameraSetSmoothingFactor( 1.00 )
                    endif
                    
                    call TimerStart( A.t, 0.01, true, function Check )
                endif
            endif
        endif
        
        call FlushChildHashtable( H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        call RemoveSavedHandle( H, GetHandleId( caster ), UnitDFTKey )
    else
        call TimerStart( t, 0.10, false, function CheckDistanceForTurret )
    endif
    
    set t = null
    set caster = null
    set target = null
endfunction

function Turret_Actions takes nothing returns nothing
    local unit target = GetOrderTargetUnit( )
    local unit caster = GetTriggerUnit( )
    local timer t
    
    if target != null then
        if GetUnitTypeId( target ) == 'h001' and ( not TurretOpen[GetPlayerId( GetOwningPlayer( caster ) )] ) and TurretS( LoadInteger( H, GetHandleId( target ), TurretStructKey ) ).caster == null then
            set t = LoadTimerHandle( H, GetHandleId( caster ), UnitDFTKey )
            
            if t == null then
                set t = CreateTimer( )
                
                call SaveUnitHandle( H, GetHandleId( t ), 0, caster )
                call SaveTimerHandle( H, GetHandleId( caster ), UnitDFTKey, t )
                
                call TimerStart( t, 0.00, false, function CheckDistanceForTurret )
            endif
            
            call SaveUnitHandle( H, GetHandleId( t ), 1, target )
            
            set t = null
        endif
    
        set target = null
    endif
    
    set caster = null
endfunction

private function PlayerPressedButton takes nothing returns nothing
    local integer i = GetPlayerId( GetTriggerPlayer( ) )
    
    set BUTTON_PRESSED[ GetHandleId( GetTriggerPlayerKey( ) ) ][i] = GetTriggerPlayerIsKeyDown( )
    
    if BUTTON_PRESSED[ GetHandleId( OSKEY_ESCAPE ) ][i] then
        set BUTTON_PRESSED_ESCAPE[i] = true
    endif
endfunction

private function TurretDeath takes nothing returns nothing
    local TurretS A = LoadInteger( H, GetHandleId( GetTriggerUnit( ) ), TurretStructKey )
    
    if A != 0 then
        call A.close( )
        call RemoveSavedInteger( H, GetHandleId( A.foundation ), TurretStructKey )
        
        if GetUnitTypeId( GetTriggerUnit( ) ) == 'h001' then
            call ShowUnit( A.foundation, false )
            call KillUnit( A.cockpit )
            call ShowUnit( A.cockpit, false )
            call KillUnit( A.weapon )
            call ShowUnit( A.weapon, false )
            call ShowUnit( A.main, true )
            call KillUnit( A.main )
            
            call FlushChildHashtable( H, GetHandleId( A.t ) )
            call DestroyTimer( A.t )
            
            set A.foundation = null
            set A.cockpit = null
            set A.weapon = null
            set A.main = null
            set A.t = null
            
            call A.v.destroy( )
            call A.destroy( )
        endif
    endif
endfunction

//===========================================================================

function RegistTurret takes unit u returns nothing
    local TurretS A = TurretS.create( )
    
    set A.caster = null
    set A.yaw = GetUnitFacing( u )
    set A.pitch = 0.00
    set A.v = vector.create( 0.00, 0.00, 0.00 )
    set A.t = CreateTimer( )
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    
    call ShowUnit( u, false )
    
    // створення турелі по частинам
    set A.foundation = CreateUnitEx( GetOwningPlayer( u ), 'h001', GetUnitX( u ), GetUnitY( u ), GetUnitFacing( u ) )
    set A.cockpit = CreateUnitEx( GetOwningPlayer( u ), 'h002', GetUnitX( u ), GetUnitY( u ), GetUnitFacing( u ) )
    set A.weapon = CreateUnitEx( GetOwningPlayer( u ), 'h003', GetUnitX( u ), GetUnitY( u ), GetUnitFacing( u ) )
    set A.main = u
    
    call SetWidgetLife( A.foundation, GetWidgetLife( u ) )
    
    call UnitEnableAutoOrientation( A.weapon, false )
    call SetUnitFlyHeightEnabled( A.weapon, true )
    
    call SetUnitFlyHeight( A.weapon, 100.00, 0.00 )
    
    call SaveInteger( H, GetHandleId( A.foundation ), TurretStructKey, A )
endfunction

function InitTrig_Turret takes nothing returns nothing
    local integer i = 0
    local unit u
    local trigger trgWASD = CreateTrigger( )
    local trigger trgDEAD = CreateTrigger( )
    local player p
    
    set gg_trg_Turret = CreateTrigger(  )
    set bj_groupEnumTypeId = 'h000' // равкод турелі
    
    loop
        set p = Player( i )
        
        call TriggerRegisterPlayerUnitEvent( gg_trg_Turret, p, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null )
        call TriggerRegisterPlayerUnitEvent( gg_trg_Turret, p, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null )
        call TriggerRegisterPlayerUnitEvent( gg_trg_Turret, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, null )
        
        call TriggerRegisterPlayerUnitEvent( trgDEAD, p, EVENT_PLAYER_UNIT_DEATH, null )
        
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_LBUTTON, META_KEY_NONE, true )
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_RBUTTON, META_KEY_NONE, true )
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_ESCAPE, META_KEY_NONE, true )
        
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_LBUTTON, META_KEY_NONE, false )
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_RBUTTON, META_KEY_NONE, false )
        call TriggerRegisterPlayerKeyEvent( trgWASD, p, OSKEY_ESCAPE, META_KEY_NONE, false )
        
        set TurretOpen[i] = false
        
        call GroupEnumUnitsOfPlayer( TempGroup, p, filterGetUnitsOfPlayerAndTypeId )
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            call RegistTurret( u )
        endloop
        
        set i = i + 1
        exitwhen i >= bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( gg_trg_Turret, function Turret_Actions )
    call TriggerAddAction( trgWASD, function PlayerPressedButton )
    call TriggerAddAction( trgDEAD, function TurretDeath )
endfunction
endlibrary


`
ОЖИДАНИЕ РЕКЛАМЫ...
13
О, помню игрушку простенькую, в детстве играл. Игрок управляет ДОТом на берегу моря, есть пулемет и пушка. И на игрока идут катера, вертолеты, самолеты, из катеров и самолетов высаживаются пехота и танки.
Просто идея: можно также доработать к финалу конкурса, для большей презентабельности.
Ответы (1)
28
AMark, мне лень просто карту оформлять да и новый конкурс от Павла стартовал, тоже хочется что-то выкатить вместе с Dragonlor
22
Ну это уже можно в варике Call of Duty делать или шутан прочий)
21
Можно наверное сделать что -то подобное и на простом варике. Камеру просто закрепить у отдельного юнита. Вот только как стрельба реализована?
Запретить не только автоатаку, но и вообще возможность атаковать и стрелять типа через способку?))
Ответы (8)
28
SсRealm, и как ты сделаешь движение камеры мышкой и стрельбу мышкой на обычном варе?)
Кста, спасибо что спросил за реализацию стрельбы, сейчас допишу
21
rsfghd, Понятное дело, что стрельбу мышкой скорее всего не осуществить. А так, это даже идея интересная, если сделать камеру от первого лица как в "Гран при Азерота" Установить камеру и прикрепить ее за юнитом транспортом, когда в него садится юнит.
Можно типа ГТА сделать. Обычная камера, когда человечек ходит. А когда в любой транспорт садится это уже вид от первого лица( или от третьего из за спины)
4
SсRealm, xgm.guru/p/wc3/inside_of_warcraft_mouse_position ещё 18 лет назад научились отслеживать мышь. Так что реально.
Впрочем, сделано это было на сторонних программах. Может, лучше вообще WC3 не подсоединять и перейти на другие проги?
21
human1, Куда, во второй старкрафт? Ты видел, что там в редакторе творится? Там чтобы простого юнита создать нужно хрен пойми что сделать.
Изучать unity - вообще вряд ли. Осталась только мысль делать игры для ретро консолей, вроде сеги или денди, но записывать игры на картриджи гемморойно:(
21
SсRealm, а зачем на картриджи? Есть же денди сега эмуляторы, для них можно делать) вряд ли сейчас кто то будет специально древнюю консоль покупать ради этого
Хотя, в игрушку тогда резонно будет встроить управление под USB версию денди/сега джойстика, если такие вообще существуют)
21
EugeAl, Потому что продать ром невозможно( в нашей стране точно)
А картридж, это уже другое дело. Он и стоить будет дороже и с кейсом и мануалом такой взять желающих будет точно достаточно.
В эмуляторы денди и Сеги играю, только джойстик для сеги уже нужен шестикнопочный для мк3( потому что с шифтами не удобно)
А уже с первой соньки начинаются проблеммы, потому что для некоторых игр эмулятор нужно подстраивать отдельно.
Закончу с вариком, может на старости лет займусь)
21
human1, ААА игру в одиночку не сделать.
Остались только двумерные Инди в стиле 80х -90х.
Можно замутить что -то вроде CupHead(a) Но я все - таки хотел бы ретро. Там меньше графики и больше простора для идеи в чистом виде, где ее точно оценят
21
Напомнило спец миссии в игрушке Armed and Dangerous, там садишься в похожую пушку и отражаешь толпы мобов, только пушка может ещё по полукруглой стене ездить влево вправо
Ответы (2)
28
EugeAl, именно, эту системку можно интересно доработать, чтобы один игрок, например, управлял исключительно пушкой, а другой движением какого-то механизма, впрочем, ничего не мешает и в соло режим это превратить, обычный first person shooter
21
rsfghd, ну там игрок стрелками или wasd пушку двигал по рельсам, здесь можно также. Кооп тоже годится, но обязательно кто нибудь из пары будет тупить)
А насчёт движения механизма - собственно управление Королевским Тигром в одной миссии первого Call of Duty )
Чтобы оставить комментарий, пожалуйста, войдите на сайт.