• 🏆 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!

AttachObject v2.05

full





NB: Make sure you download the proper version! v2+ handles special effects attachment. Anything below that is not able to do that.

v2.00 and newer versions are not backward compatible with previous versions of AttachObject (they would be called AttachUnit). This is because of some changes to main functions code to make it easier to customise, but also to accommodate attaching special effects. My apologies for any inconvenience caused.

12/04/2024
Added the older version AttachUnit v1.02 upon request.

-v2.05
- Fixed an issue which was causing Guests to appear as Hosts.​
-v2.04
- Fixed an issue with attached unit Guests updating their z axis to the incorrect value​
- Fixed an issue with attached special effect Guests failing to update their yaw (facing)​
-v2.03
- Removed LinkedList and ListItem structs as they were buggy.​
- ListT is now a requirement for AttachObject to function.​
- Updated documentation to match​
-v2.02
- Fixed a bug that was prevent re-hosting of existing guests to attach properly.​
- DettachUnit() now takes 3 arguments rather than 2. A boolean parameter is now needed to tell the system whether to reset the unit's height or not upon Dettachment. This was needed to prevent re-hosted guests to reset their heights as their are being changing hosts.​
- LinkedList struct has a new .empty() member to return whether a list is empty or not.​
- Updated test map to use RiseAndFall v1.05.​
- Updated documentation.​
- [UPDATE] re-uploaded test map to fix issues with Demo code as well as updating RiseAndFall to v1.05. There has been no change to the AttachObject library itself.​
- v2.01
- DettachGuest() replaced with DettachUnit().​
- Added GetGuestList()​
- Guest and Host are private structs. GuestEx will now be the main reference for the Guest struct.​
- Add functions that previously took Guest or returned Guest instances now take or return GuestEx instead.​
- Added EffectTimed struct for destroying special effects.​
- Updated documentation with all the new features and changes.​
- v2.00 Library renamed to AttachObject and now supports attaching special effects. Unit Event was also removed as a dependency as it was unnecessary. Now uses a linked list for better performance when removing attached Guests. Not backward compatible.
- v1.01 added functions to hide and unhide guests. Those functions are called automatically when loading into or unload from a transport but now requires Unit Event by Bribe.
- v1.00 initial release
Contents

Attach Unit v1.02 (Map)

AttachObject v2.05 (Map)

Reviews
MyPad
I see that the resource has been updated with the points being addressed. Knowing that it is now at a state where refinement isn't really needed, and that I took a glance and could not find a logical flaw (quick search), I will approve this now...

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,886
Well yeah this idea is quite interesting and fun :D
There's no reason to not use WEX. I've never had any issues with it and I've been using it this entire time. You should give it a try :)
Well the majority of people don't use WEX, so you're kind of limiting yourself.
But since we're talking about WEX, why isn't this compiling with my WEX? I disabled and re-enabled all triggers related to system and always had the same error: line 30: Unknown compile error (Syntax error). apparently it happens on the lines like library AttachObject /* and library Alloc /* v1.3.1.1.
And I have jasshelper and vJass compilers enabled...
 
UPDATED to v2.01
- v2.01
- DettachGuest() replaced with DettachUnit().
- Added GetGuestList()
- Guest and Host are private structs. GuestEx will now be the main reference for the Guest struct.
- Add functions that previously took Guest or returned Guest instances now take or return GuestEx instead.
- Added EffectTimed struct for destroying special effects.
- Updated documentation with all the new features and changes.​

Well yeah this idea is quite interesting and fun :D
Glad you think so :)

Well the majority of people don't use WEX, so you're kind of limiting yourself.
But since we're talking about WEX, why isn't this compiling with my WEX? I disabled and re-enabled all triggers related to system and always had the same error: line 30: Unknown compile error (Syntax error). apparently it happens on the lines like library AttachObject /* and library Alloc /* v1.3.1.1.
And I have jasshelper and vJass compilers enabled...
That actually sounds like it's the non-WEX users that's limiting themselves. I'm not sure what would be causing that problem (I've never encountered it before), but have you updated WEX to v0.1.3.1 and updated the addresses.xml file? That's all it took for me to get my WEX to work. Hopefully that should fix the issue. Otherwise you might have better luck asking on the Sharpcraft thread.
 
Last edited:
Updated to v2.02
-v2.02
- Fixed a bug that was prevent re-hosting of existing guests to attach properly.
- DettachUnit() now takes 3 arguments rather than 2. A boolean parameter is now needed to tell the system whether to reset the unit's height or not upon Dettachment. This was needed to prevent re-hosted guests to reset their heights as their are being changing hosts.
- LinkedList struct has a new .empty() member to return whether a list is empty or not.
- Updated test map to use RiseAndFall v1.05.
- Updated documentation.​
 
Level 3
Joined
Oct 9, 2012
Messages
28
It's a function similar to UnitAlive that has to be declared somewhere in your map for it to be able to be called. There are a few of those like that, BlzGetUnitMovementType being one of them. It takes a unit and returns an integer, which determines the movement type.
But I can find UnitAlive declared in common.ai, so it make sense. but where is BlzGetUnitMovementType?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
It's a function similar to UnitAlive that has to be declared somewhere in your map for it to be able to be called. There are a few of those like that, BlzGetUnitMovementType being one of them. It takes a unit and returns an integer, which determines the movement type.
How did you discover that? And are there any more?
 
I... actually don't remember where I found that function. It was a while ago. I also remember finding out about around the same time how to retrieve gold and lumber cost of a unit by declaring specific natives:
JASS:
native GetUnitGoldCost takes integer unitId returns integer
native GetUnitWoodCost takes integer unitId returns integer
I assume those are in common.ai, and that BlzGetUnitMovementType is a new 1.29 that didn't quite make the cut and is probably listed somewhere else.
 
Level 7
Joined
Oct 9, 2020
Messages
35
Hi Spellbound. I have been testing your AttachObject system to see if it will work with a project that I am working on. For the most part, it's working great, but I did run into a few issues. Would you (or anyone else with the know-how) mind helping me out?

I have a Horse Archer unit that I want to behave like a mobile turret, so naturally I have Riderless Horse = host unit and Archer = guest unit. The issues I am having are as follows:
  • When a host dies, there is a chance that other host/guest combinations on the map will have their movements decoupled, meaning the guest is stationary even when the host is moving. The strange thing is is that the unit facing is still coupled, so the guest will still turn to match the host facing, but will not move with the host. Here is my initialization trigger and screenshot to give you an idea of what's happening. Maybe you can see if I am doing anything wrong.
upload_2020-11-18_9-56-46.png


WC3ScrnShot_111820_091533_01.png
  • There is a slight lag spike when dettaching a guest when a host dies. For a single unit this isn't that big of a deal, but I can foresee this being problematic if many host units are killed at around the same time. To be clear, the guest dies with the host (set the timed-life parameter to 0.01 as instructed).
  • I want to synchronize orders of the guest with the host, but still have the guest able to attack while the host is moving, i.e. have guest attack what host is attacking, have guest stop attacking when host is ordered to stop, etc. Does your system have built in support for this? I can figure out a way to do this, but I didn't want to proceed with my triggers if a simple solution to this already exists.
Thanks!
 
Hmm, can you PM me the map? Not sure I can debug this from here.

EDIT: Okay, so it would appear that the LinkedList struct provided with AttachObject isn't coded properly (whoopse), so the solution would be to just use ListT. It provides better performance, anyway. I'll update the resource to remove LinkedList and make ListT mandatory since I don't have time to update it.
 
Last edited:
Level 4
Joined
May 19, 2020
Messages
319
Perfect! This can be great for creating archer towers, having the animated representation of the Tower with each unit collected, The Settlers III style (see attachment), being able to stack units on the Tower and increasing its attack capacity by the number of units stacked, style Orc Burrow.
maxresdefault.jpg
 
That is indeed weird. There's no reason anything should get hidden at all, given that at no point in DettachObject (DettahUnit calls that function) does any hiding. Are you using the latest version of the system? v2.02 was still optionally using the in-built linked list, which had a bug. v2.03 now uses ListT as a dependency.
 
That is indeed weird. There's no reason anything should get hidden at all, given that at no point in DettachObject (DettahUnit calls that function) does any hiding. Are you using the latest version of the system? v2.02 was still optionally using the in-built linked list, which had a bug. v2.03 now uses ListT as a dependency.
Well I guess the unit its attached too also sort of dies... Currently there's a players unit that gets attached to an enemy unit which later unattaches the player unit and expires after about a minute. There is also up to 50-100 extra enemy units that attach to the player unit eventually. The problems are the players unit getting stolen/hidden by the system and the extra enemy units along with it. When the system does work, the player doesn't get stolen however the extra enemy units also got deattached even though they weren't suppose too.

Edit: Yes am using the latest version copied from the trigger view of the hive upload spot.
 
The system will not hide the Host itself, only the Guests IF the Host is hidden, so if the host is being hidden then either it's because it's being Hosted on something that becomes hidden or something else is hiding the Host like entering a transport.

As for DettachObject(), the only times the system calls it is if you are trying to attach a unit that is already attached to another Host (it will decouple it and couple it with the new Host) or if a Guest dies. I've looked at the code and I don't really see anything that would be causing that kind of behaviour.
 
Looks like Mana Flare is activating some sort of pathing flag on the Faerie Dragon, which is causing the Hosts's movement to glitch because I assume it's constantly recalculating as the 'obstacle' moves with it. It's what happens to Guests when if they're not given the Ghost (Visibile) ability, which the system does automatically.

I've tried manually turning off unit collision when Mana Flare is activated/deactivated but that didn't seem to do anything. It's especially odd because the Faerie Dragon's movement type is Flying, which regardless of whether Mana Flare is on or not should be interfering with Foot movement type...
 
Level 2
Joined
Jul 8, 2020
Messages
10
interesting!😃 but, how can i download old version in 1.3X or 1.2X, not Reforged😶
 
Level 2
Joined
Jul 8, 2020
Messages
10
Thank you for your reply. you're so helpful. much appreciated.
I'm not sure how the versioning works if you don't own Reforged but my understanding is that this should still work with 1.32 in SD. If you're looking for a version that was before the new native functions (like moving special effects), you can try AttachUnit v1.02
Thank you for your reply. you're so helpful. much appreciated.
🙂
 
Level 7
Joined
Oct 9, 2020
Messages
35
Hey Spellbound, I think the zOffset might be bugged? On my original test map, the cliff height was level 2 on flat terrain and it seemed to be fine. However, when I tested it later on varied terrain and cliff heights, the guest will appear to float in the air on high cliffs and terrain, and will appear to sink to the ground on lower cliffs and terrain. It is as if the zOffset of the guest is being overcorrected when syncing to the host.

I have attached examples of the issue below. I have tried all of the different movement types for the guest (fly, float, hover, etc.), but it doesn't seem to make a difference. Thoughts?

screenshot1.pngscreenshot2.png

Edit: I just tested your Mountain Giant with Archers demo and it has the same zOffset issue with high and low terrain.
 
Last edited:
That... makes no sense. I'm not sure why it's behaving this way but the offset values seem to work fine with special effects, so I'm at a loss at what's causing this. I did, however, notice that I forgot to take the host's fly height into consideration (which did not solve the issue), so at the very least this particular problem has been identified. I'll keep looking.

EDIT: OKAY, problem identified, although now I need separate behaviour for effect z and unit z. Will update later.

EDIT 2: Issue identified and solved.

-v2.04
  • Fixed an issue with attached unit Guests updating their z axis to the incorrect value
  • Fixed an issue with attached special effect Guests failing to update their yaw (facing)
 
Last edited:
Level 7
Joined
Mar 16, 2014
Messages
152
Great system.

A few things: 1: Any idea how to make guest units play walk animation alongside the host unit when it walks?
2: More importantly, the flying height fails if the unit transforms into another unit with a metamorphosis or bear form ability. Simply having a metamorph ability is enough to make a unit unable to fly when picked up as a guest, for some reason. No transformation required.
3: When the host's flying height gradually changes in a trigger, the guest's flying height changes instantly. So if the host is using a jump ability, the guest will appear instantly at the top of the jump, then instantly at the bottom of the jump, rather than smoothly moving with the host.
 
1: Simplest way I can think of is to simply track when a Host is moving and then grab all attached guests and order them to play their walk animation. When the Host stops, have the Guests play their stand animation.

2: non-flying Guests use the Storm Crow Form trick gain the ability to change their fly height. From what you're describing I would assume a morph ability would be interfering with this. I'm not sure there's a solution for this beyond making those specific units unable to attach as Guests or not have this morph ability.

3: a Guest's flying height is changed based on the Host's own flying height. From your description, it seems that changing a unit's fly height regardless of rate will alter that value instantly. The only fix to this is to not use Blizzard's native rate of change but to have a system that does this manually.
 
Level 7
Joined
Mar 16, 2014
Messages
152
1: Simplest way I can think of is to simply track when a Host is moving and then grab all attached guests and order them to play their walk animation. When the Host stops, have the Guests play their stand animation.

2: non-flying Guests use the Storm Crow Form trick gain the ability to change their fly height. From what you're describing I would assume a morph ability would be interfering with this. I'm not sure there's a solution for this beyond making those specific units unable to attach as Guests or not have this morph ability.

3: a Guest's flying height is changed based on the Host's own flying height. From your description, it seems that changing a unit's fly height regardless of rate will alter that value instantly. The only fix to this is to not use Blizzard's native rate of change but to have a system that does this manually.
On 2, entirely with the test map, as soon as a demon hunter learns metamorph, his flying height will be stuck at 0 instead of what the system wants it to go at. He does not even have to cast it, merely learning the ability is enough.

ekSTDQG.png
 
Level 5
Joined
Oct 16, 2018
Messages
57
It can be done in GUI easily with one or two lines of custom script:
  • GUI Example
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of UDexUnits[UDex]) Equal to Spell Breaker
        • Then - Actions
          • Set host = UDexUnits[UDex]
          • Set TempLoc = (Position of host)
          • Unit - Create 1 Faerie Dragon for (Owner of host) at TempLoc facing Default building facing degrees
          • Set guest = (Last created unit)
          • Custom script: call AttachUnitToHost(udg_guest, udg_host, 0., false, GetUnitFacing(udg_host), 0., 200., -16.)
          • Custom script: call SetGuestFacingProperties(udg_guest, GetUnitFacing(udg_host),10., 4., false, true)
          • Custom script: call RemoveLocation(udg_TempLoc)
        • Else - Actions
Refer to the API section of the code to know what argument does what. It's a bit messy in GUI because of no syntax-highlighting, but it's pretty simple.
JASS:
call AttachUnitToHost takes unit guest, unit host, real angle, boolean staticAngle, real angleFacing, real distance, real zOffset, real offsetFix
            ^ This function will attach a unit to a host.
       
            [_ARGUMENTS_]
            unit guest              - the unit to attach (aka the Guest)
            unit host               - the Host
            real angle              - the angle relative to the Host's facing angle at which the Guest is offset to.
            boolean staticAngle     - if true, the Guest's angle offset will ignore the Host's facing direction
            real angleFacing        - the starting facing angle of the Guest
            real distance           - the distance between the Host and the Guest
            real zOffset            - the height difference from the Host
            real offsetFix          - if your Guest is off-center, try setting this to -16 or 16.
       
       
        call SetGuestFacingProperties takes unit guest, real startAngle, real rate, real cooldown, boolean dynamicFacing, boolean turretMode
            ^ This sets an attached unit's facing properties. If this is not called, the unit will always face the same direction.
       
            [_ARGUMENTS_]
            unit guest              - the attached unit (aka Guest)
            real startAngle         - the angle at which the Guest begins at. If dynamicFacing is false, the guest will always face this specific angle.
            real rate               - the speed at which the Guest rotates over time. Set to zero to ignore.
            real cooldown           - this is neccessary if the Guest can attack. It will resume it facing parameters after that cooldown has expired.
            boolean dynamicFacing   - if this is true, the facing angle of the Guest will depend on the facing of the Host.
            boolean turretMode      - Set this to true if you want your Guest to be able to attack. Otherwise, the facing parameters will keep interferring.

Hope that helps!

im a GUI user, pls assist me.
i dont understand these stuff, i want to say when Knight casts Mount on Horse then attach that knight to Horse but lack the ability to do this myself :ugly:
there are over 10 units that have the Mount ability, and after a unit Mounted a Horse then if they cast Dismount then dismount the unit from horse.
sorry for bad english, hope you understand my meaning, and HELP.
 
Last edited:
Why not just use the default Mount Hippogryph ability? With AttachObject your Knight is still going to be selectable. Mount Hippogyph will actually combine the two units into one. It's also a lot easier than using this library if you're unfamiliar with JASS/vJASS 😅

That being said, if you've already thought this through and still want to use this, then you'll want to attach/detach on spell effect, so start your event with:
  • Events
    • Unit starts the effect of an ability
  • Conditions
    • Or
      • Ability being cast equals to Mount
      • Ability being cast equals to Dismount
  • Actions
    • Set caster to triggering unit
    • Set target to target unit of ability being cast
    • If
      • Ability being cast equal to Mount
    • Then
      • If
        • udg_target has ability Mountable
      • Then
        • Custom Script: call AttachUnitToHost(udg_caster, udg_target, 0., false, GetUnitFacing(target), 0., 60., 0.)
        • Custom script: call SetGuestFacingProperties(udg_caster, GetUnitFacing(udg_target),0., 0., true, false)
        • -------- If you want the Knight to be attacking while the Horse is running around, use this instead --------
        • Custom script: call SetGuestFacingProperties(udg_caster, GetUnitFacing(udg_target),1., 1., true, true)
        • -------- this will prevent other units from Mounting on the Horse which it's already being ridden --------
        • remove Mountable from Horse
      • Else
    • Else
      • -------- If the Horse is the one to cast Dismount --------
      • Custom Script: call DettachAllGuests(udg_caster, true, 0.)
      • add Mountable to Horse // so it can be Mounted again in the future
      • -------- if the Knight is the one to cast Dismount. 'A000' is an example of an ability ID. In this context, you need to put the Mountable ability id --------
      • Custom Script: call UnitAddAbility(GetHost(GetGuestUnitId(udg_caster)), 'A000')
      • Custom Script: call DettachUnit(udg_caster, true, 0.)
 
Level 5
Joined
Oct 16, 2018
Messages
57
Hello, for those who are working with 1.26 and older, here is a version that works with that AttachObject

Note, this verison does not work with special effects.
what are those Expected end of line errors?
-
Edit*: just found that your file is not working in warcraft 1.26.
it was not letting me play my map so i turned all 26 Expected end of line errors to comment // and then it issued another 1400 end line errors.
 
Last edited:
Level 11
Joined
Jul 4, 2016
Messages
627
what are those Expected end of line errors?
-
Edit*: just found that your file is not working in warcraft 1.26.
it was not letting me play my map so i turned all 26 Expected end of line errors to comment // and then it issued another 1400 end line errors.
it is working for me, you have to use a third party editor in 1.26 such as JGNP or sharpcraft if you are getting errors.
 
Level 5
Joined
Oct 16, 2018
Messages
57
Why not just use the default Mount Hippogryph ability? With AttachObject your Knight is still going to be selectable. Mount Hippogyph will actually combine the two units into one. It's also a lot easier than using this library if you're unfamiliar with JASS/vJASS 😅

That being said, if you've already thought this through and still want to use this, then you'll want to attach/detach on spell effect, so start your event with:
  • Events
    • Unit starts the effect of an ability
  • Conditions
    • Or
      • Ability being cast equals to Mount
      • Ability being cast equals to Dismount
  • Actions
    • Set caster to triggering unit
    • Set target to target unit of ability being cast
    • If
      • Ability being cast equal to Mount
    • Then
      • If
        • udg_target has ability Mountable
      • Then
        • Custom Script: call AttachUnitToHost(udg_caster, udg_target, 0., false, GetUnitFacing(target), 0., 60., 0.)
        • Custom script: call SetGuestFacingProperties(udg_caster, GetUnitFacing(udg_target),0., 0., true, false)
        • -------- If you want the Knight to be attacking while the Horse is running around, use this instead --------
        • Custom script: call SetGuestFacingProperties(udg_caster, GetUnitFacing(udg_target),1., 1., true, true)
        • -------- this will prevent other units from Mounting on the Horse which it's already being ridden --------
        • remove Mountable from Horse
      • Else
    • Else
      • -------- If the Horse is the one to cast Dismount --------
      • Custom Script: call DettachAllGuests(udg_caster, true, 0.)
      • add Mountable to Horse // so it can be Mounted again in the future
      • -------- if the Knight is the one to cast Dismount. 'A000' is an example of an ability ID. In this context, you need to put the Mountable ability id --------
      • Custom Script: call UnitAddAbility(GetHost(GetGuestUnitId(udg_caster)), 'A000')
      • Custom Script: call DettachUnit(udg_caster, true, 0.)
how do i?:
action: pick the Horse of the knight and then tell the Horse to move to the issued order point :grin:
 
Can I get the older versions, Attach Unit system?
I've uploaded it to this page. Check the Contents section for AttachUnit v1.02
PS: I'm not sure if this version is working correctly or not because it was never uploaded here. If you find any bugs I will downgrade it to v1.01, which was uploaded here before I moved to v2.00.
 
Top