System Abduct

Jesus4Lyf

Good Idea™
Reaction score
397
Abduct​
Version 1.02​

Requirements:
- Jass NewGen
- AIDS
- Transport

Code:
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  ~~    Abduct     ~~    By Jesus4Lyf    ~~    Version 1.02    ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//  What is Abduct?
//         - Abduct allows a unit to load units of an enemy player.
//
//  Functions:
//         - SetAbductCapacity(unit, integer)
//           Sets the number of units a unit may abduct successfully
//           at once. Use a number from 1 to 8, excluding 7. Warcraft III
//           does not allow a transport to have a maximum capacity of 7.
//
//         - GetAbductCapacity(unit)
//           Returns the abduction capacity (integer) of the unit, based on
//           SetAbductCapacity.
//
//         - RemoveAbductCapacity(unit)
//           Disallows a unit to abduct other units.
//
//         - Abduct(abductor, target)
//           Returns a boolean of success. This success is anticipated.
//           There is a slight delay until the unit is actually abducted.
//           Use this to load an enemy unit into a transport. It will
//           interrupt the transport's current order.
//
//  Details:
//         - Abduct changes the target's owner for a small amount of time while
//           it is loaded into the abductor. It then changes ownership back.
//
//  How to import:
//         - Create a trigger named Abduct.
//         - Convert it to custom text and replace the whole trigger text with this.
//         - Save the map, close it, reopen it, and then delete the "!" from the
//           FAR left side of the next lines (so "external" will line up with this line):
//!           external ObjectMerger w3a Sch3 AACG ansf "(Abduct System)" aefs "" alev 8 Car1 1 1 Car1 2 2 Car1 3 3 Car1 4 4 Car1 5 5 Car1 6 6 Car1 7 7 Car1 8 8 aare 1 0 ahdu 1 0 adur 1 0 aran 1 99999 aran 2 99999 aran 3 99999 aran 4 99999 aran 5 99999 aran 6 99999 aran 7 99999 aran 8 99999 atar 1 "friend,ground,invulnerable,vulnerable" atar 2 "friend,ground,invulnerable,vulnerable" atar 3 "friend,ground,invulnerable,vulnerable" atar 4 "friend,ground,invulnerable,vulnerable" atar 5 "friend,ground,invulnerable,vulnerable" atar 6 "friend,ground,invulnerable,vulnerable" atar 7 "friend,ground,invulnerable,vulnerable" atar 8 "friend,ground,invulnerable,vulnerable" aare 1 256 aare 2 256 aare 3 256 aare 4 256 aare 5 256 aare 6 256 aare 7 256 aare 8 256
//!           external ObjectMerger w3a Aloa AALD ansf "(Abduct System)" aran 1 99999
//
//  Thanks:
//         - Weep, for reporting the Mac unload bug and suggesting a resolution.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library Abduct initializer OnInit uses AIDS, Transport optional DummyCaster
    globals
        private constant integer ABIL_CARGO='AACG'
        private constant integer ABIL_LOAD='AALD'
        private constant integer OID_LOAD=852046
    endglobals
    private struct Data extends array
        // Abductee
        player previousOwner
        // Abductor
        unit target
        integer capacity
        private method AIDS_onDestroy takes nothing returns nothing
            // Abductee
            if this.target!=null then
                call SetUnitOwner(this.target,Data[this.target].previousOwner,false)
                set this.target=null
            endif
            // Abductor
            set this.capacity=0
        endmethod
        //! runtextmacro AIDS()
    endstruct
    function GetAbductCapacity takes unit u returns integer
        return Data<u>.capacity
    endfunction
    
    globals//locals
        private Data OrderedData
    endglobals
    private function OnAnyOrder takes nothing returns boolean
        // Safety.
        set OrderedData=Data[GetTriggerUnit()]
        if OrderedData.target!=null then
            if GetIssuedOrderId()!=OID_LOAD or GetOrderTargetUnit()!=OrderedData.target then
                call SetUnitOwner(OrderedData.target,Data[OrderedData.target].previousOwner,false)
                call UnitRemoveAbility(OrderedData.unit,ABIL_LOAD)
                set OrderedData.target=null
            endif
        endif
        return false
    endfunction
    globals//locals
        private Data LoadedData
        private Data LoadingData
    endglobals
    private function OnLoad takes nothing returns boolean
        set LoadedData=Data[GetTriggerUnit()]
        set LoadingData=Data[GetTransportUnit()]
        if LoadingData.target==LoadedData.unit then
            set LoadingData.target=null
            call SetUnitOwner(LoadedData.unit,LoadedData.previousOwner,false)
            call UnitRemoveAbility(LoadingData.unit,ABIL_LOAD)
        endif
        return false
    endfunction
    globals
        private Data AbducteeData
        private Data AbductorData
    endglobals
    function Abduct takes unit abductor, unit abductee returns boolean
        set AbductorData=Data[abductor]
        if Transport_CountPassengers(abductor)&gt;=AbductorData.capacity then
            return false
        endif
        
        set AbducteeData=Data[abductee]
        
        // So it can be loaded.
        set AbducteeData.previousOwner=GetOwningPlayer(abductee)
        call SetUnitOwner(abductee,GetOwningPlayer(abductor),false)
        
        call UnitAddAbility(abductor,ABIL_LOAD)
        if IssueTargetOrderById(abductor,OID_LOAD,abductee) then
            if AbductorData.target!=null then
                call SetUnitOwner(AbductorData.target,Data[AbductorData.target].previousOwner,false)
            endif
            set AbductorData.target=abductee
            return true
        endif
        // upon failure
        call SetUnitOwner(abductee,AbducteeData.previousOwner,false)
        call UnitRemoveAbility(abductor,ABIL_LOAD)
        return false
    endfunction
    
    function SetAbductCapacity takes unit u, integer cargo returns nothing
        debug if cargo==7 then
        debug   call BJDebugMsg(&quot;Transport: WARNING! 7 is an invalid transport capacity in Warcraft III.&quot;)
        debug endif
        call UnitAddAbility(u,ABIL_CARGO)
        set Data<u>.capacity=SetUnitAbilityLevel(u,ABIL_CARGO,cargo)
    endfunction
    function RemoveAbductCapacity takes unit u returns nothing
        call UnitRemoveAbility(u,ABIL_CARGO)
        set Data<u>.capacity=0
    endfunction
    
    private function OnInit takes nothing returns nothing
        local trigger t
        
        // Preload
        static if LIBRARY_DummyCaster then
            if UnitAddAbility(DUMMY,ABIL_LOAD) then
                call UnitRemoveAbility(DUMMY,ABIL_LOAD)
            endif
            if UnitAddAbility(DUMMY,ABIL_CARGO) then
                call UnitRemoveAbility(DUMMY,ABIL_CARGO)
            endif
        else
            local unit u=CreateUnit(Player(15),&#039;uloc&#039;,0,0,0)
            call UnitAddAbility(u,ABIL_LOAD)
            call UnitAddAbility(u,ABIL_CARGO)
            call RemoveUnit(u)
            set u=null
        endif
        
        // On load event.
        set t=CreateTrigger()
        call TriggerAddCondition(t,Filter(function OnLoad))
        call Transport_RegisterLoadEvent(t)
        
        // On any order.
        set t=CreateTrigger()
        call TriggerAddCondition(t,Filter(function OnAnyOrder))
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ISSUED_ORDER)
        
        set t=null
    endfunction
endlibrary
</u></u></u>

This allows you to force load an enemy unit into a transport unit. It makes a good replacement for Devour, as you can trigger the effects yourself, and unload the loaded units at will instead of forcing them to remain until they die. It also allows you to load multiple units at once (unlike Devour). In addition, you can call this from whatever context you like (not just as an ability).

Example:
Add a single footman to a map and it will abduct enemies instead of attack them with this code.
JASS:
scope AbductDemo initializer OnInit
    private function OnAttack takes nothing returns boolean
        if Abduct(GetAttacker(),GetTriggerUnit()) then
            call BJDebugMsg(GetUnitName(GetAttacker())+&quot; has abducted &quot;+GetUnitName(GetTriggerUnit())+&quot;.&quot;)
        else
            call BJDebugMsg(GetUnitName(GetAttacker())+&quot; failed to abduct &quot;+GetUnitName(GetTriggerUnit())+&quot;.&quot;)
        endif
        return false
    endfunction
    private function OnInit takes nothing returns nothing
        local trigger t=CreateTrigger()
        local unit footman=GroupPickRandomUnit(GetUnitsOfTypeIdAll(&#039;hfoo&#039;))
        call SetAbductCapacity(footman,2)
        
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddCondition(t,Filter(function OnAttack))
    endfunction
endscope
Use the Transport functions to iterate over all units abducted by a unit, or detect when a unit is released, etc. :)

Updates:
- Version 1.02: Fixed a bug where Mac users could not unload Abducted units. Fixed a typo in a debug message.
- Version 1.01: Added GetAbductCapacity and optional DummyCaster use for preloading.
- Version 1.00: Release.
 

Attachments

  • Abduct.w3x
    46.5 KB · Views: 262

black.sheep

Active Member
Reaction score
24
Possible for the unit to fight back?

Anyway, I could use this for some crazy blob like monster in my map that can eat people, should be fun.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Anyway, I could use this for some crazy blob like monster in my map that can eat people, should be fun.
Actually, this was inspired by the Blob model NullCurrent released a while ago. Funny that we think the same...

Look at the features in Transport and you'll see they tie in closely as well. :)

>Possible for the unit to fight back?
Not once abducted, of course... you trigger when the abduction happens yourself though, so that should not be an issue. ;)
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
om nom nom nom nom

Shouldn't this be integrated into Transport?
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
Shouldn't this be integrated into Transport?
Nah, there's no reason to build two systems together just because one can detect actions carried out by the other. It makes sense with things like damage detection systems where, for full functionality, you must monopolize on on a gameplay element (such as spell-inflicted damage). But this isn't such a case. Transport does not need to specifically control transportation in order to properly detect transportation-related stuff.


On the other hand, I haven't tested it; does transport properly detect the owner of a unit being transported via Abduct? If not, I suppose there is at least some argument for making the systems recognize each other better.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>On the other hand, I haven't tested it; does transport properly detect the owner of a unit being transported via Abduct?
Considering that Abduct is a function called by the mapper, not something natural that happens in gameplay, I don't think this is an issue...
I could add a function to get the true owner of an abducted unit, but at the moment, I expect when the OnLoad event fires, the abducted unit's owner will be the transport's owner... =/

I was originally going to integrate them, but then figured it was overkill to have objectmerger stuff in transport.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
How come, in your demo map, when I try to drop an abducted peasant, it says, "Unable to land there," and won't unload it?
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
Replay attached, Mac/1.24c beta.
[edit] Same result in 1.24b.
 

Attachments

  • AbductError.w3g
    1.6 KB · Views: 248

Weep

Godspeed to the sound of the pounding
Reaction score
400
Edit: What if you have a blank map with just Transport implemented, a goblin zeplin and a footman? Can you unload the footman?
Yes, the Transport demo map works fine.

[edit] I don't know if this makes any difference or is intentional, but in the Abduct map, the footman does not have any load/unload buttons - the only way to drop (which fails for me) is to click on the abducted unit's portrait in the unit status box area thing.
 

Tru_Power22

You can change this now in User CP.
Reaction score
144
Very cool +rep.

Was reading the documentation, I lol'd at the fact that you can't load 7 units.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Lol, thanks. :)
Was reading the documentation, I lol'd at the fact that you can't load 7 units.
Yea... well you can load 7 units but that can't be the maximum capacity - it must be 8. Wtf? :p WC3 thing.

>Was reading the documentation
Always good to hear. ;)

Edit:
>I don't know if this makes any difference or is intentional, but in the Abduct map, the footman does not have any load/unload buttons - the only way to drop (which fails for me) is to click on the abducted unit's portrait in the unit status box area thing.

Tried getting your replay to work but couldn't. <_< It just wouldn't find the map...

Hm, when I run the map I also don't have an unload button, but it doesn't seem to matter. I click the portrait of the peasant, and it unloads fine... Mac issue?

Let me know if you find a solution. Perhaps adding the unload ability. If it works with the unload ability, but disabled for that player, I can add that as a fix (or something)... :)
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
Tried getting your replay to work but couldn't. <_< It just wouldn't find the map...
Yeah, I test maps from a different folder. It was a boring replay anyway - the error text didn't even show up in playback. :p

The problem is with the AOE of your Cargo Hold ability. Too low, and it gives an error when attempting to drop. This seems to be related to the collision sizes of the units, but I don't know how (eg. 85 was not enough to drop a Blood Mage from a Footman, but 90 was; 90 was not enough to drop an Infernal from a Footman, but 125 was.)
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
The default is 250, so, sure...

[edit] Abduct 1.02 works.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top