- Joined
- Sep 9, 2007
- Messages
- 6,759
Err, you are right, my mistake, fixed it.
library TestLib uses TableMacros
struct test
implement TableMacros
endstruct
endlibrary
library CustomSpells initializer Init
private hashtable Hash
#define private SPELL_BEGIN_KEY = 0
private function interface SpellFunction takes nothing returns nothing
private void OnBegin(){
SpellFunction(LoadInteger(Hash, SPELL_BEGIN_KEY, GetSpellAbilityId())).execute()
}
private void Init(){
trigger t = CreateTrigger()
TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
TriggerAddAction(t, function OnBegin)
Hash = InitHashtable()
}
public void AddOnBegin(int id, SpellFunction sf){
SaveInteger(Hash, SPELL_BEGIN_KEY, id, int(sf))
}
endlibrary
if (GetSpellAbilityId == MY_ABIL) //etc
function SetPathingRect takes rect re, pathingtype pt, boolean pathable returns nothing
//probably this trigger won't work if you don't snap the regions to the grid
//available pathing types
//PATHING_TYPE_ANY //if this is false you can't walk/build/fly on it
//PATHING_TYPE_WALKABILITY //if this is false you can't walk on it
//PATHING_TYPE_FLYABILITY //if this is false you can't fly on it
//PATHING_TYPE_BUILDABILITY //if this is false you can't build on it
//PATHING_TYPE_PEONHARVESTPATHING //don't know
//PATHING_TYPE_BLIGHTPATHING //if this is false you can't build ziggs on it
//PATHING_TYPE_FLOATABILITY //don't know
//PATHING_TYPE_AMPHIBIOUSPATHING //don't know
local real r = 32 //size of pathing blocks
local real x = GetRectMinX(re)
local real y
local real x2 = GetRectMaxX(re)
local real y2 = GetRectMaxY(re)
loop
exitwhen x == x2
set y = GetRectMinY(re)
loop
exitwhen y == y2
call SetTerrainPathable(x, y, pt, pathable)
set y = y + r
endloop
set x = x + r
endloop
endfunction
//! zinc
library HashtableUtils
{
integer Count = 0;
hashtable HashArr[];
public function NewHashtable () -> hashtable
{
if (Count > 0)
{
Count -= 1;
return HashArr[Count];
}
else
{
return InitHashtable();
}
}
public function ReleaseHashtable (hashtable h)
{
if (h != null)
{
FlushParentHashtable(h);
HashArr[Count] = h;
Count += 1;
}
else
{
debug BJDebugMsg("HashtableUtils: attempt to release a null hashtable");
}
}
}
//! endzinc
call CreateTimedEffect(x, y, time, modelname)
call CreateTimedEffectAtUnit(unit, time, modelname, attachpoint)
function CreateTimedEffect_Cleanup takes nothing returns nothing
local timer cleanup_cte_tim = GetExpiredTimer()
call DestroyEffect(LoadEffectHandle(udg_cte_Table, GetHandleId(cleanup_cte_tim), 0))
call FlushChildHashtable(udg_cte_Table, GetHandleId(cleanup_cte_tim))
call DestroyTimer(cleanup_cte_tim)
set cleanup_cte_tim = null
endfunction
function CreateTimedEffect takes real x, real y, real t, string s returns nothing
local effect cte_eff = AddSpecialEffect(s, x, y)
local timer cte_tim = CreateTimer()
call SaveEffectHandle(udg_cte_Table, GetHandleId(cte_tim), 0, cte_eff)
call TimerStart(cte_tim, t, false, function CreateTimedEffect_Cleanup)
set cte_eff = null
set cte_tim = null
endfunction
function CreateTimedEffectAtUnit takes unit u, real t, string s, string p returns nothing
local effect cteu_eff = AddSpecialEffectTarget(s, u, p)
local timer cteu_tim = CreateTimer()
call SaveEffectHandle(udg_cte_Table, GetHandleId(cteu_tim), 0, cteu_eff)
call TimerStart(cteu_tim, t, false, function CreateTimedEffect_Cleanup)
set cteu_eff = null
set cteu_tim = null
endfunction
function factorial takes integer n returns integer
if n <= 1 then
return 1
endif
return n*factorial(n-1)
endfunction
function parity takes integer n returns boolean
return ModuloInteger(n,2) != 1
endfunction
function B2S takes boolean b returns string
if b then
return "True"
endif
return "False"
endfunction
function I2B takes integer i returns boolean
if i == 1 then
return true
endif
return false
endfunction
function B2I takes boolean b returns integer
if b == true then
return 1
endif
return 0
endfunction
globals
private unit u = null
endglobals
function UNIT2B takes unit u returns boolean
if u != null then
return true
endif
return false
endfunction
function B2UNIT takes boolean b returns unit
if b == true then
set u = CreateUnit(Player(15), 'rofl', 0., 0., 0.)
call HideUnit(u)
return u
endif
return null
endfunction
function GetClosestNumberToX takes integer base, integer x returns integer
if base == 0 or IAbsBJ(base) <= IAbsBJ(x) then
return x
endif
loop
exitwhen base-base/x*x == 0
if base-base/x*x <= x/2 then
set base = base - 1
else
set base = base + 1
endif
endloop
return base
endfunction
library IsPointInRectangle
//determins if point P is in rectangle ABCD
function IsPointInRectangle takes real ax, real ay, real bx, real by, real cx, real cy, real dx, real dy, real px, real py returns boolean
local real cross0 = (py-ay)*(bx-ax)-(px-ax)*(by-ay)
local real cross1 = (py-cy)*(ax-cx)-(px-cx)*(ay-cy)
local real cross4 = (py-dy)*(ax-dx)-(px-dx)*(ay-dy)
return ((cross0*cross1 >= 0) and (((py-by)*(cx-bx)-(px-bx)*(cy-by))*cross1 >= 0)) or ((cross0*cross4 >= 0) and (((py-by)*(dx-bx)-(px-bx)*(dy-by))*cross4 >= 0))
endfunction
endlibrary
library GetTriangleCentroid
//get centroid x,y of triangle ABC
function GetTriangleCentroidX takes real ax, real bx, real cx returns real
return (ax+bx+cx)/3
endfunction
function GetTriangleCentroidY takes real ay, real by, real cy returns real
return (ay+by+cy)/3
endfunction
endlibrary
library IsPointInTriangle
//check to see if a point P is in triangle ABC
function IsPointInTriangle takes real ax, real ay, real bx, real by, real cx, real cy, real px, real py returns boolean
local real cross0 = (py-ay)*(bx-ax)-(px-ax)*(by-ay)
local real cross1 = (py-cy)*(ax-cx)-(px-cx)*(ay-cy)
return (cross0*cross1 >= 0) and (((py-by)*(cx-bx)-(px-bx)*(cy-by))*cross1 >= 0)
endfunction
endlibrary
library LineSlopeIntercept
//returns the slope given vector [(x1, y1), (x2, y2)]
function GetVectorSlope takes real x1, real y1, real x2, real y2 returns real
return (y2-y1)/(x2-x1)
endfunction
//returns y intercept given point (x,y) and slope m
function GetLineYIntercept takes real x, real y, real m returns real
return y-m*x
endfunction
endlibrary
function IsPointOnLine takes real slope, real yIntercept, real x, real y returns boolean
return y == slope * x + yIntercept
endfunction
// We've got a line given by P1(x1, y1) and P2(x2, y2) as well as a ray given by P3(x3, y3) and angle a.
// This function returns the distance from P3 to the intersection point.
// The distance returned is negative if the ray points away from the line.
//
library GetIntersectionDistance
function GetIntersectionDistance takes real x1, real y1, real x2, real y2, real x3, real y3, real a returns real
local real m = x1 - x2
if (m == 0) then // Avoid division by zero
return (x1 - x3) / Cos(a)
endif
set m = (y1 - y2) / m
if (m == Tan(a)) then // Parallel (avoid division by zero again: Sin(a) - Tan(a) * Cos(a) == 0)
return 0.
endif
return (m * (x3 - x1) + y1 - y3) / (Sin(a) - m * Cos(a))
endfunction
endlibrary
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table
globals
private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice
endglobals
// don't touch below this line
globals
private boolean Is_game_loaded = false
endglobals
static if CARE_ABOUT_SAVED_GAMES then // works for a global block but not for a variable inside a global block
globals
private Table Tab
endglobals
endif
function IsGameLoaded takes nothing returns boolean
return Is_game_loaded
endfunction
function IsUnitTypeId takes integer unitid returns boolean
static if CARE_ABOUT_SAVED_GAMES then
local unit u
if IsGameLoaded() then
if Tab.exists(unitid) then
return Tab[unitid] != 0
endif
// IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id
// so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here
set u = CreateUnit(Player(13),unitid,0.,0.,0.)
if u != null then
call RemoveUnit(u)
set u = null
set Tab[unitid] = 1
return true
else
set Tab[unitid] = 0
return false
endif
endif
endif
return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug
endfunction
private function GameLoaded takes nothing returns boolean
set Is_game_loaded = true
call DestroyBoolExpr(Condition(function GameLoaded))
call DestroyTrigger(GetTriggeringTrigger())
return false
endfunction
static if CARE_ABOUT_SAVED_GAMES then
// coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ...
// but in some case this kind of initializer can be "handy", here we avoid an unecessary init
module onInit
static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED)
call TriggerAddCondition(trig,Condition(function GameLoaded))
set trig = null
static if CARE_ABOUT_SAVED_GAMES then
set Tab = Table.create()
endif
endmethod
endmodule
struct s_dummy extends array
implement onInit
endstruct
endif
endlibrary
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table
globals
private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice
endglobals
// don't touch below this line
globals
private boolean Is_game_loaded = true
private integer Tab
endglobals
function IsGameLoaded takes nothing returns boolean
return Is_game_loaded
endfunction
function IsUnitTypeId takes integer unitid returns boolean
static if CARE_ABOUT_SAVED_GAMES then
local unit u
if IsGameLoaded() then
if Table(Tab).exists(unitid) then
return Table(Tab)[unitid] != 0
endif
// IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id
// so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here
set u = CreateUnit(Player(13),unitid,0.,0.,0.)
if u != null then
call RemoveUnit(u)
set u = null
set Table(Tab)[unitid] = 1
return true
else
set Table(Tab)[unitid] = 0
return false
endif
endif
endif
return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug
endfunction
private function GameLoaded takes nothing returns boolean
set Is_game_loaded = true
call DestroyBoolExpr(Condition(function GameLoaded))
call DestroyTrigger(GetTriggeringTrigger())
return false
endfunction
static if CARE_ABOUT_SAVED_GAMES then
// coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ...
// but in some case this kind of initializer can be "handy", here we avoid an unecessary init
module onInit
static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED)
call TriggerAddCondition(trig,Condition(function GameLoaded))
set trig = null
static if CARE_ABOUT_SAVED_GAMES then
set Tab = integer(Table.create())
endif
endmethod
endmodule
struct s_dummy extends array
implement onInit
endstruct
endif
endlibrary
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table
globals
private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice
endglobals
// don't touch below this line
static if CARE_ABOUT_SAVED_GAMES then
private keyword s_dummy
private function GameLoaded takes nothing returns boolean
set s_dummy.is_game_loaded = true
call DestroyBoolExpr(Condition(function GameLoaded))
call DestroyTrigger(GetTriggeringTrigger())
return false
endfunction
// coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ...
// but in some case this kind of initializer can be "handy", here we avoid an unecessary init
private module onInit
static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED)
call TriggerAddCondition(trig,Condition(function GameLoaded))
set trig = null
set s_dummy.tab = Table.create()
endmethod
endmodule
private struct s_dummy extends array // the extends array avoid some unneeded stuff
static Table tab
static boolean is_game_loaded = false
implement onInit
endstruct
function IsGameLoaded takes nothing returns boolean
return s_dummy.is_game_loaded
endfunction
endif
function IsUnitTypeId takes integer unitid returns boolean
static if CARE_ABOUT_SAVED_GAMES then
local unit u
if IsGameLoaded() then
if s_dummy.tab.exists(unitid) then
return s_dummy.tab[unitid] != 0
endif
// IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id
// so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here
set u = CreateUnit(Player(13),unitid,0.,0.,0.)
if u != null then
call RemoveUnit(u)
set u = null
set s_dummy.tab[unitid] = 1
return true
else
set s_dummy.tab[unitid] = 0
return false
endif
endif
endif
return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug
endfunction
endlibrary
//SetCameraField() has an input of degrees, but GetCameraField() returns radians.
//This script will keep everything in degrees for ease of usage.
function GetCameraFieldEx takes camerafield whichField returns real
if (whichField != CAMERA_FIELD_FARZ and whichField != CAMERA_FIELD_TARGET_DISTANCE and whichField != CAMERA_FIELD_ZOFFSET) then
return GetCameraField(whichField) * bj_RADTODEG
endif
return GetCameraField(whichField)
endfunction
//This function will control whether or not transmissions can be skipped
function EnableTransmissionSkip takes boolean flag returns nothing
if (flag) then
call DestroyTrigger(bj_cineSceneBeingSkipped) //just in case it was created in this function
call TryInitCinematicBehaviorBJ() //recreate it
else
if (bj_cineSceneBeingSkipped == null) then //if it is null, create it
set bj_cineSceneBeingSkipped = CreateTrigger() //creating it without events will bypass the init behavior
else
call DisableTrigger(bj_cineSceneBeingSkipped) //disable it if it already exists
endif
endif
endfunction
library KnuthChecksum uses BigInt
function GetKnuthChecksum takes BigInt k, BigInt m returns BigInt
local BigInt c = k.copy()
call c.add(3)
call c.multiplyBig(k)
set k = c.modBig(m)
call c.destroy()
return k
endfunction
endlibrary
struct Tester extends array
private static method onInit takes nothing returns nothing
local string checksumStr = "3234567"
local BigInt security = BigInt.convertString(checksumStr, Base["0123456789"])
local BigInt int = BigInt.convertString("1234567890123456789", Base["0123456789"])
local BigInt checksum = KnuthChecksum(int, security)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, int.toString())
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, checksum.toString())
endmethod
endstruct
1=1(1+3) = 4
2=2(2+3) = 10
3=3(3+3) = 18
4=4(4+3) = 28
And why it would ? (vJass uses double underscore not single)s_dummy in the IsUnitTypeId... won't that throw a syntax error?
Actually they do (i used them like that since my beginning with vJass which is few years), but ofc for naming variables and functions you have to begin with a letter and end with a letter or a number, so it's the same for a struct since methods and members are named depends the struct name.(structs with underscore don't compile with JassHelper)
function valueBetween takes integer oInt1, integer oInt2 returns integer
// Let us calculate the value between the integers.
//
if ( oInt1 > oInt2 ) then
return ( oInt1 - oInt2 ) / 2
else if ( oInt1 < oInt2 ) then
return ( oInt2 - oInt1 ) / 2
endif
endfunction
// Just to make this function a little bit clearer, I made a examble.
//
// call valueBetween( 2, 1 )
// [ return = 0.5 ]
//
// call valueBetween( 1, 2 )
// [ return = -0.5 ]
//
set i = i1 - i2
if i <0 then
set i = -i
endif
// Sets a boolean of a player's playing state
library IsPlaying
struct IsPlaying extends array
static boolean array player
static method operator [] takes integer i returns boolean
return thistype.player[i]
endmethod
static method onInit takes nothing returns nothing
local integer i = 11
loop
set thistype.player[i] = GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER
//modify this condition as needed
exitwhen i == 0
set i = i - 1
endloop
endmethod
endstruct
endlibrary
IsPlaying[integer]
or IsPlaying.player[integer]
. Why did I make this though? Well, let's say you do something as simple as this:library TriggerRegisterAnyUnitEvent
function TriggerRegisterAnyUnitEvent takes trigger t, playerunitevent whichEvent returns nothing
local integer i = 15
loop
if IsPlaying[i] or i > 11 then
call TriggerRegisterPlayerUnitEvent(t,Player(i),whichEvent,null)
endif
exitwhen i == 0
set i = i - 1
endloop
endfunction
endlibrary
TriggerRegisterAnyUnitEventBJ
, I had 272 total handles (running single-player). In a map using the modified one with 10 registries, I had 162 handles (running single-player). That is a saving of 110 handles. Not bad. library TriggerRegisterAnyUnitEvent requires PlayerManager
function TriggerRegisterAnyUnitEvent takes trigger t, playerunitevent whichEvent returns nothing
local ActivePlayer p = 0
loop
call TriggerRegisterPlayerUnitEvent(t, p.get, whichEvent, null)
set p = p.next
exitwhen p.end
endloop
endfunction
endlibrary