• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[General] Check type of variable

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,338
Hi,

Suppose I write the following function:

JASS:
function foo takes handle h returns nothing
...
endfunction

Now if I understand correctly, foo will accept any handle (i.e. a reference to something which is an instance: unit in the map, a tree in the map, a region/rect in the map, an item in the map).

But say I want to have separate behavior depending on the handle passed in. Is there a function that does this, i.e. tells me if a handle is of a certain type?

JASS:
native function isTypeOf takes handle whichHandle, type whichType returns boolean
...
endfunction
 
You can use typecasting. In the past, typecasting was used to save handles in gamecaches (before hashtables were implemented). You would just typecast the handle to an integer (a.k.a. GetHandleId()[icode=jass], before it existed we used a function H2I), and then you would store the integer in a gamecache, and then you would load the integer and typecast it back to a handle (the user is expected to know what type was saved). However, typecasting was done through exploiting the return bug. [url]http://wiki.thehelper.net/wc3/Return_Bug[/url] Now there is a different method that works with the latest patch. It isn't used all too often, but it is useful in some cases and/or for testing: [url]http://www.thehelper.net/threads/typecasting.121176/[/url] However, it won't work for all types since you can't arbitrarily save a [icode=jass]handle into a hashtable anymore. However, you can still do so with agents, with SaveAgentHandle.

To check if something is a particular type, the function is something like this:
JASS:
globals
    hashtable h = InitHashtable()
endglobals

function IsAgentUnit takes agent a returns boolean
    call SaveAgentHandle(h, 0, 0, a)
    return LoadUnitHandle(h, 0, 0) != null
endfunction

Something like that. I forget the exact method, I tested it a long time ago. You might have to load it and then run a different function, like GetUnitTypeId() or something. But anyway, if it is != null, it is a unit agent. If it is null, then it is not a unit. Basically, this "attempts" to typecast the agent to the type you want to check. It will fail if it tries to load it as the incorrect type.

Probably not super convenient, but hey at least it works. ;P

EDIT: DIMF beat me to the post.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
To be clear, all the types that are listed in the linked library are ones which I can check for their type using the function you gave?

JASS:
globals
    hashtable h = InitHashtable()
endglobals

function IsAgentRegion takes agent a returns boolean
    call SaveAgentHandle(h, 0, 0, a)
    return LoadRegionHandle(h, 0, 0) != null
endfunction

So this would tell me if an agent is a region?

Edit: This doesn't work. It always returns null. Strange, because region extends agent...
 
Last edited:
My bad. I hadn't tested it, and I lost my old code. Try this:
JASS:
globals
	trigger array t
	hashtable ht = InitHashtable()
endglobals

library A initializer Init
	private function Handle2Region takes handle h returns region
		call SaveFogStateHandle(ht, 0, 0, ConvertFogState(GetHandleId(h)))
		return LoadRegionHandle(ht, 0, 0)
	endfunction

	private function IsHandleRegion takes handle h returns boolean
		return Handle2Region(h) != null
	endfunction

	public function Cond takes nothing returns boolean
		local region r = CreateRegion()
		local handle h = r
		
		if IsHandleRegion(h) then
			call BJDebugMsg("True")
		else
			call BJDebugMsg("False")
		endif
		
		return false 
	endfunction

	private function Init takes nothing returns nothing 
		set t[0] = CreateTrigger()
		call TriggerRegisterPlayerEventEndCinematic(t[0], Player(0))
		call TriggerAddCondition(t[0], Condition(function Cond))
	endfunction
endlibrary

It is a more generalized typecast (and I can confirm it works). Apparently Agent2Region doesn't work with the SaveAgentHandle() method. Oh well.
 
Status
Not open for further replies.
Top