HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

ConstructionStatus

05-12-2009, 08:14 PM#1
Troll-Brain
I'm back with the new version of my library ConstructionStatus, graveyarded because it didn't handle created units with the functions CreateUnit..., and also morphed structures.
http://www.wc3c.net/showthread.php?t=105415
Now it handles theses things.
Sure now it's less sexy because i need to use 2 events, but it's the price of theses adds.

Requires vJass and GroupUtils.

This is just a simple library to know if an unit is being built or constructed, it will return false if the unit is dead.

Collapse JASS:
library ConstructionStatus initializer init uses GroupUtils

globals
    private constant real TIME_OUT = 30.0 // It is the periodic time (seconds) which the group will be refreshed (ghost units are removed)
endglobals

//==============================================================================
//  ConstructionStatus -- by Troll-Brain -- v 1.2
//==============================================================================
//
//  PURPOUSE:
//       * To know if an unit is finished, or being built/upgraded
//       * Note that it doesn't care about trained units, but ofc a trained unit will be considered as finished
//
//  HOW TO USE:
//       * function IsUnitFinished takes unit u returns boolean
//       * function IsUnitBeingBuilt takes unit u returns boolean
//       * function IsUnitBeingUpgraded takes unit u returns boolean
//
//       * Note that these 3 functions will return false if the unit is dead or not valid (for example == null)
//
//  PROS: 
//       * Easy to use, can be done in a single custom script for gui users
//         
//  CONS:
//       * It will fail if the unit has an usable revive ability if the unit die during the upgrade or construction
//       * I could handle it thought, let me know if you have the use of it, but then you have to know that it will require more stuff
//
//  DETAILS:
//       * I simply catch construct and upgrade events
//
//  THANKS TO:
//       * Rising_Dusk : to tell me that i've forgotten the upgraded units
//       * grim001 : for more sexy functions/library names 

//
//  HOW TO IMPORT:
//       * Just create a trigger named ConstructionStatus
//       * convert it to text and replace the whole trigger text with this one
//       * Do the same for the library GroupUtils if you don't already use it
//
//==============================================================================

globals
    private group BeingBuiltUnits
    private group BeingUpgradedUnits
endglobals

function IsUnitFinished takes unit u returns boolean
    return GetUnitTypeId(u) != 0 and not IsUnitType(u,UNIT_TYPE_DEAD) and not IsUnitInGroup(u,BeingBuiltUnits) and not IsUnitInGroup(u,BeingUpgradedUnits)
endfunction

function IsUnitBeingBuilt takes unit u returns boolean
    return not IsUnitType(u,UNIT_TYPE_DEAD) and IsUnitInGroup(u,BeingBuiltUnits)
endfunction

function IsUnitBeingUpgraded takes unit u returns boolean
    return not IsUnitType(u,UNIT_TYPE_DEAD) and IsUnitInGroup(u,BeingUpgradedUnits)
endfunction

private function HandleUnits takes nothing returns boolean
    
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_CONSTRUCT_START then
        call GroupAddUnit(BeingBuiltUnits,GetConstructingStructure())
        
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_CONSTRUCT_FINISH then
        call GroupRemoveUnit(BeingBuiltUnits,GetConstructedStructure())
        
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_UPGRADE_START then
        call GroupAddUnit(BeingUpgradedUnits,(GetTriggerUnit()))
        
    else
        call GroupRemoveUnit(BeingUpgradedUnits,GetTriggerUnit())
    endif

    return false
endfunction

private function RefreshGroup takes nothing returns nothing
    call GroupRefresh(BeingBuiltUnits)
    call GroupRefresh(BeingUpgradedUnits)
endfunction

private function init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local timer tim = CreateTimer()

    set BeingBuiltUnits = NewGroup()
    set BeingUpgradedUnits = NewGroup()
    call TimerStart(tim,TIME_OUT,true,function RefreshGroup)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_CONSTRUCT_START)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_START)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_FINISH)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_CANCEL)
    call TriggerAddCondition(trig,Condition(function HandleUnits))
    
    // unneeded but i tend to null all handles, even if it is never destroyed 
    set trig = null
    set tim = null
endfunction

//==============================================================================
//  CHANGELOG
//==============================================================================
//
//  v 1.2 :
//       * IsUnitFinished return false instead of true when the unit argument is not valid.
//
//  v 1.1 :
//       * It handles upgrading units as well, so IsUnitBeingUpgraded is added
//
//  v 1.0 :
//       * Since the initial release didn't handle morphed units and units created by trigger,
//       * i've fixed that
//
//  v 0.1 :
//       * Initial release

endlibrary
05-12-2009, 08:27 PM#2
Rising_Dusk
It should be called the StructureStatus library or something, it's way too long a name now. Also, test maps aren't necessary, but are really nice to have. It helps the reviewers verify that the script works before approving, which we have to do anyways. I always make a testmap, personally.
05-13-2009, 03:33 PM#3
Troll-Brain
Quote:
Originally Posted by Rising_Dusk
It should be called the StructureStatus library or something, it's way too long a name now. Also, test maps aren't necessary, but are really nice to have. It helps the reviewers verify that the script works before approving, which we have to do anyways. I always make a testmap, personally.
I could rename the library StructureStatus, but the purpose of it would be less obvious, and also SS hurts my ears, i hope you know why.
But meh it's just an abbreviation, so i will probably rename it with this name.

However do you think including the units in the checks is a good idea ? (Of course i ask it for all potential users of the library)
If yes, i need a better name to the library and rename functions.

About the test map, i will make one.
05-13-2009, 07:00 PM#4
Rising_Dusk
Well, it needs to be renamed to something shorter, anything. Your library name should describe what the thing does, but shouldn't be titanic. If some other library ever required this, it'd be a real pain in the butt.
Quote:
Originally Posted by Troll-Brain
However do you think including the units in the checks is a good idea ? (Of course i ask it for all potential users of the library)
I feel like the user can just call the function on whatever he wants, structure or unit. In that case, it should just be called "IsUnitConstructed" and "IsUnitBeingConstructed" or something like that.
05-13-2009, 07:25 PM#5
Troll-Brain
As i said i will change the names, don't worry.

Quote:
I feel like the user can just call the function on whatever he wants, structure or unit. In that case, it should just be called "IsUnitConstructed" and "IsUnitBeingConstructed" or something like that.
I think i will use "IsUnitFinished" and "IsUnitBeingConstructed", because it doesn't make sense if the function "IsUnitConstructed" return true for an unit which has never be constructed (in fact that should almost(all) of the no-structure-type-units on the map ...).

But then, should i also check for trained units ?

I feel like not, because you can't enum them AFAIK, not like units which are being built on the map, you can only catch them with the training events.
And if the user is enough idiot to use them like they are targetable on the map, we can't really do anything for him, can we ?

Or i miss an important thing where a "IsUnitBeingTrained" should be useful ?
05-13-2009, 07:30 PM#6
Rising_Dusk
Quote:
Originally Posted by Troll-Brain
I think i will use "IsUnitFinished" and "IsUnitBeingConstructed", because it doesn't make sense if the function "IsUnitConstructed" return true for an unit which has never be constructed (in fact that should almost(all) of the no-structure-type-units on the map ...).
Yes, I agree.
Quote:
Originally Posted by Troll-Brain
I feel like not, because you can't enum them AFAIK, not like units which are being built on the map, you can only catch them with the training events.
And if the user is enough idiot to use them like they are targetable on the map, we can't really do anything for him, can we ?
I also agree with this.
05-14-2009, 05:45 PM#7
Troll-Brain
Updated and a test map is added on the first post.
05-14-2009, 08:28 PM#8
Rising_Dusk
I was testing this, and it returned that the Nerubian Ziggurat was 'finished' and 'not being built' while in fact I was in the process of upgrading it from Ziggurat to Nerubian Ziggurat. Is this system intended to not deal with upgrading? Is there no way to detect that?

Otherwise, it seems to work happily. Let me know about that thing I mentioned above.
05-14-2009, 09:00 PM#9
grim001
I think the name UnitStatus is a little too vague.
05-14-2009, 09:13 PM#10
Alevice
How about DeploymentStatus?!
05-14-2009, 11:34 PM#11
Rising_Dusk
Quote:
Originally Posted by grim001
I think the name UnitStatus is a little too vague.
Very. I recommend -- UnitCompletionStatus.
05-14-2009, 11:51 PM#12
grim001
ConstructionStatus.
05-14-2009, 11:56 PM#13
Alevice
units aint constructed! they are trained!
05-15-2009, 12:01 AM#14
Rising_Dusk
But the point is that you can construct them, and that is what this library tracks. It doesn't care about units being trained.
Quote:
Originally Posted by grim001
ConstructionStatus.
Yes, this.
05-15-2009, 12:17 AM#15
Alevice
Quote:
Originally Posted by Rising_Dusk
It doesn't care about units being trained.
Whoops, you are right. I misread that.