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

Replacing Units and Item Charges

Status
Not open for further replies.
Level 2
Joined
May 10, 2019
Messages
18
Hi everyone,

What I'm trying to do is replace a unit with another unit using the GUI's Unit - Replace function, and I'd like to preserve the original unit's inventory. Here's the code I have so far to preserve the inventory.

  • For each (Integer A) from 1 to 6, do (Actions)
    • Loop - Actions
      • Set VariableSet transferitems[(Integer A)] = (Item-type of (Item carried by Unit_Advance in slot (Integer A)))
This stores the items from each item slot into the variable array transferitems. I then replace the unit. Then I run this:

  • Set VariableSet Unit_Replaced = (Last replaced unit)
  • For each (Integer A) from 1 to 6, do (Actions)
    • Loop - Actions
      • Set VariableSet transferitempos = (Position of Unit_Replaced)
      • Item - Create transferitems[(Integer A)] at transferitempos
      • Hero - Give (Last created item) to Unit_Replaced
      • Custom script: call RemoveLocation(udg_transferitempos)
The trigger above is working as expected.

The issue I'm running into is that I'm not quite sure how to manage items with charges. This trigger above only creates a single item. Does anyone have any advice for a trigger that handles item charges?
 
Level 2
Joined
May 10, 2019
Messages
18
use this:

Item - Set charges remaining in (x) to ((Charges remaining in (y)))

Thank you so much for the reply. I did see this trigger and thought it could help in some way. Where I was getting confused is where it should be implemented within the larger structure.

For example, in the first set of triggers do I need to do something like this:

  • For each (Integer A) from 1 to 6, do (Actions)
    • Loop - Actions
      • Set VariableSet transferitems[(Integer A)] = (Item-type of (Item carried by Unit_Advance in slot (Integer A)))
      • Set VariableSet transferitems_charges[(Integer A)] = (Charges remaining in (Item carried by Unit_Advance in slot (Integer A)))
Or something completely different?
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
that seems right. of course you would need to add that to the second part of the trigger too.

a few notes about your trigger -

not really a big deal, but it would be better to have the creation and destruction of "transferitempos" be out of the loop (before and after). no reason to do this 6 times.

you could do the entire transfer at once if you create the new unit before destroying the old one- then just make the old unit drop each of it's items and give them to the new unit all in one "for" loop. you might need to save the original position of the first unit and move the new unit there after you destroy the first unit - this would be to compensate for collision. the fact that both of them existed at the same time would not be noticeable, as being in one trigger it would happen too fast to see. - not necessarily better than what you have now, but just a way to do the same thing without dealing with all of this indexing (because you would actually just be passing around the same item).
 
Level 2
Joined
May 10, 2019
Messages
18
that seems right. of course you would need to add that to the second part of the trigger too.

a few notes about your trigger -

not really a big deal, but it would be better to have the creation and destruction of "transferitempos" be out of the loop (before and after). no reason to do this 6 times.

you could do the entire transfer at once if you create the new unit before destroying the old one- then just make the old unit drop each of it's items and give them to the new unit all in one "for" loop. you might need to save the original position of the first unit and move the new unit there after you destroy the first unit - this would be to compensate for collision. the fact that both of them existed at the same time would not be noticeable, as being in one trigger it would happen too fast to see. - not necessarily better than what you have now, but just a way to do the same thing without dealing with all of this indexing (because you would actually just be passing around the same item).

Thanks again--this has been immensely helpful.

that seems right. of course you would need to add that to the second part of the trigger too.

a few notes about your trigger -

not really a big deal, but it would be better to have the creation and destruction of "transferitempos" be out of the loop (before and after). no reason to do this 6 times.

you could do the entire transfer at once if you create the new unit before destroying the old one- then just make the old unit drop each of it's items and give them to the new unit all in one "for" loop. you might need to save the original position of the first unit and move the new unit there after you destroy the first unit - this would be to compensate for collision. the fact that both of them existed at the same time would not be noticeable, as being in one trigger it would happen too fast to see. - not necessarily better than what you have now, but just a way to do the same thing without dealing with all of this indexing (because you would actually just be passing around the same item).

I changed the creation and destruction as you recommended; that's good advice. I guess I was thinking that it would leak each time.

As far as the ideas to drop the items, I like it. It's simpler and more elegant.

  • For each (Integer A) from 1 to 6, do (Actions)
    • Loop - Actions
      • Hero - Drop (Item carried by Unit_Advance in slot (Integer A)) from Unit_Advance.
      • Hero - Give (Last dropped item) to Unit_Replaced
I'm actually having a problem with this--and with the arrays you helped me with above--with the following trigger:

  • Hero - Give (Last dropped item) to Unit_Replaced
When I don't use this trigger, all the items are correctly placed on the ground next to the replaced unit as they should be. But when I use this trigger, I typically only get one item (the first inventory slot) correctly transferred into the replaced unit's inventory. I know wait triggers are ill-advised, but I tried them just to de-bug and they didn't help.

I get the same problem if I try something like

  • For each (Integer A) from 1 to 6, do (Actions)
    • Loop - Actions
      • Hero - Give (Item carried by Unit_Advance in slot (Integer A)) to Unit_Replaced
 
Level 18
Joined
Oct 17, 2012
Messages
820
The following worked as expected. All items were transferred. No arrays, just three simple variables - Source (unit), Target (unit), LoopInt (Integer).
  • SwitchInventories
    • Events
    • Conditions
    • Actions
      • For each (Integer LoopInt) from 1 to 6, do (Actions)
        • Loop - Actions
          • Hero - Give (Item carried by Source in slot LoopInt) to Target
  • Init
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set VariableSet Source = Paladin 0000 <gen>
      • Set VariableSet Target = Archmage 0001 <gen>
      • Trigger - Run SwitchInventories <gen> (ignoring conditions)
 
Level 2
Joined
May 10, 2019
Messages
18
Thanks, Ghost. I guess when in doubt, go back to basics in a fresh map.

I think I may have detected the issue. It's arising with another item trigger in the map that allows for items to stack:

  • Item Stacking Alt
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-class of (Item being manipulated)) Equal to Charged
    • Actions
      • For each (Integer A) from 1 to 6, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Item-type of (Item carried by (Triggering unit) in slot (Integer A))) Equal to (Item-type of (Item being manipulated))
              • (Item carried by (Triggering unit) in slot (Integer A)) Not equal to (Item being manipulated)
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Charges remaining in (Item carried by (Triggering unit) in slot (Integer A))) Less than 20
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Charges remaining in (Item being manipulated)) + (Charges remaining in (Item carried by (Triggering unit) in slot (Integer A)))) Less than or equal to 20
                    • Then - Actions
                      • Item - Set charges remaining in (Item carried by (Triggering unit) in slot (Integer A)) to ((Charges remaining in (Item carried by (Triggering unit) in slot (Integer A))) + (Charges remaining in (Item being manipulated)))
                      • Hero - Drop (Item being manipulated) from (Triggering unit).
                      • Item - Remove (Item being manipulated)
                    • Else - Actions
                • Else - Actions
            • Else - Actions
I'm not quite sure how to fix this with the unit replacement problem. Have any of you run across this?

EDIT: Update. I think I got it by switching the trigger from Integer A to Integer B to avoid the trigger conflict. Will let you all know if I'm still having difficulties but this shows great promise and I don't need the cumbersome arrays with this idea! Thank you all so much.
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,514
I imagine you can do it like this:
  • Replace
    • Events
    • Conditions
    • Actions
      • -------- Store old items --------
      • Set VariableSet ReplaceUnit = (Triggering unit)
      • For each (Integer ReplaceLoop) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set VariableSet TempItems[ReplaceLoop] = (Item carried by ReplaceUnit in slot ReplaceLoop)
          • Hero - Drop TempItems[ReplaceLoop] from ReplaceUnit.
      • -------- --------
      • -------- Replace unit --------
      • Unit - Replace ReplaceUnit with a Paladin using The old unit's relative life and mana
      • Set VariableSet ReplaceUnit = (Last replaced unit)
      • -------- --------
      • -------- Give back old items --------
      • For each (Integer ReplaceLoop) from 1 to 6, do (Actions)
        • Loop - Actions
          • Hero - Give TempItems[ReplaceLoop] to ReplaceUnit
I don't see the need for creating new items or keeping track of charges.

If some items "Cannot be Dropped" you can make them Droppable temporarily:
  • Replace
    • Events
    • Conditions
    • Actions
      • -------- Store old items --------
      • Set VariableSet ReplaceUnit = (Triggering unit)
      • For each (Integer ReplaceLoop) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set VariableSet TempItems[ReplaceLoop] = (Item carried by ReplaceUnit in slot ReplaceLoop)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Item: TempItems[ReplaceLoop]'s Boolean Field: Can Be Dropped ('idro')) Equal to False
            • Then - Actions
              • Item - Set Item: TempItems[ReplaceLoop]'s Boolean Field: Can Be Dropped ('idro') to Value: True
              • Set VariableSet CannotBeDropped = True
            • Else - Actions
          • Hero - Drop TempItems[ReplaceLoop] from ReplaceUnit.
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CannotBeDropped Equal to True
            • Then - Actions
              • Item - Set Item: TempItems[ReplaceLoop]'s Boolean Field: Can Be Dropped ('idro') to Value: False
              • Set VariableSet CannotBeDropped = False
            • Else - Actions
      • -------- --------
      • -------- Replace unit --------
      • Unit - Replace ReplaceUnit with a Paladin using The old unit's relative life and mana
      • Set VariableSet ReplaceUnit = (Last replaced unit)
      • -------- --------
      • -------- Give back old items --------
      • For each (Integer ReplaceLoop) from 1 to 6, do (Actions)
        • Loop - Actions
          • Hero - Give TempItems[ReplaceLoop] to ReplaceUnit
 
Status
Not open for further replies.
Top