[Log in / Register]
| News | Chat | Pastebin | Donations | Tutorials | Rules | Forums |
| Maps | Skins | Icons | Models | Spells | Tools | Jass | Packs | Hosted Projects | Starcraft II Modding | Starcraft II Resources | Galaxy Wiki |
(Keeps Hive Alive)
Go Back   The Hive Workshop > Warcraft III Modding > JASS Resources


JASS Resources Find JASS code snippets and functions here or write your own and post it on the Submissions sub-forum.

Reply
 
Thread Tools
Old 05-30-2012, 07:58 AM   #1 (permalink)
Registered User Cokemonkey11
\m/
 
Cokemonkey11's Avatar
 
Join Date: May 2006
Posts: 1,997
Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)
Contest [System] StructuredDD

StructuredDD

Preface:

StructuredDD is a damage detection system which enables users to register a pseudo-generic "unit damaged" event. Many systems exist to accomplish the same result, but the intended design paradigms represented by StructuredDD make it unique:
  • Code Simplicity: StructuredDD is well commented and is self-documented. The design concept is easy to understand for programmers and JASS users with intermediate experience.
  • Fully independent of UnitUserData. Many inexperienced spell programmers use UnitUserData to create their abilities, and I want to ensure that it is always available for that.
  • Cohesion: The system does exactly what it intends to do, and nothing more. There are no required libraries, and any additional functionality is handled in separate components.

Design Explanation:
  1. User defines one or more code to be executed on damage detection
  2. User indexes units they want to be used for damage detection (alternatively StructuredDD can auto-index all units)
  3. StructuredDD handles instances of detection triggers, each tied to a "bucket" of units
  4. StructuredDD automatically checks each trigger periodically if the entire bucket contains null units before destroying the trigger

Limitations:
  • StructuredDD requires vJass
  • There is currently no support for deallocating handlers for dynamic use
  • There is currently no support for periodic cleanup timeouts that self-optimize.
  • There is currently no support for "long-term" unit buckets built to handle units that aren't removed from the game (for example heroes)
  • There is no included "safe" method for damaging a unit - it is trivial for the client to do this in their own handler(s).
  • There is no included method to check for physical/spell/code damage - the computational cost for such systems is a higher order of magnitude than the system itself, thus these systems are built as extensions.
  • Handlers are added in order to an array and are executed in order. If you have handlers that depend on each other, it is your job to avoid race conditions.

API:

Customization
  • StructuredDD.ADD_ALL_UNITS - Set this to true if you want all units in your map to be automatically added to StructuredDD. Otherwise you will have to manually add them with StructuredDD.add(unit).
  • StructuredDD.BUCKET_SIZE - This is the amount of units that exist in each trigger bucket. This number should be something between 5 and 30. A good starting value will be an estimate of your map's average count of units, divided by 10. When in doubt, just use 20.
  • StructuredDD.PER_CLEANUP_TIMEOUT - This is how often StructuredDD will search for empty buckets. If your map has units being created and dying often, a lower value is better. Anything between 10 and 180 is good. When in doubt just use 60.


Methods
  • StructuredDD.addHandler(code) - This method is for adding a handler to the system. Whenever a handler is added, damage detection will immediately trigger that handler. There is no way to deallocate a handler, so don't try to do this dynamically (!) Support for handler deallocation is possible (please contact me)
  • StructuredDD.add(unit) - This method adds a unit to the damage detection system. If ADD_ALL_UNITS is enabled, you don't have to (and should not) ever use this method. If you add a unit that's already in the system, it will be added that second time and hence damage to it will fire all handlers twice.


The script:

Jass:

//*     API:
//* boolean ADD_ALL_UNITS: If enabled, a trigger turns on which automatically
//*     registers all units in the map.
//* integer BUCKET_SIZE: How many units to add to each 'bucket' - a larger
//*     bucket will have their trigger refresh less frequently but will be
//*     more computationally expensive. A good starting value is about 20.
//* real PER_CLEANUP_TIMEOUT: How many seconds to wait in between each
//*     scan for empty buckets. This value should be lower if units die often
//*     in your map. A good starting value is about 60.
//* static method addHandler: Registers a callback function to the generic
//*     unit damage event. Example: call StructuredDD.addHandler(function h)
//* static method add: Adds a unit to a bucket. If ADD_ALL_UNITS is enabled,
//*     this method need not be used.
library StructuredDD
    globals
   
        //<< BEGIN SETTINGS SECTION
       
        //* Set this to true if you want all units in your map to be
        //* automatically added to StructuredDD. Otherwise you will have to
        //* manually add them with StructuredDD.add(u).
        private constant boolean ADD_ALL_UNITS=true
       
        //* This is the amount of units that exist in each trigger bucket.
        //* This number should be something between 5 and 30. A good starting
        //* value will be an estimate of your map's average count of units,
        //* divided by 10. When in doubt, just use 20.
        private constant integer BUCKET_SIZE=20
       
        //* This is how often StructuredDD will search for empty buckets. If
        //* your map has units being created and dying often, a lower value
        //* is better. Anything between 10 and 180 is good. When in doubt,
        //* just use 60.
        private constant real PER_CLEANUP_TIMEOUT=60.
       
        //>> END SETTINGS SECTION
       
    endglobals

    //* Our bucket struct which contains a trigger and its associated contents.
    private struct bucket
        integer bucketIndex=0
        trigger trig=CreateTrigger()
        unit array members[BUCKET_SIZE]
    endstruct
   
    //* Our wrapper struct. We never intend to actually instanciate "a
    //* StructuredDD", we just use this for a pretty, java-like API :3
    struct StructuredDD extends array
        private static boolexpr array conditions
        private static bucket array bucketDB
        private static integer conditionsIndex=-1
        private static integer dbIndex=-1
        private static integer maxDBIndex=-1
       
        //* This method gets a readily available bucket for a unit to be added.
        //* If the "current" bucket is full, it returns a new one, otherwise
        //* it just returns the current bucket.
        private static method getBucket takes nothing returns integer
            local integer index=0
            local integer returner=-1
            local bucket tempDat
            if thistype.dbIndex!=-1 and thistype.bucketDB[thistype.dbIndex].bucketIndex<BUCKET_SIZE then
                return thistype.dbIndex
            else
                set thistype.maxDBIndex=thistype.maxDBIndex+1
                set thistype.dbIndex=thistype.maxDBIndex
                set tempDat=bucket.create()
                set thistype.bucketDB[.maxDBIndex]=tempDat
                loop
                    exitwhen index>thistype.conditionsIndex
                    call TriggerAddCondition(tempDat.trig,thistype.conditions[index])
                    set index=index+1
                endloop
                return thistype.dbIndex
            endif
            return -1
        endmethod
       
        //* This method is for adding a handler to the system. Whenever a
        //* handler is added, damage detection will immediately trigger that
        //* handler. There is no way to deallocate a handler, so don't try to
        //* do this dynamically (!) Support for handler deallocation is
        //* feasible (please contact me)
        public static method addHandler takes code func returns nothing
            local bucket tempDat
            local integer index=0
            set thistype.conditionsIndex=thistype.conditionsIndex+1
            set thistype.conditions[thistype.conditionsIndex]=Condition(func)
            loop
                exitwhen index>thistype.maxDBIndex
                set tempDat=thistype.bucketDB[index]
                call TriggerAddCondition(tempDat.trig,thistype.conditions[thistype.conditionsIndex])
                set index=index+1
            endloop
        endmethod
       
        //* This method adds a unit to the damage detection system. If
        //* ADD_ALL_UNITS is enabled, this method need not be used.
        public static method add takes unit member returns nothing
            local bucket tempDat
            local integer whichBucket=thistype.getBucket()
            set tempDat=thistype.bucketDB[whichBucket]
            set tempDat.bucketIndex=tempDat.bucketIndex+1
            set tempDat.members[tempDat.bucketIndex]=member
            call TriggerRegisterUnitEvent(tempDat.trig,member,EVENT_UNIT_DAMAGED)
        endmethod
       
        //* This is just an auxillary function for ADD_ALL_UNITS' implementation
        static if ADD_ALL_UNITS then
            private static method autoAddC takes nothing returns boolean
                call thistype.add(GetTriggerUnit())
                return false
            endmethod
        endif
       
        //* This method is used to check if a given bucket is empty (and thus
        //* can be deallocated) - this is an auxillary reoutine for the
        //* periodic cleanup system.
        private static method bucketIsEmpty takes integer which returns boolean
            local bucket tempDat=thistype.bucketDB[which]
            local integer index=0
            loop
                exitwhen index==BUCKET_SIZE
                //GetUnitTypeId(unit)==0 means that the unit has been removed.
                if GetUnitTypeId(tempDat.members[index])!=0 then
                    return false
                endif
                set index=index+1
            endloop
            return true
        endmethod
       
        //* This method cleans up any empty buckets periodically by checking
        //* if it has been fully allocated and then checking if all its
        //* members no longer exist.
        private static method perCleanup takes nothing returns nothing
            local integer index=0
            loop
                exitwhen index>thistype.maxDBIndex
                if index!=thistype.dbIndex and thistype.bucketIsEmpty(index) then
                    call DestroyTrigger(thistype.bucketDB[index].trig)
                    call thistype.bucketDB[index].destroy()
                    set thistype.bucketDB[index]=thistype.bucketDB[thistype.maxDBIndex]
                    set thistype.maxDBIndex=thistype.maxDBIndex-1
                    if thistype.maxDBIndex==thistype.dbIndex then
                        set thistype.dbIndex=index
                    endif
                    set index=index-1
                endif
                set index=index+1
            endloop
        endmethod
       
        //* This is a initialization function necessary for the setup of
        //* StructuredDD.
        private static method onInit takes nothing returns nothing
            local group grp
            local region reg
            local trigger autoAddUnits
            local timer perCleanup
            local unit FoG
            static if ADD_ALL_UNITS then
                //Add starting units
                set grp=CreateGroup()
                call GroupEnumUnitsInRect(grp,bj_mapInitialPlayableArea,null)
                loop
                    set FoG=FirstOfGroup(grp)
                    exitwhen FoG==null
                    call thistype.add(FoG)
                    call GroupRemoveUnit(grp,FoG)
                endloop
                //Add entering units
                set autoAddUnits=CreateTrigger()
                set reg=CreateRegion()
                call RegionAddRect(reg,bj_mapInitialPlayableArea)
                call TriggerRegisterEnterRegion(autoAddUnits,reg,null)
                call TriggerAddCondition(autoAddUnits,Condition(function thistype.autoAddC))
                set autoAddUnits=null
                set reg=null
            endif
            //enable periodic cleanup:
            set perCleanup=CreateTimer()
            call TimerStart(perCleanup,PER_CLEANUP_TIMEOUT,true,function thistype.perCleanup)
            set perCleanup=null
        endmethod
    endstruct
endlibrary

Example Test Scope:

test

Jass:

//This script assumes that StructuredDD.ADD_ALL_UNITS is true

scope test initializer i
    globals
        private group grp=CreateGroup()
    endglobals
   
    private function h takes nothing returns nothing
        call DisplayTextToPlayer(GetLocalPlayer(),0.,0.,GetUnitName(GetEventDamageSource())+" dealt "+R2S(GetEventDamage())+" to: "+GetUnitName(GetTriggerUnit()))
    endfunction
   
    private function i takes nothing returns nothing
        call FogMaskEnable(false)
        call FogEnable(false)
        call StructuredDD.addHandler(function h)
    endfunction
endscope

(Yes, it's that simple)


Change Log:

list

2013.05.25 - removed UnitAlive declaration and reduced length of processed code using static if
2013.05.24 - made one small change (StructuredDD extends array) which will reduce the size of the compiled code. This change does not affect the API.
2013.05.13 - updated the API and documentation
2013.01.18 - big update - updated API, removed some components, fixed a massive bug. Please note that I have also stopped maintaining the version pastebin mirrors as they were a waste of time to maintain.
2012.06.03 - Updated the null check to use GetUnitTypeId() which fixes a deindexing bug where DEAD_UNITS_ARE_NULL was false. The script now declares native UnitAlive, thus IsUnitType() has been replaced with UnitAlive(). Will revert this change if it is not recommended.
2012.06.02 - The periodic cleanup now uses a timer instead of a trigger for efficiency reasons.
2012.06.01 - Updating the script to follow proper CamelCase. The API has also been changed to reflect only 1 use of addHandler, which takes code as an argument as suggested by fellow hive users. Also fixed two major bugs in the decrement portion of the stack.
2012.05.30 #2 - Updated submission with additional method and changed constant nomenclature.
2012.05.30 - Initial submission to Hive: Jass Resources: Submissions


Special Thanks:
  • PurplePoot who thought of bucket-based damage detection systems and created it in the first place, but never released his version.
  • Nestharus and Troll-Brain for explaining how to use GetUnitTypeId() for null checks.
  • -Kobas- for creating a map submission template, which turned out useful for system submissions as well.
  • Vexorian for developing JassHelper. Without vJass, I almost certainly would not still be scripting for wc3.
  • The various developers of JNGP including PitzerMike and MindworX. Integrating JassHelper and TESH is a godsend.

Last edited by Cokemonkey11; Yesterday at 01:24 AM. Reason: updated API and documentation
Cokemonkey11 is online now   Reply With Quote
Old 05-30-2012, 08:42 AM   #2 (permalink)
Forum Moderator Bribe
Keep it simple
 
Bribe's Avatar
Spells, Help Zones & JASS Moderator
 
Join Date: Sep 2009
Posts: 5,581
Bribe has much of which to be proud (1209)Bribe has much of which to be proud (1209)
PayPal Donor: This user has donated to The Hive. 
Please remove your signature. Also, APILIKETHISISHARDLYREADABLE, IT_IS_MUCH_MORE_READABLE_LIKE_THIS. Also, boolexpr's as an argument is pretty ugly syntax, I recommend using code arguments and convert them to boolexpr's yourself, saving the user the workload. Also, bj_mapInitialPlayableArea does not cover the whole map where units may be and you also miss out on Locust units this way (not that you need them for a damage detection system, but it's possible). Basing this off an indexer makes a lot more sense.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.

Bribe is offline   Reply With Quote
Old 05-30-2012, 09:10 AM   #3 (permalink)
Registered User Cokemonkey11
\m/
 
Cokemonkey11's Avatar
 
Join Date: May 2006
Posts: 1,997
Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)
Thanks for the reply.

Quote:
Also, boolexpr's as an argument is pretty ugly syntax, I recommend using code arguments and convert them to boolexpr's yourself, saving the user the workload.
That's your opinion. Blizzard seems to disagree since they take boolexpr's as arguments, but regardless I've added a new method to the API which takes code as an argument instead.

Quote:
Also, bj_mapInitialPlayableArea does not cover the whole map where units may be and you also miss out on Locust units this way (not that you need them for a damage detection system, but it's possible).
The ADD_ALL_UNITS functionality is just for users who want to make using my system easy. If they are doing something complex like locust units outside the initial playable map are on initialization, they can write their own "add all units" script. Regardless, I've added this as a note in the API to save users the trouble of reading my script.

Quote:
Basing this off an indexer makes a lot more sense.
I don't use indexing systems (and neither should you). This script is open source however, if you'd like to change it, you're more than welcome.


---

Again, thanks for the comments. (+reps of course)
Cokemonkey11 is online now   Reply With Quote
Old 05-30-2012, 09:39 AM   #4 (permalink)
Forum Moderator Bribe
Keep it simple
 
Bribe's Avatar
Spells, Help Zones & JASS Moderator
 
Join Date: Sep 2009
Posts: 5,581
Bribe has much of which to be proud (1209)Bribe has much of which to be proud (1209)
PayPal Donor: This user has donated to The Hive. 
>> Blizzard seems to disagree since they take boolexpr's as arguments

If you are not using the true or false utility of boolexpr's, accept code as the argument.

>> I don't use indexing systems (and neither should you).

Indexing systems are great. You have provided no reason why you nor I shouldn't use indexing systems. GUI Unit Indexer has been a really great help for lots of users recently, which was unprecedented seeing as how Jesus4Lyf's "GUI AIDS" never really took off.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.

Bribe is offline   Reply With Quote
Old 05-30-2012, 09:52 AM   #5 (permalink)
Registered User Cokemonkey11
\m/
 
Cokemonkey11's Avatar
 
Join Date: May 2006
Posts: 1,997
Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)
Quote:
Originally Posted by Bribe View Post
If you are not using the true or false utility of boolexpr's, accept code as the argument.
Yep I've added that to the API as I said. But I have no plans to use TriggerAddAction. If you want to use TSA in your DD handlers, don't use this script.

Quote:
Indexing systems are great. You have provided no reason why you nor I shouldn't use indexing systems. GUI Unit Indexer has been a really great help for lots of users recently, which was unprecedented seeing as how Jesus4Lyf's "GUI AIDS" never really took off.
Because unit indexing systems use unit custom value and/or hashtables. My system isn't intended for "new" or "casual" developers, but instead for people who want to use efficient vJass. Chances are the users of this system know how to make it themself, but simply don't want to spend the time (I know I've been putting this off for awhile)
Cokemonkey11 is online now   Reply With Quote
Old 05-30-2012, 10:42 AM   #6 (permalink)
Forum Moderator Bribe
Keep it simple
 
Bribe's Avatar
Spells, Help Zones & JASS Moderator
 
Join Date: Sep 2009
Posts: 5,581
Bribe has much of which to be proud (1209)Bribe has much of which to be proud (1209)
PayPal Donor: This user has donated to The Hive. 
>> But I have no plans to use TriggerAddAction.

You don't need to. Trigger conditions can return nothing and therefore give the same speed benefit. However, when using vJass which is slaved to pJass, pJass blocks those kind of "returns nothing" conditions from compiling. The way to bypass it is to pass the code argument to a function and that function calls the "Filter/Condition" native to compile it without pJass' obsolete safety. Thus it is less verbose to the user and preserves conditions as replacements to actions.

>> My system is ... for people who want to use efficient vJass.

UnitUserData / hashtables are too slow to be useful? Don't go down this slippery slope of efficiency. Once you crop you can't stop. Seriously, no one cares. Except Nestharus but he really is addicted to it. Your system is not the most efficient anyway, you might as well focus on more important areas.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.

Bribe is offline   Reply With Quote
Old 05-30-2012, 11:10 AM   #7 (permalink)
Registered User Cokemonkey11
\m/
 
Cokemonkey11's Avatar
 
Join Date: May 2006
Posts: 1,997
Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)Cokemonkey11 is just really nice (351)
Quote:
Originally Posted by Bribe View Post
You don't need to. Trigger conditions can return nothing and therefore give the same speed benefit. However, when using vJass which is slaved to pJass, pJass blocks those kind of "returns nothing" conditions from compiling. The way to bypass it is to pass the code argument to a function and that function calls the "Filter/Condition" native to compile it without pJass' obsolete safety. Thus it is less verbose to the user and preserves conditions as replacements to actions.
That's quite nice to know actually, can you show me how in an example?

Quote:
UnitUserData / hashtables are too slow to be useful? Don't go down this slippery slope of efficiency. Once you crop you can't stop. Seriously, no one cares. Except Nestharus but he really is addicted to it. Your system is not the most efficient anyway, you might as well focus on more important areas.
UnitUserData is too limited because it only supports 1 value per unit.

Hashtables are too slow for unit control and spells. They are useful in other ways, like when O(n) is slower than the hashtable counter-part, but for my own preferences I'm going to stick with my linear stacks.

I understand you don't care about efficiency (Or you wouldn't still be making systems for GUI) but that doesn't mean that "no one" cares. Seriously don't generalize stuff like that.
Cokemonkey11 is online now   Reply With Quote
Old 05-30-2012, 11:25 AM   #8 (permalink)
Forum Moderator Bribe
Keep it simple
 
Bribe's Avatar
Spells, Help Zones & JASS Moderator
 
Join Date: Sep 2009
Posts: 5,581
Bribe has much of which to be proud (1209)Bribe has much of which to be proud (1209)
PayPal Donor: This user has donated to The Hive. 
>> Hashtables are too slow for unit control and spells.

I use hashtables pretty frequently in Retro for really comprehensive data, my poor-grade Intel Atom N450 can handle it even on the scale of 100+ units without dropping in FPS.

>> UnitUserData is too limited because it only supports 1 value per unit.

Too limited? It provides an array index for every unit, it is a supplementary utility. You don't need more than one UnitUserData.

>> When O(n) is slower than the hashtable counter-part.

Which is essentially every time "n" exceeds 2 or 3. JASS reading is extremely "slow" thanks to it being an interpreted language. Calling hashtables slow is like saying the FLASH is slower than SUPERMAN. Who cares? Which brings us to...

>> That doesn't mean that "no one" cares.

No one cares about a 0.0000001% margin, which is the case here. If people think they care, they are overanalyzing and need to look at real-world scenarios. It's ridiculous percentiles like this that allows Intel to sell i3-2130's at a price difference 5x the difference between the 2100 and the 2120, despite providing only half the edge in performance (a 100MHz overclock instead of a 200MHz overclock costing $25 more instead of $5 more resulting in a huge, totally worth the money 3% performance gain).
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.

Bribe is offline   Reply With Quote
Old 05-30-2012, 11:50 AM   #9 (permalink)
Forum Moderator Magtheridon96
JESUS MAN
 
Magtheridon96's Avatar
Resource Moderator
 
Join Date: Dec 2008
Posts: 5,702
Magtheridon96 has a brilliant future (1824)
Merit Badge - Level 0: This user has proven to be extremely valuable to the Warcraft III Modding Community. 
Here's an example:

Jass:
function Hi takes nothing returns nothing


endfunction

// ...
local code c = function Hi
call TriggerAddCondition(t, Filter(c))
// ...

The compiler can't stop you from doing this since you're passing a variable ;)
Of course, when the code is a parameter, you would need to make your function 2 lines long (add a return statement after the actual code) so that it wouldn't inline.

If it inlines, pJass says "Woah bro, that function doesn't return a boolean. You're in big trouble Mister."
__________________
Magtheridon96 is offline   Reply With Quote
Old 05-30-2012, 12:59 PM   #10 (permalink)
Registered User LeP
lol, *****
 
Join Date: Feb 2008
Posts: 134
LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)
Quote:
Originally Posted by Bribe View Post
However, when using vJass which is slaved to pJass, pJass blocks those kind of "returns nothing" conditions from compiling.
Someone counted how often i mentioned Zoxcs Jass Parser?
Or how to use it.

But this is new: using my incredible google-fu i ofc found a valid download of the cli-parser here.

And ofc you could always compile it from source.

Or change pJass' source.
__________________
___________________________________________________
/!\ Don't call it Schnitzel /!\

Please excuse my english. I know that it's not that good, but i'm doing my best.
LeP is offline   Reply With Quote
Old 05-30-2012, 01:24 PM   #11 (permalink)
Forum Moderator Bribe
Keep it simple
 
Bribe's Avatar
Spells, Help Zones & JASS Moderator
 
Join Date: Sep 2009
Posts: 5,581
Bribe has much of which to be proud (1209)Bribe has much of which to be proud (1209)
PayPal Donor: This user has donated to The Hive. 
LeP, it's fine for your own resources, but for public resources people don't like to download a new .exe just to run your script. I know about that resource and yes one can get it to work but no one cannot expect everyone to have it.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.

Bribe is offline   Reply With Quote
Old 05-30-2012, 01:40 PM   #12 (permalink)
Registered User LeP
lol, *****
 
Join Date: Feb 2008
Posts: 134
LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)
Quote:
Originally Posted by Bribe View Post
LeP, it's fine for your own resources, but for public resources people don't like to download a new .exe just to run your script. I know about that resource and yes one can get it to work but no one cannot expect everyone to have it.
But it's okay for a public resource to circumvent the syntax-checker?
Cool idea.
__________________
___________________________________________________
/!\ Don't call it Schnitzel /!\

Please excuse my english. I know that it's not that good, but i'm doing my best.
LeP is offline   Reply With Quote
Old 05-30-2012, 01:59 PM   #13 (permalink)
Forum Moderator Magtheridon96
JESUS MAN
 
Magtheridon96's Avatar
Resource Moderator
 
Join Date: Dec 2008
Posts: 5,702
Magtheridon96 has a brilliant future (1824)
Merit Badge - Level 0: This user has proven to be extremely valuable to the Warcraft III Modding Community. 
Yes, it is.

There's no reason as to why workarounds are bad, hence, they are not bad, in other words, it's fine to use them.
__________________
Magtheridon96 is offline   Reply With Quote
Old 05-30-2012, 02:39 PM   #14 (permalink)
Registered User LeP
lol, *****
 
Join Date: Feb 2008
Posts: 134
LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)LeP has little to show at this moment (45)
Quote:
Originally Posted by Magtheridon96 View Post
Yes, it is.

There's no reason as to why workarounds are bad, hence, they are not bad, in other words, it's fine to use them.
They were technically bad (desync).
They are still semantically bad (TriggerAddCondition, and we all know a conditions return something truthy or falsy.).

______
Also, when your needs change you adopt your tools.

"Hey heard of this new tool called JassHelper?", "Yeah, user don't want to download any programm.", "Okay, let's continue using Jass the way it is."
__________________
___________________________________________________
/!\ Don't call it Schnitzel /!\

Please excuse my english. I know that it's not that good, but i'm doing my best.
LeP is offline   Reply With Quote
Old 05-30-2012, 02:53 PM   #15 (permalink)
Forum Moderator Magtheridon96
JESUS MAN
 
Magtheridon96's Avatar
Resource Moderator
 
Join Date: Dec 2008
Posts: 5,702
Magtheridon96 has a brilliant future (1824)
Merit Badge - Level 0: This user has proven to be extremely valuable to the Warcraft III Modding Community. 
Users wouldn't care.

They would rather just omit the return false line (It's such an evil line.)
__________________
Magtheridon96 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


All times are GMT. The time now is 09:07 AM.





Powered by vBulletin
Copyright 2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.5.1 PL2
Copyright © Ralle