• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Help with custom turret system

Status
Not open for further replies.
Hi.
I just made a turret system for the ships in WiF, which will use dummy turret units with positions automatically adjusted to their position on the ship every 0.033 seconds. However, i am experiencing a lot of trouble with this.

here is the script:

JASS:
library Ship requires ListModule

globals
      private constant real TIMER_INTERVAL = 0.045
endglobals

   struct turret

     implement List
    
     real z
     real ang
     real dist
     unit turret
     unit ship

     private static location height
     private static timer interval

     private static method setTurrets takes nothing returns nothing
         local thistype this = .first
         local real x
         local real y
         local real a 
         local real z
         
         loop
             exitwhen this == 0      
             
             call MoveLocation(.height, GetUnitX(.turret), GetUnitY(.turret))
             set z = GetLocationZ(.height)  //At first, i used this to obtain the corrected height of the unit, but it turned out wrong. Explanation below.

             call ClearTextMessages()  //just debug
             call BJDebugMsg(R2S(GetUnitFlyHeight(.turret)))

             set a = ModuloReal(GetUnitFacing(.ship)+.ang, 360)
             set x = GetUnitX(.ship) + .dist * Cos(a * bj_DEGTORAD)
             set y = GetUnitY(.ship) + .dist * Sin(a * bj_DEGTORAD)
             
             set a = ModuloReal(GetUnitFacing(.ship)-GetUnitFacing(.turret), 360)
             call SetUnitX(.turret, x)
             call SetUnitY(.turret, y)
             call SetUnitFacing(.turret, a)
             call SetUnitFlyHeight(.turret, .z, 0)
             
             if .count < 1 then
                call PauseTimer(.interval)
             endif
             
             set this = .next
         endloop
     
     endmethod
     
     static method create takes integer unitid, real x, real y, real z, real ang, real faceang, real dist, unit ship returns turret
         local thistype this = thistype.allocate()
         local unit u = CreateUnit(GetOwningPlayer(ship), unitid, x, y, ModuloReal(faceang+GetUnitFacing(ship), 360))
         
         call UnitAddAbility(u, 'Aloc')
         
         call .listAdd()
                     
         set .ang = ang
         set .dist = dist
         set .ship = ship
         set .turret = u
         set .z = z
  
         if .count == 1 then
             call TimerStart(.interval, TIMER_INTERVAL, true, function thistype.setTurrets)
         endif
        
            return this
     endmethod


     private method onDestroy takes nothing returns nothing
         call .listRemove()
         set .ship = null  //While we're at it, i don't actually need to null theese, do i? I mean, they are technically inside a global array?
         set .turret = null
     endmethod
     
     private static method onInit takes nothing returns nothing
         set .interval = CreateTimer()
         set .height = Location(0, 0)
     endmethod
     
   endstruct


endlibrary

and here is the script for attaching turrets to the units:

  • Turret Spawn
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
    • Actions
      • Custom script: local turret T
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Unit-type of (Triggering unit)) Equal to (==) Cruiser (Graf Spee)
          • Then - Actions
            • Custom script: set T = turret.create( 'h01I', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 33, 0, 0, 120, GetTriggerUnit() )
            • Custom script: set T = turret.create( 'h01I', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 33, 180, 0, 120, GetTriggerUnit() )
          • Else - Actions
First of all, the height of the turrets keep screwing up. They will lift off when the ship moves closer to land and just generally won't stay in one spot. I tried using the storm crow glitch and use ground movement type instead, but i'm not sure it did any difference, and besides, the ship then started "stumbling" on the turrets and had trouble moving (the ships in this man have very large collision).

Second, despite that the calculation for the polar coordinate seems correct, the turrets seem to end up slightly to the side of the model instead of the center, and just feels generallt illusive.

Third and last, when i move hte unit, i must also change the facing of the turret to match the rotation of the ship itself. My intention was for the turret to have the same relative angle towards the ship when the ship rotates, but instead, the turrets will face a set angle and spin around towards this angle as the ship moves.
What i would like help to achive is this: If the turret is attacking, it will ofcourse be facing the target. When no enemies are nearby, it will be facing forwards (in the same angle as the ship). When attacking, the turret will turn around by itself, but how do i make it so that it always faces forwards otherwise?


Any help greately appreciated.
 
Level 7
Joined
Apr 1, 2010
Messages
289
well, you could add in a check to see if the turret the turrets current order=attack
to make so that it won't change its facing while attacking,
for the turret i would advise using a structure that has a hidden root ability
JASS:
set a = ModuloReal(GetUnitFacing(.ship)-GetUnitFacing(.turret), 360)
the problem with this is it is the "ships" facing - the turrets facing you will encounter a problem with negative numbers, you should just set it to the Ships facing + whatever angle offset you want.
using a structure that has Root should fix the problem with it spinning.
edit1: sorry if i didn't explain what i meant. you should add a check to see if it is attacking, then if it wasn't attacking you should change its facing to the ships.
for the flying height you don't need to change it(i think) except when it is near a shore that uses warcraft 3's cliffs
 
Last edited:
What "ModuloReal" does is basically to make sure that you DONT get negative numbers for angles, so that is already taken care of.

And ofcourse, i do want it to change facing when attacking, otherwise it would look wierd.
What i want is for it to inherit the facing of the boat when it is not attacking.

My biggest problem though is that the height of the turret is not properly set, as i don't know how to retrieve the proper height when it is on water.
 
Status
Not open for further replies.
Top