- Joined
- Mar 25, 2005
- Messages
- 252
If we never made mistakes, we would never need to learn 
It depends on how you interpret it; if you were to mean that you would not even stray into that area, then there would be a disadvantageIf we never made mistakes, we would never need to learn![]()
You don't get around much, do you?This is the first time I've seen a mod spam.
function getGroupUnitsNum takes group g returns integer
local unit u
local integer i = 0
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
set i = i + 1
endloop
return i
endfunction
function GroupCountUnits takes group g returns integer
set bj_groupCountUnits = 0
call ForGroup(g, function CountUnitsInGroupEnum)
return bj_groupCountUnits
endfunction
function Text takes string s, string color, real x, real y returns nothing
local texttag t = CreateTextTag()
call SetTextTagText(t, s, .023)
call SetTextTagPos(t, x,y, 100)
call SetTextTagVelocity(t, 0, .0277)
if color == "red" then
call SetTextTagColor(t, 255, 0, 0, 255)
elseif color == "orange" then
call SetTextTagColor(t, 255, 138, 8, 255)
elseif color == "yellow" then
call SetTextTagColor(t, 255, 255, 0, 255)
elseif color == "green" then
call SetTextTagColor(t, 24, 190, 0, 255)
elseif color == "blue" then
call SetTextTagColor(t, 0, 0, 255, 255)
elseif color == "purple" then
call SetTextTagColor(t, 82, 0, 132, 255)
elseif color == "black" then
call SetTextTagColor(t, 0,0,0, 255)
endif call SetTextTagLifespan( t, 3.00 )
call SetTextTagFadepoint( t, 2.00 )
call SetTextTagPermanent( t, false )
set t = null
endfunction
function SetTextTagColor takes texttag t, integer red , integer blue, integer green, integer alpha returns nothing
local string colorcode = "|" + I2S(C2H(alpha)) + I2S(C2H(red)) + I2S(C2H(blue)) + I2S(C2H(green))
local string originaltext = SomeHowGetsTheTextTagText(t)
set colorcode = colorcode + originaltext + "|r"
call SetTextTagText(t, colorcode, DoesNotAffectTheFont(t))
endfunction
function Floatie takes string s, string colorcode, real x, real y returns nothing
local texttag t = CreateTextTag()
call SetTextTagText(t, colorcode + s + "|r", .023)
call SetTextTagPos(t, x,y, 100)
call SetTextTagVelocity(t, 0, .0277)
call SetTextTagLifespan( t, 3.00 )
call SetTextTagFadepoint( t, 2.00 )
call SetTextTagPermanent( t, false )
set t = null
endfunction
You know, you're actually right.
If Pooty ever comes here, you can improve the code (so that Pooty posts the most efficient one).
As if I'm always wrong![]()
library QuickTimer
//============================================================================
// Attaches and integer to a timer and makes it expire after about 0 seconds.
//
function TimerExpireQuick takes timer t, integer data, code handlerFunc returns nothing
call TimerStart(t, data/2147483648., false, handlerFunc)
endfunction
//============================================================================
// Returns the integer attached to a timer.
//
function QuickTimerGetData takes timer t returns integer
return R2I(TimerGetTimeout(t)*2147483648.)
endfunction
endlibrary
library IssuePostStopOrder requires QuickTimer
private struct Data
unit u
endstruct
private function PostActions takes nothing returns nothing
local timer t = GetExpiredTimer()
local Data d = Data(QuickTimerGetData(t))
call IssueImmediateOrderById(d.u, 851972)
call d.destroy()
call DestroyTimer(t)
set t = null
endfunction
function IssuePostStopOrder takes unit u returns nothing
local Data d = Data.create()
set d.u = u
call TimerExpireQuick(CreateTimer(), integer(d), function PostActions)
endfunction
endlibrary
JASS:library QuickTimer //============================================================================ // Attaches and integer to a timer and makes it expire after about 0 seconds. // function TimerExpireQuick takes timer t, integer data, code handlerFunc returns nothing call TimerStart(t, data/2147483648., false, handlerFunc) endfunction //============================================================================ // Returns the integer attached to a timer. // function QuickTimerGetData takes timer t returns integer return R2I(TimerGetTimeout(t)*2147483648.) endfunction endlibrary
Both of these functions are inline friendly (afaik) which means that the latest version of jasshelper inlines them. The only thing in this that requires vJass is the library so by removing it you can make a no-vJass version of it.
JASS:library IssuePostTriggerStopOrder requires QuickTimer private struct Data unit u endstruct private function PostTriggerActions takes nothing returns nothing local timer t = GetExpiredTimer() local Data d = Data(QuickTimerGetData(t)) call IssueImmediateOrderById(d.u, 851972) call d.destroy() call DestroyTimer(t) set t = null endfunction function IssuePostTriggerStopOrder takes unit u returns nothing local Data d = Data.create() set d.u = u call TimerExpireQuick(CreateTimer(), integer(d), function PostTriggerActions) endfunction endlibrary
Is it necessary to have vJASS for that?, that seems like a simple concept that really wouldn't require vJASS at all
library QuickTimer
and endlibrary
lines, so it doesn't really need vJass, but it is something that vJass using people would place in a library anyway so I wanted to be the one who names that library. To make a vJassless version out of it just remove those library lines from it.function Func2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetHandleUnit(t, "u")
call RemoveUnit(u)
call SetHandleHandle(t, "u", null)
call DestroyTimer(t)
set t = null
set u = null
endfunction
function Func1 takes nothing returns nothing
local timer t = CreateTimer()
local unit u = GetSpellTargetUnit()
call SetHandleHandle(t, "u", u)
call TimerStart(t, 0, false, function Func2)
set t = null
set u = null
endfunction
function Func takes nothing returns nothing
call RemoveUnit(GetSpellTargetUnit())
endfunction
Though I really must say that I don't see why is that function useful. It's same like I do this:
--
I don't have anything against your function, Disciple, but I would be grateful if you gave one good example of it's usage.
sorry but wtf ?If you have a trigger that fires when a unit is issued an order, you can't issue orders to the unit directly in that trigger's actions (or conditions).
call PauseUnit(GetTriggerUnit(),true) // generate an location order (0,0), 851973
call IssueImmediateOrderById ( GetTriggerUnit() , 851973) // or order stop if you want this order
call PauseUnit(GetTriggerUnit(),false)
// your order if it's different to stop
// or nothing if you want the unit to keep his last immediate order
sorry but wtf ?
I know only one problem.
Trying to give an immediate order to an unit when a location/widget order fire on it.
If you have a trigger that fires when a unit is issued an order, you can't issue orders to the unit directly in that trigger's actions (or conditions). It just won't do anything. Using TriggerExecute/Evaluate or ExecuteFunc won't help. Giving the order right after the event works instead.
So, at the risk of sounding like a big-time n00b, which I kinda am, I am having a nightmare getting the trigger editor on WorldEdit to perform what it seems should be a simple task: checking what kind of unit the triggering unit is. The best I can come up with is generic types, like buildings, town halls, workers, etc. - but I need to have it work on a specific breed of unit only, because I want it to replace unit X with unit Y.
Basically what I'm trying to do is make my eggs in my StarCraft mod hatch when they finish building, but I can't figure out how.
I considered trying Jass to achieve my ends until, much to my dismay, it looked an awful lot like programming. Which I lack the capacity to do.
So if anyone knows a good way to achieve what I'm trying to do with the trigger editor, or they have some pre-fabricated code that will help me achieve my goal, I would be very grateful.
I think what you're looking for is the unit-type comparison, look at the conditions and you'll find it (you were obviously trying to find it in the boolean comparison).
I tested only one target order scenario and though it applies to all target orders. That the fuck, incase you honestly couldn't figure it out yourself.
function SafeFilter takes nothing returns boolean
return true
endfunction
call GroupEnumUnitsInRange(g,x,y,radius,Condition(function SafeFilter))
There is something I have come across that leaks with events, but the Condition() function creates a boolexpr handle, whch would need to be destroyed when you are through with the function
By my understanding, using Condition(function SafeFilter) would create a handle that will leak if you do not set it to a variable to be removed/deleted
I may be totally wrong
Hm, I read those threads
Really didn't explain much
Memory leaks are memory that is no longer used, but has not been removed from memory
When you make a trigger handle, register events, and add condition/actions, its all memory
But my problem is this, if your going to create a boolexpr handle, and never use it again, the handle must be eliminated (when using GroupEnum() you never use the handle again)
In triggerconditions it is considered not a memory leak, because if you were to destroy the condition attached to your trigger, your trigger wouldn't function properly :O, so you leave it, taking up memory
I am totally unfamiliar with the boolexpr cache, which makes very little sense to me, so for now I will continue to remove any boolexpr I am not using
(like boolexprs for groupenum() functions)
I think the TriggerRegisterAnyUnitEventBJ() only leaks due to using null (I think)
I hope PurplePoot sees this thread and responds
TriggerRemoveCondition()
when you locally create a trigger (you also destroy triggeractions).local trigger t = CreateTrigger()
local triggeraction ta = TriggerAddAction(function Actions)
local triggercondition tc = TriggerAddCondition(function Conditions)
// ...
// ...
call TriggerRemoveAction(t, ta)
call TriggerRemoveCondition(t, tc)
call DestroyTrigger(t)
set t = null
set ta = null
set tc = null
People think that triggeractions/triggerconditions are destroyed when you destroy the actual trigger, but in reality, they aren't destroyed and they leak.
Because the reference counters on the objects are greater than zero, and thus their handle ids cannot be recycled, supposedly.I do not know why null leaks, but I have tested for myself a trigger destroy system for a damage detection system, and null leaks like a dirty mother
According to Vexorian triggerconditions are destroyed when you destroy the trigger.
//***************************
//----GetUnitSomewhere by Quraji----
//***************************
//
// To use in your map simply paste this whole code into your custom script
// section, or an empty trigger (above all functions that will use this code)
//
//
// Contains two functions:
//
// SubtractGroupFromGroup takes group source, group todestroy...
// This function removes all units in a reference group (todestroy)from a
// source group (source).
// You must include it for GetUnitSomewhere(), but also feel free to use it for
// other functions
//
//
//
// GetUnitSomewhere takes real sourceX, real sourceY, real range, boolean outsiderange, boolean nearest, boolean considerdead, boolexpr cond returns unit
// Don't let the number of parameters scare you, this is easy to use. This
// function allows you to select the nearest or farthest unit inside or outside
// a designated circle.
//
// Parameters:
//
// real sourceX and real sourceY
// these are the X and Y coordinates of the point at the center of the area
// to be considered.
//
// real range
// this is the range of the function, or the radius of the area to be considered
// (a circle).
//
// boolean outsiderange
// if false, the function will consider units inside the circle, if true it will
// consider all units selected BUT the ones in the circle.
// (remember that the circle's radius is decided by the range parameter)
//
// boolean nearest
// if true, the function will select the nearest unit to the center point inside
// the area to be considered (as you'd expect a normal GetClosestUnit()
// function to do. if false, however, it will select the farthest unit
//
// boolean considerdead
// if false the function will ignore dead units.
// (leave this at false unless you need the function to select recently killed
// units)
//
// boolexpr cond
// finally, this is where you add your own conditions if you need them by
// using a boolexpr.
//
//
// Extra feature:
//
// This function sets the bj_lastHauntedGoldMine game variable to the unit
// it selects, as well as returning the unit. This enables JASS users to use
// the function as normal, but provides a convenience for GUI users, as they
// can simply select the unit from the drop down menu for any unit field by
// selecting "Last Haunted Gold Mine". This also allows all variables to be
// nulled.
//**********************
function SubtractGroupFromGroup takes group source, group todestroy returns group
local unit current
loop
set current = FirstOfGroup(todestroy)
exitwhen current==null
call GroupRemoveUnit(source, current)
call GroupRemoveUnit(todestroy, current)
endloop
set current = null
return source
endfunction
function GetUnitSomewhere takes real sourceX, real sourceY, real range, boolean outsiderange, boolean nearest, boolean considerdead, boolexpr cond returns unit
local group g=CreateGroup()
local group tempg=CreateGroup()
local unit current
local unit winner
local real currentX
local real currentY
local real dist
call GroupEnumUnitsInRange(g,sourceX,sourceY,range,cond)
if not nearest then
set range=.0
endif
if outsiderange then
call GroupEnumUnitsInRect(tempg,bj_mapInitialPlayableArea,cond)
set g = SubtractGroupFromGroup(tempg,g)
endif
loop
set current=FirstOfGroup(g)
exitwhen current==null
if GetWidgetLife(current)>0.405 or considerdead then
set currentX=GetWidgetX(current)-sourceX
set currentY=GetWidgetY(current)-sourceY
set dist=SquareRoot(currentX*currentX+currentY*currentY)
if outsiderange then
set range=dist
set outsiderange = not outsiderange
endif
if (nearest and dist<=range) or (not nearest and dist>=range) then
set winner=current
set range=dist
endif
endif
call GroupRemoveUnit(g,current)
endloop
call DestroyGroup(g)
call DestroyGroup(tempg)
set tempg=null
set g=null
set current=null
set bj_lastHauntedGoldMine=winner
set winner=null
return bj_lastHauntedGoldMine
endfunction
Ideally, you should only use globals for temp groups such as these, not locals.requires no Globals
Because then you don't have to declare a local, create the group, destroy the group, and null the local.Why?
The biggest problem with this method is the horribly long parameter list.There is a boolexpr allowed for extra conditions, however I found those 3 booleans to be very useful. "outsiderange" and "nearest" are simply part of the main function of the erm....function. And "considerdead" I added because many people use functions like this without realizing that they do return dead units.
The GetClosestUnit function in the first post.Can you point me to Silvenon's function please? I can't find it.
Fix up Silv's so it uses a global group, among other things. Or get him to, of course.Also, I'm confused as to what you mean by "however, I'm tempted to revise even it to quicken it."![]()