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

Attaching an item model to an item on the ground

Status
Not open for further replies.
Hey guys;

This is what I want to do:

When an item is on the ground (that uses the Spinner model http://www.hiveworkshop.com/forums/...48293/?prev=search=item%20spinner&d=list&r=20), I simply want to attach the actual attachment model to the spinner bone.

I don't want to create a new item spinner model for each attachment model (as is suggested by the author), so I thought about directly attaching the specific model to the item on the ground.


This is my current solution:
- the item has an invisible, but clickable model (I used calculate extends on the pathing blocker box and then made the material invisible)
- When an item is dropped on the ground, create a dummy unit with locust on top of it, that uses the item spinner model
- Attach the specific attachment model to the dummy unit as an SFX

As you can probably see, it's not very efficient, due to the use of dummy units. Any suggestions how I can get rid of the dummy unit and attach the model directly to the ground item?
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Hey guys;

This is what I want to do:

When an item is on the ground (that uses the Spinner model http://www.hiveworkshop.com/forums/...48293/?prev=search=item%20spinner&d=list&r=20), I simply want to attach the actual attachment model to the spinner bone.

I don't want to create a new item spinner model for each attachment model (as is suggested by the author), so I thought about directly attaching the specific model to the item on the ground.


This is my current solution:
- the item has an invisible, but clickable model (I used calculate extends on the pathing blocker box and then made the material invisible)
- When an item is dropped on the ground, create a dummy unit with locust on top of it, that uses the item spinner model
- Attach the specific attachment model to the dummy unit as an SFX

As you can probably see, it's not very efficient, due to the use of dummy units. Any suggestions how I can get rid of the dummy unit and attach the model directly to the ground item?

It is possible to make items have multiple animations for this purpose.
By default, attachments simply face wrong when used as items, but this can be fixed.
I've seen a solution proposed that goes like this:
"stand" animation is the item form.
"stand,alternate" or something like this is the attachment. Then every unit that uses it has to have "alternate" in required animations.

Not sure if it's viable in your case, but it can be done like this.
 
That would have three drawbacks, though:
1) the file size of the models increases a little, as all items need the second animation
2) it requires changing all attachment models
3) I can not put in combinations of multiple attachment models on one spinner (i.e. shoulders+chestpiece for an armor)

Currently, my approach allows all that, but it requires a lot of dummy unit recycling for performance.


EDIT:
I remember "Pause Unit" to be very effective to reduce the cpu load of dummy units. As I only need them to attach SFX models, I should be able to use that. Does "Pause Unit" interfere with hiding units? Do I need to re-pause them after unhiding? I remember hiding units had a lot of bugs.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
That would have three drawbacks, though:
1) the file size of the models increases a little, as all items need the second animation
2) it requires changing all attachment models
3) I can not put in combinations of multiple attachment models on one spinner (i.e. shoulders+chestpiece for an armor)

Currently, my approach allows all that, but it requires a lot of dummy unit recycling for performance.


EDIT:
I remember "Pause Unit" to be very effective to reduce the cpu load of dummy units. As I only need them to attach SFX models, I should be able to use that. Does "Pause Unit" interfere with hiding units? Do I need to re-pause them after unhiding? I remember hiding units had a lot of bugs.

I don't think it does interfere. I guess you can just try to find out. As long as the dummies don't get buffed, everything should work fine.
One thing is for sure - Pausing and hiding work separately.
 
Okay, so this is what I have so far:
JASS:
library SpinItem

	globals
		private constant integer rawcode = 'hfoo'
		private constant string attachpoint = "center"

		private hashtable hash = InitHashtable()
		private integer stackcount = 0
	endglobals

	function ItemAddModel takes item it, string subpath1, string subpath2, string subpath3 returns nothing
		local unit dummy = null
		if stackcount > 0 then
			set stackcount = stackcount - 1
			set dummy = LoadUnitHandle(hash, 0, stackcount)
			call RemoveSavedHandle(hash, 0, stackcount)
			call PauseUnit(dummy, false)
			call SetUnitX(dummy, GetItemX(it))
			call SetUnitY(dummy, GetItemY(it))
			call ShowUnit(dummy, true)
			call UnitRemoveAbility(dummy, 'Aloc')
			call UnitAddAbility(dummy, 'Aloc')
		else
			set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), rawcode, GetItemX(it), GetItemY(it), 0)
		endif
		call PauseUnit(dummy, true)
		call SaveUnitHandle(hash, GetHandleId(it), 0, dummy)
		if subpath1 != "" then
			call SaveEffectHandle(hash, GetHandleId(it), 1, AddSpecialEffectTarget(subpath1, dummy, attachpoint))
			if subpath2 != "" then
				call SaveEffectHandle(hash, GetHandleId(it), 2, AddSpecialEffectTarget(subpath2, dummy, attachpoint))
				if subpath3 != "" then
					call SaveEffectHandle(hash, GetHandleId(it), 3, AddSpecialEffectTarget(subpath3, dummy, attachpoint))
				endif
			endif
		endif
		set dummy = null
	endfunction

	function ItemRemoveModel takes item it returns nothing
		local unit dummy = LoadUnitHandle(hash, GetHandleId(it), 0)
		local effect sfx1 = LoadEffectHandle(hash, GetHandleId(it), 1)
		local effect sfx2 = LoadEffectHandle(hash, GetHandleId(it), 2)
		local effect sfx3 = LoadEffectHandle(hash, GetHandleId(it), 3)
		if sfx1 != null then
			call DestroyEffect(sfx1)
			set sfx1 = null
		endif
		if sfx2 != null then
			call DestroyEffect(sfx2)
			set sfx2 = null
		endif
		if sfx3 != null then
			call DestroyEffect(sfx3)
			set sfx3 = null
		endif
		call FlushChildHashtable(hash, GetHandleId(it))
		call SaveUnitHandle(hash, 0, stackcount, dummy)
		call PauseUnit(dummy, false)
		call ShowUnit(dummy, false)
		call PauseUnit(dummy, true)
		set stackcount = stackcount + 1
		set dummy = null
	endfunction

endlibrary

Any ideas to improve it?
I used some kind of simple dummy recycler for this.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
I believe you don't have to unpause or unlocust the dummy in this case.
Also, I'm quite certain that Show and Pause don't cancel eachother out in any way.

You can test both of these. They'll make your code shorter if I'm right or prove me wrong otherwise.
 
I believe you don't have to unpause or unlocust the dummy in this case.
Also, I'm quite certain that Show and Pause don't cancel eachother out in any way.

You can test both of these. They'll make your code shorter if I'm right or prove me wrong otherwise.
Yeah I'll try to see if I can delete some statements.
Then again, I won't spam thousands of items periodically, so the impact of some extra lines doesn't really matter (especially not compared to the additional overhead the dummy units produce).
 
Status
Not open for further replies.
Top