Name | Type | is_array | initial_value |
//TESH.scrollpos=61
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this), $key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("String","string","StringHash(key)" )
endlibrary
//TESH.scrollpos=18
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 13th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* Table
What this module does:
Adds the ability to save/load/remove
object instances.
*/
/* ----------------------------------- */
module TableMacros
public static Table INSTANCES = 0
public static boolean DEBUG = false
public integer ID = 0
private static method onInit takes nothing returns nothing
set thistype.INSTANCES = Table.create()
debug if thistype.DEBUG then
debug call BJDebugMsg("[|cffffcc00" + I2S(.INSTANCES) + "|r] Initialized.")
debug endif
endmethod
public method save takes nothing returns nothing
set thistype.INSTANCES[.ID] = integer(this)
debug if thistype.DEBUG then
debug call BJDebugMsg("[|cffffcc00" + I2S(.INSTANCES) + "|r] SAVED (|cffffcc00Key|r: " + GetObjectName(.ID) + " | |cffffcc00ID|r: " + I2S(integer(this)) + " )")
debug endif
endmethod
public method remove takes nothing returns nothing
debug if thistype.DEBUG then
debug call BJDebugMsg("[|cffffcc00" + I2S(.INSTANCES) + "|r] KILLED (|cffffcc00Key|r: " + GetObjectName(.ID) + " | |cffffcc00ID|r: " + I2S(integer(this)) + " )")
debug endif
call thistype.INSTANCES.flush(.ID)
call .destroy()
endmethod
public method clear takes nothing returns nothing
debug if thistype.DEBUG then
debug call BJDebugMsg("[|cffffcc00" + I2S(.INSTANCES) + "|r] CLEARED (|cffffcc00Key|r: " + GetObjectName(.ID) + " | |cffffcc00ID|r: " + I2S(integer(this)) + " )")
debug endif
call thistype.INSTANCES.flush(.ID)
endmethod
public static method load takes integer id returns thistype
debug if thistype.DEBUG then
debug call BJDebugMsg("[|cffffcc00" + I2S(.INSTANCES) + "|r] LOADED (|cffffcc00Key|r: " + GetObjectName(id) + " | |cffffcc00ID|r: " + I2S(integer(thistype(thistype.INSTANCES[id]))) + " )")
debug endif
return thistype(thistype.INSTANCES[id])
endmethod
endmodule
//TESH.scrollpos=37
//TESH.alwaysfold=0
library AdvancedTable
//: CnP from Vexorians Table.
//: Sorry dude, there is no other way.
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
private hashtable ht
// Actually this is the data holder
endglobals
//=========================================================
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//: Setup textmacros for table creation.
//! textmacro AdvancedTable_make takes name, valType, func, funcPref, hashType, paraType, keyType, key, value
struct $name$Table extends GTable
method operator [] takes $keyType$ key returns $valType$
return Load$func$$funcPref$(ht, integer(this), $key$)
endmethod
method operator []= takes $keyType$ key, $paraType$ value returns nothing
call Save$func$$funcPref$(ht, integer(this) ,$key$, $value$)
endmethod
method flush takes $keyType$ key returns nothing
call RemoveSaved$hashType$(ht, integer(this), $key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$Table(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$Table
return $name$Table(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//: Finally create our crazy tables.
// TableName DataType Func Prefix hashID paraType keyType key value
//! runtextmacro AdvancedTable_make("Integer", "integer", "Integer", "", "Integer", "integer", "integer", "key", "value")
//! runtextmacro AdvancedTable_make("Boolean", "boolean", "Boolean", "", "Boolean", "boolean", "integer", "key", "value")
//! runtextmacro AdvancedTable_make("Unit", "unit", "Unit", "Handle", "Handle", "unit", "integer", "key", "value")
//! runtextmacro AdvancedTable_make("Item", "item", "Item", "Handle", "Handle", "item", "integer", "key", "value")
//! runtextmacro AdvancedTable_make("Effect", "effect", "Effect", "Handle", "Handle", "effect", "integer", "key", "value")
//! runtextmacro AdvancedTable_make("Dest", "destructable", "Destructable", "Handle", "Handle", "destructable", "integer", "key", "value")
endlibrary
//TESH.scrollpos=36
//TESH.alwaysfold=0
library AbilityPreload
//===========================================================================
// Information:
//==============
//
// Preloading removes the noticeable delay the first time an ability
// is loaded in a game. If an ability was not already on a pre-placed unit
// or a unit that was created during initialization, preloading is needed
// to prevent a delay.
//
//===========================================================================
// AbilityPreload API:
//=====================
//
// AbilityPreload(abilityid) :
// Call this before any time has elapsed to preload a specific
// ability. If debug mode is enabled, you will see an error message
// if you call this after initialization, or if you try to preload
// an ability that does not exist. Will inline to a UnitAddAbility
// call if debug mode is disabled.
//
// AbilityRangePreload(start, end) :
// Same as AbilityPreload, but preloads a range of abilities.
// It will iterates between the two rawcode values and preload
// every ability along the way. It will not show an error message
// for non-existent abilities.
//
//===========================================================================
// Configuration:
//================
globals
private constant integer PreloadUnitRawcode = 'zsmc'
//This is the rawcode for "Sammy!". It is never used and has no model,
//which makes an ideal preloading unit. Change it if you want to.
endglobals
//===========================================================================
globals
private unit PreloadUnit
endglobals
function AbilityPreload takes integer abilityid returns nothing
static if DEBUG_MODE then
if GetUnitTypeId(PreloadUnit) == 0 then
call BJDebugMsg("AbilityPreload error: Can't preload an ability after initialization")
return
endif
endif
call UnitAddAbility(PreloadUnit, abilityid)
static if DEBUG_MODE then
if GetUnitAbilityLevel(PreloadUnit, abilityid) == 0 then
call BJDebugMsg("AbilityPreload error: Attempted to preload a non-existent ability")
endif
endif
endfunction
function AbilityRangePreload takes integer start, integer end returns nothing
local integer i = 1
static if DEBUG_MODE then
if GetUnitTypeId(PreloadUnit) == 0 then
call BJDebugMsg("AbilityPreload error: Can't preload an ability after initialization")
return
endif
endif
if start > end then
set i = -1
endif
loop
exitwhen start > end
call UnitAddAbility(PreloadUnit, start)
set start = start + i
endloop
endfunction
//===========================================================================
private struct Init extends array
private static method onInit takes nothing returns nothing
set PreloadUnit = CreateUnit(Player(15), PreloadUnitRawcode, 0., 0., 0.)
call UnitApplyTimedLife(PreloadUnit, 0, .001)
call ShowUnit(PreloadUnit, false)
call UnitAddAbility(PreloadUnit, 'Aloc')
endmethod
endstruct
endlibrary
//TESH.scrollpos=189
//TESH.alwaysfold=0
library AutoIndex
//===========================================================================
// Information:
//==============
//
// AutoIndex is a very simple script to utilize. Just call GetUnitId(unit) to
// get get the unique value assigned to a particular unit. AutoIndex differs from
// other unit indexing libraries because it automatically assigns an ID to each
// unit as it enters the map, and automatically frees that ID as the unit leaves
// the map. This gives you several advantages as the user:
// -The GetUnitId function inlines directly to a GetUnitUserData call (or a
// LoadInteger call if the UseUnitUserData constant is set to false.)
// -You don't need to manually free IDs as units leave the map.
// -Detecting removing units to free their indexes is O(1), and less costly
// performance-wise than a timer scanning the map for removed units.
//
// If you turn on debug mode, AutoIndex will become slower, but it will be able
// to display several helpful error messages. It can detect the following issues:
// -Passing a removed or decayed unit to GetUnitId
// -Code outside of AutoIndex has overwritten a unit's UserData value.
// -GetUnitId was used on a filtered unit (a unit you don't want indexed).
//
// AutoIndex uses UnitUserData by default. If something else in your map
// would conflict with that, you can set the UseUnitUserData configuration
// constant to false, and a hashtable will be used instead. Note that hash-
// tables are about 60% slower.
//
// AutoIndex provides events upon indexing or deindexing units. This
// effectively allows you to notice when units enter or leave the game, and
// handle the creation or destruction of attached data or other things. Also
// included is the AutoStruct module, which automatically creates and destroys
// struct instances associated with units as they enter and leave the game.
//
//===========================================================================
// How to install AutoIndex:
//===========================
//
// 1.) Copy and paste this script into your map.
// 2.) Save it to allow the ObjectMerger macro to generate the "Leave Detect"
// ability for you. Close and re-open the map. After that, disable the macro
// to prevent the save delay.
//
//===========================================================================
// How to use AutoIndex:
//=======================
//
// So you can get a unique integer for each unit, but how do you use that to
// attach data to a unit? GetUnitId will always return a number in the range of
// 1-8190. This means it can be used as an array index, as demonstrated below:
/*
globals
integer array IntegerData
real array RealData
SomeStruct array SomeStructData
englobals
function Example takes nothing returns nothing
local unit u = CreateUnit(...)
local integer id = GetUnitId(u)
//You now have a unique index for the unit, so you can
//attach or retrieve data about the unit using arrays.
set IntegerData[id] = 5
set RealData[id] = 25.0
set SomeStructData[id] = SomeStruct.create()
//If you have access to the same unit in another function, you can
//retrieve the data by using GetUnitId() and reading the arrays.
endfunction
*/
// The UnitFilter function in the configuration section is provided so that
// you can make AutoIndex completely ignore certain unit-types. Ignored units
// won't be indexed or fire indexed/deindexed events. You may want to filter out
// dummy casters or system-private units, especially ones that use UnitUserData
// internally. xe dummy units are automatically filtered.
//
//===========================================================================
// How to use OnUnitIndexed / OnUnitDeindexed:
//=============================================
//
// AutoIndex will fire the OnUnitIndexed event when a unit enters the map,
// and the OnUnitDeindexed event when a unit leaves the map. Functions used
// as events must take a unit and return nothing. An example is given below:
/*
function UnitEntersMap takes unit u returns nothing
call BJDebugMsg(GetUnitName(u)+" was indexed with the ID "+I2S(GetUnitId(u)))
endfunction
function UnitLeavesMap takes unit u returns nothing
call BJDebugMsg(GetUnitName(u)+" was deindexed with the ID "+I2S(GetUnitId(u)))
endfunction
function Init takes nothing returns nothing
call OnUnitIndexed(UnitEntersMap)
call OnUnitDeindexed(UnitLeavesMap)
endfunction
*/
// As you can see, it works perfectly fine to call GetUnitId() on a unit
// during either of these events.
//
// If you call OnUnitIndexed during map initialization, every existing
// unit will be considered as entering the map. This saves you from needing
// to manually enumerate preplaced units (or units created by initialization
// code that ran before OnUnitIndexed was called).
//
// OnUnitDeindexed runs while a unit still exists, which means you can
// still do things such as destroy special effects attached to the unit.
// The unit will cease to exist immediately after the event is over.
//
//===========================================================================
// AutoIndex API:
//================
//
// GetUnitId(unit) -> integer
// This function returns a unique ID in the range of 1-8190 for the
// specified unit. Ruturns 0 if a null unit was passed. This function
// inlines directly to GetUnitUserData or LoadInteger if debug mode
// is disabled. If debug mode is enabled, this function will print
// an error message when passed a decayed or filtered unit.
//
// IsUnitIndexed(unit) -> boolean
// This function returns a boolean indicating whether the specified
// unit has been indexed. The only time this will return false is
// for units you have filtered using the UnitFilter function, or
// for xe dummy units. You can use this function to easily detect
// dummy units and avoid performing certain actions on them.
//
// OnUnitIndexed(IndexFunc)
// This function accepts an IndexFunc, which must take a unit and
// return nothing. The IndexFunc will be fired instantly whenever
// a unit enters the map. You may use GetUnitId on the unit. When
// you call this function during map initialization, every existing
// unit will be considered as entering the map.
//
// OnUnitDeindexed(IndexFunc)
// Same as above, but runs whenever a unit is leaving the map. When
// this event runs, the unit still exists, but it will cease to exist
// as soon as the event ends. You may use GetUnitId on the unit.
//
//===========================================================================
// How to use the AutoStruct module:
//===================================
//
// The AutoStruct module allows you to automatically create and destroy
// struct instances as units enter and leave the game. An instance of the
// implementing struct will be created each time a unit enters the game,
// and destroyed when that unit leaves the game. (You cannot create or dest-
// roy instances manually.) This means that you should consider each inst-
// ance of an AutoStruct to be "owned by" a specific unit.
//
// AutoStruct restrictions:
// -You may not implement AutoStruct in any struct that declares its
// own create, destroy, or operator[] methods.
// -You may not manually create or destroy structs implementing AutoStruct.
// -AutoStruct may be implemented in structs that extend interfaces or
// other structs, but only if the allocate() method takes no parameters.
// (The restriction of allocate() taking no parameters may be changed soon.)
// -AutoStruct will not work with structs that extend array, since they
// can't be created or destroyed.
//
// AutoStruct features:
// -An instance of the implementing struct will be created each time a
// unit enters the game. That instance will be destroyed when that unit
// leaves the game. The struct will always exist while the unit does.
// -You can retrieve an AutoStruct from a unit by using the syntax:
// local StructName mystruct = StructName[unit]
// //This inlines to a GetUnitId() call + array lookup.
// -You can refer to the unit that owns the instance by the member "me":
// //Outside of the struct: call BJDebugMsg(GetUnitName(mystruct.me))
// //From within the struct: call BJDebugMsg(GetUnitName(me))
// -You can use the optional methods onCreate and onDestroy to notice when
// instances of a struct implementing AutoStruct are created and destroyed.
// This is equivalent to detecting a unit entering and leaving the game.
/*
struct Example
private method onCreate takes nothing returns nothing
call BJDebugMsg(GetUnitName(me)+" has entered the game!")
endmethod
private method onDestroy takes nothing returns nothing
call BJDebugMsg(GetUnitName(me)+" has left the game!")
endmethod
implement AutoStruct
endstruct
*/
// -You can filter which units will recieve an AutoStruct by using the
// optional static method createFilter. The createFiler method must take
// a unit parameter and return a boolean (true if created, false if not).
/*
struct Example
private static method createFiler takes unit u returns boolean
return GetUnitTypeId(u) == 'hfoo' //Only Footmen will recieve this AutoStruct.
endmethod
implement AutoStruct
endstruct
*/
//
//===========================================================================
// Configuration:
//================
static if CI_NEW_MAP then
//! external ObjectMerger w3a Adef lvdt anam "Leave Detect" aart "" arac 0
endif
//Save your map with this Object Merger call enabled, then close and reopen your
//map. Disable it by removing the exclamation to remove the delay while saving.
globals
private constant integer LeaveDetectAbilityID = 'lvdt'
//This rawcode must match the parameter after "Adef" in the
//ObjectMergermacro above. You can change both if you want.
private constant boolean UseUnitUserData = true
//If this is set to true, UnitUserData will be used. You should only set
//this to false if something else in your map already uses UnitUserData.
//A hashtable will be used instead, but it is about 60% slower.
endglobals
private function UnitFilter takes unit u returns boolean
return true
endfunction
//Make this function return false for any unit-types you wish to be ignored.
//Ignored units won't be indexed or fire OnUnitIndexed/OnUnitDeindexed
//events. Use the unit u parameter to refer to the unit being filtered.
//You do not need to filter out xe dummy units; they are already filtered.
//===========================================================================
// AutoStruct module:
//====================
function interface AutoStructCreator takes unit u returns integer
function interface AutoStructDestroyer takes unit u returns nothing
module AutoStruct
private static thistype array data
unit me //The unit that "owns" this struct instance is referred to as "me".
static method operator [] takes unit u returns thistype
return data[GetUnitId(u)] //Return the struct instance associated with the unit.
endmethod
private static method create takes unit u returns thistype
local thistype this
static if thistype.createFilter.exists then //If the createFiler exists...
if not createFilter(u) then //If the unit fails the createFilter...
return 0 //Don't allocate a struct for this unit.
endif
endif
set this = allocate() //Allocate the struct.
set me = u //Assign the "me" unit of this struct to the entering unit.
set data[GetUnitId(u)] = this //Attach this instance to the unit.
static if thistype.onCreate.exists then //If onCreate exists...
call onCreate() //Call the onCreate() method for this struct.
endif
return this
endmethod
//create is private; the user doesn't create AutoStructs. They are created
//automatically when a unit enters the game and passes the createFilter.
private method destroy takes nothing returns nothing
endmethod
//destroy is private; the user doesn't destroy AutoStructs. They are destroyed
//automatically when their corresponding units leave the game.
private static method destroyer takes unit u returns nothing
local thistype this = thistype[u] //Get the instance of the struct for this unit.
if this != 0 then //If it has an instance...
call deallocate() //Deallocate it, calling onDestroy.
set .data[GetUnitId(me)] = 0 //Null the unit's associated struct instance.
set me = null //Null the unit reference.
endif
endmethod
private static method onInit takes nothing returns nothing
call AutoIndex.addAutoStruct(thistype.create, thistype.destroyer)
//Pass pointers to the create and destroyer functions to AutoIndex, so
//that it can create/destroy instances as units are indexed/deindexed.
endmethod
endmodule
//===========================================================================
// AutoIndex struct:
//===================
function interface IndexFunc takes unit u returns nothing
hook RemoveUnit AutoIndex.hook_RemoveUnit
hook ReplaceUnitBJ AutoIndex.hook_ReplaceUnitBJ
debug hook SetUnitUserData AutoIndex.hook_SetUnitUserData
private keyword getIndex
private keyword getIndexDebug
private keyword isUnitIndexed
private keyword onUnitIndexed
private keyword onUnitDeindexed
struct AutoIndex
private static trigger enter = CreateTrigger()
private static trigger order = CreateTrigger()
private static trigger creepdeath = CreateTrigger()
private static group preplaced = CreateGroup()
private static timer allowdecay = CreateTimer()
private static hashtable ht
private static boolean array dead
private static boolean array summoned
private static boolean array animated
private static boolean array nodecay
private static boolean array removing
private static IndexFunc array indexfuncs
private static integer indexfuncs_n = -1
private static IndexFunc array deindexfuncs
private static integer deindexfuncs_n = -1
private static IndexFunc indexfunc
private static AutoStructCreator array creators
private static AutoStructDestroyer array destroyers
private static integer autostructs_n = -1
private static unit array allowdecayunit
private static integer allowdecay_n = -1
private static boolean duringinit = true
private static boolean array altered
private static unit array idunit
//===========================================================================
static method getIndex takes unit u returns integer
static if UseUnitUserData then
return GetUnitUserData(u)
else
return LoadInteger(ht, 0, GetHandleId(u))
endif
endmethod
//Resolves to an inlinable one-liner after the static if.
static method getIndexDebug takes unit u returns integer
if u == null then
return 0
elseif GetUnitTypeId(u) == 0 then
call BJDebugMsg("AutoIndex error: Removed or decayed unit passed to GetUnitId.")
elseif idunit[getIndex(u)] != u and GetIssuedOrderId() != 852056 then
call BJDebugMsg("AutoIndex error: "+GetUnitName(u)+" is a filtered unit.")
endif
return getIndex(u)
endmethod
//If debug mode is enabled, use the getIndex method that shows errors.
private static method setIndex takes unit u, integer index returns nothing
static if UseUnitUserData then
call SetUnitUserData(u, index)
else
call SaveInteger(ht, 0, GetHandleId(u), index)
endif
endmethod
//Resolves to an inlinable one-liner after the static if.
static method isUnitIndexed takes unit u returns boolean
return u != null and idunit[getIndex(u)] == u
endmethod
static method isUnitAnimateDead takes unit u returns boolean
return animated[getIndex(u)]
endmethod
//Don't use this; use IsUnitAnimateDead from AutoEvents instead.
//===========================================================================
private static method onUnitIndexed_sub takes nothing returns nothing
call indexfunc.evaluate(GetEnumUnit())
endmethod
static method onUnitIndexed takes IndexFunc func returns nothing
set indexfuncs_n = indexfuncs_n + 1
set indexfuncs[indexfuncs_n] = func
if duringinit then
set indexfunc = func
//During initialization, evaluate the indexfunc for every preplaced unit.
call ForGroup(preplaced, function AutoIndex.onUnitIndexed_sub)
endif
endmethod
static method onUnitDeindexed takes IndexFunc func returns nothing
set deindexfuncs_n = deindexfuncs_n + 1
set deindexfuncs[deindexfuncs_n] = func
endmethod
static method addAutoStruct takes AutoStructCreator creator, AutoStructDestroyer destroyer returns nothing
set autostructs_n = autostructs_n + 1
set creators[autostructs_n] = creator
set destroyers[autostructs_n] = destroyer
endmethod
//===========================================================================
private static method hook_RemoveUnit takes unit whichUnit returns nothing
set removing[getIndex(whichUnit)] = true
endmethod
private static method hook_ReplaceUnitBJ takes unit whichUnit, integer newUnitId, integer unitStateMethod returns nothing
set removing[getIndex(whichUnit)] = true
endmethod
//Intercepts whenever RemoveUnit or ReplaceUnitBJ is called and sets a flag.
private static method hook_SetUnitUserData takes unit whichUnit, integer data returns nothing
static if UseUnitUserData then
if idunit[getIndex(whichUnit)] == whichUnit then
if getIndex(whichUnit) == data then
call BJDebugMsg("AutoIndex error: Code outside AutoIndex attempted to alter "+GetUnitName(whichUnit)+"'s index.")
else
call BJDebugMsg("AutoIndex error: Code outside AutoIndex altered "+GetUnitName(whichUnit)+"'s index.")
if idunit[data] != null then
call BJDebugMsg("AutoIndex error: "+GetUnitName(whichUnit)+" and "+GetUnitName(idunit[data])+" now have the same index.")
endif
set altered[data] = true
endif
endif
endif
endmethod
//In debug mode, intercepts whenever SetUnitUserData is used on an indexed unit.
//Displays an error message if outside code tries to alter a unit's index.
//===========================================================================
private static method allowDecay takes nothing returns nothing
local integer n = allowdecay_n
loop
exitwhen n < 0
set nodecay[getIndex(allowdecayunit[n])] = false
set allowdecayunit[n] = null
set n = n - 1
endloop
set allowdecay_n = -1
endmethod
//Iterate through all the units in the stack and allow them to decay again.
private static method detectStatus takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer index = getIndex(u)
local integer n
if idunit[index] == u then //Ignore non-indexed units.
if not IsUnitType(u, UNIT_TYPE_DEAD) then
if dead[index] then //The unit was dead, but now it's alive.
set dead[index] = false //The unit has been resurrected.
//! runtextmacro optional RunAutoEvent("Resurrect")
//If AutoEvents is in the map, run the resurrection events.
if IsUnitType(u, UNIT_TYPE_SUMMONED) and not summoned[index] then
set summoned[index] = true //If the unit gained the summoned flag,
set animated[index] = true //it's been raised with Animate Dead.
//! runtextmacro optional RunAutoEvent("AnimateDead")
//If AutoEvents is in the map, run the Animate Dead events.
endif
endif
else
if not removing[index] and not dead[index] and not animated[index] then
set dead[index] = true //The unit was alive, but now it's dead.
set nodecay[index] = true //A dead unit can't decay for at least 0. seconds.
set allowdecay_n = allowdecay_n + 1 //Add the unit to a stack. After the timer
set allowdecayunit[allowdecay_n] = u //expires, allow the unit to decay again.
call TimerStart(allowdecay, 0., false, function AutoIndex.allowDecay)
//! runtextmacro optional RunAutoEvent("Death")
//If AutoEvents is in the map, run the Death events.
//! runtextmacro optional TransportUnload()
//If TransportEvents is in the map, remove the dead unit from whatever transport it's in.
elseif removing[index] or (dead[index] and not nodecay[index]) or (not dead[index] and animated[index]) then
//If .nodecay was false and the unit is dead and was previously dead, the unit decayed.
//If .animated was true and the unit is dead, the unit died and exploded.
//If .removing was true, the unit is being removed or replaced.
//! runtextmacro optional TransportUnload()
//If TransportEvents is in the map, remove the leaving unit from whatever transport it's in.
set n = deindexfuncs_n
loop //Run the OnUnitDeindexed events.
exitwhen n < 0
call deindexfuncs[n].evaluate(u)
set n = n - 1
endloop
//! runtextmacro optional DestroyUnitLists()
//If UnitListModule is in the map, destroy all of the UnitLists associated with the leaving unit.
set n = autostructs_n
loop //Destroy AutoStructs for the leaving unit.
exitwhen n < 0
call destroyers[n].evaluate(u)
set n = n - 1
endloop
//! runtextmacro optional TransportClean()
//If TransportEvents is in the map, and the leaving unit is a
//transport, clean the transport- related data from the unit.
call AutoIndex(index).destroy() //Free the index by destroying the AutoIndex struct.
set idunit[index] = null //Null this unit reference to prevent a leak.
endif
endif
endif
set u = null
return false
endmethod
//===========================================================================
private static method unitEntersMap takes unit u returns nothing
local integer index
local integer n = 0
if getIndex(u) != 0 then
return //Don't index a unit that already has an ID.
endif
static if LIBRARY_xebasic then
if GetUnitTypeId(u) == XE_DUMMY_UNITID then
return //Don't index xe dummy units.
endif
endif
if not UnitFilter(u) then
return //Don't index units that fail the unit filter.
endif
set index = create()
call setIndex(u, index) //Assign an index to the entering unit.
call UnitAddAbility(u, LeaveDetectAbilityID) //Add the leave detect ability to the entering unit.
call UnitMakeAbilityPermanent(u, true, LeaveDetectAbilityID) //Prevent it from disappearing on morph.
set dead[index] = IsUnitType(u, UNIT_TYPE_DEAD) //Reset all of the flags for the entering
set summoned[index] = IsUnitType(u, UNIT_TYPE_SUMMONED) //unit. These flags are necessary to detect
set animated[index] = false //when the unit leaves the map.
set nodecay[index] = false
set removing[index] = false
debug set altered[index] = false //In debug mode, this flag tracks wheter a unit's index was altered.
set idunit[index] = u //Attach the unit that is supposed to have this index to the index.
if duringinit then
call GroupAddUnit(preplaced, u) //Add units that are created during initialization to the preplaced
//units group. This ensures that all units are noticed by OnUnitIndexed during initialization.
endif
loop //Create AutoStructs for the entering unit.
exitwhen n > autostructs_n
call creators[n].evaluate(u)
set n = n + 1
endloop
set n = 0
loop //Run the OnUnitIndexed events.
exitwhen n > indexfuncs_n
call indexfuncs[n].evaluate(u)
set n = n + 1
endloop
endmethod
private static method onIssuedOrder takes nothing returns boolean
if getIndex(GetTriggerUnit()) == 0 then
call unitEntersMap(GetTriggerUnit())
endif //If the unit doesn't have an index at this point, assign it one.
//This is necessary to catch units with default-on autocast abilities
//when using GetUnitId on a newly created unit within an order event.
//! runtextmacro optional TransportUnloadCheck()
//If TransportEvents is in the map, check whether a unit is unloading.
return GetIssuedOrderId() == 852056 //If the order is Undefend, allow detectStatus to run.
endmethod
private static method initEnteringUnit takes nothing returns boolean
call unitEntersMap(GetFilterUnit())
return false
endmethod
//===========================================================================
private static method afterInit takes nothing returns nothing
set duringinit = false //Initialization is over; set a flag.
call DestroyTimer(GetExpiredTimer()) //Destroy the timer.
call GroupClear(preplaced) //The preplaced units group is
call DestroyGroup(preplaced) //no longer needed, so clean it.
set preplaced = null
endmethod
private static method onInit takes nothing returns nothing
local region maparea = CreateRegion()
local rect bounds = GetWorldBounds()
local group g = CreateGroup()
local integer i = 15
static if not UseUnitUserData then
set ht = InitHashtable() //Only create a hashtable if it will be used.
endif
loop
exitwhen i < 0
call SetPlayerAbilityAvailable(Player(i), LeaveDetectAbilityID, false)
//Make the LeaveDetect ability unavailable so that it doesn't show up on the command card of every unit.
call TriggerRegisterPlayerUnitEvent(order, Player(i), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
//Register the "EVENT_PLAYER_UNIT_ISSUED_ORDER" event for each player.
call GroupEnumUnitsOfPlayer(g, Player(i), function AutoIndex.initEnteringUnit)
//Enum every non-filtered unit on the map during initialization and assign it a unique
//index. By using GroupEnumUnitsOfPlayer, even units with Locust can be detected.
set i = i - 1
endloop
call TriggerAddCondition(order, And(function AutoIndex.onIssuedOrder, function AutoIndex.detectStatus))
//The detectStatus method will fire every time a non-filtered unit recieves an undefend order.
//And() is used here to avoid using a trigger action, which starts a new thread and is slower.
call TriggerRegisterPlayerUnitEvent(creepdeath, Player(12), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(creepdeath, function AutoIndex.detectStatus)
//The detectStatus method must also fire when a neutral hostile creep dies, in case it was
//sleeping. Sleeping creeps don't fire undefend orders on non-damaging deaths.
call RegionAddRect(maparea, bounds) //GetWorldBounds() includes the shaded boundry areas.
call TriggerRegisterEnterRegion(enter, maparea, function AutoIndex.initEnteringUnit)
//The filter function of an EnterRegion trigger runs instantly when a unit is created.
call TimerStart(CreateTimer(), 0., false, function AutoIndex.afterInit)
//After any time elapses, perform after-initialization actions.
call GroupClear(g)
call DestroyGroup(g)
call RemoveRect(bounds)
set g = null
set bounds = null
endmethod
endstruct
//===========================================================================
// User functions:
//=================
function GetUnitId takes unit u returns integer
static if DEBUG_MODE then
return AutoIndex.getIndexDebug(u)
else
return AutoIndex.getIndex(u)
endif
endfunction
function IsUnitIndexed takes unit u returns boolean
return AutoIndex.isUnitIndexed(u)
endfunction
function OnUnitIndexed takes IndexFunc func returns nothing
call AutoIndex.onUnitIndexed(func)
endfunction
function OnUnitDeindexed takes IndexFunc func returns nothing
call AutoIndex.onUnitDeindexed(func)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ARGB initializer init
//******************************************************************************
//*
//* ARGB 1.1
//* ====
//* For your color needs.
//*
//* An ARGB object is a by-value struct, this means that assigning copies the
//* contents of the struct and that you don't have to use .destroy(), the
//* downside is that you cannot assign its members (can't do set c.r= 123 )
//*
//* This library should have plenty of uses, for example, if your spell involves
//* some unit recoloring you can allow users to input the color in the config
//* section as 0xAARRGGBB and you can then use this to decode that stuff.
//*
//* You can also easily merge two colors and make fading effects using ARGB.mix
//*
//* There's ARGB.fromPlayer which gets an ARGB object containing the player's
//* color. Then you can use the previous utilities on it.
//*
//* The .str() instance method can recolor a string, and the recolorUnit method
//* will apply the ARGB on a unit
//*
//* For other uses, you can use the .red, .green, .blue and .alpha members to get
//* an ARGB object's color value (from 0 to 255).
//*
//* structs that have a recolor method that takes red,green,blue and alpha as 0.255
//* integers can implement the ARGBrecolor module to gain an ability to quickly
//* recolor using an ARGB object.
//*
//********************************************************************************
//=================================================================================
globals
private string array i2cc
endglobals
//this double naming stuff is beginning to make me insane, if only TriggerEvaluate() wasn't so slow...
struct ARGB extends array
static method create takes integer a, integer r, integer g, integer b returns ARGB
return ARGB(b + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
static method fromPlayer takes player p returns ARGB
local playercolor pc=GetPlayerColor(p)
if(pc==PLAYER_COLOR_RED) then
return 0xFFFF0303
elseif(pc==PLAYER_COLOR_BLUE) then
return 0xFF0042FF
elseif(pc==PLAYER_COLOR_CYAN) then
return 0xFF1CB619
elseif(pc==PLAYER_COLOR_PURPLE) then
return 0xFF540081
elseif(pc==PLAYER_COLOR_YELLOW) then
return 0xFFFFFF01
elseif(pc==PLAYER_COLOR_ORANGE) then
return 0xFFFE8A0E
elseif(pc==PLAYER_COLOR_GREEN) then
return 0xFF20C000
elseif(pc==PLAYER_COLOR_PINK) then
return 0xFFE55BB0
elseif(pc==PLAYER_COLOR_LIGHT_GRAY) then
return 0xFF959697
elseif(pc==PLAYER_COLOR_LIGHT_BLUE) then
return 0xFF7EBFF1
elseif(pc==PLAYER_COLOR_AQUA) then
return 0xFF106246
elseif(pc==PLAYER_COLOR_BROWN) then
return 0xFF4E2A04
endif
return 0xFF111111
endmethod
method operator alpha takes nothing returns integer
if( integer(this) <0) then
return 0x80+(-(-integer(this)+0x80000000))/0x1000000
else
return (integer(this))/0x1000000
endif
endmethod
method operator alpha= takes integer na returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + r*0x10000 + na*0x1000000)
endmethod
method operator red takes nothing returns integer
local integer c=integer(this)*0x100
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator red= takes integer nr returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + nr*0x10000 + a*0x1000000)
endmethod
method operator green takes nothing returns integer
local integer c=integer(this)*0x10000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator green= takes integer ng returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + ng*0x100 + r*0x10000 + a*0x1000000)
endmethod
//=======================================================
//
//
method operator blue takes nothing returns integer
local integer c=integer(this)*0x1000000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator blue= takes integer nb returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(nb + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
//====================================================================
// Mixes two colors, s would be a number 0<=s<=1 that determines
// the weight given to color c2.
//
// mix(c1,c2,0) = c1
// mix(c1,c2,1) = c2
// mix(c1,c2,0.5) = Mixing the colors c1 and c2 in equal proportions.
//
static method mix takes ARGB c1, ARGB c2, real s returns ARGB
//widest function ever
return ARGB( R2I(c2.blue*s+c1.blue*(1-s)+0.5) + R2I(c2.green*s+c1.green*(1-s)+0.5)*0x100 + R2I(c2.red*s+c1.red*(1-s)+0.5)*0x10000 + R2I(c2.alpha*s+c1.alpha*(1-s)+0.5)*0x1000000)
endmethod
method str takes string s returns string
return "|c"+i2cc[.alpha]+i2cc[.red]+i2cc[.green]+i2cc[.blue]+s+"|r"
endmethod
method recolorUnit takes unit u returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call SetUnitVertexColor(u,r,g,b,a)
endmethod
endstruct
module ARGBrecolor
method ARGBrecolor takes ARGB color returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call this.recolor(r, g , b, a)
endmethod
endmodule
private function init takes nothing returns nothing
local integer i=0
// Don't run textmacros you don't own!
//! textmacro ARGB_CHAR takes int, chr
set i=0
loop
exitwhen i==16
set i2cc[$int$*16+i]="$chr$"+i2cc[$int$*16+i]
set i2cc[i*16+$int$]=i2cc[i*16+$int$]+"$chr$"
set i=i+1
endloop
//! endtextmacro
//! runtextmacro ARGB_CHAR( "0","0")
//! runtextmacro ARGB_CHAR( "1","1")
//! runtextmacro ARGB_CHAR( "2","2")
//! runtextmacro ARGB_CHAR( "3","3")
//! runtextmacro ARGB_CHAR( "4","4")
//! runtextmacro ARGB_CHAR( "5","5")
//! runtextmacro ARGB_CHAR( "6","6")
//! runtextmacro ARGB_CHAR( "7","7")
//! runtextmacro ARGB_CHAR( "8","8")
//! runtextmacro ARGB_CHAR( "9","9")
//! runtextmacro ARGB_CHAR("10","A")
//! runtextmacro ARGB_CHAR("11","B")
//! runtextmacro ARGB_CHAR("12","C")
//! runtextmacro ARGB_CHAR("13","D")
//! runtextmacro ARGB_CHAR("14","E")
//! runtextmacro ARGB_CHAR("15","F")
endfunction
endlibrary
//TESH.scrollpos=240
//TESH.alwaysfold=0
library BonusMod initializer OnInit requires optional AbilityPreload, optional xepreload
private keyword AbilityBonus
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ BonusMod - v3.3.1
//@=============================================================================
//@ Credits:
//@-----------------------------------------------------------------------------
//@ Written by:
//@ Earth-Fury
//@ Based on the work of:
//@ weaaddar
//@-----------------------------------------------------------------------------
//@ If you use this system, please at least credit weaaddar. Without him, this
//@ system would not exist. I would be happy if you credited me as well.
//@=============================================================================
//@ Requirements:
//@-----------------------------------------------------------------------------
//@ This library is written in vJass and thus requires JASS Helper in order to
//@ function correctly. This library also uses the ObjectMerger created by
//@ PitzerMike. The ObjectMerger must be configured as an external tool for
//@ JASS Helper.
//@
//@ All of these things are present in the NewGen world editor.
//@
//@=============================================================================
//@ Introduction:
//@-----------------------------------------------------------------------------
//@ BonusMod is a system for applying reversible bonuses to certain stats, such
//@ as attack speed or mana regen, for specific units. Most of the bonuses
//@ provided by BonusMod show green or red numbers in the command card, exactly
//@ like the bonuses provided by items.
//@
//@ BonusMod has two kinds of bonuses:
//@ 1. Ability based bonuses
//@ 2. Code based bonuses
//@
//@ All of the bonuses in the configuration section for the basic BonusMod
//@ library are ability-based bonuses. Code-based bonuses are provided by
//@ additional libraries.
//@
//@ Ability based bonuses have a limit to how much of a bonus they can apply.
//@ The actual limit depends on the number of abilities that type of bonus uses.
//@ See the "Default bonuses" section of this readme for the default limits
//@ of the bonuses that come with BonusMod. For changing the limits of the
//@ default bonuses, or for adding new types of bonuses, see the below
//@ configuration section.
//@
//@ Code based bonuses may or may not have a limit to how much of a bonus they
//@ can apply. The limits for code based bonuses depend entirely on how the
//@ bonus is implemented. See their documentation for more information.
//@
//@=============================================================================
//@ Adding BonusMod to your map:
//@-----------------------------------------------------------------------------
//@ First, you must place the BonusMod library in a custom-text trigger in your
//@ map.
//@
//@ You must then save your map with ability generation enabled. After you save
//@ your map with ability generation enabled, you must close your map in the
//@ editor, and reopen it. You can then disable ability generation.
//@ See the configuration section for information on how to enable and disable
//@ ability generation.
//@
//@=============================================================================
//@ Default bonuses:
//@-----------------------------------------------------------------------------
//@
//@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//@ | Bonus Type constants: | Minimum bonus: | Maximum bonus: |
//@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//@ | BONUS_SIGHT_RANGE | -2048 | +2047 |
//@ | BONUS_ATTACK_SPEED | -512 | +511 |
//@ | BONUS_ARMOR | -1024 | +1023 |
//@ | BONUS_MANA_REGEN_PERCENT | -512% | +511% |
//@ | BONUS_LIFE_REGEN | -256 | +255 |
//@ | BONUS_DAMAGE | -1024 | +1023 |
//@ | BONUS_STRENGTH | -256 | +255 |
//@ | BONUS_AGILITY | -256 | +255 |
//@ | BONUS_INTELLIGENCE | -256 | +255 |
//@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//@
//@ Notes:
//@ - The bonuses for stength, agility, and intelligence can only be
//@ applied to heroes. Attempting to add them to normal units will
//@ fail to work completely.
//@ - Using a negative BONUS_STRENGTH bonus can give a unit negative
//@ maximum life. Don't do that. It really messes stuff up.
//@ - Using a negative BONUS_INTELLIGENCE bonus can remove a hero's
//@ mana. This is not a big issue, as mana will return when the
//@ bonus is removed.
//@ - The maximum effective sight range for a unit is 1800.
//@ - There is a maximum attack speed. I have no idea what it is.
//@
//@ See the configuration section for information on how to change the range of
//@ bonuses, as well as how to add new ability-based bonuses, and remove unused
//@ ones.
//@
//@=============================================================================
//@ Public API / Function list:
//@-----------------------------------------------------------------------------
//@ Note that BonusMod will only output error messages if JASS Helper is set to
//@ compile in debug mode.
//@
//@ Bonus constants such as BONUS_DAMAGE have .min and .max properties which
//@ are the minimum and maximum bonus that type of bonus can apply. Note that
//@ for code based bonuses, these constants may not reflect the minimum or
//@ maximum bonus for a specific unit. Use the IsBonusValid() function to check
//@ if the given bonus value is okay for a given unit.
//@
//@ function SetUnitBonus
//@ takes unit u, Bonus bonusType, integer amount
//@ returns integer
//@
//@ This function sets the bonus of the type bonusType for the given unit to
//@ the given amount. The returned integer is the unit's actual current
//@ bonus, after it has been changed. If the given amount is above the
//@ maximum possible bonus for this type, then the maximum possible bonus
//@ is applied to the unit. The same is true if the given value is below
//@ the minimum possible bonus.
//@
//@ function GetUnitBonus
//@ takes unit u, Bonus bonusType
//@ returns integer
//@
//@ Returns the given unit's current bonus of bonusType. A value of 0 means
//@ that the given unit does not have a bonus of the given type.
//@
//@ function AddUnitBonus
//@ takes unit u, Bonus bonusType, integer amount
//@ returns integer
//@
//@ Increases the unit's bonus by the given amount. You can use a negitive
//@ amount to subtract from the unit's current bonus. Note that the same
//@ rules SetUnitBonus has apply for going over/under the maximum bonus.
//@ The returned value is the unit's actual new bonus.
//@
//@ function RemoveUnitBonus
//@ takes unit u, Bonus bonusType
//@ returns nothing
//@
//@ Sets the bonus of the type bonusType to 0 for the given unit. This
//@ function is faster then using SetUnitBonus(u, bonusType, 0).
//@
//@ function IsBonusValid
//@ takes unit u, Bonus abstractBonus, integer value
//@ returns boolean
//@
//@ Returns true if the given value is a valid bonus value for the given
//@ unit. This will also return false if the given bonus type is a hero-
//@ only bonus type, and the given unit is not a hero.
//@
//@=============================================================================
//@ Writing code-based bonuses:
//@-----------------------------------------------------------------------------
//@ This section of the readme tells you how to create your own bonus types
//@ that apply their bonuses using vJass code instead of abilities. You do not
//@ need to read or understand this to use BonusMod as-is.
//@
//@ Creating a new bonus type is simple. Extend the Bonus struct, implement the
//@ methods provided within it, and create a single instance of your struct
//@ within a variable named BONUS_YOUR_BONUS_TYPES_NAME of the type Bonus.
//@
//@ The methods you must implement are:
//@
//@ method setBonus takes unit u, integer amount returns integer
//@ This method sets the given unit's current bonus to amount, returning
//@ the actual bonus that was applied. If the given amount is higher then
//@ the maximum amount your bonus type can apply to a unit, you must apply
//@ the maximum possible bonus, and return that amount. The same holds true
//@ for the minimum bonus.
//@
//@ method getBonus takes unit u returns integer
//@ This method returns the current bonus the given unit has.
//@
//@ method removeBonus takes unit u returns nothing
//@ This method sets the current bonus of the given unit to 0.
//@
//@ method isValueInRange takes integer value returns boolean
//@ This method returns true if the given integer is a valid bonus amount
//@ for this bonus type, and false otherwise.
//@
//@ Note that it is your responsibility to do any clean up in the event a unit
//@ dies or is removed with an active bonus on it. There is no guarantee that
//@ removeBonus() will be called before a unit dies or is removed.
//@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////
//==============================================================================
// Configuration:
//==============================================================================
//------------------------------------------------------------------------------
// If the following constant is set to true, the abilities used by this library
// will be preloaded at map initialization. This will slightly increase loading
// time, but will prevent a slight to medium lag spike the first time a bonus
// of a type is applied.
//
// Note that your map must contain either the xepreload library, or the
// AbilityPreload library for preloading to work.
//
// It is highly recommended that you do not set this to false.
//------------------------------------------------------------------------------
globals
private constant boolean PRELOAD_ABILITIES = true
endglobals
//------------------------------------------------------------------------------
// The BonusMod_BeginBonuses macro takes a single boolean type parameter.
// If set to true, bonus abilities will be created (or recreated) on save.
// If set to false, abilities will not be generated.
//
// If you modify any of the bonus declaration macros, or add new ones, you must
// regenerate abilities.
//
// Note that if you remove a bonus, the abilities it had created will not be
// automatically removed. This is also true of reducing the number of abilities
// a bonus uses.
//
// After you generate abilities, you must close your map and reopen it in the
// editor. You can then disable ability generation until the next time you
// modify the bonus types.
//------------------------------------------------------------------------------
//! runtextmacro BonusMod_BeginBonuses("false")
//--------------------------------------------------------------------------
// Below are where bonus types are defined.
//
// The first parameter is the name of the bonus type. A constant will be
// generated for each bonus type, that will take the form: BONUS_NAME
//
// The second parameter is the maximum power of 2 the bonus type can add
// to a unit. For example, 8 abilities gives a range of -256 to +255.
//
// The third parameter is the base ability. The base ability must give the
// desired effect when the given field is changed.
//
// The fourth parameter is the rawcode prefix of the bonuses generated
// abilities. The prefix must be 3 characters long. Your map must not
// already contain bonuses which start with the given prefix.
//
// The fifth parameter is the object field to modify for each generated
// ability.
//
// The sixth parameter must be true of the bonus should only work on hero
// units, and false otherwise.
//
// The final parameter is the icon that will be displayed in the object
// editor. This has no effect on anything ingame.
//--------------------------------------------------------------------------
// | NAME |ABILITY|SOURCE |PREFIX|FIELD | HERO | ICON
// | | COUNT |ABILITY| | | ONLY |
//! runtextmacro BonusMod_DeclareBonus("ARMOR", "10", "AId1", "(A)", "Idef", "false", "BTNHumanArmorUpOne.blp")
//! runtextmacro BonusMod_DeclareBonus("DAMAGE", "10", "AItg", "(B)", "Iatt", "false", "BTNSteelMelee.blp")
//! runtextmacro BonusMod_DeclareBonus("SIGHT_RANGE", "11", "AIsi", "(C)", "Isib", "false", "BTNTelescope.blp")
//! runtextmacro BonusMod_DeclareBonus("LIFE_REGEN", "8", "Arel", "(E)", "Ihpr", "false", "BTNRingSkull.blp")
//! runtextmacro BonusMod_DeclareBonus("STRENGTH", "8", "AIa1", "(F)", "Istr", "true" , "BTNGoldRing.blp")
//! runtextmacro BonusMod_DeclareBonus("AGILITY", "8", "AIa1", "(G)", "Iagi", "true" , "BTNGoldRing.blp")
//! runtextmacro BonusMod_DeclareBonus("INTELLIGENCE", "8", "AIa1", "(H)", "Iint", "true" , "BTNGoldRing.blp")
// | NAME |ABILITY|SOURCE |PREFIX|FIELD |HERO | ICON
// | | COUNT |ABILITY| | | ONLY |
//! runtextmacro BonusMod_DeclarePercentBonus("ATTACK_SPEED", "9", "AIsx", "(I)", "Isx1", "false", "BTNGlove.blp")
//! runtextmacro BonusMod_DeclarePercentBonus("MANA_REGEN_PERCENT", "9", "AIrm", "(D)", "Imrp", "false", "BTNSobiMask.blp")
//! runtextmacro BonusMod_EndBonuses()
//==============================================================================
// End of configuration
//==============================================================================
//! textmacro BonusMod_BeginBonuses takes SHOULD_GENERATE_ABILITIES
private function Setup takes nothing returns nothing
// The following is a lua script for the ObjectMerger, used to generate abilities
//*
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i if "$SHOULD_GENERATE_ABILITIES$" == "true" then
//! i function FormatName(name)
//! i name = string.lower(name)
//! i name = string.gsub(name, "_", " ")
//! i s = name
//! i name = ""
//! i for w in string.gmatch(s, "%a%w*") do
//! i name = name .. string.upper(string.sub(w, 1, 1)) .. string.sub(w, 2, -1)
//! i name = name .. " "
//! i end
//! i name = string.sub(name, 1, string.len(name) - 1)
//! i return name
//! i end
//! i function SetupAbility(name, suffix, icon, hero)
//! i makechange(current, "anam", "BonusMod - " .. FormatName(name))
//! i makechange(current, "ansf", "(" .. suffix .. ")")
//! i makechange(current, "aart", "ReplaceableTextures\\CommandButtons\\" .. icon)
//! i makechange(current, "aite", 0)
//! i if hero then
//! i makechange(current, "Iagi", 1, 0)
//! i makechange(current, "Iint", 1, 0)
//! i makechange(current, "Istr", 1, 0)
//! i end
//! i end
//! i function CreateAbility(sourceAbility, prefix, field, abilityCount, name, icon)
//! i powOf2 = abilityCount - 1
//! i lengthOfMax = string.len(tostring(2^abilityCount))
//! i for i = 0, powOf2 do
//! i padding = ""
//! i for k = 0, lengthOfMax - string.len(tostring(2^i)) - 1 do
//! i padding = padding .. "0"
//! i end
//! i createobject(sourceAbility, prefix .. string.sub(chars, i + 1, i + 1))
//! i SetupAbility(name, "+" .. padding .. tostring(2 ^ i), icon, true)
//! i makechange(current, field, 1, tostring(2^i))
//! i end
//! i createobject(sourceAbility, prefix .. "-")
//! i SetupAbility(name, "-" .. tostring(2 ^ abilityCount), icon, true)
//! i makechange(current, field, 1, tostring(-(2^abilityCount)))
//! i end
//! i function CreatePercentageAbility(sourceAbility, prefix, field, abilityCount, name, icon)
//! i powOf2 = abilityCount - 1
//! i lengthOfMax = string.len(tostring(2^abilityCount))
//! i for i = 0, powOf2 do
//! i padding = ""
//! i for k = 0, lengthOfMax - string.len(tostring(2^i)) - 1 do
//! i padding = padding .. "0"
//! i end
//! i createobject(sourceAbility, prefix .. string.sub(chars, i + 1, i + 1))
//! i SetupAbility(name, "+" .. padding .. tostring(2 ^ i) .. "%", icon, false)
//! i makechange(current, field, 1, tostring((2 ^ i) / 100))
//! i end
//! i createobject(sourceAbility, prefix .. "-")
//! i SetupAbility(name, "-" .. tostring(2 ^ abilityCount) .. "%", icon, false)
//! i makechange(current, field, 1, tostring(-((2 ^ abilityCount) / 100)))
//! i end
//! i setobjecttype("abilities")
//! i chars = "abcdefghijklmnopqrstuvwxyz"
//! i
// */
//! endtextmacro
//! textmacro BonusMod_DeclareBonus takes NAME, ABILITY_COUNT, SOURCE_ABILITY, RAWCODE_PREFIX, FIELD, HERO_ONLY, ICON
//! i CreateAbility("$SOURCE_ABILITY$", "$RAWCODE_PREFIX$", "$FIELD$", $ABILITY_COUNT$, "$NAME$", "$ICON$")
globals
Bonus BONUS_$NAME$
endglobals
set BONUS_$NAME$ = AbilityBonus.create('$RAWCODE_PREFIX$a', $ABILITY_COUNT$, '$RAWCODE_PREFIX$-', $HERO_ONLY$)
//! endtextmacro
//! textmacro BonusMod_DeclarePercentBonus takes NAME, ABILITY_COUNT, SOURCE_ABILITY, RAWCODE_PREFIX, FIELD, HERO_ONLY, ICON
//! i CreatePercentageAbility("$SOURCE_ABILITY$", "$RAWCODE_PREFIX$", "$FIELD$", $ABILITY_COUNT$, "$NAME$", "$ICON$")
globals
Bonus BONUS_$NAME$
endglobals
set BONUS_$NAME$ = AbilityBonus.create('$RAWCODE_PREFIX$a', $ABILITY_COUNT$, '$RAWCODE_PREFIX$-', $HERO_ONLY$)
//! endtextmacro
//! textmacro BonusMod_EndBonuses
//*
//! i end
//! endexternalblock
// */
endfunction
//! endtextmacro
// ===
// Precomputed integer powers of 2
// ===
globals
private integer array powersOf2
private integer powersOf2Count = 0
endglobals
// ===
// Utility functions
// ===
private function ErrorMsg takes string func, string s returns nothing
call BJDebugMsg("|cffFF0000BonusMod Error|r|cffFFFF00:|r |cff8080FF" + func + "|r|cffFFFF00:|r " + s)
endfunction
private function LoadAbility takes integer abilityId returns nothing
static if PRELOAD_ABILITIES then
static if LIBRARY_xepreload then
call XE_PreloadAbility(abilityId)
else
static if LIBRARY_AbilityPreload then
call AbilityPreload(abilityId)
endif
endif
endif
endfunction
// ===
// Bonus Types
// ===
private interface BonusInterface
integer minBonus = 0
integer maxBonus = 0
private method destroy takes nothing returns nothing defaults nothing
endinterface
private keyword isBonusObject
struct Bonus extends BonusInterface
boolean isBonusObject = false
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set this.isBonusObject = true
return this
endmethod
stub method setBonus takes unit u, integer amount returns integer
debug call ErrorMsg("Bonus.setBonus()", "I have no idea how or why you did this, but don't do it.")
return 0
endmethod
stub method getBonus takes unit u returns integer
debug call ErrorMsg("Bonus.getBonus()", "I have no idea how or why you did this, but don't do it.")
return 0
endmethod
stub method removeBonus takes unit u returns nothing
call this.setBonus(u, 0)
endmethod
stub method isValidBonus takes unit u, integer value returns boolean
return true
endmethod
method operator min takes nothing returns integer
return this.minBonus
endmethod
method operator max takes nothing returns integer
return this.maxBonus
endmethod
endstruct
private struct AbilityBonus extends Bonus
public integer count
public integer rawcode
public integer negativeRawcode
public integer minBonus = 0
public integer maxBonus = 0
public boolean heroesOnly
public static method create takes integer rawcode, integer count, integer negativeRawcode, boolean heroesOnly returns thistype
local thistype bonus = thistype.allocate()
local integer i
debug local boolean error = false
// Error messages
static if DEBUG_MODE then
if rawcode == 0 then
call ErrorMsg("AbilityBonus.create()", "Bonus constructed with a rawcode of 0?!")
call bonus.destroy()
return 0
endif
if count < 0 or count == 0 then
call ErrorMsg("AbilityBonus.create()", "Bonus constructed with an ability count <= 0?!")
call bonus.destroy()
return 0
endif
endif
// Grow powers of 2
if powersOf2Count < count then
set i = powersOf2Count
loop
exitwhen i > count
set powersOf2[i] = 2 * powersOf2[i - 1]
set i = i + 1
endloop
set powersOf2Count = count
endif
// Preload this bonus' abilities
static if PRELOAD_ABILITIES then
set i = 0
loop
exitwhen i == count
call LoadAbility(rawcode + i)
set i = i + 1
endloop
if negativeRawcode != 0 then
call LoadAbility(negativeRawcode)
endif
endif
// Set up this bonus object
set bonus.count = count
set bonus.negativeRawcode = negativeRawcode
set bonus.rawcode = rawcode
set bonus.heroesOnly = heroesOnly
// Calculate the minimum and maximum bonuses
if negativeRawcode != 0 then
set bonus.minBonus = -powersOf2[count]
else
set bonus.minBonus = 0
endif
set bonus.maxBonus = powersOf2[count] - 1
// Return the bonus object
return bonus
endmethod
// Interface methods:
method setBonus takes unit u, integer amount returns integer
return SetUnitBonus.evaluate(u, this, amount)
endmethod
method getBonus takes unit u returns integer
return GetUnitBonus.evaluate(u, this)
endmethod
method removeBonus takes unit u returns nothing
call RemoveUnitBonus.evaluate(u, this)
endmethod
public method isValidBonus takes unit u, integer value returns boolean
return (value >= this.minBonus) and (value <= this.maxBonus)
endmethod
endstruct
// ===
// Public API
// ===
function IsBonusValid takes unit u, Bonus abstractBonus, integer value returns boolean
local AbilityBonus bonus = AbilityBonus(abstractBonus)
static if DEBUG_MODE then
if not abstractBonus.isBonusObject then
call ErrorMsg("IsBonusValid()", "Invalid bonus type given")
endif
endif
if abstractBonus.min > value or abstractBonus.max < value then
return false
endif
if abstractBonus.getType() != AbilityBonus.typeid then
return abstractBonus.isValidBonus(u, value)
endif
if bonus.heroesOnly and not IsUnitType(u, UNIT_TYPE_HERO) then
return false
endif
return (value >= bonus.minBonus) and (value <= bonus.maxBonus)
endfunction
function RemoveUnitBonus takes unit u, Bonus abstractBonus returns nothing
local integer i = 0
local AbilityBonus bonus = AbilityBonus(abstractBonus)
static if DEBUG_MODE then
if not abstractBonus.isBonusObject then
call ErrorMsg("RemoveUnitBonus()", "Invalid bonus type given")
endif
endif
if abstractBonus.getType() != AbilityBonus.typeid then
call abstractBonus.removeBonus(u)
return
endif
if bonus.heroesOnly and not IsUnitType(u, UNIT_TYPE_HERO) then
debug call ErrorMsg("RemoveUnitBonus()", "Trying to remove a hero-only bonus from a non-hero unit")
return
endif
call UnitRemoveAbility(u, bonus.negativeRawcode)
loop
exitwhen i == bonus.count
call UnitRemoveAbility(u, bonus.rawcode + i)
set i = i + 1
endloop
endfunction
function SetUnitBonus takes unit u, Bonus abstractBonus, integer amount returns integer
local integer i
local integer output = 0
local AbilityBonus bonus = AbilityBonus(abstractBonus)
local boolean applyMinBonus = false
static if DEBUG_MODE then
if not abstractBonus.isBonusObject then
call ErrorMsg("SetUnitBonus()", "Invalid bonus type given")
endif
endif
if amount == 0 then
call RemoveUnitBonus(u, bonus)
return 0
endif
if abstractBonus.getType() != AbilityBonus.typeid then
return abstractBonus.setBonus(u, amount)
endif
if bonus.heroesOnly and not IsUnitType(u, UNIT_TYPE_HERO) then
debug call ErrorMsg("SetUnitBonus()", "Trying to set a hero-only bonus on a non-hero unit")
return 0
endif
if amount < bonus.minBonus then
debug call ErrorMsg("SetUnitBonus()", "Attempting to set a bonus to below its min value")
set amount = bonus.minBonus
elseif amount > bonus.maxBonus then
debug call ErrorMsg("SetUnitBonus()", "Attempting to set a bonus to above its max value")
set amount = bonus.maxBonus
endif
if amount < 0 then
set amount = -(bonus.minBonus - amount)
set applyMinBonus = true
endif
call UnitRemoveAbility(u, bonus.negativeRawcode)
set i = bonus.count - 1
loop
exitwhen i < 0
if amount >= powersOf2[i] then
call UnitAddAbility(u, bonus.rawcode + i)
call UnitMakeAbilityPermanent(u, true, bonus.rawcode + i)
static if DEBUG_MODE then
if GetUnitAbilityLevel(u, bonus.rawcode + i) <= 0 then
call ErrorMsg("SetUnitBonus()", "Failed to give the 2^" + I2S(i) + " ability to the unit!")
endif
endif
set amount = amount - powersOf2[i]
set output = output + powersOf2[i]
else
call UnitRemoveAbility(u, bonus.rawcode + i)
static if DEBUG_MODE then
if GetUnitAbilityLevel(u, bonus.rawcode + i) > 0 then
call ErrorMsg("SetUnitBonus()", "Unit still has the 2^" + I2S(i) + " ability after it was removed!")
endif
endif
endif
set i = i - 1
endloop
if applyMinBonus then
call UnitAddAbility(u, bonus.negativeRawcode)
call UnitMakeAbilityPermanent(u, true, bonus.negativeRawcode)
else
call UnitRemoveAbility(u, bonus.negativeRawcode)
endif
return output
endfunction
function GetUnitBonus takes unit u, Bonus abstractBonus returns integer
local integer i = 0
local integer amount = 0
local AbilityBonus bonus = AbilityBonus(abstractBonus)
static if DEBUG_MODE then
if not abstractBonus.isBonusObject then
call ErrorMsg("GetUnitBonus()", "Invalid bonus type given")
endif
endif
if abstractBonus.getType() != AbilityBonus.typeid then
return abstractBonus.getBonus(u)
endif
if bonus.heroesOnly and not IsUnitType(u, UNIT_TYPE_HERO) then
debug call ErrorMsg("GetUnitBonus()", "Trying to get a hero-only bonus from a non-hero unit")
return 0
endif
if GetUnitAbilityLevel(u, bonus.negativeRawcode) > 0 then
set amount = bonus.minBonus
endif
loop
exitwhen i == bonus.count
if GetUnitAbilityLevel(u, bonus.rawcode + i) > 0 then
set amount = amount + powersOf2[i]
endif
set i = i + 1
endloop
return amount
endfunction
function AddUnitBonus takes unit u, Bonus bonus, integer amount returns integer
return SetUnitBonus(u, bonus, GetUnitBonus(u, bonus) + amount)
endfunction
// ===
// Initialization
// ===
private function OnInit takes nothing returns nothing
local integer i
// Set up powers of 2
set powersOf2[0] = 1
set powersOf2Count = 1
static if DEBUG_MODE and PRELOAD_ABILITIES and not LIBRARY_xepreload and not LIBRARY_AbilityPreload then
call ErrorMsg("Initialization", "PRELOAD_ABILITIES is set to true, but neither usable preloading library is detected")
endif
// Setup bonuses
call Setup()
endfunction
endlibrary
//TESH.scrollpos=615
//TESH.alwaysfold=0
library Board requires ARGB
//==============================================================================
// Board v0.2.0
//==============================================================================
// Credits:
//------------------------------------------------------------------------------
// Written By:
// Earth-Fury
//------------------------------------------------------------------------------
// I don't care if you credit me or not if you use this. However, you must not
// misrepresent the source of this library in any way. This includes, but is not
// limited to claiming yourself to be the sole contributor to a map which uses
// this library.
//
//==============================================================================
// Introduction:
//------------------------------------------------------------------------------
// Board is a library which provides decorators for multiboards. Basically, the
// Board library gives you multiboards with a more manageable API. You can not
// mix usage of the Board class and usage of the multiboard natives. You can
// have multiboards which in no way use the Board library, as well as ones that
// do.
//
// Board does not impose limits on the number of boards, columns, rows, or
// items within boards. You can create an arbitrary number of boards with an
// arbitrary number of rows and columns, without running in to problems with
// the array size limit.
//
//==============================================================================
// API Guide
//------------------------------------------------------------------------------
// The API for this library is very big. However, most of the methods do the
// exact same thing as their native counterparts. As well, methods which share
// the same name do the same thing, with some minor differences.
//
//------------------------------------------------------------------------------
// An Important Note:
//
// All of the array access methods (That is, the [] methods) which return a
// BoardRow, BoardColumn, or BoardItem, will accept values greater than the size
// of the Board. They will resize the board so that it contains the requested
// item.
//
// Note that if you have a BoardItem, BoardRow, or BoardColumn object, and
// destroy the board they point to, weird things can happen if you use them. So
// please try to make sure you don't use BoardItem/Row/Column objects if the
// Board they belong to has been destroyed.
//
// The values of BoardRow, BoardColumn, and BoardItem instances can and will go
// above 8190. They are not suitable for use as array indexes. Instances of the
// Board struct itself are suitable for that use.
//
//------------------------------------------------------------------------------
// The Board struct:
//
// local Board board = Board.create()
// When created, a Board object will have 0 columns and 0 rows. It will have
// no title. The default settings for items are set such that new items will
// display only text, not icons, and will have a width of 0.
//
// set board.title = "string"
// Sets the title of the multiboard. Identical to the native.
//
// set board.titleColor = 0xFFFF00
// Sets the color of the title of the multiboard to the given ARGB color.
//
//
// set board.visible = true
// Makes the board visible for all players if set to true, and hidden for all
// players if set to false.
//
// set board.visible[Player(0)] = false
// Makes the board visible/hidden for the given player
//
// local boolean b = board.visible[Player(0)]
// Returns true if the board is visible for the given player; false otherwise.
//
//
// set board.minimized = true
// Minimizes/restores the board for all players.
//
// set board.minimized[Player(0)] = false
// Minimizes/restores the board for the given player only.
//
//
// call board.clear()
// Removes all items from the board. The same as the native.
//
//
// local BoardItem it = board[x][y]
// Returns the BoardItem located in column x, row y.
//
//
// local BoardColumn col = board.col[x]
// Returns the BoardColumn object for the given column of the board.
//
// set board.col.count = 10
// Resizes the board such that it has the given number of columns.
//
// local integer i = board.col.count
// Returns the number of columns a board currently has.
//
//
// local BoardRow row = board.row[y]
// Returns the BoardRow object for the given row of the board.
//
// set board.row.count = 10
// Resizes the board such that it has the given number of rows.
//
// local integer i = board.row.count
// Returns the number of rows a board currently has.
//
// board.all
// Using board.all, you can modify the item properties of all items at once,
// as well as change the default properties for items in new rows and
// columns. Example:
//
// set board.all.width = 0.03
//
// See the "Item Manipulation" section for information on the methods that
// board.all has.
//------------------------------------------------------------------------------
// Item Manipulation:
//
// This section details the methods which all structs this library provides has.
// Namely, the methods that modify the properties of board items.
//
// When these methods are called from a row, they modify all of the items in
// that row of the board.
//
// The same for columns.
//
// When called on BoardItems, they only modify the given item.
//
// When called from board.all, they modify all the items on the board, and
// change the default properties for newly added items. (Items are added by the
// board gaining rows and columns.)
//
// Explanation of the methods follows:
//
// local BoardItem it = board[0][0]
//
// set it.text = "string"
// Changes the displayed text for the given item/row/etc.
//
// set it.color = 0xFFFFFF
// Changes the colour of the displayed text.
//
// set it.icon = "ReplaceableTextures\\..."
// Changes the icon of the item/row/etc.
//
// set it.width = 0.04
// Changes the width of the item/row/etc. These width values are the same
// as those used by native multiboards.
//
// call it.setDisplay(shouldDisplayText, shouldDisplayIcon)
// The same as the MultiboardSetItemStyle() native. The first parameter
// determines if the text for the item/row/etc. will be displayed.
// The second parameter determines if the icon will be displayed.
//
//------------------------------------------------------------------------------
// The BoardRow and BoardColumn structs:
//
// Note that these both have the exact same methods. The difference is, of
// course, one represents a row of items in a Board, while the other represents
// a column of items. BoardRow is used below, but it is fully interchangeable.
//
// local BoardRow row = board.row[10]
//
// local BoardItem it = row[y]
// Returns the BoardItem that is in the row, at column y. For a BoardColumn
// object, it takes the row as it's parameter instead of the column.
//
// local integer whatRow = row.position
// Returns the row or columns position in the board. That is to say:
// board.row[10].position is equal to 10.
//
// The BoardRow and BoardColumn structs have all of the methods listed in the
// "Item Manipulation" section.
//
//------------------------------------------------------------------------------
// The BoardItem struct:
//
// local BoardItem it = board[0][1]
//
// local integer itemsColumn = it.x
// Returns the item's x position in the board. (The ID of the column the
// item is in.)
//
// local integer itemsRow = it.y
// The same as it.x, but it returns the row.
//
// The BoardItem struct has all of the methods listed in the "Item Manipulation"
// section of this API guide.
//
//==============================================================================
// There is nothing to configure.
//==============================================================================
// Hopefully this will be inlined one day...
private constant function Mod takes integer dividend, integer divisor returns integer
return dividend - (dividend / divisor) * divisor
endfunction
private constant function B2S takes boolean b returns string
if b then
return "true"
endif
return "false"
endfunction
private function ErrorMsg takes string what, string error returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Board Error: " + what + ": " + error)
endfunction
// ============================================================
// Private keywords
// ============================================================
private keyword bBoard
private keyword bColCount
private keyword bRowCount
private keyword bTemp
private keyword bVisibleFor
// ============================================================
// Item Struct
// ============================================================
struct BoardItem extends array
// =====
// Notes:
// -----
// this = board * 10000 + row * 100 + col
//
// k = Mod(integer(this), 10000)
//
// row = (k - Mod(k, 100)) / 100
// col = Mod(k, 100)
// board = (integer(this) - k) / 10000
//
// row = (Mod(integer(this), 10000) - Mod(Mod(integer(this), 10000), 100)) / 100
// col = Mod(Mod(integer(this), 10000), 100)
// board = (integer(this) - Mod(integer(this), 10000)) / 10000
// =====
public method operator x takes nothing returns integer
return Mod(Mod(integer(this), 10000), 100)
endmethod
public method operator y takes nothing returns integer
return (Mod(integer(this), 10000) - Mod(Mod(integer(this), 10000), 100)) / 100
endmethod
// ==============
public method operator text= takes string val returns nothing
local integer k = Mod(integer(this), 10000)
local Board board = Board((integer(this) - k) / 10000)
local integer row = (k - Mod(k, 100)) / 100
local integer col = Mod(k, 100)
local multiboarditem mbi
if board.bBoard == null then
debug call ErrorMsg("BoardItem[" + I2S(col) + "][" + I2S(row) + "].text=", "The board this item belongs to does not exist anymore")
return
endif
if row >= board.bRowCount then
debug call ErrorMsg("BoardItem.text=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, row + 1)
set board.bRowCount = row + 1
endif
if col >= board.bColCount then
debug call ErrorMsg("BoardItem.text=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetColumnCount(board.bBoard, col + 1)
set board.bColCount = col + 1
endif
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemValue(mbi, val)
call MultiboardReleaseItem(mbi)
set mbi = null
endmethod
public method operator icon= takes string val returns nothing
local integer k = Mod(integer(this), 10000)
local Board board = Board((integer(this) - k) / 10000)
local integer row = (k - Mod(k, 100)) / 100
local integer col = Mod(k, 100)
local multiboarditem mbi
if board.bBoard == null then
debug call ErrorMsg("BoardItem[" + I2S(col) + "][" + I2S(row) + "].icon=", "The board this item belongs to does not exist anymore")
return
endif
if row >= board.bRowCount then
debug call ErrorMsg("BoardItem.icon=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, row + 1)
set board.bRowCount = row + 1
endif
if col >= board.bColCount then
debug call ErrorMsg("BoardItem.icon=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetColumnCount(board.bBoard, col + 1)
set board.bColCount = col + 1
endif
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemIcon(mbi, val)
call MultiboardReleaseItem(mbi)
set mbi = null
endmethod
public method operator color= takes ARGB c returns nothing
local integer k = Mod(integer(this), 10000)
local Board board = Board((integer(this) - k) / 10000)
local integer row = (k - Mod(k, 100)) / 100
local integer col = Mod(k, 100)
local multiboarditem mbi
if board.bBoard == null then
debug call ErrorMsg("BoardItem[" + I2S(col) + "][" + I2S(row) + "].color=", "The board this item belongs to does not exist anymore")
return
endif
if row >= board.bRowCount then
debug call ErrorMsg("BoardItem.color=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, row + 1)
set board.bRowCount = row + 1
endif
if col >= board.bColCount then
debug call ErrorMsg("BoardItem.color=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetColumnCount(board.bBoard, col + 1)
set board.bColCount = col + 1
endif
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemValueColor(mbi, c.red, c.green, c.blue, c.alpha)
call MultiboardReleaseItem(mbi)
set mbi = null
endmethod
public method operator width= takes real r returns nothing
local integer k = Mod(integer(this), 10000)
local Board board = Board((integer(this) - k) / 10000)
local integer row = (k - Mod(k, 100)) / 100
local integer col = Mod(k, 100)
local multiboarditem mbi
if board.bBoard == null then
debug call ErrorMsg("BoardItem[" + I2S(col) + "][" + I2S(row) + "].width=", "The board this item belongs to does not exist anymore")
return
endif
if row >= board.bRowCount then
debug call ErrorMsg("BoardItem.width=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, row + 1)
set board.bRowCount = row + 1
endif
if col >= board.bColCount then
debug call ErrorMsg("BoardItem.width=", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetColumnCount(board.bBoard, col + 1)
set board.bColCount = col + 1
endif
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemWidth(mbi, r)
call MultiboardReleaseItem(mbi)
set mbi = null
endmethod
public method setDisplay takes boolean text, boolean icon returns nothing
local integer k = Mod(integer(this), 10000)
local Board board = Board((integer(this) - k) / 10000)
local integer row = (k - Mod(k, 100)) / 100
local integer col = Mod(k, 100)
local multiboarditem mbi
if board.bBoard == null then
debug call ErrorMsg("BoardItem[" + I2S(col) + "][" + I2S(row) + "].setDisplay()", "The board this item belongs to does not exist anymore")
return
endif
if row >= board.bRowCount then
debug call ErrorMsg("BoardItem.setDisplay()", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, row + 1)
set board.bRowCount = row + 1
endif
if col >= board.bColCount then
debug call ErrorMsg("BoardItem.setDisplay()", "The board has been shrunk to no longer include this item. Will resize the board.")
call MultiboardSetColumnCount(board.bBoard, col + 1)
set board.bColCount = col + 1
endif
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemStyle(mbi, text, icon)
call MultiboardReleaseItem(mbi)
set mbi = null
endmethod
endstruct
// ============================================================
// BoardRow and BoardColumn structs
// ============================================================
//! textmacro Board_DeclareRowCol takes I, K, NAME, COUNT_FUNC, OTHER, THIS
struct Board$NAME$ extends array
// =====
// Notes:
// -----
// this = board * 100 + pos
// pos = Mod(integer(this), 100)
// board = (integer(this) - Mod(integer(this), 100)) / 100
// =====
public method operator [] takes integer $K$ returns BoardItem
local Board board = ((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = Mod(integer(this), 100)
if $K$ >= board.b$OTHER$Count then
call MultiboardSet$COUNT_FUNC$Count(board.bBoard, $K$ + 1)
set board.b$OTHER$Count = $K$ + 1
endif
return BoardItem(integer(board) * 10000 + $I$ * 100 + $K$)
endmethod
public method operator position takes nothing returns integer
return Mod(integer(this), 100)
endmethod
// ==============
public method operator text= takes string val returns nothing
local Board board = Board((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = thistype(Mod(integer(this), 100))
local multiboarditem mbi
local integer $K$ = 0
if board.bBoard == null then
debug call ErrorMsg("Board$NAME$[" + I2S(col) + "][" + I2S(row) + "].text=", "The board this $I$ belongs to does not exist anymore")
return
endif
if $I$ >= board.b$THIS$Count then
debug call ErrorMsg("Board$NAME$.text=", "The board has been shrunk to no longer include this $I$. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, $I$ + 1)
set board.b$THIS$Count = $I$ + 1
endif
loop
exitwhen $K$ == board.b$OTHER$Count
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemValue(mbi, val)
call MultiboardReleaseItem(mbi)
set $K$ = $K$ + 1
endloop
set mbi = null
endmethod
public method operator icon= takes string val returns nothing
local Board board = Board((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = thistype(Mod(integer(this), 100))
local multiboarditem mbi
local integer $K$ = 0
if board.bBoard == null then
debug call ErrorMsg("Board$NAME$[" + I2S(col) + "][" + I2S(row) + "].icon=", "The board this $I$ belongs to does not exist anymore")
return
endif
if $I$ >= board.b$THIS$Count then
debug call ErrorMsg("Board$NAME$.icon=", "The board has been shrunk to no longer include this $I$. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, $I$ + 1)
set board.b$THIS$Count = $I$ + 1
endif
loop
exitwhen $K$ == board.b$OTHER$Count
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemIcon(mbi, val)
call MultiboardReleaseItem(mbi)
set $K$ = $K$ + 1
endloop
set mbi = null
endmethod
public method operator color= takes ARGB c returns nothing
local Board board = Board((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = thistype(Mod(integer(this), 100))
local multiboarditem mbi
local integer $K$ = 0
if board.bBoard == null then
debug call ErrorMsg("Board$NAME$[" + I2S(col) + "][" + I2S(row) + "].color=", "The board this $I$ belongs to does not exist anymore")
return
endif
if $I$ >= board.b$THIS$Count then
debug call ErrorMsg("Board$NAME$.color=", "The board has been shrunk to no longer include this $I$. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, $I$ + 1)
set board.b$THIS$Count = $I$ + 1
endif
loop
exitwhen $K$ >= board.b$OTHER$Count
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemValueColor(mbi, c.red, c.green, c.blue, c.alpha)
call MultiboardReleaseItem(mbi)
set $K$ = $K$ + 1
endloop
set mbi = null
endmethod
public method operator width= takes real r returns nothing
local Board board = Board((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = thistype(Mod(integer(this), 100))
local multiboarditem mbi
local integer $K$ = 0
if board.bBoard == null then
debug call ErrorMsg("Board$NAME$[" + I2S(col) + "][" + I2S(row) + "].width=", "The board this $I$ belongs to does not exist anymore")
return
endif
if $I$ >= board.b$THIS$Count then
debug call ErrorMsg("Board$NAME$.width=", "The board has been shrunk to no longer include this $I$. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, $I$ + 1)
set board.b$THIS$Count = $I$ + 1
endif
loop
exitwhen $K$ == board.b$OTHER$Count
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemWidth(mbi, r)
call MultiboardReleaseItem(mbi)
set $K$ = $K$ + 1
endloop
set mbi = null
endmethod
public method setDisplay takes boolean text, boolean icon returns nothing
local Board board = Board((integer(this) - Mod(integer(this), 100)) / 100)
local integer $I$ = thistype(Mod(integer(this), 100))
local multiboarditem mbi
local integer $K$ = 0
if board.bBoard == null then
debug call ErrorMsg("Board$NAME$[" + I2S(col) + "][" + I2S(row) + "].setDisplay()", "The board this $I$ belongs to does not exist anymore")
return
endif
if $I$ >= board.b$THIS$Count then
debug call ErrorMsg("Board$NAME$.setDisplay()", "The board has been shrunk to no longer include this $I$. Will resize the board.")
call MultiboardSetRowCount(board.bBoard, $I$ + 1)
set board.b$THIS$Count = $I$ + 1
endif
loop
exitwhen $K$ == board.b$OTHER$Count
set mbi = MultiboardGetItem(board.bBoard, row, col)
call MultiboardSetItemStyle(mbi, text, icon)
call MultiboardReleaseItem(mbi)
set $K$ = $K$ + 1
endloop
set mbi = null
endmethod
endstruct
//! endtextmacro
//! runtextmacro Board_DeclareRowCol("row", "col", "Row", "Column", "Col", "Row")
//! runtextmacro Board_DeclareRowCol("col", "row", "Column", "Row", "Row", "Col")
// ============================================================
// Helper Structs (For [][], .col[], .row[], etc)
// ============================================================
private struct ItemHelper extends array
public method operator[] takes integer row returns BoardItem
local integer col = Board.bTemp
if row < 0 then
debug call ErrorMsg("Board[" + I2S(col) + "][" + I2S(row) + "]", "Given row id is less than 0")
return 0
elseif col < 0 then
debug call ErrorMsg("Board[" + I2S(col) + "][" + I2S(row) + "]", "Given col id is less than 0")
return 0
endif
//i = brd * 10000 + row * 100 + col
if col >= Board(this).bColCount then
call MultiboardSetColumnCount(Board(this).bBoard, col + 1)
set Board(this).bColCount = col + 1
endif
if row >= Board(this).bRowCount then
call MultiboardSetRowCount(Board(this).bBoard, row + 1)
set Board(this).bRowCount = row + 1
endif
return integer(this) * 10000 + row * 100 + Board(this).bTemp
endmethod
endstruct
private struct RowHelper extends array
public method operator count takes nothing returns integer
return Board(this).bRowCount
endmethod
public method operator count= takes integer i returns nothing
call MultiboardSetRowCount(Board(this).bBoard, i + 1)
set Board(this).bRowCount = i + 1
endmethod
public method operator[] takes integer row returns BoardRow
if row < 0 then
debug call ErrorMsg("Board.row[" + I2S(row) + "]", "Given row id is less than 0")
return 0
endif
if row >= Board(this).bRowCount then
call MultiboardSetRowCount(Board(this).bBoard, row + 1)
set Board(this).bRowCount = row + 1
endif
if Board(this).bColCount < 1 then
call MultiboardSetColumnCount(Board(this).bBoard, 1)
set Board(this).bColCount = 1
endif
return BoardRow(row + integer(this) * 100)
endmethod
endstruct
private struct ColumnHelper extends array
public method operator count takes nothing returns integer
return Board(this).bColCount
endmethod
public method operator count= takes integer i returns nothing
call MultiboardSetColumnCount(Board(this).bBoard, i + 1)
set Board(this).bColCount = i + 1
endmethod
public method operator[] takes integer col returns BoardColumn
if col < 0 then
debug call ErrorMsg("Board.col[" + I2S(col) + "]", "Given column id is less than 0")
return 0
endif
if col >= Board(this).bColCount then
call MultiboardSetColumnCount(Board(this).bBoard, col + 1)
set Board(this).bColCount = col + 1
endif
if Board(this).bRowCount < 1 then
call MultiboardSetRowCount(Board(this).bBoard, 1)
set Board(this).bRowCount = 1
endif
return BoardColumn(col + integer(this) * 100)
endmethod
endstruct
private struct VisibleHelper extends array
public method operator []= takes player p, boolean b returns nothing
if GetPlayerId(p) > 11 then
debug call ErrorMsg("Board.visible[\"" + GetPlayerName(p) + "\"]=" + B2S(b), "Given player is a neutral player")
return
endif
set Board(this).bVisibleFor[GetPlayerId(p)] = b
if GetLocalPlayer() == p then
call MultiboardDisplay(Board(this).bBoard, b)
endif
endmethod
public method operator [] takes player p returns boolean
if GetPlayerId(p) > 11 then
debug call ErrorMsg("Board.visible[\"" + GetPlayerName(p) + "\"]", "Given player is a neutral player")
return false
endif
return Board(this).bVisibleFor[GetPlayerId(p)]
endmethod
endstruct
private struct MinimizedHelper extends array
public method operator[]= takes player p, boolean b returns nothing
if GetPlayerId(p) > 11 then
debug call ErrorMsg("Board.minimized[\"" + GetPlayerName(p) + "\"]=" + B2S(b), "Given player is a neutral player")
return
endif
if GetLocalPlayer() == p then
call MultiboardMinimize(Board(this).bBoard, b)
endif
endmethod
endstruct
private struct AllHelper extends array
public method operator text= takes string val returns nothing
call MultiboardSetItemsValue(Board(this).bBoard, val)
endmethod
public method operator icon= takes string val returns nothing
call MultiboardSetItemsIcon(Board(this).bBoard, val)
endmethod
public method operator color= takes ARGB c returns nothing
call MultiboardSetItemsValueColor(Board(this).bBoard, c.red, c.green, c.blue, c.alpha)
endmethod
public method operator width= takes real r returns nothing
call MultiboardSetItemsWidth(Board(this).bBoard, r)
endmethod
public method setDisplay takes boolean text, boolean icon returns nothing
call MultiboardSetItemsStyle(Board(this).bBoard, text, icon)
endmethod
endstruct
// ============================================================
// Board Struct
// ============================================================
struct Board
multiboard bBoard
integer bColCount = 0
integer bRowCount = 0
boolean array bVisibleFor[12]
static integer bTemp
public static method create takes nothing returns thistype
local thistype this = allocate()
set bBoard = CreateMultiboard()
call MultiboardSetItemsWidth(bBoard, 0)
call MultiboardSetItemsStyle(bBoard, true, false)
return this
endmethod
private method onDestroy takes nothing returns nothing
call DestroyMultiboard(bBoard)
set bBoard = null
endmethod
//==================
public method operator[] takes integer column returns ItemHelper
set bTemp = column
return ItemHelper(this)
endmethod
public method operator col takes nothing returns ColumnHelper
return ColumnHelper(this)
endmethod
public method operator row takes nothing returns RowHelper
return RowHelper(this)
endmethod
//==================
public method operator all takes nothing returns AllHelper
return AllHelper(this)
endmethod
public method operator title= takes string value returns nothing
call MultiboardSetTitleText(bBoard, value)
endmethod
public method operator titleColor= takes ARGB color returns nothing
call MultiboardSetTitleTextColor(bBoard, color.red, color.green, color.blue, color.alpha)
endmethod
public method operator visible takes nothing returns VisibleHelper
return VisibleHelper(this)
endmethod
public method operator visible= takes boolean b returns nothing
local integer i = 0
loop
exitwhen i == 12
set bVisibleFor[i] = b
set i = i + 1
endloop
call MultiboardDisplay(bBoard, b)
endmethod
public method operator minimized takes nothing returns MinimizedHelper
return MinimizedHelper(this)
endmethod
public method operator minimized= takes boolean b returns nothing
call MultiboardMinimize(bBoard, b)
endmethod
public method clear takes nothing returns nothing
call MultiboardClear(bBoard)
endmethod
endstruct
endlibrary
//TESH.scrollpos=208
//TESH.alwaysfold=0
library MovementBonus initializer OnInit requires BonusMod, AutoIndex
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ MovementBonus for BonusMod
//@=============================================================================
//@ Credits:
//@-----------------------------------------------------------------------------
//@ Written by:
//@ Earth-Fury
//@=============================================================================
//@ Requirements:
//@-----------------------------------------------------------------------------
//@ This library requires the BonusMod library, and the AutoIndex library.
//@
//@=============================================================================
//@ Readme:
//@-----------------------------------------------------------------------------
//@ This library provides one new bonus type:
//@
//@ - BONUS_MOVEMENT_SPEED
//@ Modifies a unit's movement speed.
//@
//@ A unit's movement speed can never go below or above the values configured
//@ in the gameplay constants for a map.
//@
//@ You should not modify a unit's movement speed any way other than via
//@ BonusMod. Doing so will cause issues.
//@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////
//==============================================================================
// Configuration:
//==============================================================================
//------------------------------------------------------------------------------
// The following constants must be equal to the equivalent gameplay constants.
// By default, these are set to the default vlues for the gameplay constants.
//------------------------------------------------------------------------------
globals
constant integer MAX_UNIT_MOVEMENT = 400
constant integer MIN_UNIT_MOVEMENT = 150
constant integer MAX_BUILDING_MOVEMENT = 400
constant integer MIN_BUILDING_MOVEMENT = 25
endglobals
//==============================================================================
// End of configuration
//==============================================================================
globals
Bonus BONUS_MOVEMENT_SPEED
endglobals
private function ErrorMsg takes string func, string s returns nothing
call BJDebugMsg("|cffFF0000MovementBonus Error|r|cffFFFF00:|r |cff8080FF" + func + "|r|cffFFFF00:|r " + s)
endfunction
private struct BonusValue
public integer speed = 0
public unit owner
private static thistype array owners
public static thistype array all
public static integer count = 0
public integer index
private static method create takes unit u returns thistype
local thistype this = thistype.allocate()
set this.owner = u
set thistype.owners[GetUnitId(u)] = this
set thistype.all[thistype.count] = this
set this.index = thistype.count
set thistype.count = thistype.count + 1
return this
endmethod
private method onDestroy takes nothing returns nothing
set thistype.owners[GetUnitId(this.owner)] = thistype(0)
set thistype.all[this.index] = thistype.all[thistype.count]
set thistype.count = thistype.count - 1
set this.owner = null
endmethod
public static method getInstance takes unit u returns thistype
if thistype.owners[GetUnitId(u)] == 0 then
return thistype.create(u)
else
return thistype.owners[GetUnitId(u)]
endif
endmethod
public static method operator[] takes unit u returns thistype
return thistype.owners[GetUnitId(u)]
endmethod
public static method operator[]= takes unit u, thistype i returns nothing
set thistype.owners[GetUnitId(u)] = i
endmethod
endstruct
private struct MovementBonus extends Bonus
integer minBonus
integer maxBonus
static method create takes integer min, integer max returns thistype
local thistype this = allocate()
set this.minBonus = min
set this.maxBonus = max
return this
endmethod
method setBonus takes unit u, integer amount returns integer
local BonusValue value
local integer min
local integer max
local integer actualSpeed
if not IsUnitIndexed(u) then
debug call ErrorMsg("MovementBonus.setBonus()", "Unit that is not indexed by AutoIndex given")
return 0
endif
set value = BonusValue.getInstance(u)
if IsUnitType(u, UNIT_TYPE_STRUCTURE) then
set min = MIN_BUILDING_MOVEMENT
set max = MAX_BUILDING_MOVEMENT
else
set min = MIN_UNIT_MOVEMENT
set max = MAX_UNIT_MOVEMENT
endif
set actualSpeed = R2I(GetUnitMoveSpeed(u)) - value.speed
if actualSpeed + amount < min then
debug call ErrorMsg("MovementBonus.setBonus()", "Attempting to set a unit's speed below it's minimum")
set amount = -actualSpeed + min
elseif actualSpeed + amount > max then
debug call ErrorMsg("MovementBonus.setBonus()", "Ateempting to set a unit's speed above it's maximum")
set amount = max - actualSpeed
endif
call SetUnitMoveSpeed(u, actualSpeed + amount)
set value.speed = amount
return amount
endmethod
method getBonus takes unit u returns integer
local BonusValue value
if not IsUnitIndexed(u) then
debug call ErrorMsg("MovementBonus.getBonus()", "Unit that is not indexed by AutoIndex given")
return 0
endif
set value = BonusValue[u]
if value == 0 then
return 0
endif
return value.speed
endmethod
method removeBonus takes unit u returns nothing
call this.setBonus(u, 0)
endmethod
method isValidBonus takes unit u, integer value returns boolean
local integer min
local integer max
local integer currentBonus
local integer actualSpeed
if not IsUnitIndexed(u) then
return false
endif
if IsUnitType(u, UNIT_TYPE_STRUCTURE) then
set min = MIN_BUILDING_MOVEMENT
set max = MAX_BUILDING_MOVEMENT
else
set min = MIN_UNIT_MOVEMENT
set max = MAX_UNIT_MOVEMENT
endif
set actualSpeed = R2I(GetUnitMoveSpeed(u)) - this.getBonus(u)
if actualSpeed + value < min then
return false
elseif actualSpeed + value > max then
return false
else
return true
endif
endmethod
endstruct
private function OnLeaveMap takes unit u returns nothing
if BonusValue[u] != 0 then
call BonusValue[u].destroy()
endif
endfunction
private function OnInit takes nothing returns nothing
local integer min
local integer max
call OnUnitDeindexed(OnLeaveMap)
if MAX_UNIT_MOVEMENT > MAX_BUILDING_MOVEMENT then
set max = MAX_UNIT_MOVEMENT
else
set max = MAX_BUILDING_MOVEMENT
endif
if MIN_UNIT_MOVEMENT < MIN_BUILDING_MOVEMENT then
set min = MIN_UNIT_MOVEMENT
else
set min = MIN_BUILDING_MOVEMENT
endif
set BONUS_MOVEMENT_SPEED = MovementBonus.create(min, max)
endfunction
endlibrary
//TESH.scrollpos=45
//TESH.alwaysfold=0
/***********************************************************
* PreventOrders
* by Element of Water
************************************************************
* Requirements:
* - AutoIndex by grim001
* - JassHelper by Vexorian (for vJass)
************************************************************
* What is it?
*
* PreventOrders is a simple library which provides a few
* useful functions to do with the preventing and
* cancelling of certain orders. Whenever an order is
* "prevented", the unit will carry on with its previous
* order as usual (but if it has multiple orders queued
* up, it will not continue with those).
*
* CancelOrders immediately cancels a unit's orders. It
* is different to simply issuing a "stop" order, because
* it works even in response to SpellCast or IssuedOrder
* events. It takes just a single unit parameter. Call
* it like this:
*
* call CancelOrders(myUnit)
*
* It's that simple!
*
* PreventCurrentOrder immediately stops the unit from
* performing its current order and returns it to its
* previous order. The syntax for calling it is as follows:
*
* call PreventCurrentOrder(myUnit)
*
* Simplez!
*
* PreventOrders permanently stops a unit from responding
* to immediate, point and/or target orders. Call it like
* this:
*
* call PreventOrders(myUnit, immediate, point, target)
*
* immediate, point and target are booleans. These should
* be true if you want to disable immediate, point or
* target orders respectively. If you want to re-enable
* a type of order, simply call the function again with
* the desired parameters as false, and the unit will be
* able to recieve orders again
*
* PreventSpecificOrder permanently stops a unit from
* responding to a specific order, such as "move", "smart",
* "channel", "acidbomb", etc. Call it like this:
*
* call PreventSpecificOrder(myUnit, order, prevent)
*
* order is the order string which determines which order
* is prevented, and prevent is a boolean. prevent should
* be true if you want to disable the order, and false if
* you want to re-enable it. Also, if it is false it will
* bypass the blocking of all orders just for this order.
* You can call ClearSpecificOrderPrevention(myUnit, order)
* to reset for one specific order, or call
* ClearAllSpecificOrderPrevention(myUnit) to reset all
* orders for that unit.
*
* There is a variation of this function,
* PreventSpecificOrderById, which takes an integer instead
* of a string for if you prefer to work with order ids.
* You may also use ClearSpecificOrderPreventionById.
*
* AllowNextOrder allows a unit to respond to the next order
* it is issued, whatever that may be. Even if the order
* would not be blocked anyway, this is cleared immediately
* after the next order issued to the unit. The syntax to
* call it is as follows:
*
* call AllowNextOrder(myUnit)
*
* This function is useful for when you want to control the
* unit through triggers, but make it unresponsive to
* player control. The PreventOrdersHooks add-on utilises
* this function to allow all triggered orders via hooks.
***********************************************************/
library PreventOrders initializer Init requires AutoIndex
private keyword Data
globals
private timer Tim = CreateTimer()
private Data array CancelStack
private integer CancelCount = 0
private hashtable Hash = InitHashtable()
private constant integer ORDER_STOP = 851972
// Purely for debugging purposes, this displays when an order is prevented
private constant boolean DISPLAY_PREVENTED_ORDERS = false
// Set this to true to make units keep their old orders rather than simply stopping when an order is prevented
private constant boolean RETAIN_PREVIOUS_ORDERS = false
endglobals
private function DebugMsg takes string unitName, string orderType, string orderString returns nothing
debug static if DISPLAY_PREVENTED_ORDERS then
debug call BJDebugMsg("PreventOrders: Prevented " + unitName + " from being issued a" + orderType + " " + orderString + " order")
debug endif
endfunction
private struct Data extends array
static constant integer IMMEDIATE = 1
static constant integer POINT = 2
static constant integer TARGET = 3
unit u
boolean i
boolean p
boolean t
boolean doNext
integer lastOrderType
integer lastOrderId
widget lastOrderTargetW
real lastOrderTargetX
real lastOrderTargetY
boolean cancel
method lastImmediateOrder takes integer id returns nothing
set lastOrderType = IMMEDIATE
set lastOrderId = id
endmethod
method lastPointOrder takes integer id, real x, real y returns nothing
set lastOrderType = POINT
set lastOrderId = id
set lastOrderTargetX = x
set lastOrderTargetY = y
endmethod
method lastTargetOrder takes integer id, widget target returns nothing
set lastOrderType = TARGET
set lastOrderId = id
set lastOrderTargetW = target
endmethod
method doLastOrder takes nothing returns nothing
if cancel then
set doNext = true
call IssueImmediateOrderById(u, ORDER_STOP)
else
if lastOrderType == IMMEDIATE then
set doNext = true
call IssueImmediateOrderById(u, lastOrderId)
elseif lastOrderType == POINT then
set doNext = true
call IssuePointOrderById(u, lastOrderId, lastOrderTargetX, lastOrderTargetY)
elseif lastOrderType == TARGET then
set doNext = true
call IssueTargetOrderById(u, lastOrderId, lastOrderTargetW)
else
set doNext = true
call IssueImmediateOrderById(u, ORDER_STOP)
endif
endif
endmethod
method assign takes unit whichUnit returns nothing
set u = whichUnit
endmethod
method destroy takes nothing returns nothing
call FlushChildHashtable(Hash, this)
set u = null
set i = false
set p = false
set t = false
set doNext = false
set lastOrderType = 0
set cancel = false
endmethod
endstruct
private function Cancel takes nothing returns nothing
loop
set CancelCount = CancelCount - 1
static if RETAIN_PREVIOUS_ORDERS then
call CancelStack[CancelCount].doLastOrder()
else
set CancelStack[CancelCount].doNext = true
call IssueImmediateOrderById(CancelStack[CancelCount].u, ORDER_STOP)
endif
exitwhen CancelCount == 0
endloop
endfunction
private function PreventCurrentOrderFromData takes Data d returns nothing
if CancelCount == 0 then
call TimerStart(Tim, 0., false, function Cancel)
endif
set CancelStack[CancelCount] = d
set CancelCount = CancelCount + 1
endfunction
function PreventCurrentOrder takes unit u returns nothing
call PreventCurrentOrderFromData(Data[GetUnitId(u)])
endfunction
function CancelOrders takes unit u returns nothing
local Data d = Data[GetUnitId(u)]
static if RETAIN_PREVIOUS_ORDERS then
set d.cancel = true
endif
call PreventCurrentOrderFromData(d)
endfunction
function PreventOrders takes unit u, boolean i, boolean p, boolean t returns nothing
local Data d = Data[GetUnitId(u)]
if i or p or t then
set d.i = i
set d.p = p
set d.t = t
endif
endfunction
function PreventSpecificOrderById takes unit u, integer orderId, boolean prevent returns nothing
local Data d = Data[GetUnitId(u)]
if orderId != 0 then
if prevent then
call SaveBoolean(Hash, d, orderId, true)
elseif d != 0 then
call SaveBoolean(Hash, d, orderId, false)
endif
endif
endfunction
function PreventSpecificOrder takes unit u, string order, boolean prevent returns nothing
call PreventSpecificOrderById(u, OrderId(order), prevent)
endfunction
function ClearSpecificOrderPreventionById takes unit u, integer orderId returns nothing
local Data d = Data[GetUnitId(u)]
if orderId != 0 and orderId != ORDER_STOP then
call RemoveSavedBoolean(Hash, d, orderId)
endif
endfunction
function ClearSpecificOrderPrevention takes unit u, string order returns nothing
call ClearSpecificOrderPreventionById(u, OrderId(order))
endfunction
function ClearAllSpecificOrderPrevention takes unit u returns nothing
local Data d = Data[GetUnitId(u)]
call FlushChildHashtable(Hash, d)
endfunction
function AllowNextOrder takes unit u returns nothing
local Data d = Data[GetUnitId(u)]
set d.doNext = true
endfunction
private function ImmediateOrder takes nothing returns boolean
local unit u = GetTriggerUnit()
local Data d = Data[GetUnitId(u)]
local integer i = GetIssuedOrderId()
if d.doNext then
set d.doNext = false
call d.lastImmediateOrder(i)
else
if d.i then
if (not HaveSavedBoolean(Hash, d, i)) or (LoadBoolean(Hash, d, i)) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), "n immediate", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastImmediateOrder(i)
endif
endif
elseif LoadBoolean(Hash, d, i) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), "n immediate", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastImmediateOrder(i)
endif
endif
endif
set u = null
return false
endfunction
private function PointOrder takes nothing returns boolean
local unit u = GetTriggerUnit()
local Data d = Data[GetUnitId(u)]
local integer i = GetIssuedOrderId()
if d.doNext then
set d.doNext = false
call d.lastPointOrder(i, GetOrderPointX(), GetOrderPointY())
else
if d.p then
if (not HaveSavedBoolean(Hash, d, i)) or (LoadBoolean(Hash, d, i)) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), " point", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastPointOrder(i, GetOrderPointX(), GetOrderPointY())
endif
endif
elseif LoadBoolean(Hash, d, i) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), " point", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastPointOrder(i, GetOrderPointX(), GetOrderPointY())
endif
endif
endif
set u = null
return false
endfunction
private function TargetOrder takes nothing returns boolean
local unit u = GetTriggerUnit()
local Data d = Data[GetUnitId(u)]
local integer i = GetIssuedOrderId()
if d.doNext then
set d.doNext = false
call d.lastTargetOrder(i, GetOrderTarget())
else
if d.t then
if (not HaveSavedBoolean(Hash, d, i)) or (LoadBoolean(Hash, d, i)) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), " target", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastTargetOrder(i, GetOrderTarget())
endif
endif
elseif LoadBoolean(Hash, d, i) then
call PreventCurrentOrderFromData(d)
debug call DebugMsg(GetUnitName(u), " target", OrderId2String(i))
else
static if RETAIN_PREVIOUS_ORDERS then
call d.lastTargetOrder(i, GetOrderTarget())
endif
endif
endif
set u = null
return false
endfunction
private function UnitIndexed takes unit u returns nothing
local Data d = Data[GetUnitId(u)]
call d.assign(u)
endfunction
private function UnitDeindexed takes unit u returns nothing
local Data d = Data[GetUnitId(u)]
call d.destroy()
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t, Condition(function ImmediateOrder))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(t, Condition(function PointOrder))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Condition(function TargetOrder))
call OnUnitIndexed(UnitIndexed)
call OnUnitDeindexed(UnitDeindexed)
endfunction
endlibrary
//TESH.scrollpos=9
//TESH.alwaysfold=0
library SimError initializer init
//**************************************************************************************************
//*
//* SimError
//*
//* Mimic an interface error message
//* call SimError(ForPlayer, msg)
//* ForPlayer : The player to show the error
//* msg : The error
//*
//* To implement this function, copy this trigger and paste it in your map.
//* Unless of course you are actually reading the library from wc3c's scripts section, then just
//* paste the contents into some custom text trigger in your map.
//*
//**************************************************************************************************
//==================================================================================================
globals
private sound error
endglobals
//====================================================================================================
function SimError takes player ForPlayer, string msg returns nothing
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+msg+"|r"
if (GetLocalPlayer() == ForPlayer) then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, 0.96, 2.00, msg )
call StartSound( error )
endif
endfunction
private function init takes nothing returns nothing
set error=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
//call StartSound( error ) //apparently the bug in which you play a sound for the first time
//and it doesn't work is not there anymore in patch 1.22
endfunction
endlibrary
//TESH.scrollpos=51
//TESH.alwaysfold=0
library UnitMaxState initializer Initialize requires optional AbilityPreload, optional xepreload
//==============================================================================
// UnitMaxState v2.1
//==============================================================================
// Credits:
//------------------------------------------------------------------------------
// Written By:
// Earth-Fury
//
// Original System By:
// Blade.dk
//
// Intermittent Version By:
// Deaod
//
// With Thanks To:
// - weaaddar for BonusMod and thus inspiration
// - PitzerMike for the ObjectMerger
// - Vexorian for vJass and Jass Helper
// - PipeDream for Grimoire
// - SFilip for TESH
// - MindWorX for maintaining NewGen
//------------------------------------------------------------------------------
// If you use this library in your map, please at least give credit to Blade.dk.
// Without him, this library would not exist.
//==============================================================================
// Introduction:
//------------------------------------------------------------------------------
// UnitMaxState is a library which allows you to modify a unit's maximum life,
// or maximum mana. To achieve this, the library abuses a bug with the AIlf and
// AImz abilities, which is too complex to explain here.
//
// I do believe it was indeed Blade.dk who initially found this bug. If not,
// it's still his system I stole and rewrote. Further, let me thank Deaod for
// writing up his version of this system, which inspired both the reality of
// this rewrite, and the method abilities are handled within it.
//
//==============================================================================
// Requirements:
//------------------------------------------------------------------------------
// UnitMaxState is written in vJass and requires the NewGen editor, or
// Jass Helper with PitzerMike's Object Merger configured for it.
//
// UnitMaxState requires the latest version of Jass Helper.
//
// Preloading of abilities requires either AbilityPreload or xepreload. Neither
// are required for the library to function; however, having one or the other
// will remove the slight delay the first time a unit's max state is changed.
//
//==============================================================================
// Using UnitMaxState:
//------------------------------------------------------------------------------
// UnitMaxState comes with two useful functions:
//
// nothing SetUnitMaxState(unit <target>, unitstate <state>, real <value>)
// Changes <target>'s unitstate <state> to be equal to <value>.
//
// nothing AddUnitMaxState(unit <target>, unitstate <state>, real <value>)
// Adds <value> to <target>'s <state> unitstate. Note that you can use
// negative values with this function.
//
// Both of these functions accept unitstate's other than UNIT_STATE_MAX_LIFE and
// UNIT_STATE_MAX_MANA. There is a small performance penalty in using these over
// direct usage of SetUnitState.
//
// You must not use life/mana boosting upgrades in combination with this system.
//
// Attempting to set a unit's maximum life below 1, or mana below 0 will do
// nothing. A debug message will be output if the script is compiled in
// debug mode.
//==============================================================================
//==============================================================================
// Configuration:
//------------------------------------------------------------------------------
// The below textmacro call is an all-in-one configuration line.
//------------------------------------------------------------------------------
// The first parameter is a boolean.
//
// If true, the abilities used by this system will be created on save. This adds
// a slight delay to saving your map. You only ever have to create the abilities
// the first time this library is added to your map, or if you modify any of
// the other configuration options.
//
// Note that to make the ability creation permanent, you must save with ability
// creation enabled, close your map, and reopen it in the editor. You can then
// disable ability creation, as the abilities will be permanently in your map.
//------------------------------------------------------------------------------
// The second parameter is an integer.
//
// This is the number of abilities this system will use for adding/removing
// life/mana. Note that this system uses four sets of abilities, so the actual
// number of abilities generated and used will be the value you pass here,
// multiplied by 4.
//
// The higher this number, the faster large bonuses will be added. This number
// should never have to go above 13. Between 3 and 5 will work fine for most
// maps.
//------------------------------------------------------------------------------
// The fourth and fifth parameters are 3 character prefixes for rawcodes.
//
// The first one is for the life-modifying abilities, while the second is for
// the mana-modifying abilities.
//
// Please, make sure your map has no abilities whose rawcodes begin with either
// of these prefixes before saving! Otherwise, those abilities will be
// overwritten. You can change these to any 3 character combination, if your
// map does already contain abilities whose rawcodes begin with these prefixes.
//------------------------------------------------------------------------------
//! runtextmacro UnitMaxState_Configuration("true", "3", "ZxL", "ZxM")
//------------------------------------------------------------------------------
// End of configuration
//------------------------------------------------------------------------------
//! textmacro UnitMaxState_Configuration takes LOAD_ABILITIES, ABILITY_COUNT, LIFE_PREFIX, MANA_PREFIX
//*
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i function CreateAbilities(baseAbility, rawcodePrefix, field, name, icon)
//! i k = 0
//! i for sign = -1, 1, 2 do
//! i signStr = "+"
//! i if sign < 0 then
//! i signStr = "-"
//! i end
//! i j = 0
//! i for i = 0, (abilityCount - 1) * 3, 3 do
//! i j = j + 1
//! i createobject(baseAbility, rawcodePrefix .. string.sub(Chars, k + 1, k + 1))
//! i makechange(current, "anam", "UnitMaxState - " .. name)
//! i makechange(current, "ansf", "(" .. signStr .. tostring(j) .. ")")
//! i makechange(current, "aart", "ReplaceableTextures\\CommandButtons\\" .. icon)
//! i makechange(current, "aite", 0)
//! i makechange(current, "alev", 4)
//! i makechange(current, field, 1, 0)
//! i makechange(current, field, 2, 2^(i + 0) * sign)
//! i makechange(current, field, 3, 2^(i + 1) * sign)
//! i makechange(current, field, 4, 2^(i + 2) * sign)
//! i k = k + 1
//! i end
//! i end
//! i end
//! i if $LOAD_ABILITIES$ then
//! i setobjecttype("abilities")
//! i abilityCount = $ABILITY_COUNT$
//! i Chars = "abcdefghijklmnopqrstuvwxyz"
//! i CreateAbilities("AIlf", "$LIFE_PREFIX$", "Ilif", "Life", "BTNHealthStone.blp")
//! i CreateAbilities("AImz", "$MANA_PREFIX$", "Iman", "Mana", "BTNManaStone.blp")
//! i end
//! endexternalblock
// */
globals
private constant integer RAWCODE_LIFE = '$LIFE_PREFIX$a'
private constant integer RAWCODE_MANA = '$MANA_PREFIX$a'
public constant integer ABILITY_COUNT = $ABILITY_COUNT$
endglobals
//! endtextmacro
globals
private constant boolean PRELOAD_ABILITIES = true
private integer array POWERS_OF_2
endglobals
private function ErrorMsg takes string s returns nothing
debug call BJDebugMsg("SetUnitMaxState: " + s)
endfunction
function SetUnitMaxState takes unit target, unitstate state, real targetValue returns nothing
local integer difference
local integer rawcode
local integer abilityId
local integer abilityLevel
local integer currentAbility
if state == UNIT_STATE_MAX_LIFE then
set rawcode = RAWCODE_LIFE
if targetValue < 1 then
call ErrorMsg("You can not set a unit's max life to below 1")
return
endif
elseif state == UNIT_STATE_MAX_MANA then
set rawcode = RAWCODE_MANA
if targetValue < 0 then
call ErrorMsg("You can not set a unit's max mana to below 0")
return
endif
else
call SetUnitState(target, state, targetValue)
return
endif
set difference = R2I(targetValue) - R2I(GetUnitState(target, state))
if difference < 0 then
set difference = -difference
set rawcode = rawcode + ABILITY_COUNT
endif
set abilityId = ABILITY_COUNT - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
loop
exitwhen difference == 0
if difference >= POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)] then
call UnitAddAbility(target, currentAbility)
call SetUnitAbilityLevel(target, currentAbility, abilityLevel)
call UnitRemoveAbility(target, currentAbility)
set difference = difference - POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)]
else
set abilityLevel = abilityLevel - 1
if abilityLevel <= 1 then
set abilityId = abilityId - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
endif
endif
endloop
endfunction
function AddUnitMaxState takes unit target, unitstate state, real additionalValue returns nothing
call SetUnitMaxState(target, state, GetUnitState(target, state) + additionalValue)
endfunction
//! textmacro UnitMaxState_Preload takes RAWCODE
set i = 0
loop
exitwhen i == ABILITY_COUNT * 2 - 1
static if LIBRARY_AbilityPreload then
call AbilityPreload($RAWCODE$ + i)
elseif LIBRARY_xepreload then
call XE_PreloadAbility($RAWCODE$ + i)
endif
set i = i + 1
endloop
//! endtextmacro
private function Initialize takes nothing returns nothing
local integer i
local integer k
set i = 1
set POWERS_OF_2[0] = 1
loop
exitwhen i == ABILITY_COUNT * 2 * 2 * 3 + 1
set POWERS_OF_2[i] = POWERS_OF_2[i - 1] * 2
set i = i + 1
endloop
static if DEBUG_MODE and PRELOAD_ABILITIES and not LIBRARY_AbilityPreload and not LIBRARY_xepreload then
call ErrorMsg("Ability preloading was enabled, but neither of the supported preload libraries are present")
elseif PRELOAD_ABILITIES then
//! runtextmacro UnitMaxState_Preload("RAWCODE_LIFE")
//! runtextmacro UnitMaxState_Preload("RAWCODE_MANA")
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UnitMaxStateBonuses initializer OnInit requires BonusMod, UnitMaxState, AutoIndex
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ UnitMaxStateBonuses for BonusMod
//@=============================================================================
//@ Credits:
//@-----------------------------------------------------------------------------
//@ Written by:
//@ Earth-Fury
//@=============================================================================
//@ Requirements:
//@-----------------------------------------------------------------------------
//@ This library requires the BonusMod library, the UnitMaxState library by
//@ Earth-Fury, and the AutoIndex library by grim001.
//@
//@=============================================================================
//@ Readme:
//@-----------------------------------------------------------------------------
//@ This library provides two new bonus types:
//@
//@ - BONUS_LIFE
//@ - BONUS_MANA
//@
//@ These bonuses, of course, raise a unit's maximum life and mana.
//@
//@ Note that if you simply wish to permanently increase or decrease the maximum
//@ life or mana of a unit, you are likely best off using UnitMaxState directly.
//@
//@ The minimum life and mana bonuses are 1 more than -(unit's max state).
//@ That is to say, these bonuses can not fully remove a unit's life or mana.
//@
//@ There is no maximum bonus.
//@
//@ There is nothing to configure.
//@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////
globals
Bonus BONUS_LIFE
Bonus BONUS_MANA
endglobals
private function ErrorMsg takes string func, string s returns nothing
call BJDebugMsg("|cffFF0000UnitMaxStateBonus Error|r|cffFFFF00:|r |cff8080FF" + func + "|r|cffFFFF00:|r " + s)
endfunction
private struct BonusValues
public integer mana = 0
public integer life = 0
public unit owner
private static thistype array owners
private static method create takes unit u returns thistype
local thistype this = thistype.allocate()
set this.owner = u
set thistype.owners[GetUnitId(u)] = this
return this
endmethod
private method onDestroy takes nothing returns nothing
set thistype.owners[GetUnitId(this.owner)] = thistype(0)
set this.owner = null
endmethod
public static method getInstance takes unit u returns thistype
if thistype.owners[GetUnitId(u)] == 0 then
return thistype.create(u)
else
return thistype.owners[GetUnitId(u)]
endif
endmethod
public static method operator[] takes unit u returns thistype
return thistype.owners[GetUnitId(u)]
endmethod
public static method operator[]= takes unit u, thistype i returns nothing
set thistype.owners[GetUnitId(u)] = i
endmethod
endstruct
//! textmacro UnitMaxStateBonus_DefineBonus takes NAME, STATE, MIN
private struct MaxStateBonus_$NAME$ extends Bonus
integer minBonus = -2147483648
integer maxBonus = 2147483647
method setBonus takes unit u, integer amount returns integer
local BonusValues values
local integer actual
local integer new
local real factor
if not IsUnitIndexed(u) then
debug call ErrorMsg("MaxStateBonus_$NAME$.setBonus()", "Unit that is not indexed by AutoIndex given")
return 0
endif
set values = BonusValues.getInstance(u)
set actual = R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - values.$NAME$
set new = actual + amount
set factor = GetUnitState(u, UNIT_STATE_$STATE$) / GetUnitState(u, UNIT_STATE_MAX_$STATE$)
if new < $MIN$ then
if actual < $MIN$ then
set values.$NAME$ = 0
else
set values.$NAME$ = -actual + $MIN$
endif
call SetUnitState(u, UNIT_STATE_$STATE$, $MIN$)
call SetUnitMaxState(u, UNIT_STATE_MAX_$STATE$, $MIN$)
return values.$NAME$
else
set values.$NAME$ = amount
call SetUnitMaxState(u, UNIT_STATE_MAX_$STATE$, new)
call SetUnitState(u, UNIT_STATE_$STATE$, new * factor)
return values.$NAME$
endif
endmethod
method getBonus takes unit u returns integer
local BonusValues values
local integer actual
local integer new
local real factor
if not IsUnitIndexed(u) then
debug call ErrorMsg("MaxStateBonus_$NAME$.getBonus()", "Unit that is not indexed by AutoIndex given")
return 0
endif
set values = BonusValues[u]
if values == 0 then
return 0
endif
set values.$NAME$ = R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - (R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - values.$NAME$)
return values.$NAME$
endmethod
method removeBonus takes unit u returns nothing
call this.setBonus(u, 0)
endmethod
method isValidBonus takes unit u, integer value returns boolean
local integer currentBonus
if not IsUnitIndexed(u) then
return false
endif
set currentBonus = this.getBonus(u)
return R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - currentBonus + value >= $MIN$
endmethod
endstruct
//! endtextmacro
//! runtextmacro UnitMaxStateBonus_DefineBonus("life", "LIFE", "1")
//! runtextmacro UnitMaxStateBonus_DefineBonus("mana", "MANA", "1")
private function OnLeaveMap takes unit u returns nothing
if BonusValues[u] != 0 then
call BonusValues[u].destroy()
endif
endfunction
private function OnInit takes nothing returns nothing
call OnUnitDeindexed(OnLeaveMap)
set BONUS_LIFE = MaxStateBonus_life.create()
set BONUS_MANA = MaxStateBonus_mana.create()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CWDestructable
//: The textmacros for the system
//! textmacro IMAGE_getVar takes method, variable, type
public method $method$ takes nothing returns $type$
return .$variable$
endmethod
//! endtextmacro
//! textmacro IMAGE_setVar takes method, variable, type
public method $method$ takes $type$ val returns nothing
set .$variable$ = val
endmethod
//! endtextmacro
struct CWDestructable
private destructable Handle = null
private integer id = 0
private real Size = 0.
private player Owner = null
public static method create takes player p, integer id, real size, real posX, real posY, real posZ, real posF returns thistype
local thistype this = thistype.allocate()
set .Handle = CreateDestructableZ(id, posX, posY, posZ, posF, size, 0)
set .Owner = p
set .id = id
if GetLocalPlayer() != .Owner then
call ShowDestructable(.Handle, false)
endif
return this
endmethod
public method show takes boolean b returns nothing
if GetLocalPlayer() == .Owner then
call ShowDestructable(.Handle, b)
endif
endmethod
private method onDestroy takes nothing returns nothing
call RemoveDestructable(.Handle)
endmethod
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Textmacros
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//! runtextmacro IMAGE_getVar("getHandle", "Handle", "destructable")
//==-------------------------------------------
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CWTrackAble
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: Change anything below to what you need!
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: The interfaces for the system
public function interface iHover takes CWTrackAble t returns nothing
public function interface iHit takes CWTrackAble t returns nothing
//: Default methods
public function defHover takes CWTrackAble t returns nothing
endfunction
public function defHit takes CWTrackAble t returns nothing
endfunction
//: The customizeable constants.
//: I hope the names are self-explaining.
globals
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: TrackAble defaults.
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
private constant trackable DEFAULT_HANDLE = null
private constant string DEFAULT_MODEL = ""
private constant player DEFAULT_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
private constant real DEFAULT_POSF = 0.
private constant real DEFAULT_POSX = 0.
private constant real DEFAULT_POSY = 0.
private constant real DEFAULT_POSZ = 0.
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: TrackAble settings.
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
private constant integer SYSTEM_DESTID = 'OTip'
endglobals
//: The textmacros for the system
//! textmacro getVar takes method, variable, type
public method $method$ takes nothing returns $type$
return .$variable$
endmethod
//! endtextmacro
//! textmacro setVar takes method, variable, type
public method $method$ takes $type$ val returns nothing
set .$variable$ = val
endmethod
//! endtextmacro
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: I don't recommend changing code below this!
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
struct CWTrackAble
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Members
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
private trackable Handle = DEFAULT_HANDLE
private string Model = DEFAULT_MODEL
private iHit OnHit = defHit
private iHover OnHover = defHover
private player Owner = DEFAULT_OWNER
private real PosF = DEFAULT_POSF
private real PosX = DEFAULT_POSX
private real PosY = DEFAULT_POSY
private real PosZ = DEFAULT_POSZ
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Methods
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
public static method create takes player p, string s, real x, real y, real z, real f returns thistype
local thistype this = thistype.allocate()
//local destructable d = CreateDestructableZ(SYSTEM_DESTID, x, y, z, f, 1., 0)
local string path = ""
if GetLocalPlayer() == p then
set path = s
else
set path = ""
endif
set .Handle = CreateTrackable(path, x, y, f)
set .Model = s
set .PosF = f
set .PosX = x
set .PosY = y
set .PosZ = z
set .Owner = p
//call RemoveDestructable(d)
//set d = null
return this
endmethod
public method registerHit takes trigger t returns nothing
call TriggerRegisterTrackableHitEvent(t, .Handle)
endmethod
public method registerHover takes trigger t returns nothing
call TriggerRegisterTrackableTrackEvent(t, .Handle)
endmethod
public method hit takes nothing returns nothing
call .OnHit.execute(this)
endmethod
public method hover takes nothing returns nothing
call .OnHover.execute(this)
endmethod
public method getOwner takes nothing returns player
return .Owner
endmethod
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Textmacros
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//! runtextmacro getVar("getF", "PosF", "real")
//! runtextmacro getVar("getX", "PosX", "real")
//! runtextmacro getVar("getY", "PosY", "real")
//! runtextmacro getVar("getZ", "PosZ", "real")
//! runtextmacro getVar("getHandle", "Handle", "trackable")
//==-------------------------------------------
//! runtextmacro setVar("setOnHover", "OnHover", "iHover")
//! runtextmacro setVar("setOnHit", "OnHit", "iHit")
//==-------------------------------------------
endstruct
endlibrary
//TESH.scrollpos=100
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This library actually creates playerbased
windows with trackevents depending on player.
*/
/* ----------------------------------- */
library CustomWindow initializer init requires Table, CWTrackAble, CWDestructable
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: Change anything below to what you need!
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: The interfaces for the system
public function interface iTrackHover takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
public function interface iTrackHit takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
public function interface iOnEvent takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
//: Default functions for this system
public function defTrackHover takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
endfunction
public function defTrackHit takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
endfunction
public function defOnEvent takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
endfunction
//: The customizeable constants.
//: I hope the names are self-explaining.
globals
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Window defaults.
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Table WindowTable = 0
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Window settings.
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
endglobals
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
//: I don't recommend changing code below this!
//=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
struct CustomWindow
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Members
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
private iTrackHover OnTrackHover = defTrackHover
private iTrackHit OnTrackHit = defTrackHit
private iOnEvent OnEvent = defOnEvent
public Table TrackTable = 0
public Table DestructTable = 0
private trigger Trigger = null
private integer Id = -1
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Methods
//==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
public stub method Event takes CWTrackAble eventTrack, eventid eventID returns nothing
//: Fire the onEvent function
call .OnEvent.execute(this, eventTrack)
//: Depending on gameevent, we need
//: to call diffrent methods
if eventID == EVENT_GAME_TRACKABLE_HIT then
//: Game event is hit, so run those
call eventTrack.hit()
call .OnTrackHit.execute(this, eventTrack)
elseif eventID == EVENT_GAME_TRACKABLE_TRACK then
//: Game event is hover, so run those
call eventTrack.hover()
call .OnTrackHover.execute(this, eventTrack)
endif
endmethod
private static method onTrackEvent takes nothing returns nothing
local trigger eventTrig = GetTriggeringTrigger()
local integer windowID = WindowTable[GetHandleId(eventTrig)]
local thistype window = thistype(windowID)
local trackable eventTrack = GetTriggeringTrackable()
local integer trackID = window.TrackTable[GetHandleId(eventTrack)]
local CWTrackAble track = CWTrackAble(trackID)
local eventid eventID = GetTriggerEventId()
//: Fire the actual event
//: for the specific window
call window.Event(track, eventID)
set eventTrig = null
set eventTrack = null
set eventID = null
endmethod
public static method create takes iOnEvent e, iTrackHit hit, iTrackHover hover returns thistype
local thistype this = thistype.allocate()
//: Set a few members
set .OnTrackHit = hit
set .OnTrackHover = hover
set .OnEvent = e
//: Init tables
set .DestructTable = Table.create()
set .TrackTable = Table.create()
//: Create a new system trigger
set .Trigger = CreateTrigger()
set .Id = GetHandleId(.Trigger)
call TriggerAddAction(.Trigger, function thistype.onTrackEvent)
//: Save the window instance
set WindowTable[.Id] = integer(this)
return this
endmethod
public method createTrack takes player p, string s, real x, real y, real z, real f returns CWTrackAble
local CWTrackAble t = CWTrackAble.create(p, s, x, y, z, f)
//: Register the events of the trackable
call t.registerHit(.Trigger)
call t.registerHover(.Trigger)
//: Save the trackable
set .TrackTable[GetHandleId(t.getHandle())] = integer(t)
return t
endmethod
public method createDestructable takes player p, integer id, real size, real posX, real posY, real posZ, real posF returns CWDestructable
local CWDestructable d = CWDestructable.create(p, id, size, posX, posY, posZ, posF)
//: Save the image
set .DestructTable[GetHandleId(d.getHandle())] = integer(d)
return d
endmethod
endstruct
private function init takes nothing returns nothing
set WindowTable = Table.create()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 21th Feb 2010
Release information:
Do not use this library without
copyright information.
Copyright 2010
This is the container for borders
*/
/* ----------------------------------- */
library CWBorder requires AdvancedTable
struct CWBorder
private real startX = 0.
private real startY = 0.
private real endX = 0.
private real endY = 0.
private integer typ = 0
private method createDests takes real size returns nothing
local real xStep = 0.
local real yStep = 0.
local real x = .startX
local real y = .startY
local integer i = 0
local integer end = 0
if .startX != .endX and .startY != .endY then
return
endif
if .startX != .endX then
set xStep = 64. * size
set end = R2I((.endX - .startX) /xStep)
if .startX > .endX then
set xStep = -xStep
set end = -end
endif
else
set yStep = 64. * size
set end = R2I((.endY - .startY) /yStep)
if .startY > .endY then
set yStep = -yStep
set end = -end
endif
endif
loop
exitwhen i >= end
set x = x + xStep
set y = y + yStep
call CreateDestructable(.typ, x, y, 270., size, 0)
set i = i +1
endloop
endmethod
public static method create takes real x1, real y1, real x2, real y2, integer t, real size returns thistype
local thistype this = thistype.allocate()
set .startX = x1
set .startY = y1
set .endX = x2
set .endY = y2
set .typ = t
call .createDests(size)
return this
endmethod
endstruct
struct CWSquareBorder
private real centX = 0.
private real centY = 0.
private real width = 0.
private real height = 0.
private method createDests takes real size returns nothing
call CreateDestructable('cwlu', .centX - .width /2, .centY + .height /2, 270., size, 0)
call CreateDestructable('cwld', .centX - .width /2, .centY - .height /2, 270., size, 0)
call CreateDestructable('cwru', .centX + .width /2, .centY + .height /2, 270., size, 0)
call CreateDestructable('cwrd', .centX + .width /2, .centY - .height /2, 270., size, 0)
call CWBorder.create(.centX - .width /2, .centY - .height /2, .centX + .width /2, .centY - .height /2, 'cwbt', size).destroy()
call CWBorder.create(.centX - .width /2, .centY + .height /2, .centX + .width /2, .centY + .height /2, 'cwup', size).destroy()
call CWBorder.create(.centX + .width /2, .centY + .height /2, .centX + .width /2, .centY - .height /2, 'cwrg', size).destroy()
call CWBorder.create(.centX - .width /2, .centY - .height /2, .centX - .width /2, .centY + .height /2, 'cwlf', size).destroy()
endmethod
public static method create takes real x, real y, real w, real h, real size returns thistype
local thistype this = thistype.allocate()
set .centX = x
set .centY = y
set .width = w
set .height = h
call .createDests(size)
return this
endmethod
endstruct
endlibrary
//TESH.scrollpos=169
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This is the general container.
*/
/* ----------------------------------- */
library CIAll requires Table, AdvancedTable, CIWindow, CustomWindow, CIContent,
//! textmacro CIAll_NewButton takes DEST_ID, X, Y, DESTSAFE, TRACKSAFE, WINDOW, PLAYER, SIZE
set $TRACKSAFE$ = $WINDOW$.createTrack($PLAYER$, "CustomWindow\\Track75.mdx", CI_UI_BASE_X +$X$, CI_UI_BASE_Y +$Y$, 0., 0.)
set $DESTSAFE$ = $WINDOW$.createDestructable($PLAYER$, $DEST_ID$, $SIZE$ +.01, CI_UI_BASE_X +$X$, CI_UI_BASE_Y +$Y$, 0., 270)
//! endtextmacro
struct CIAll
public IntegerTable Buttons = 0
public IntegerTable Tracks = 0
public BooleanTable HasItem = 0
public ItemTable Items = 0
public CustomWindow window = 0
public CustomInventory inventory = 0
public CIContent content = 0
public Table ItemToSlot = 0
public Table SlotToItem = 0
public integer maximum = 0
public stub method init takes nothing returns nothing
endmethod
public stub method refresh takes nothing returns nothing
endmethod
public stub method pick takes CustomItem ci returns nothing
endmethod
public stub method pickCond takes CustomItem ci, integer slot returns boolean
return true
endmethod
public stub method drop takes CustomItem ci returns nothing
endmethod
public stub method dropCond takes CustomItem ci, integer slot returns boolean
return true
endmethod
public stub method getSlotIcon takes integer slot returns integer
return -1
endmethod
public static method create takes integer m, CustomWindow w, CustomInventory i, CIContent c returns thistype
local thistype this = thistype.allocate()
set .maximum = m
set .window = w
set .inventory = i
set .content = c
set Buttons = IntegerTable.create()
set Tracks = IntegerTable.create()
set HasItem = BooleanTable.create()
set Items = ItemTable.create()
set ItemToSlot = Table.create()
set SlotToItem = Table.create()
return this
endmethod
public method refreshSlot takes integer slot returns nothing
local real x = CWTrackAble(.Tracks[slot]).getX()
local real y = CWTrackAble(.Tracks[slot]).getY()
local player slotPlayer = GetOwningPlayer(.inventory.getOwner())
local integer slotDest = .getSlotIcon(slot)
call CWDestructable(.Buttons[slot]).destroy()
set .Buttons[slot] = .window.createDestructable(slotPlayer, slotDest, .76, x, y, .1, 270)
endmethod
public method addItemToSlot takes CustomItem ci, integer slot returns boolean
local integer ID = GetHandleId(ci.getHandle())
if not .HasItem[slot] then
if .pickCond(ci, slot) then
set .ItemToSlot[ID] = slot
set .SlotToItem[slot] = ID
set .Items[slot] = ci.getHandle()
set .HasItem[slot] = true
call .refreshSlot(slot)
call .pick(ci)
return true
else
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.inventory.getOwner()), "You can't equip this item.")
else
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Error|r: " + "Can't equip item!")
endif
endif
else
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.inventory.getOwner()), "This slot is already in use.")
else
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Error|r: " + "This slot is already in use!")
endif
endif
return false
endmethod
public method addItem takes CustomItem ci returns boolean
local integer i = 0
loop
exitwhen i >= .maximum
if not .HasItem[i] then
return .addItemToSlot(ci, i)
endif
set i = i +1
endloop
return false
endmethod
public method moveItemToSlot takes CustomItem ci, integer targ returns boolean
local integer id = GetHandleId(ci.getHandle())
local integer slot = .ItemToSlot[id]
if .HasItem[targ] then
return false
endif
call .removeItemFromSlot(slot)
call .addItemToSlot(ci, targ)
return true
endmethod
public method switchItems takes CustomItem left, CustomItem right returns boolean
local integer slotOne = getItemSlot(left)
local integer idOne = GetHandleId(left.getHandle())
local integer slotTwo = getItemSlot(right)
local integer idTwo = GetHandleId(right.getHandle())
if slotOne != -1 and slotTwo != -1 then
set .ItemToSlot[idOne] = slotTwo
set .SlotToItem[slotOne] = idTwo
set .Items[slotOne] = right.getHandle()
set .HasItem[slotOne] = true
set .ItemToSlot[idTwo] = slotOne
set .SlotToItem[slotTwo] = idOne
set .Items[slotTwo] = left.getHandle()
set .HasItem[slotTwo] = true
call .refreshSlot(slotOne)
call .refreshSlot(slotTwo)
return true
endif
return false
endmethod
public method removeItemFromSlot takes integer slot returns boolean
local CustomItem slotItem = CustomItem.load(.SlotToItem[slot])
if not .HasItem[slot] then
return false
endif
if not .dropCond(slotItem, slot) then
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.inventory.getOwner()), "You can't drop this item.")
else
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Error|r: " + "You can't drop this item.")
endif
return false
endif
call .ItemToSlot.flush(GetHandleId(.Items[slot]))
call .SlotToItem.flush(slot)
set .HasItem[slot] = false
set .Items[slot] = null
call .refreshSlot(slot)
call .drop(slotItem)
return true
endmethod
public method removeItem takes CustomItem ci returns boolean
return .removeItemFromSlot(.getItemSlot(ci))
endmethod
public method getItemSlot takes CustomItem ci returns integer
local integer id = GetHandleId(ci.getHandle())
if not .ItemToSlot.exists(id) then
return -1
endif
return .ItemToSlot[id]
endmethod
public method getSlotItem takes integer slot returns CustomItem
return CustomItem.load(.SlotToItem[slot])
endmethod
public method hasItem takes CustomItem ci returns boolean
return .getItemSlot(ci) != -1
endmethod
public method hasSlotItem takes integer slot returns boolean
return .SlotToItem[slot] != 0
endmethod
public method check takes CustomItem ci returns boolean
return not .hasItem(ci)
endmethod
public method compareTracks takes CWTrackAble eventTrack, integer slot returns boolean
return .Tracks[slot] == eventTrack
endmethod
endstruct
endlibrary
//TESH.scrollpos=85
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This library actually checks the UI actions
you do in your CustomInventory.
*/
/* ----------------------------------- */
library CIActions requires CustomWindow, CustomInventory, CIContent
struct CIActions
private CIContent content = 0
private integer array lastKeys[5]
private string array lastSources[5]
private string array lastActs[5]
private integer curKey = -1
private string curSource = null
private string curAct = null
private CustomItem curItem = 0
public static method create takes CIContent c returns thistype
local thistype this = thistype.allocate()
set .content = c
return this
endmethod
//##=====!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==
//: Actions...
//##=====!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==
private method prepareChange takes nothing returns nothing
local CustomItem left = 0
local CustomItem right = 0
local CIAll cont = 0
if .curSource == "SLOT" then
set cont = .content.getSlots()
elseif .curSource == "EQUIP" then
return // Don't allow equipment to be changed
set cont = .content.getEquipment()
elseif .curSource == "POTION" then
set cont = .content.getPotions()
endif
set left = cont.getSlotItem(.lastKeys[0])
set right = cont.getSlotItem(.curKey)
if left.isLocked() or right.isLocked() then
return
endif
call .content.getSlots().switchItems(left, right)
endmethod
private method prepareMove takes nothing returns nothing
local CustomItem toMove = 0
if .curSource == "SLOT" then
set toMove = .content.getSlots().getSlotItem(.lastKeys[0])
elseif .curSource == "EQUIP" then
return // Don't allow equipment to be changed
set toMove = .content.getEquipment().getSlotItem(.lastKeys[0])
elseif .curSource == "POTION" then
set toMove = .content.getPotions().getSlotItem(.lastKeys[0])
endif
if toMove.isLocked() then
return
endif
call .content.getSlots().moveItemToSlot(toMove, .curKey)
endmethod
private method prepareEquip takes nothing returns nothing
local CustomItem toMove = .content.getSlots().getSlotItem(.lastKeys[0])
if toMove.isLocked() then
return
endif
if .content.getEquipment().addItemToSlot(toMove, .curKey) then
call .content.getSlots().removeItem(toMove)
call .content.getInventory().refresh()
endif
endmethod
private method prepareUnequip takes nothing returns nothing
local CustomItem toMove = .content.getEquipment().getSlotItem(.lastKeys[0])
if .content.getEquipment().removeItem(toMove) then
call .content.getSlots().addItemToSlot(toMove, .curKey)
call .content.getInventory().refresh()
endif
endmethod
private method preparePotion takes nothing returns nothing
local CustomItem toMove = .content.getSlots().getSlotItem(.lastKeys[0])
if toMove.isLocked() then
return
endif
if .content.getPotions().addItemToSlot(toMove, .curKey) then
call .content.getSlots().removeItem(toMove)
endif
endmethod
private method prepareUnpotion takes nothing returns nothing
local CustomItem toMove = .content.getPotions().getSlotItem(.lastKeys[0])
if .content.getPotions().removeItem(toMove) then
call .content.getSlots().addItemToSlot(toMove, .curKey)
endif
endmethod
public method dropItem takes nothing returns nothing
local CustomItem ci = 0
local CIAll cont = 0
if .lastKeys[0] != -1 then
if .lastSources[0] == "SLOT" then
set cont = .content.getSlots()
elseif .lastSources[0] == "EQUIP" then
set cont = .content.getEquipment()
elseif .lastSources[0] == "POTION" then
set cont = .content.getPotions()
endif
set ci = cont.getSlotItem(.lastKeys[0])
if ci != 0 then
call cont.removeItemFromSlot(.lastKeys[0])
call .disselect()
call .content.getInventory().dropItem(ci, true)
call .content.getInventory().drop(ci)
endif
endif
endmethod
public method prepareDrop takes nothing returns nothing
call .dropItem()
endmethod
//##=====!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==!==
private method updateQuery takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= 5
set .lastKeys[i +1] = .lastKeys[i]
set .lastSources[i +1] = .lastSources[i]
set .lastActs[i +1] = .lastActs[i]
set i = i +1
endloop
set .lastKeys[0] = .curKey
set .lastSources[0] = .curSource
set .lastActs[0] = .curAct
endmethod
public method checkSource takes CWTrackAble eventTrack returns nothing
local integer i = 0
loop
exitwhen i >= .content.getSlots().maximum
if .content.getSlots().compareTracks(eventTrack, i) then
set .curKey = i
set .curSource = "SLOT"
set .curAct = ""
return
endif
set i = i +1
endloop
set i = 0
loop
exitwhen i >= .content.getSlots().maximum
if .content.getEquipment().compareTracks(eventTrack, i) then
set .curKey = i
set .curSource = "EQUIP"
set .curAct = ""
return
endif
set i = i +1
endloop
set i = 0
loop
exitwhen i >= .content.getSlots().maximum
if .content.getPotions().compareTracks(eventTrack, i) then
set .curKey = i
set .curSource = "POTION"
set .curAct = ""
return
endif
set i = i +1
endloop
endmethod
private method disselect takes nothing returns nothing
set .curKey = -1
set .curSource = null
set .curAct = null
call .content.select(false)
endmethod
private method updateAction takes CWTrackAble eventTrack returns nothing
set .curKey = -1
set .curSource = null
set .curAct = null
call .checkSource(eventTrack)
endmethod
public method getHoverOrder takes CWTrackAble eventTrack returns nothing
call .updateAction(eventTrack)
static if LIBRARY_CIItemBoard then
if .curSource == "SLOT" then
set .curItem = .content.getSlots().getSlotItem(.curKey)
elseif .curSource == "EQUIP" then
set .curItem = .content.getEquipment().getSlotItem(.curKey)
elseif .curSource == "POTION" then
set .curItem = .content.getPotions().getSlotItem(.curKey)
endif
call .content.getSlots().inventory.updateBoard(.curItem)
endif
endmethod
public method getSelectOrder takes CWTrackAble eventTrack returns nothing
call .updateAction(eventTrack)
if .curKey == .lastKeys[0] and .curSource == .lastSources[0] then
set .curKey = -1
set .curSource = ""
set .curAct = ""
call .updateQuery()
call .disselect()
return
endif
if .curKey != .lastKeys[0] or .curSource != .lastSources[0] then
if .lastSources[0] == "SLOT" then
if .curSource == "SLOT" then
if .content.getSlots().hasSlotItem(.curKey) and .content.getSlots().hasSlotItem(.lastKeys[0]) then
call .prepareChange()
call .disselect()
elseif .content.getSlots().hasSlotItem(.lastKeys[0]) then
call .prepareMove()
call .disselect()
endif
elseif .curSource == "EQUIP" then
if not .content.getEquipment().hasSlotItem(.curKey) and .content.getSlots().hasSlotItem(.lastKeys[0]) then
call .prepareEquip()
call .disselect()
endif
elseif .curSource == "POTION" then
if not .content.getPotions().hasSlotItem(.curKey) and .content.getSlots().hasSlotItem(.lastKeys[0]) then
call .preparePotion()
call .disselect()
endif
endif
elseif .lastSources[0] == "EQUIP" then
if .curSource == "SLOT" then
if not .content.getSlots().hasSlotItem(.curKey) and .content.getEquipment().hasSlotItem(.lastKeys[0]) then
call .prepareUnequip()
call .disselect()
endif
endif
elseif .lastSources[0] == "POTION" then
if .curSource == "SLOT" then
if not .content.getSlots().hasSlotItem(.curKey) and .content.getPotions().hasSlotItem(.lastKeys[0]) then
call .prepareUnpotion()
call .disselect()
endif
elseif .curSource == "POTION" then
if .content.getPotions().hasSlotItem(.curKey) and .content.getPotions().hasSlotItem(.lastKeys[0]) then
call .prepareChange()
call .disselect()
elseif .content.getPotions().hasSlotItem(.lastKeys[0]) then
call .prepareMove()
call .disselect()
endif
endif
endif
endif
call .updateQuery()
endmethod
endstruct
endlibrary
//TESH.scrollpos=39
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This is a content helper for all containers
and the actionhelper.
*/
/* ----------------------------------- */
library CIContent requires CustomWindow, CIItemSlot, optional CIEventHandler
globals
private real tmpX = 0.
private real tmpY = 0.
private player tmpP = null
endglobals
struct CIContent
private boolean viewing = false
private fogmodifier visible = null
private unit fakeUnit = null
private CWDestructable selector = 0
private CWDestructable EscButton = 0
private CWTrackAble EscTrack = 0
private CWDestructable DropButton = 0
private CWTrackAble DropTrack = 0
private integer Player = -1
CustomWindow window = 0
CustomInventory inventory = 0
CIActions action = 0
CISlots Slots = 0
CIEquips Equipment = 0
CIPotions Potions = 0
private real camX = 0.
private real camY = 0.
private real camZ = 0.
private real camDist = 0.
private real camAngle = 0.
private real camAttack = 0.
public method refresh takes nothing returns nothing
call .Slots.refresh()
call .Equipment.refresh()
call .Potions.refresh()
endmethod
public static method create takes integer i, CustomInventory ci, CustomWindow iw, unit invUnit returns thistype
local thistype this = thistype.allocate()
set .Player = i
set .window = iw
set .inventory = ci
set .action = CIActions.create(this)
//! runtextmacro CIAll_NewButton("'cwdp'", "224", "-96", ".DropButton", ".DropTrack", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
//! runtextmacro CIAll_NewButton("'cwcc'", "224", "-32", ".EscButton", ".EscTrack", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set .fakeUnit = invUnit
if GetLocalPlayer() != Player(.Player) then
call ShowUnit(.fakeUnit, false)
endif
set .Slots = CISlots.create(20, iw, ci, this)
call .Slots.init()
set .Equipment = CIEquips.create(4, iw, ci, this)
call .Equipment.init()
set .Potions = CIPotions.create(12, iw, ci, this)
call .Potions.init()
call .refresh()
return this
endmethod
//. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
//: Camera Area
//. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public method show takes boolean bol returns nothing
call FogModifierStop(.visible)
call DestroyFogModifier(.visible)
set .viewing = bol
if bol then
if GetLocalPlayer() == Player(.Player) then
set .camX = GetCameraTargetPositionX()
set .camY = GetCameraTargetPositionY()
set .camZ = GetCameraTargetPositionZ()
set .camDist = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
endif
set .visible = CreateFogModifierRect(Player(.Player), FOG_OF_WAR_VISIBLE, CI_UI_RECT, false, false)
call .refresh()
call PreventSpecificOrder(.inventory.getOwner(), "move", true)
call PreventSpecificOrder(.inventory.getOwner(), "smart", true)
static if LIBRARY_CIItemBoard then
call .inventory.showBoard(true)
endif
else
set .visible = CreateFogModifierRect(Player(.Player), FOG_OF_WAR_MASKED, CI_UI_RECT, false, false)
if GetLocalPlayer() == Player(.Player) then
call SetCameraPosition(.camX, .camY)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 305., 0)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, .camDist, 0)
endif
call ClearAllSpecificOrderPrevention(.inventory.getOwner())
static if LIBRARY_CIItemBoard then
call .inventory.showBoard(false)
endif
endif
call FogModifierStart(.visible)
endmethod
public method changeView takes nothing returns nothing
call .show(not .viewing)
endmethod
//. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
//: Check for actions that have to be done here.
//. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public method checkHoverItem takes CWTrackAble eventTrack returns nothing
if not .viewing then
return
endif
call .action.getHoverOrder(eventTrack)
endmethod
public method checkHitItem takes CWTrackAble eventTrack returns nothing
if not .viewing then
return
endif
call .action.getSelectOrder(eventTrack)
endmethod
public method select takes boolean bol returns nothing
call .selector.show(bol)
endmethod
public method updateSelect takes CWTrackAble eventTrack returns nothing
local real x = eventTrack.getX()
local real y = eventTrack.getY()
if .selector != 0 then
call RemoveDestructable(.selector.getHandle())
call .selector.destroy()
endif
set .selector = .window.createDestructable(Player(.Player), 'cwsl', .76, x, y, .1, 270)
endmethod
public method trackHit takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
call .select(true)
call .updateSelect(eventTrack)
if eventTrack == .EscTrack then
call .changeView()
return
endif
if eventTrack == .DropTrack then
call .action.prepareDrop()
return
endif
call .checkHitItem(eventTrack)
endmethod
public method trackHover takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
local integer i = GetPlayerId(eventTrack.getOwner())
if eventTrack == .EscTrack then
return
endif
if eventTrack == .DropTrack then
return
endif
call .checkHoverItem(eventTrack)
endmethod
public method getInventory takes nothing returns CustomInventory
return .inventory
endmethod
public method lockCam takes nothing returns nothing
if .viewing then
if GetLocalPlayer() == Player(.Player) then
call SetCameraPosition(CI_UI_BASE_X, CI_UI_BASE_Y +128)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 270, 0)
call SetCameraField(CAMERA_FIELD_ROTATION, 90, 0)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1200, 0)
endif
endif
endmethod
public method getSlots takes nothing returns CIAll
return .Slots
endmethod
public method getEquipment takes nothing returns CIAll
return .Equipment
endmethod
public method getPotions takes nothing returns CIAll
return .Potions
endmethod
public method getPlayer takes nothing returns integer
return .Player
endmethod
endstruct
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* ...
What this module does:
Adds the CustomInventory window.
*/
/* ----------------------------------- */
library CIWindow initializer init requires CustomWindow, CustomInventory, CIContent
globals
CIContent array InventoryWindows[15]
CustomWindow InventoryMainWindow = 0
endglobals
private function lockCamera takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
if InventoryWindows[i] != 0 then
call InventoryWindows[i].lockCam()
endif
set i = i +1
endloop
endfunction
private function onEvent takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
endfunction
private function onHit takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
call InventoryWindows[GetPlayerId(eventTrack.getOwner())].trackHit(eventWindow, eventTrack)
endfunction
private function onHover takes CustomWindow eventWindow, CWTrackAble eventTrack returns nothing
call InventoryWindows[GetPlayerId(eventTrack.getOwner())].trackHover(eventWindow, eventTrack)
endfunction
private function showInv takes nothing returns boolean
local integer i = GetPlayerId(GetTriggerPlayer())
if InventoryWindows[i] != 0 then
call InventoryWindows[i].changeView()
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
set InventoryMainWindow = CustomWindow.create(onEvent, onHit, onHover)
call CWSquareBorder.create(CI_UI_BASE_X, CI_UI_BASE_Y + 256., 96., 96., .5).destroy()
call CWSquareBorder.create(CI_UI_BASE_X, CI_UI_BASE_Y + 256., 256., 256., .5).destroy()
call CWSquareBorder.create(CI_UI_BASE_X, CI_UI_BASE_Y - 64., 256., 192., .5).destroy()
call CWSquareBorder.create(CI_UI_BASE_X + 224, CI_UI_BASE_Y + 192. , 0., 192., .5).destroy()
call CWSquareBorder.create(CI_UI_BASE_X + 224, CI_UI_BASE_Y - 64. , 0., 64., .5).destroy()
loop
exitwhen i >= 12
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_END_CINEMATIC)
endif
set i = i +1
endloop
call TimerStart(CreateTimer(), .1, true, function lockCamera)
call TriggerAddCondition(t, Condition(function showInv))
endfunction
function CreateInventoryUnit takes player thePlayer, integer theType returns unit
return CreateUnit(thePlayer, theType, CI_UI_BASE_X, CI_UI_BASE_Y + 192., 0)
endfunction
function CreateInventoryUI takes unit theUnit, unit inventoryUnit returns nothing
local integer i = GetPlayerId(GetOwningPlayer(theUnit))
if GetOwningPlayer(theUnit) != GetOwningPlayer(inventoryUnit) then
return
endif
set InventoryWindows[i] = CIContent.create(i, CustomInventory.create(theUnit), InventoryMainWindow, inventoryUnit)
endfunction
endlibrary
//TESH.scrollpos=87
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This is the container for slots.
*/
/* ----------------------------------- */
library CISlots requires CIAll
globals
private real tmpX = 0.
private real tmpY = 0.
endglobals
struct CISlots extends CIAll
public method init takes nothing returns nothing
local integer rows = 4
local integer columns = 5
local integer max = rows * columns
local integer r = 0
local integer c = 0
local integer nr = 0
loop
exitwhen r >= rows
set c = columns -1
loop
exitwhen c < 0
//! runtextmacro CIAll_NewButton("'cwit'", "(c - columns/2) * 64.", " -32. + (r - rows/2) * 64.", ".Buttons[(max -1) -nr]", ".Tracks[(max -1) -nr]", ".window", "GetOwningPlayer(.inventory.getOwner())","0.75")
set .HasItem[nr] = false
set .Items[nr] = null
set nr = nr +1
set c = c -1
endloop
set r = r +1
endloop
endmethod
public method refresh takes nothing returns nothing
local CustomInventory inv = .inventory
local CIEquips equip = .content.getEquipment()
local CIPotions potions = .content.getPotions()
local CustomItem ci = 0
local integer i = 0
loop
exitwhen i >= .maximum
set ci = .getSlotItem(i)
if not inv.hasItem(ci) or ci == 0 then
call .removeItemFromSlot(i)
endif
set i = i +1
endloop
set i = 0
set ci = 0
loop
exitwhen i >= inv.getIndex() or i >= .maximum
set ci = inv.getItem(i)
if ci != 0 and not .hasItem(ci) then
if not equip.hasItem(ci) and not potions.hasItem(ci) then
call .addItem(ci)
endif
endif
set i = i +1
endloop
endmethod
private method getSlotIcon takes integer slot returns integer
local integer destID = -1
static if LIBRARY_CIItemDest then
if .getSlotItem(slot) != 0 then
set destID = .getSlotItem(slot).dest
endif
endif
if destID != -1 then
return destID
endif
return 'cwit'
endmethod
public method pick takes CustomItem ci returns nothing
return
endmethod
public method pickCond takes CustomItem ci, integer slot returns boolean
return GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
endmethod
public method drop takes CustomItem ci returns nothing
return
endmethod
public method dropCond takes CustomItem ci, integer slot returns boolean
return GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
endmethod
endstruct
endlibrary
//TESH.scrollpos=116
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This is the container for equipment
*/
/* ----------------------------------- */
library CIEquips initializer initSlots requires CIAll, CIItemSlot
globals
private real tmpX = 0.
private real tmpY = 0.
private integer array Slots[12]
private integer array SlotIcons[12]
endglobals
private function initSlots takes nothing returns nothing
//! textmacro CWEquipment__addItemClasses takes CLASS, I
set Slots[$I$] = ITEM_CLASS_$CLASS$
set SlotIcons[$I$] = ITEM_CLASS_ICON_$CLASS$
//! endtextmacro
//! runtextmacro CWEquipment__addItemClasses("RING", "0")
//! runtextmacro CWEquipment__addItemClasses("RING", "1")
//! runtextmacro CWEquipment__addItemClasses("MISC", "2")
//! runtextmacro CWEquipment__addItemClasses("BOOTS", "3")
//! runtextmacro CWEquipment__addItemClasses("MAIN", "4")
//! runtextmacro CWEquipment__addItemClasses("TROUSER", "5")
//! runtextmacro CWEquipment__addItemClasses("AMULET", "6")
//! runtextmacro CWEquipment__addItemClasses("GLOVE", "7")
//! runtextmacro CWEquipment__addItemClasses("HELMET", "8")
//! runtextmacro CWEquipment__addItemClasses("SHOULDER", "9")
//! runtextmacro CWEquipment__addItemClasses("HAND", "10")
//! runtextmacro CWEquipment__addItemClasses("HAND", "11")
endfunction
struct CIEquips extends CIAll
public method init takes nothing returns nothing
local integer r = 0
local integer c = 0
loop
exitwhen c >= 5
//! runtextmacro CIAll_NewButton("SlotIcons[r]", "-128", "288 +(c - 2.5) * 64", ".Buttons[r]", ".Tracks[r]", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set .HasItem[r] = false
set .Items[r] = null
set r = r +1
//! runtextmacro CIAll_NewButton("SlotIcons[r]", "128", "288 +(c - 2.5) * 64", ".Buttons[r]", ".Tracks[r]", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set .HasItem[r] = false
set .Items[r] = null
set r = r +1
set c = c +1
endloop
//! runtextmacro CIAll_NewButton("SlotIcons[r]", "-48", "128", ".Buttons[10]", ".Tracks[10]", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set HasItem[10] = false
set .Items[10] = null
set r = r +1
//! runtextmacro CIAll_NewButton("SlotIcons[r]", "48", "128", ".Buttons[11]", ".Tracks[11]", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set .HasItem[11] = false
set .Items[11] = null
set r = r +1
endmethod
public method refresh takes nothing returns nothing
endmethod
private method getSlotIcon takes integer slot returns integer
local integer destID = -1
static if LIBRARY_CIItemDest then
if .getSlotItem(slot) != 0 then
set destID = .getSlotItem(slot).dest
endif
endif
if destID != -1 then
return destID
endif
return SlotIcons[slot]
endmethod
public method pick takes CustomItem ci returns nothing
local unit eventUnit = .inventory.getOwner()
call ci.addBoni(eventUnit)
call ci.lock()
call ci.equip()
call ci.addEffects(eventUnit)
set eventUnit = null
endmethod
public method pickCond takes CustomItem ci, integer slot returns boolean
local boolean pick = true
local CustomItem tmpOne = 0
local CustomItem tmpTwo = 0
static if LIBRARY_CIItemSlot then
if slot == 10 or slot == 11 then
set tmpOne = .getSlotItem(10)
set tmpTwo = .getSlotItem(11)
if ci.class == ITEM_CLASS_TWOHANDER then
set pick = tmpOne.class == 0 and tmpTwo.class == 0
elseif ci.class == ITEM_CLASS_HAND then
set pick = tmpOne.class != ITEM_CLASS_TWOHANDER and tmpTwo.class != ITEM_CLASS_TWOHANDER
else
set pick = false
endif
else
set pick = (Slots[slot] == ci.class)
endif
endif
set pick = pick and ci.check(.inventory.getOwner())
set pick = pick and GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
return pick
endmethod
public method drop takes CustomItem ci returns nothing
local unit eventUnit = .inventory.getOwner()
call ci.remBoni(eventUnit)
call ci.unLock()
call ci.unEquip()
call ci.removeEffects()
set eventUnit = null
endmethod
public method dropCond takes CustomItem ci, integer slot returns boolean
return GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
endmethod
endstruct
endlibrary
//TESH.scrollpos=68
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
This is the container for potions.
*/
/* ----------------------------------- */
library CIPotions requires CIAll
globals
private real tmpX = 0.
private real tmpY = 0.
endglobals
struct CIPotions extends CIAll
public method init takes nothing returns nothing
local integer r = 0
local integer c = 0
loop
exitwhen c >= 4
//! runtextmacro CIAll_NewButton("'cwit'", "224", "92 + c * 64", ".Buttons[c]", ".Tracks[c]", ".window", "GetOwningPlayer(.inventory.getOwner())", ".75")
set .HasItem[c] = false
set .Items[c] = null
set c = c +1
endloop
endmethod
public method refresh takes nothing returns nothing
local CustomItem ci = 0
local integer i = 0
loop
exitwhen i >= .maximum
if .HasItem[i] then
set ci = .getSlotItem(i)
if not .inventory.hasItem(ci) then
call .removeItemFromSlot(i)
endif
endif
set i = i +1
endloop
endmethod
private method getSlotIcon takes integer slot returns integer
local integer destID = -1
static if LIBRARY_CIItemDest then
if .getSlotItem(slot) != 0 then
set destID = .getSlotItem(slot).dest
endif
endif
if destID != -1 then
return destID
endif
return 'cwit'
endmethod
public method pick takes CustomItem ci returns nothing
call ci.lock()
call SetItemDroppable(ci.getHandle(), false)
call .inventory.pickupItem(ci, true)
endmethod
public method pickCond takes CustomItem ci, integer slot returns boolean
local boolean canPick = ci.check(.inventory.getOwner())
set canPick = canPick and ci.class == ITEM_CLASS_POTION
set canPick = canPick and GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
return canPick
endmethod
public method drop takes CustomItem ci returns nothing
call ci.unLock()
call SetItemDroppable(ci.getHandle(), true)
call .inventory.dropItem(ci, false)
endmethod
public method dropCond takes CustomItem ci, integer slot returns boolean
return GetUnitState(.inventory.getOwner(), UNIT_STATE_LIFE) >= 1.
endmethod
endstruct
endlibrary
//TESH.scrollpos=157
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 11th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
What this module does:
Adds the ability to forge items in your
CustomInventory.
*/
/* ----------------------------------- */
/* This debugs the static ifs */
library CIForging
struct CIForgeItem
// Information holders.
// Data: Information about the amount of ForgeItems being created
public static hashtable data = InitHashtable()
// Ids: ItemIDs of the required items
public static hashtable ids = InitHashtable()
// Amounts: Integer of how many items of that type are required
public static hashtable amounts = InitHashtable()
// Static index of this struct
private static integer Index = 0
// Temporary information holder
private static thistype TmpObject = 0
// Object related members
private integer CurReq = 0
private integer ID = 0
private integer key = 0
public static method onInit takes nothing returns nothing
set thistype.TmpObject = thistype.allocate()
endmethod
public static method getIndex takes nothing returns integer
return thistype.Index
endmethod
public static method create takes integer ID returns thistype
local thistype this = thistype.TmpObject
set .ID = ID
set .CurReq = 0
set .key = thistype.Index
set thistype.Index = thistype.Index + 1
call SaveInteger(thistype.data, .key, 0, .ID)
call SaveInteger(thistype.data, .key, 1, .CurReq)
return this
endmethod
public method addReq takes integer id, integer amount returns nothing
call SaveInteger(.ids, .key, .CurReq, id)
call SaveInteger(.amounts, .key, .CurReq, amount)
set .CurReq = .CurReq + 1
call SaveInteger(thistype.data, .key, 1, .CurReq)
endmethod
endstruct
function CreateForgeItem takes integer id returns CIForgeItem
return CIForgeItem.create(id)
endfunction
globals
string CIForgeEffect = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl"
endglobals
module CIForging
implement CIItemDrop
implement CIItemSeek
private static integer CIForgeItemID = -1
private static method forgeCheck takes CustomItem cit returns boolean
local boolean doRem = true
// Check whether the itemTypes are the same and
// whether the item is not equipped and not locked
set doRem = doRem and GetItemTypeId(cit.getHandle()) == CIForgeItemID
// If this module has been used, you have to check those values too
static if LIBRARY_CIItemProtection then
set doRem = doRem and not cit.isEquipped() and not cit.isLocked()
endif
return doRem
endmethod
private method forgeOne takes integer i returns boolean
local boolean forge = true
local integer j = 0
local integer id = LoadInteger(CIForgeItem.data, i, 0) // Temporary forgeID
local integer c = LoadInteger(CIForgeItem.data, i, 1) // Temporary amountInteger
local integer req = 0 // Current required ID
local integer amount = 0 // Current required amount
local item new = null // Current new item
local CustomItem newObj = 0 // Current new itemObj
if c <= 0 or id == 0 then
set forge = false
else
loop
exitwhen j >= c or not forge
// Save the requirements and the amount into the variables
set req = LoadInteger(CIForgeItem.ids, i, j)
set amount = LoadInteger(CIForgeItem.amounts, i, j)
// Save the required ID temporary into this dataholder
set thistype.CIForgeItemID = req
// Compare whether we have enough items or not
if .advancedCount(forgeCheck) < amount then
set forge = false
endif
set j = j + 1
endloop
// If we have enough items
if forge then
set j = 0
loop
exitwhen j >= c
// Save the temporary items again
set req = LoadInteger(CIForgeItem.ids, i, j)
set amount = LoadInteger(CIForgeItem.amounts, i, j)
// Now we remove that amount of items
set thistype.CIForgeItemID = req
call .advancedRemove(forgeCheck, amount)
set j = j + 1
endloop
// We create the new item
set new = CreateItem(id, GetUnitX(.carrier), GetUnitY(.carrier))
set newObj = CustomItem.new(new)
if CIForgeEffect != "" then
call DestroyEffect(AddSpecialEffect(CIForgeEffect, GetUnitX(.carrier), GetUnitY(.carrier)))
endif
// Finally, we take the item
if .pick(newObj) and INV_SHOW_ITEMS then
call .pickupItem(newObj, true)
endif
set new = null
endif
endif
return forge
endmethod
public method forge takes nothing returns boolean
local integer i = 0
local boolean d = false
loop
exitwhen i >= CIForgeItem.getIndex() or d
set d = .forgeOne(i)
set i = i + 1
endloop
return d
endmethod
endmodule
endlibrary
//TESH.scrollpos=123
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
* CIAdvancedItemSeek
What this module does:
Adds the ability to stack items in your
CustomInventory.
*/
/* ----------------------------------- */
library CIStacking requires Table, CIItemSeek
globals
string CIStackEffect = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
endglobals
module CIStackingItem
private integer stackMax = 0
method operator stack takes nothing returns integer
return .stackMax
endmethod
method operator stack= takes integer val returns nothing
set stackMax = val
endmethod
endmodule
module CIStacking
implement CIItemSeek
private static CustomItem CIStackingCurItem = -1
// This method is an advanced seek which actually seeks the inventory
// for another item of the same type that can be stacked.
private static method getNextStackItem takes CustomItem cit returns boolean
local boolean stack = true
local integer stackMax = CustomItem.load(GetItemTypeId(cit.getHandle())).stack
// Actually, the same item shouldn't be taken again
set stack = stack and cit.getHandle() != thistype.CIStackingCurItem.getHandle()
// Also, we do want to have the same item types.
set stack = stack and GetItemTypeId(CIStackingCurItem.getHandle()) == GetItemTypeId(cit.getHandle())
// Yes, we also need to have an item that actually can stack.
set stack = stack and stackMax > 0
// Also we check whether the stack can be changed
set stack = stack and GetItemCharges(cit.getHandle()) < stackMax
// And we check whether the item is locked or not.
static if LIBRARY_CIProtection then
set stack = stack and not cit.isEquipped() and not cit.isLocked()
endif
return stack
endmethod
// This method is there to stack items of a slot with another one.
private method stackOne takes integer slot returns boolean
local CustomItem curItem = thistype.CIStackingCurItem // Save the current item
local CustomItem nextItem = .advancedSeek(getNextStackItem, slot, .index) // Save the item that is the stack partner
local integer stackMax = CustomItem.load(GetItemTypeId(curItem.getHandle())).stack // Save the amount of stacks the itemtype can do
local integer curStackFirst = GetItemCharges(curItem.getHandle()) // Save the current stacking of item #1
local integer curStackSecond = GetItemCharges(nextItem.getHandle()) // Save the current stacking of item #2
local integer stackFirst = 0 // Temporary holder for stacks for item #1
local integer stackSecond = 0 // Temporary holder for stacks for item #2
local integer stackTogether = 0 // Temporary holder for stacks together
local boolean haveStacked = false // A boolean whether the stack successed or not
local item itemTwo = nextItem.getHandle()
// Wew need to check whether the objects are valid and we can stack
// and whether the items do have charges that can be used.
if curItem == 0 or nextItem == 0 or curStackFirst == 0 or curStackSecond == 0 or stackMax == 0 then
set itemTwo = null
return false
endif
set stackTogether = curStackFirst + curStackSecond
// Calculates how much charges the items have to have
// when we are done.
if stackTogether > stackMax then
set stackFirst = stackMax
set stackSecond = stackTogether - stackFirst
else
set stackFirst = stackTogether
set stackSecond = 0
endif
// If we actually recalculated it
// (This should be everytime the fault, if not this does
// not bug and just skips the stacking.
if stackFirst != curStackFirst or stackSecond != curStackSecond then
set haveStacked = true
// If the stack has more charges as 0 we refresh
if stackFirst != 0 then
call SetItemCharges(curItem.getHandle(), stackFirst)
else
call .drop(curItem)
call RemoveItem(curItem.getHandle())
endif
// If the stack has more charges as 0 we refresh this aswell
if stackSecond != 0 then
call SetItemCharges(nextItem.getHandle(), stackSecond)
else
call .drop(nextItem)
call RemoveItem(itemTwo)
endif
// We create an effect if its set
if CIStackEffect != "" then
call DestroyEffect(AddSpecialEffect(CIStackEffect, GetUnitX(.carrier), GetUnitY(.carrier)))
endif
endif
set itemTwo = null
return haveStacked
endmethod
public method stack takes nothing returns boolean
local boolean doStack = false
local integer i = 0
set thistype.CIStackingCurItem = -1
loop
exitwhen i >= .index or doStack
// Set the current item temporary
set thistype.CIStackingCurItem = .items[i]
// and check whether we can stack
set doStack = .stackOne(i)
set i = i + 1
endloop
// Return to the user if we stacked or not
return doStack
endmethod
endmodule
endlibrary
//TESH.scrollpos=279
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIBonus
What this module does:
Adds the ability to add itemsets into your map!
*/
/* ----------------------------------- */
library CISet initializer init requires Table
//: The interfaces for the system
private function interface iOnCheck takes CISet setObj, unit setUnit returns boolean
private function interface iOnApply takes CISet setObj, unit setUnit returns boolean
private function interface iOnRemove takes CISet setObj, unit setUnit returns boolean
//: Default functions for this system
private function defFunc takes CISet setObj, unit setUnit returns boolean
return true
endfunction
private function defCheck takes CISet setObj, unit setUnit returns boolean
return true
endfunction
//! textmacro CISet__changeInterfaces takes type
public method get$type$Func takes nothing returns i$type$
return .$type$
endmethod
public method set$type$Func takes i$type$ i returns nothing
set .$type$ = i
endmethod
//! endtextmacro
globals
private iOnApply DEFAULT_ONAPPLY
private iOnRemove DEFAULT_ONREMOVE
private iOnCheck DEFAULT_ONCHECK
endglobals
struct CISet
//: This contains a table with index
//: for saving temporary items.
private static Table TmpItems = 0
private static integer TmpIndex = 0
//: These includes every object
private static thistype array instances[8191]
private static integer index = 0
//: This are temporary values
private static integer checkIDType = 0
private static thistype tmpObj = 0
//: This saves the required data
//: into the table.
private Table SaveTable = 0
private Table items = 0
private Table ReqIDS = 0
private Table ReqAmount = 0
private integer ind = 0
private iOnCheck OnCheck = DEFAULT_ONCHECK
private iOnApply OnApply = DEFAULT_ONAPPLY
private iOnRemove OnRemove = DEFAULT_ONREMOVE
implement TableMacros //: Module for instances
implement CIBonus //: Module for ItemSetBonuses
//! runtextmacro CISet__changeInterfaces("OnCheck")
//! runtextmacro CISet__changeInterfaces("OnApply")
//! runtextmacro CISet__changeInterfaces("OnRemove")
private static method onInit takes nothing returns nothing
set thistype.TmpItems = Table.create()
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set .ID = thistype.index
set thistype.instances[thistype.index] = this
set thistype.index = thistype.index +1
set .SaveTable = Table.create()
set .items = Table.create()
set .ReqIDS = Table.create()
set .ReqAmount = Table.create()
call .save()
return this
endmethod
public method addReq takes integer id, integer amount returns nothing
set .ReqIDS[.ind] = id
set .ReqAmount[.ind] = amount
set .ind = .ind +1
endmethod
//: ===-------------------------------------------------------------------
//: Add another bonus
public method incBonus takes unit u returns nothing
local integer times = .SaveTable[GetHandleId(u)]
set .SaveTable[GetHandleId(u)] = times +1
call .OnApply.execute(this, u)
static if LIBRARY_CIBonus then
call .applyBonus(u)
endif
endmethod
private static method countValidAddItems takes CustomItem cit returns boolean
local integer key = GetHandleId(cit.getHandle())
local boolean valid = true
set valid = thistype.tmpObj.items[key] == 0 and GetItemTypeId(cit.getHandle()) == thistype.checkIDType and cit.isEquipped()
if valid then
set thistype.TmpItems[key] = 1
endif
return valid
endmethod
private static method checkValidAddItems takes CustomItem cit returns boolean
local integer key = GetHandleId(cit.getHandle())
return thistype.TmpItems[key] != 0
endmethod
private static method addValidItem takes CustomItem cit returns nothing
local integer key = GetHandleId(cit.getHandle())
call thistype.TmpItems.flush(key)
set thistype.tmpObj.items[key] = 1
endmethod
public method addSet takes unit u returns boolean
local CustomInventory cin = CustomInventory.load(GetHandleId(u))
local integer i = 0
local boolean haveSet = true
call thistype.TmpItems.reset()
loop
exitwhen i >= .ind or not haveSet
// Now lets check all items, remember to save them if they are used.
set thistype.checkIDType = .ReqIDS[i]
if cin.advancedCount(thistype.countValidAddItems) < .ReqAmount[i] then
set haveSet = false
endif
set i = i +1
endloop
if haveSet then
set i = 0
loop
exitwhen i >= .ind
set thistype.checkIDType = .ReqIDS[i]
call cin.advCondExecLimited(thistype.checkValidAddItems, thistype.addValidItem, .ReqAmount[i])
set i = i +1
endloop
call .incBonus(u)
endif
return haveSet
endmethod
//: ===-------------------------------------------------------------------
//: ===-------------------------------------------------------------------
//: Add another bonus
public method decBonus takes unit u returns nothing
local integer times = .SaveTable[GetHandleId(u)]
if times <= 0 then
return
endif
set .SaveTable[GetHandleId(u)] = times -1
call .OnRemove.execute(this, u)
static if LIBRARY_CIBonus then
call .removeBonus(u)
endif
endmethod
private static method countValidRemItems takes CustomItem cit returns boolean
local integer key = GetHandleId(cit.getHandle())
local boolean valid = true
set valid = thistype.tmpObj.items[key] != 0 and GetItemTypeId(cit.getHandle()) == thistype.checkIDType
if valid then
set thistype.TmpItems[key] = 1
endif
set valid = valid and cit.isEquipped()
return valid
endmethod
private static method checkValidRemItems takes CustomItem cit returns boolean
local integer key = GetHandleId(cit.getHandle())
return thistype.TmpItems[key] != 0
endmethod
private static method remValidItem takes CustomItem cit returns nothing
local integer key = GetHandleId(cit.getHandle())
call thistype.TmpItems.flush(key)
call thistype.tmpObj.items.flush(key)
endmethod
public method removeSet takes unit u returns boolean
local CustomInventory cin = CustomInventory.load(GetHandleId(u))
local integer i = 0
local boolean remSet = false
call thistype.TmpItems.reset()
loop
exitwhen i >= .ind or remSet
// Now lets check all items, remember to save them if they are used.
set thistype.checkIDType = .ReqIDS[i]
if cin.advancedCount(thistype.countValidRemItems) < .ReqAmount[i] then
set remSet = true
endif
set i = i +1
endloop
if remSet then
set i = 0
loop
exitwhen i >= .ind
set thistype.checkIDType = .ReqIDS[i]
call cin.advCondExecLimited(thistype.checkValidRemItems, thistype.remValidItem,.ReqAmount[i])
set i = i +1
endloop
call .decBonus(u)
endif
return remSet
endmethod
//: ===-------------------------------------------------------------------
public static method getIndex takes nothing returns integer
return thistype.index
endmethod
public static method checkInst takes unit u, integer i returns boolean
local thistype this = thistype.instances[i]
set thistype.tmpObj = this
if not .OnCheck.evaluate(this, u) then
return false
endif
if .SaveTable[GetHandleId(u)] == 0 then
return .addSet(u)
else
return .removeSet(u)
endif
endmethod
endstruct
private function init takes nothing returns nothing
set DEFAULT_ONCHECK = defCheck
set DEFAULT_ONAPPLY = defFunc
set DEFAULT_ONREMOVE = defFunc
endfunction
module CISet
public method checkSets takes nothing returns boolean
local integer i = 0
local boolean appliedSet = false
loop
exitwhen i >= CISet.getIndex()
set appliedSet = CISet.checkInst(.carrier, i)
set i = i + 1
endloop
return appliedSet
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 19th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* BonusMod
What this module does:
Adds the ability to add bonuses
to objects
*//* ----------------------------------- */
/* This debugs the static ifs */
library CIBonus requires Table, BonusMod
module CIBonus
private Table times = 0
private integer BonusArmor = 0
private integer BonusDamage = 0
private integer BonusSightRange = 0
private integer BonusLifeRegen = 0
private integer BonusStrength = 0
private integer BonusAgility = 0
private integer BonusIntelligence = 0
private integer BonusAttackSpeed = 0
private integer BonusManaRegen = 0
private integer BonusMoveSpeed = 0
private integer BonusHitpoints = 0
private integer BonusManapoints = 0
//! textmacro CIBonus_BonusMacro takes type, shortkey
method operator $shortkey$ takes nothing returns integer
return .Bonus$type$
endmethod
method operator $shortkey$= takes integer i returns nothing
set .Bonus$type$ = i
endmethod
//! endtextmacro
//! runtextmacro CIBonus_BonusMacro("Armor", "amr")
//! runtextmacro CIBonus_BonusMacro("Damage", "dmg")
//! runtextmacro CIBonus_BonusMacro("SightRange", "sr")
//! runtextmacro CIBonus_BonusMacro("LifeRegen", "lr")
//! runtextmacro CIBonus_BonusMacro("Strength", "str")
//! runtextmacro CIBonus_BonusMacro("Intelligence", "int")
//! runtextmacro CIBonus_BonusMacro("Agility", "agy")
//! runtextmacro CIBonus_BonusMacro("AttackSpeed", "as")
//! runtextmacro CIBonus_BonusMacro("ManaRegen", "mr")
//! runtextmacro CIBonus_BonusMacro("MoveSpeed", "ms")
//! runtextmacro CIBonus_BonusMacro("Hitpoints", "hp")
//! runtextmacro CIBonus_BonusMacro("Manapoints", "mp")
// This function checks whether a value is not default or not
// returns true on value changes, false on native values.
public method hasBonus takes nothing returns boolean
local boolean hasBonus = false
static if LIBRARY_BonusMod then
set hasBonus = hasBonus or .BonusArmor != 0 or .BonusDamage != 0 or .BonusSightRange != 0
set hasBonus = hasBonus or .BonusLifeRegen != 0 or .BonusAttackSpeed != 0 or .BonusManaRegen != 0
set hasBonus = hasBonus or .BonusStrength != 0 or .BonusAgility != 0 or .BonusIntelligence != 0
static if LIBRARY_UnitMaxStateBonuses then
set hasBonus = hasBonus or .BonusHitpoints != 0 or .BonusManapoints != 0
endif
static if LIBRARY_MovementBonus then
set hasBonus = hasBonus or .BonusMoveSpeed != 0
endif
endif
return hasBonus
endmethod
// This function removes all the objects bonuses
// from the parameter unit
public method removeBonus takes unit u returns nothing
local integer key = GetHandleId(u)
local integer numb = .times[key]
if numb != 0 then
static if LIBRARY_BonusMod then
call AddUnitBonus(u, BONUS_ARMOR, - numb * .BonusArmor)
call AddUnitBonus(u, BONUS_DAMAGE, - numb * .BonusDamage)
call AddUnitBonus(u, BONUS_SIGHT_RANGE, - numb * .BonusSightRange)
call AddUnitBonus(u, BONUS_LIFE_REGEN, - numb * .BonusLifeRegen)
call AddUnitBonus(u, BONUS_STRENGTH, - numb * .BonusStrength)
call AddUnitBonus(u, BONUS_AGILITY, - numb * .BonusAgility)
call AddUnitBonus(u, BONUS_INTELLIGENCE, - numb * .BonusIntelligence)
call AddUnitBonus(u, BONUS_ATTACK_SPEED, - numb * .BonusAttackSpeed)
call AddUnitBonus(u, BONUS_MANA_REGEN_PERCENT, - numb * .BonusManaRegen)
static if LIBRARY_UnitMaxStateBonuses then
call AddUnitBonus(u, BONUS_LIFE, - numb * .BonusHitpoints)
call AddUnitBonus(u, BONUS_MANA, - numb * .BonusManapoints)
endif
static if LIBRARY_MovementBonus then
call AddUnitBonus(u, BONUS_MOVEMENT_SPEED, - numb * .BonusMoveSpeed)
endif
endif
set .times[key] = 0
endif
endmethod
// This function adds all bonuses to the parameter unit
public method applyBonus takes unit u returns nothing
local integer key = GetHandleId(u)
local integer numb = .times[key]
if .times == 0 then
set .times = Table.create()
elseif numb != 0 then
return
endif
set numb = 1
set .times[key] = numb
static if LIBRARY_BonusMod then
call AddUnitBonus(u, BONUS_ARMOR, numb * .BonusArmor)
call AddUnitBonus(u, BONUS_DAMAGE, numb * .BonusDamage)
call AddUnitBonus(u, BONUS_SIGHT_RANGE, numb * .BonusSightRange)
call AddUnitBonus(u, BONUS_LIFE_REGEN, numb * .BonusLifeRegen)
call AddUnitBonus(u, BONUS_STRENGTH, numb * .BonusStrength)
call AddUnitBonus(u, BONUS_AGILITY, numb * .BonusAgility)
call AddUnitBonus(u, BONUS_INTELLIGENCE, numb * .BonusIntelligence)
call AddUnitBonus(u, BONUS_ATTACK_SPEED, numb * .BonusAttackSpeed)
call AddUnitBonus(u, BONUS_MANA_REGEN_PERCENT, numb * .BonusManaRegen)
static if LIBRARY_UnitMaxStateBonuses then
call AddUnitBonus(u, BONUS_LIFE, numb * .BonusHitpoints)
call AddUnitBonus(u, BONUS_MANA, numb * .BonusManapoints)
endif
static if LIBRARY_MovementBonus then
call AddUnitBonus(u, BONUS_MOVEMENT_SPEED, numb * .BonusMoveSpeed)
endif
endif
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
What this module does:
Adds the ability to generate your own errors*/
/* ----------------------------------- */
library CIError initializer init requires SimError
struct CIErrorType
public integer val = 0
public string name = null
private static integer type = 1
public static method create takes string name returns thistype
local thistype this = thistype.allocate()
set .val = thistype.type
set .name = name
set thistype.type = thistype.type *2
return this
endmethod
endstruct
struct CIErrorTarget
public integer val = 0
public string name = null
private static integer type = 1
public static method create takes string name returns thistype
local thistype this = thistype.allocate()
set .val = thistype.type
set .name = name
set thistype.type = thistype.type *2
return this
endmethod
endstruct
globals
CIErrorType array CIETypes
CIErrorTarget array CIETargets
endglobals
struct CIError
public integer lvl = 0
public integer targ = 0
public string msg = ""
public player src = null
private static integer errorLevel = 0
private static integer targetType = 0
public static method setErrorLevel takes integer error returns nothing
if CIETypes[error] == 0 then
return
endif
set errorLevel = error
endmethod
public static method setTargetLevel takes integer target returns nothing
if CIETargets[target] == 0 then
return
endif
set targetType = target
endmethod
public method raiseError takes nothing returns nothing
//debug if true then
//debug call BJDebugMsg("|cffffcc00" + I2S(CIETypes[.lvl]) + ": |r" + .msg)
//debug call .destroy()
//debug return
//debug endif
call SimError(.src, .msg)
call .destroy()
endmethod
public static method create takes integer lvl, integer targ, player src, string msg returns thistype
local thistype this = thistype.allocate()
set .lvl = lvl
set .targ = targ
set .msg = msg
set .src = src
call .raiseError()
return this
endmethod
endstruct
//! textmacro CIE_newType takes name
set tmpType = CIErrorType.create("$name$")
set CIETypes[tmpType.val] = tmpType
//! endtextmacro
//! textmacro CIE_newTarget takes name
set tmpTarg = CIErrorTarget.create("$name$")
set CIETargets[tmpTarg.val] = tmpTarg
//! endtextmacro
private function init takes nothing returns nothing
local CIErrorType tmpType = 0
local CIErrorTarget tmpTarg = 0
//! runtextmacro CIE_newType("INFO")
//! runtextmacro CIE_newType("NOTICE")
//! runtextmacro CIE_newType("ERROR")
//! runtextmacro CIE_newType("ALL")
call CIError.setErrorLevel(tmpType.val)
//! runtextmacro CIE_newTarget("PLAYER")
//! runtextmacro CIE_newTarget("HOST")
//! runtextmacro CIE_newTarget("MAPPER")
//! runtextmacro CIE_newTarget("ALL")
call CIError.setTargetLevel(tmpTarg.val)
endfunction
endlibrary
//TESH.scrollpos=36
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
* CIAdvancedItemSeek
What this module does:
Adds the ability to interfere with the standard
warcraft III events.
*/
/* ----------------------------------- */
library CIEventHandler initializer init requires CustomInventory
private function interface CIEHonEvent takes nothing returns nothing
private function interface CIEHonPick takes unit u, item i returns boolean
private function interface CIEHonDrop takes unit u, item i returns boolean
private function interface CIEHonPawn takes unit u, item i returns boolean
private function interface CIEHonUse takes unit u, item i returns boolean
globals
private constant boolean AutoGenerate = true
trigger CIEHeventTrigger = CreateTrigger()
endglobals
//! textmacro CIEventHandler__EventVars
local integer uID = GetHandleId(u)
local integer iID = GetHandleId(i)
local CustomInventory cin = CustomInventory.load(uID)
local CustomItem cit = CustomItem.load(iID)
local boolean did = false
//! endtextmacro
function CIEHPick takes unit u, item i returns boolean
//! runtextmacro CIEventHandler__EventVars()
if cit != 0 then
call cin.drop(cit)
endif
set cit = CustomItem.new(i)
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Notice|r: " + GetUnitName(u) + " |cff808080ItemPick:|r " + GetItemName(cit.getHandle()))
set did = cin.pick(cit)
if not did then
call cin.remItem(cit)
endif
return did
endfunction
function CIEHDrop takes unit u, item i returns boolean
//! runtextmacro CIEventHandler__EventVars()
if cit == 0 then
return false
endif
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Notice|r: " + GetUnitName(u) + " |cff808080ItemDrop:|r " + GetItemName(cit.getHandle()))
return cin.drop(cit)
endfunction
function CIEHPawn takes unit u, item i returns boolean
//! runtextmacro CIEventHandler__EventVars()
if cit == 0 then
return false
endif
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Notice|r: " + GetUnitName(u) + " |cff808080ItemPawn:|r " + GetItemName(cit.getHandle()))
return cin.pawn(cit)
endfunction
function CIEHUse takes unit u, item i returns boolean
//! runtextmacro CIEventHandler__EventVars()
if cit == 0 then
return false
endif
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Notice|r: " + GetUnitName(u) + " |cff808080ItemUse:|r " + GetItemName(cit.getHandle()))
return cin.use(cit)
endfunction
globals
CIEHonPick CIEHPickAct = 0
CIEHonDrop CIEHDropAct = 0
CIEHonPawn CIEHPawnAct = 0
CIEHonUse CIEHUseAct = 0
endglobals
function CIEventCall takes unit u, item i, eventid e returns nothing
local integer uID = GetHandleId(u)
local integer iID = GetHandleId(i)
local CustomInventory cin = CustomInventory.load(uID)
local boolean did = false
if cin == 0 then
if AutoGenerate then
set cin = CustomInventory.create(u)
debug else
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Error|r: " + "Inventory for " + GetUnitName(u) + " cannot be load.")
endif
else
if e == EVENT_PLAYER_UNIT_PICKUP_ITEM then
set did = CIEHPickAct.evaluate(u, i)
elseif e == EVENT_PLAYER_UNIT_DROP_ITEM then
set did = CIEHDropAct.evaluate(u, i)
elseif e == EVENT_PLAYER_UNIT_PAWN_ITEM then
set did = CIEHPawnAct.evaluate(u, i)
elseif e == EVENT_PLAYER_UNIT_USE_ITEM then
set did = CIEHUseAct.evaluate(u, i)
debug else
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "Error|r: " + "Eventhandler has no valid event")
endif
if did then
call cin.refresh()
endif
endif
endfunction
private function CIEHdefEvent takes nothing returns nothing
debug call BJDebugMsg("-------------------------------------------------------")
call CIEventCall(GetTriggerUnit(), GetManipulatedItem(), GetTriggerEventId())
endfunction
private function InvDummyFilter takes nothing returns boolean
return true
endfunction
private function InvNullFilter takes nothing returns boolean
return true
endfunction
globals
boolexpr CIEHDummyFilter = null
boolexpr CIEHNullFilter = null
endglobals
private function init takes nothing returns nothing
local integer i = 0
set CIEHPickAct = CIEHPick
set CIEHDropAct = CIEHDrop
set CIEHPawnAct = CIEHPawn
set CIEHUseAct = CIEHUse
set CIEHDummyFilter = Condition(function InvDummyFilter)
set CIEHNullFilter = Condition(function InvNullFilter)
call TriggerAddAction(CIEHeventTrigger, function CIEHdefEvent)
call TriggerAddCondition(CIEHeventTrigger, CIEHDummyFilter)
loop
exitwhen i >= 15
call TriggerRegisterPlayerUnitEvent(CIEHeventTrigger, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, CIEHNullFilter)
call TriggerRegisterPlayerUnitEvent(CIEHeventTrigger, Player(i), EVENT_PLAYER_UNIT_DROP_ITEM, CIEHNullFilter)
call TriggerRegisterPlayerUnitEvent(CIEHeventTrigger, Player(i), EVENT_PLAYER_UNIT_PAWN_ITEM, CIEHNullFilter)
call TriggerRegisterPlayerUnitEvent(CIEHeventTrigger, Player(i), EVENT_PLAYER_UNIT_USE_ITEM, CIEHNullFilter)
set i = i + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=17
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 11th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
-none-
What this module does:
Adds a few default methods to the
CustomInventory which handle item events.
*/
/* ----------------------------------- */
/* This debugs the static ifs */
library CIEvents
endlibrary
module CIEvents
public method pick takes CustomItem ci returns boolean
if .checkPickup(ci) then
call ci.pick(.carrier)
call .addItem(ci)
return true
endif
return false
endmethod
public method drop takes CustomItem ci returns boolean
if .hasItem(ci) then
call ci.drop(.carrier)
return .remItem(ci)
endif
return false
endmethod
public method pawn takes CustomItem ci returns boolean
if .hasItem(ci) then
call ci.pawn(.carrier)
return true
endif
return false
endmethod
public method use takes CustomItem ci returns boolean
if .hasItem(ci) then
call ci.use(.carrier)
return true
endif
return false
endmethod
endmodule
//TESH.scrollpos=23
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 11th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* BonusMod
What this module does:
Adds the ability to drop and pickup
items without triggering the CustomInventorys
EventHandler.
*/
/* ----------------------------------- */
/* This debugs the static ifs */
library CIItemDrop requires optional CIEventHandler
module CIItemDrop
public method dropItem takes CustomItem ci, boolean show returns nothing
call DisableTrigger(CIEHeventTrigger)
call UnitRemoveItem(.carrier, ci.getHandle())
if show then
call SetItemPosition(ci.getHandle(), GetUnitX(.carrier), GetUnitY(.carrier))
else
call SetItemPosition(ci.getHandle(), CI_UI_BASE_X, CI_UI_BASE_Y)
endif
call SetItemVisible(ci.getHandle(), show)
call EnableTrigger(CIEHeventTrigger)
endmethod
public method pickupItem takes CustomItem ci, boolean show returns nothing
call DisableTrigger(CIEHeventTrigger)
call UnitAddItem(.carrier, ci.getHandle())
call SetItemVisible(ci.getHandle(), show)
call EnableTrigger(CIEHeventTrigger)
endmethod
endmodule
endlibrary
//TESH.scrollpos=10
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
-none-
What this module does:
Adds information about the item OE values
to the object.
*/
/* ----------------------------------- */
library CIItemInfo
module CIItemInfo
//! textmacro CIItemInfo_InfoMacro takes type, name, default
private $type$ $name$Info $default$
method operator $name$ takes nothing returns $type$
return .$name$Info
endmethod
method operator $name$= takes $type$ val returns nothing
set .$name$Info = val
endmethod
//! endtextmacro
//! runtextmacro CIItemInfo_InfoMacro("string", "name", "= \"Unknown Item\"")
//! runtextmacro CIItemInfo_InfoMacro("string", "icon", "= \"ReplaceableTextures\\CommandButtons\\BTNPatrol.blp\"")
//! runtextmacro CIItemInfo_InfoMacro("string", "desc", "= \"There is no information \nabout this item\"")
endmodule
endlibrary
//TESH.scrollpos=79
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIBonus
What this module does:
Creates multiboards for items.
*/
/* ----------------------------------- */
library CIItemBoard initializer init requires Board, CIItemInfo, CIBonus, CustomItem
globals
constant string CIItemBoard_DefAmrIcon = "ReplaceableTextures\\CommandButtons\\BTNLeatherUpgradeThree.blp"
constant string CIItemBoard_DefDmgIcon = "ReplaceableTextures\\CommandButtons\\BTNClawsOfAttack.blp"
constant string CIItemBoard_DefSrIcon = "ReplaceableTextures\\CommandButtons\\BTNGem.blp"
constant string CIItemBoard_DefLrIcon = "ReplaceableTextures\\CommandButtons\\BTNReplenishHealth.blp"
constant string CIItemBoard_DefMrIcon = "ReplaceableTextures\\CommandButtons\\BTNReplenishMana.blp"
constant string CIItemBoard_DefStrIcon = "ReplaceableTextures\\CommandButtons\\BTNBelt.blp"
constant string CIItemBoard_DefAgyIcon = "ReplaceableTextures\\CommandButtons\\BTNBoots.blp"
constant string CIItemBoard_DefIntIcon = "ReplaceableTextures\\CommandButtons\\BTNRobeOfTheMagi.blp"
constant string CIItemBoard_DefAsIcon = "ReplaceableTextures\\CommandButtons\\BTNGauntletsOfOgrePower.blp"
constant string CIItemBoard_DefMsIcon = "ReplaceableTextures\\CommandButtons\\BTNBootsOfSpeed.blp"
constant string CIItemBoard_DefHpIcon = "ReplaceableTextures\\CommandButtons\\BTNPeriapt.blp"
constant string CIItemBoard_DefMpIcon = "ReplaceableTextures\\CommandButtons\\BTNPeriapt1.blp"
CustomItem CIItemBoard_Dummy = 0
endglobals
private function init takes nothing returns nothing
set CIItemBoard_Dummy = CustomItem.new(null)
set CIItemBoard_Dummy.icon = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp"
set CIItemBoard_Dummy.name = "No item"
set CIItemBoard_Dummy.desc = "There is no item in this slot."
call CIItemBoard_Dummy.clear()
endfunction
module CIItemBoard
private Board itemBoard = 0
public method initBoard takes nothing returns nothing
local BoardItem bi = 0
set .itemBoard = Board.create()
set .itemBoard.title = "CustomInventory [View Item]"
set .itemBoard.titleColor = 0xFFFFFF
set bi = .itemBoard[0][0]
set bi.width = .015
call bi.setDisplay(false, true)
set bi = .itemBoard[1][0]
set bi.width = .01
call bi.setDisplay(true, false)
set bi = .itemBoard[2][0]
set bi.width = .135
call bi.setDisplay(true, false)
set bi = .itemBoard[0][1]
set bi.width = 0.16
call bi.setDisplay(false, false)
set bi = .itemBoard[0][2]
set bi.width = .16
call bi.setDisplay(false, false)
set bi = .itemBoard[0][3]
set bi.width = .16
call bi.setDisplay(true, false)
set bi = .itemBoard[0][4]
set bi.width = .16
call bi.setDisplay(false, false)
endmethod
public method updateBoard takes CustomItem ciObj returns nothing
local BoardItem bi = 0
local integer i = 0
local integer value = 0
local integer x = 0
local integer y = 0
local string text = ""
local string icon = ""
local string valStr = ""
local integer field = 0
if ciObj == 0 then
set ciObj = CIItemBoard_Dummy
endif
call .minimizeBoard(true)
call .showBoard(false)
if .itemBoard != 0 then
call .itemBoard.clear()
call .itemBoard.destroy()
endif
call .initBoard()
set bi = .itemBoard[0][0]
set bi.icon = ciObj.icon
set bi = .itemBoard[1][0]
set value = GetItemCharges(ciObj.getHandle())
if value != 0 then
set bi.text = "[" + I2S(value) + "]"
set value = 0
endif
set bi = .itemBoard[2][0]
set bi.text = ciObj.name
set bi = .itemBoard[0][3]
set bi.text = ciObj.desc
static if LIBRARY_CIBonus then
// Create the status items
set i = 0
loop
exitwhen i >= 12
if i == 0 then
set value = ciObj.amr
set text = "Armor"
set icon = CIItemBoard_DefAmrIcon
elseif i == 1 then
set value = ciObj.dmg
set text = "Dmg"
set icon = CIItemBoard_DefDmgIcon
elseif i == 2 then
set value = ciObj.lr
set text = "Liferg"
set icon = CIItemBoard_DefLrIcon
elseif i == 3 then
set value = ciObj.mr
set text = "Manarg"
set icon = CIItemBoard_DefMrIcon
elseif i == 4 then
set value = ciObj.str
set text = "Str"
set icon = CIItemBoard_DefStrIcon
elseif i == 5 then
set value = ciObj.agy
set text = "Agy"
set icon = CIItemBoard_DefAgyIcon
elseif i == 6 then
set value = ciObj.int
set text = "Int"
set icon = CIItemBoard_DefIntIcon
elseif i == 7 then
set value = ciObj.as
set text = "Attspd"
set icon = CIItemBoard_DefAsIcon
elseif i == 8 then
set value = ciObj.ms
set text = "Mvspd"
set icon = CIItemBoard_DefMsIcon
elseif i == 9 then
set value = ciObj.hp
set text = "Life"
set icon = CIItemBoard_DefHpIcon
elseif i == 10 then
set value = ciObj.mp
set text = "Mana"
set icon = CIItemBoard_DefMpIcon
elseif i == 11 then
set value = ciObj.sr
set text = "Sight"
set icon = CIItemBoard_DefSrIcon
else
set value = 0
endif
if value != 0 then
set valStr = I2S(value)
if i == 3 or i == 7 then
set valStr = valStr + "%"
endif
if field == 0 then
set bi = .itemBoard[0][5]
set bi.text = "Attributes"
set bi.width = .08
call bi.setDisplay(true, false)
set x = 0
set y = 6
elseif field == 6 then
set x = 3
set y = 6
else
set y = y +1
endif
set bi = .itemBoard[x][y]
set bi.width = .05
set bi.icon = icon
set bi.text = text +":"
call bi.setDisplay(true, true)
// Create the textitem
set bi = .itemBoard[x +1][y]
set bi.width = .02
set bi.text = valStr
if value > 0 then
set bi.color = 0xFFFFFF
else
set bi.color = 0xFF0000
endif
call bi.setDisplay(true, false)
// Create a space
if field < 6 then
set bi = .itemBoard[x +2][y]
set bi.text = ""
set bi.width = .01
call bi.setDisplay(true, false)
endif
set field = field +1
endif
set i = i +1
endloop
endif
call .minimizeBoard(false)
call .showBoard(true)
set icon = null
set text = null
set valStr = null
endmethod
public method showBoard takes boolean bol returns nothing
set .itemBoard.visible[GetOwningPlayer(.getOwner())] = bol
endmethod
public method minimizeBoard takes boolean bol returns nothing
set .itemBoard.minimized[GetOwningPlayer(.getOwner())] = bol
endmethod
endmodule
endlibrary
//TESH.scrollpos=41
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 14th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
-none-
What this module does:
Adds the ability to lock items.
*//* ----------------------------------- */
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
* CIAdvancedItemSeek
What this module does:
Adds the ability to protect items from
further editing.
*/
/* ----------------------------------- */
library CIItemProtection
module CIItemProtection
private boolean equiped = false
private boolean locked = false
public method lock takes nothing returns nothing
set .locked = true
endmethod
public method unLock takes nothing returns nothing
set .locked = false
endmethod
public method equip takes nothing returns nothing
set .equiped = true
endmethod
public method unEquip takes nothing returns nothing
set .equiped = false
endmethod
public method isEquipped takes nothing returns boolean
return .equiped
endmethod
public method isLocked takes nothing returns boolean
return .locked
endmethod
endmodule
endlibrary
//TESH.scrollpos=7
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 14th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
-none-
What this module does:
Adds the ability to display the correct
icon for items in the FSI.
*//* ----------------------------------- */
library CIItemDest
endlibrary
module CIItemDest
private integer Dest = -1
method operator dest= takes integer d returns nothing
set .Dest = d
endmethod
method operator dest takes nothing returns integer
return .Dest
endmethod
endmodule
//TESH.scrollpos=145
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 11th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIEvents
What this module does:
Adds the functionality of searching
to your CustomInventory. For example
it counts items by type.
*/
/* ----------------------------------- */
/* This debugs the static ifs */
library CIItemSeek
endlibrary
function interface CIAdvSeek takes CustomItem cit returns boolean
function interface CIAdvExec takes CustomItem cit returns nothing
module CIItemSeek
implement CIEvents
public method countItemsOfType takes integer itemType returns integer
local integer i = 0
local integer c = 0
if itemType != 0 then
loop
exitwhen i > .index
if GetItemTypeId(.getItem(i).getHandle()) == itemType then
set c = c + 1
endif
set i = i + 1
endloop
else
set c = -1
endif
return c
endmethod
public method removeItemsOfTypeLimited takes integer itemType, integer amount, boolean drop returns boolean
local integer i = 0
local integer c = 0
local boolean d = true
local item h = null
if itemType != 0 then
loop
exitwhen c >= amount
exitwhen i > .index
set h = .getItem(i).getHandle()
if GetItemTypeId(h) == itemType then
call .drop(.getItem(i))
set i = i - 1
set c = c + 1
if not drop then
call RemoveItem(h)
endif
endif
set i = i + 1
endloop
if c >= amount then
set d = true
endif
else
set d = false
endif
set h = null
return d
endmethod
public method removeItemsOfTypeAll takes integer itemType, boolean drop returns boolean
return .removeItemsOfTypeLimited(itemType, -1, drop)
endmethod
public method advancedSeek takes CIAdvSeek advSeek, integer start, integer end returns CustomItem
local integer i = start
loop
exitwhen i >= end
if advSeek.evaluate(.getItem(i)) then
return .getItem(i)
endif
set i = i + 1
endloop
return -1
endmethod
public method advancedCount takes CIAdvSeek advSeek returns integer
local integer i = 0
local integer c = 0
loop
exitwhen i > .index
if advSeek.evaluate(.getItem(i)) then
set c = c +1
endif
set i = i + 1
endloop
return c
endmethod
public method advancedRemove takes CIAdvSeek advSeek, integer amount returns integer
local integer i = 0
local integer c = amount
loop
exitwhen i > .index or c == 0
if advSeek.evaluate(.getItem(i)) then
call .remItem(.getItem(i))
if c > 0 then
set c = c - 1
endif
endif
set i = i + 1
endloop
return c
endmethod
public method advCondExecLimited takes CIAdvSeek advSeek, CIAdvExec advExec, integer stop returns nothing
local integer i = 0
local integer j = 0
loop
exitwhen i > .index
if stop != -1 then
exitwhen j > stop
endif
if advSeek.evaluate(.getItem(i)) then
call advExec.execute(.getItem(i))
set j = j +1
endif
set i = i + 1
endloop
endmethod
public method advCondExec takes CIAdvSeek advSeek, CIAdvExec advExec returns nothing
call .advCondExecLimited(advSeek, advExec, -1)
endmethod
endmodule
//TESH.scrollpos=24
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
* CIAdvancedItemSeek
What this module does:
Adds the ability to add classes to items
so you can limit equipping of items to classes.
*/
/* ----------------------------------- */
library CIItemSlot
globals
constant integer ITEM_CLASS_HAND = 1
constant integer ITEM_CLASS_TWOHANDER = 2
constant integer ITEM_CLASS_RING = 3
constant integer ITEM_CLASS_MISC = 4
constant integer ITEM_CLASS_BOOTS = 5
constant integer ITEM_CLASS_MAIN = 6
constant integer ITEM_CLASS_TROUSER = 7
constant integer ITEM_CLASS_AMULET = 8
constant integer ITEM_CLASS_GLOVE = 9
constant integer ITEM_CLASS_HELMET = 10
constant integer ITEM_CLASS_SHOULDER = 11
constant integer ITEM_CLASS_POTION = 12
constant integer ITEM_CLASS_ICON_HAND = 'cihn'
constant integer ITEM_CLASS_ICON_TWOHANDER = 'cihn'
constant integer ITEM_CLASS_ICON_RING = 'cirg'
constant integer ITEM_CLASS_ICON_MISC = 'cimc'
constant integer ITEM_CLASS_ICON_BOOTS = 'cibt'
constant integer ITEM_CLASS_ICON_MAIN = 'cimn'
constant integer ITEM_CLASS_ICON_TROUSER = 'citr'
constant integer ITEM_CLASS_ICON_AMULET = 'ciam'
constant integer ITEM_CLASS_ICON_GLOVE = 'cigv'
constant integer ITEM_CLASS_ICON_HELMET = 'cihd'
constant integer ITEM_CLASS_ICON_SHOULDER = 'cish'
endglobals
module CIItemSlot
private integer Class = -1
method operator class= takes integer c returns nothing
set .Class = c
endmethod
method operator class takes nothing returns integer
return .Class
endmethod
endmodule
endlibrary
//TESH.scrollpos=45
//TESH.alwaysfold=0
library CIItemEffect
struct CIItemEffects
public effect array effects[4]
public string array sfx[4]
public string array attachments[4]
public integer index = 0
implement TableMacros
public static method create takes integer id returns thistype
local thistype this = thistype.allocate()
set .ID = id
call .save()
return this
endmethod
public static method new takes item theItem returns thistype
local thistype this = thistype.load(GetItemTypeId(theItem))
local thistype that = thistype.allocate()
local integer i = .index
set that.index = .index
loop
exitwhen i == 0
set that.sfx[i] = .sfx[i]
set that.attachments[i] = .attachments[i]
set i = i -1
endloop
return that
endmethod
public method activate takes unit theUnit returns nothing
local integer i = .index
loop
exitwhen i == 0
call DestroyEffect(.effects[i])
if theUnit != null then
set .effects[i] = AddSpecialEffectTarget(.sfx[i], theUnit, .attachments[i])
endif
set i = i -1
endloop
endmethod
public method addSFX takes string sfx, string pos returns nothing
if .index < 3 then
set .index = .index +1
set .sfx[.index] = sfx
set .attachments[.index] = pos
endif
endmethod
endstruct
endlibrary
module CIItemEffect
public CIItemEffects eff = 0
public method addSfx takes string sfx, string pos returns nothing
if .eff == 0 then
set .eff = CIItemEffects.create(.ID)
endif
call .eff.addSFX(sfx, pos)
endmethod
public method addEffects takes unit theUnit returns nothing
call .eff.activate(theUnit)
endmethod
public method removeEffects takes nothing returns nothing
call .eff.activate(null)
endmethod
endmodule
//TESH.scrollpos=22
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04th Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CIItemSeek
* CIAdvancedItemSeek
What this module does:
Adds the ability to manage powerup pickups.
[CURRENTLY IN DEVELOPMENT!]
*/
/* ----------------------------------- */
library CIPowerup initializer init requires CIEventHandler
private function powerupPick takes unit u, item i returns boolean
// Post your code here if you know how to do
return CIEHPick(u, i)
endfunction
private function powerupDrop takes unit u, item i returns boolean
// Post your code here if you know how to do
return CIEHDrop(u, i)
endfunction
module CIPowerupItem
private integer Link = 0
method operator link takes nothing returns integer
return .Link
endmethod
method operator link= takes integer val returns nothing
set .Link = val
endmethod
endmodule
private function init takes nothing returns nothing
//set CIEHPickAct = powerupPick
//set CIEHDropAct = powerupDrop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CISetup initializer init
globals
constant boolean CI_NEW_MAP = false
constant integer CI_UI_MAX_ITEMS = 20
constant boolean CI_UI_SHOW_ITEMS = false
constant boolean CI_UI_AUTO_APPLY_BONUSES = false
constant boolean CI_UI_AUTO_REMOVE_BONUSES = false
constant boolean CI_UI_AUTO_CHECK_PICKUP = false
constant real CI_UI_BASE_X = -650.
constant real CI_UI_BASE_Y = 2100.
constant real CI_UI_WIDTH = 2048.
constant real CI_UI_HEIGHT = 1024.
rect CI_UI_RECT = null
constant boolean ENABLE_MODULE_STACK = true
constant boolean ENABLE_MODULE_FORGE = true
constant boolean ENABLE_MODULE_SETS = true
endglobals
//: A little terrain generator
globals
private constant real TILE_DIST = 64
private constant integer TILE_SIZE = 1
private constant integer BLACK_TILE = 'cOc1'
endglobals
function makeBlack takes rect r returns nothing
local real xMin = GetRectMinX(r)
local real yMin = GetRectMinY(r)
local real xMax = GetRectMaxX(r)
local real yMax = GetRectMaxY(r)
local real x = xMin
local real y = yMin
local integer xTimes = R2I((xMax - xMin) / TILE_DIST)
local integer yTimes = R2I((yMax - yMin) / TILE_DIST)
local integer xCur = 0
local integer yCur = 0
loop
exitwhen xCur >= xTimes
set yCur = 0
set y = yMin
loop
exitwhen yCur >= yTimes
set y = y + TILE_DIST
call SetTerrainType(x, y, BLACK_TILE, 0, TILE_SIZE, 0)
set yCur = yCur + 1
endloop
set x = x + TILE_DIST
set xCur = xCur + 1
endloop
endfunction
private function init takes nothing returns nothing
set CI_UI_RECT = Rect(CI_UI_BASE_X - CI_UI_WIDTH /2,CI_UI_BASE_Y - CI_UI_HEIGHT /2, CI_UI_BASE_X + CI_UI_WIDTH /2, CI_UI_BASE_Y + CI_UI_HEIGHT /2)
call makeBlack(CI_UI_RECT)
endfunction
endlibrary
//TESH.scrollpos=196
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 13th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* TableMacros
Optional:
-many-
What this library does:
Adds the functionality of an advanced
item to the map.
*//* ----------------------------------- */
library CustomItem initializer init requires BonusMod, MovementBonus
//: The interfaces for the system
private function interface iOnUse takes CustomItem ciObj, unit ciUnit returns boolean
private function interface iOnDrop takes CustomItem ciObj, unit ciUnit returns boolean
private function interface iOnPawn takes CustomItem ciObj, unit ciUnit returns boolean
private function interface iOnPick takes CustomItem ciObj, unit ciUnit returns boolean
private function interface iOnCheck takes CustomItem ciObj, unit ciUnit returns boolean
//: Default functions for this system
private function defFunc takes CustomItem ciObj, unit ciUnit returns boolean
return true
endfunction
private function defCheck takes CustomItem ciObj, unit ciUnit returns boolean
return true
endfunction
//! textmacro CI_CustomItem__changeInterfaces takes type
public method get$type$Func takes nothing returns i$type$
return .$type$
endmethod
public method set$type$Func takes i$type$ i returns nothing
set .$type$ = i
endmethod
//! endtextmacro
//! textmacro CI_CustomItem__checkLock takes object
static if LIBRARY_CIItemProtection then
if $object$.isLocked() then
return false
endif
endif
//! endtextmacro
//: Default functions for the CustomItem
//: Can be overwritten by modules, btw.
globals
private iOnUse DEFAULT_ONUSE
private iOnDrop DEFAULT_ONDROP
private iOnPawn DEFAULT_ONPAWN
private iOnPick DEFAULT_ONPICK
private iOnCheck DEFAULT_ONCHECK
endglobals
struct CustomItem
private boolean dummy = true
private item handle = null
private thistype origin = 0
private iOnUse OnUse = DEFAULT_ONUSE
private iOnDrop OnDrop = DEFAULT_ONDROP
private iOnPawn OnPawn = DEFAULT_ONPAWN
private iOnPick OnPick = DEFAULT_ONPICK
private iOnCheck OnCheck = DEFAULT_ONCHECK
implement TableMacros // Module for saving
implement CIItemProtection // Module for protecting items
implement optional CIAttachment // Module for attachments (effects)
implement optional CIBonus // Module for adding bonuses to objects
implement optional CIStackingItem // Module that adds the feature to add stacks to the item
implement optional CIPowerupItem // Module that adds the feature to add a converter to the item
implement optional CIItemInfo // Module for adding informations to items
implement optional CIItemDest // Module for adding icons to the FSI
implement optional CIItemSlot // Module for adding slotsconditions to the item
implement optional CIItemEffect // Module for adding effects to items
//: ==------------ Primary Methods -----------=
public static method create takes integer ID returns thistype
local thistype this = thistype.allocate()
set .ID = ID
//set thistype.DEBUG = true
call .save()
return this
endmethod
public static method new takes item i returns thistype
local thistype this = thistype.allocate()
set .dummy = false
set .handle = i
set .ID = GetHandleId(i)
set .origin = thistype.load(GetItemTypeId(i))
static if LIBRARY_CIBonus then
set .amr = .origin.amr
set .dmg = .origin.dmg
set .str = .origin.str
set .agy = .origin.agy
set .int = .origin.int
set .lr = .origin.lr
set .mr = .origin.mr
set .as = .origin.as
set .ms = .origin.ms
set .hp = .origin.hp
set .mp = .origin.mp
set .sr = .origin.sr
endif
static if LIBRARY_CIItemDest then
set .dest = .origin.dest
endif
static if LIBRARY_CIItemSlot then
set .class = .origin.class
endif
static if LIBRARY_CIItemInfo then
set .icon = .origin.icon
set .desc = .origin.desc
set .name = .origin.name
endif
static if LIBRARY_CIPowerup then
set .link = .origin.link
endif
static if LIBRARY_CIItemEffect then
set .eff = CIItemEffects.new(i)
endif
set .OnUse = .origin.getOnUseFunc()
set .OnDrop = .origin.getOnDropFunc()
set .OnPick = .origin.getOnPickFunc()
set .OnPawn = .origin.getOnPawnFunc()
set .OnCheck = .origin.getOnCheckFunc()
call .save()
return this
endmethod
//: ==------------ Bonus Stage -----------=
public method addBoni takes unit u returns nothing
static if LIBRARY_CIBonus then
call .applyBonus(u)
endif
endmethod
public method remBoni takes unit u returns nothing
static if LIBRARY_CIBonus then
call .removeBonus(u)
endif
endmethod
//: ==------------ Item Events -----------=
public method pick takes unit u returns boolean
//! runtextmacro CI_CustomItem__checkLock("")
if INV_AUTO_APPLY_BONUSES then
call .addBoni(u)
endif
call .OnPick.evaluate(this, u)
return true
endmethod
public method pawn takes unit u returns boolean
//! runtextmacro CI_CustomItem__checkLock("")
if INV_AUTO_REMOVE_BONUSES then
call .remBoni(u)
endif
call .OnPawn.evaluate(this, u)
return true
endmethod
public method drop takes unit u returns boolean
//! runtextmacro CI_CustomItem__checkLock("")
if INV_AUTO_REMOVE_BONUSES then
call .remBoni(u)
endif
call .OnDrop.evaluate(this, u)
return true
endmethod
public method use takes unit u returns boolean
//! runtextmacro CI_CustomItem__checkLock("")
call .OnUse.evaluate(this, u)
return true
endmethod
public method check takes unit u returns boolean
return .OnCheck.evaluate(this, u)
endmethod
//! runtextmacro CI_CustomItem__changeInterfaces("OnUse")
//! runtextmacro CI_CustomItem__changeInterfaces("OnDrop")
//! runtextmacro CI_CustomItem__changeInterfaces("OnPawn")
//! runtextmacro CI_CustomItem__changeInterfaces("OnPick")
//! runtextmacro CI_CustomItem__changeInterfaces("OnCheck")
//: ==------------ Misc Methods -----------=
public method getHandle takes nothing returns item
return .handle
endmethod
private method onDestroy takes nothing returns nothing
static if LIBRARY_CIItemEffect then
call .eff.activate(null)
call .eff.destroy()
endif
endmethod
endstruct
private function init takes nothing returns nothing
set DEFAULT_ONUSE = defFunc
set DEFAULT_ONDROP = defFunc
set DEFAULT_ONPAWN = defFunc
set DEFAULT_ONPICK = defFunc
set DEFAULT_ONCHECK = defCheck
endfunction
function CreateCustomItem takes integer id returns CustomItem
return CustomItem.create(id)
endfunction
endlibrary
//TESH.scrollpos=185
//TESH.alwaysfold=0
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 04 Jan 2010
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* CustomItem
Optional:
* CIItemDrop
* CIEvents
* CIItemSeek
* CIForging
* CIStacking
* CIItemSets
What this library does:
Adds the functionality of an advanced
inventory system to the map.
*//* ----------------------------------- */
library CustomInventory requires CustomItem, Table, CISetup
//# ==--- --- --- --- ---== #
// Load settings
//# ==--- --- --- --- ---== #
globals
constant boolean INV_SHOW_ITEMS = CI_UI_SHOW_ITEMS
constant boolean INV_AUTO_APPLY_BONUSES = CI_UI_AUTO_APPLY_BONUSES
constant boolean INV_AUTO_REMOVE_BONUSES = CI_UI_AUTO_REMOVE_BONUSES
constant boolean INV_AUTO_CHECK_PICKUP = CI_UI_AUTO_CHECK_PICKUP
endglobals
struct CustomInventory
private integer index = 0
private unit carrier = null
private timer refreshT = null
private Table items = 0
private Table item2slot = 0
private integer max = CI_UI_MAX_ITEMS
private static Table TimerToInstance = 0
// Primary, required for most stuff
implement TableMacros //: Module for saving
implement optional CIItemDrop //: Module for handleDrop / pickup
implement optional CIEvents //: Module for item events
// Secondary. Can be disabled.
implement optional CIItemSeek //: Module for seeking items
implement optional CIForging //: Module for forging items
implement optional CIStacking //: Module for stacking items
implement optional CISet //: Module for itemsets
implement optional CIItemBoard
public static method create takes unit u returns thistype
local thistype this = thistype.allocate()
set .carrier = u
set .ID = GetHandleId(u)
set .refreshT = CreateTimer()
set .items = Table.create()
set .item2slot = Table.create()
set thistype.TimerToInstance[GetHandleId(.refreshT)] = this
call .save()
return this
endmethod
public method getItemSlot takes CustomItem ci returns integer
if not .item2slot.exists(GetHandleId(ci.getHandle())) then
return -1
endif
return .item2slot[GetHandleId(ci.getHandle())]
endmethod
public method hasItem takes CustomItem ci returns boolean
return .getItemSlot(ci) >= 0
endmethod
public method getItem takes integer slot returns CustomItem
return CustomItem(.items[slot])
endmethod
public method hasSlotItem takes integer slot returns boolean
return .getItem(slot) > 0
endmethod
public method setSlotItem takes CustomItem ci, integer slot returns nothing
set .items[slot] = integer(ci)
set .item2slot[GetHandleId(ci.getHandle())] = slot
endmethod
public method cleanSlot takes integer slot returns nothing
if .hasSlotItem(slot) then
call .item2slot.flush(GetHandleId(CustomItem(.items[slot]).getHandle()))
call .items.flush(slot)
endif
endmethod
public method addItem takes CustomItem ci returns boolean
call .cleanSlot(.index)
call .setSlotItem(ci, .index)
set .index = .index +1
if not INV_SHOW_ITEMS then
call .dropItem(ci, false)
else
call .pickupItem(ci, true)
endif
return true
endmethod
public method remItem takes CustomItem ci returns boolean
local integer slot = .getItemSlot(ci)
local CustomItem it = 0
if slot >= 0 then
call .cleanSlot(slot)
set .index = .index -1
set it = .getItem(.index)
call .cleanSlot(.index)
if it != ci and it != 0 then
call .setSlotItem(it, slot)
endif
call .dropItem(ci, true)
call ci.remove()
return true
endif
return false
endmethod
public method checkPickup takes CustomItem ci returns boolean
local boolean canPickup = true
debug local integer i = 0
static if INV_AUTO_CHECK_PICKUP then
if not ci.check(.carrier) then
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.carrier), "You can't take this item. (You didn't meet all requirements.)")
endif
return false
endif
endif
if ci.getHandle() == null then
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.carrier), "You can't take this item. (Item handle is invalid.)")
endif
return false
endif
if .hasItem(ci) then
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.carrier), "You can't take this item. (You already have this item.)")
endif
return false
endif
if .index >= CI_UI_MAX_ITEMS then
static if LIBRARY_CIError then
call CIError.create(4, 1, GetOwningPlayer(.carrier), "You can't take this item. (Your inventory is full.)")
endif
return false
endif
return true
endmethod
private static method realRefresh takes nothing returns nothing
local thistype this = thistype.TimerToInstance[GetHandleId(GetExpiredTimer())]
//: Oh well actually we use a trick.
//: We forge and stack until we can't
//: do it anymore. So we simply use an
//: endless loop which runs the method
//: in the condition and will break out as
//: soon as the action can't be done anymore.
static if ENABLE_MODULE_FORGE then
loop
exitwhen not .forge()
endloop
endif
//: Same with stacking
static if ENABLE_MODULE_STACK then
loop
exitwhen not .stack()
endloop
endif
//: Refresh the sets
static if ENABLE_MODULE_SETS then
call .checkSets()
endif
static if LIBRARY_CIWindow then
if InventoryWindows[GetPlayerId(GetOwningPlayer(.carrier))] != 0 then
call InventoryWindows[GetPlayerId(GetOwningPlayer(.carrier))].refresh()
endif
endif
endmethod
public method refresh takes nothing returns nothing
//: We start the timer.
//: Why?
//: Because to fast picking and executing refresh
//: will cause a wc3 stack overflow.
call TimerStart(.refreshT, .75, false, function thistype.realRefresh)
endmethod
public method getIndex takes nothing returns integer
return .index
endmethod
public method getOwner takes nothing returns unit
return .carrier
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope CIGenDestructibles
//: By Ammorth
// set this to true to generate the object data
// setting this to false will not generate data and therefore will speed up save times
// you can change anything between CI_GEN_START and CI_GEN_END.
// only call the CI_GEN textmacros between CI_GEN_START and CI_GEN_END
// CI_GEN_SLOT can be used by the user to generate custom destructibles for their items
//! runtextmacro CI_GEN_START("CI_NEW_MAP")
//! runtextmacro CI_GEN_BORDER("cwbt", "#CW (Bottom)", "CustomWindow\\borderD.mdl")
//! runtextmacro CI_GEN_BORDER("cwld", "#CW (Corner Left Down)", "CustomWindow\\cornerDL.mdl")
//! runtextmacro CI_GEN_BORDER("cwlu", "#CW (Corner Left Up)", "CustomWindow\\cornerUL.mdl")
//! runtextmacro CI_GEN_BORDER("cwrd", "#CW (Corner Right Down)", "CustomWindow\\cornerDR.mdl")
//! runtextmacro CI_GEN_BORDER("cwru", "#CW (Corner Right Up)", "CustomWindow\\cornerUR.mdl")
//! runtextmacro CI_GEN_BORDER("cwlf", "#CW (Left)", "CustomWindow\\borderL.mdl")
//! runtextmacro CI_GEN_BORDER("cwrg", "#CW (Right)", "CustomWindow\\borderR.mdl")
//! runtextmacro CI_GEN_BORDER("cwup", "#CW (Top)", "CustomWindow\\borderU.mdl")
//! runtextmacro CI_GEN_SLOT("cwcc", "#CW (Cancel)", "ReplaceableTextures\\CommandButtons\\BTNCancel.blp")
//! runtextmacro CI_GEN_SLOT("cwds", "#CW (Dissselect)", "UI\\Widgets\\Console\\Human\\CommandButton\\human-multipleselection-heroglow.blp")
//! runtextmacro CI_GEN_SLOT("cwdp", "#CW (Drop Item)", "ReplaceableTextures\\CommandButtons\\BTNPickUpItem.blp")
//! runtextmacro CI_GEN_SLOT("cwit", "#CW (Item Slot)", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNPickUpItem.blp")
//! runtextmacro CI_GEN_SLOT("cwsf", "#CW (Item Slot Full)", "ReplaceableTextures\\CommandButtons\\BTNDustOfAppearance.blp")
//! runtextmacro CI_GEN_SLOT("ciam", "[Amulet Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNAmulet.blp")
//! runtextmacro CI_GEN_SLOT("cibt", "[Boots Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNBoots.blp")
//! runtextmacro CI_GEN_SLOT("cigv", "[Glove Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNGauntletsOfOgrePower.blp")
//! runtextmacro CI_GEN_SLOT("cihn", "[Hand Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNGlove.blp")
//! runtextmacro CI_GEN_SLOT("cihd", "[Helmet Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNHoodOfCunning.blp")
//! runtextmacro CI_GEN_SLOT("cimn", "[Main Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNImprovedMoonArmor.blp")
//! runtextmacro CI_GEN_SLOT("cimc", "[Misc Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNBelt.blp")
//! runtextmacro CI_GEN_SLOT("cirg", "[Ring Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNGoldRing.blp")
//! runtextmacro CI_GEN_SLOT("cish", "[Shoulder Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNLeatherUpgradeTwo.blp")
//! runtextmacro CI_GEN_SLOT("citr", "[Trouser Slot]", "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDustOfAppearance.blp")
//! runtextmacro CI_GEN_SPECIAL("cwsl", "#CW (Selector)", "CustomWindow\\selector.mdl")
//! runtextmacro CI_GEN_END()
// these textmacros below generate an LUA file through vJass to send to ObjectMerger
// don't change these unless you know what you are doing.
//! textmacro CI_GEN_START takes DO_GEN
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i if "$DO_GEN$" == "true" then
//! i setobjecttype("destructables")
//! endtextmacro
//! textmacro CI_GEN_END
//! i end
//! endexternalblock
//! endtextmacro
//! textmacro CI_GEN_SPECIAL takes RAWCODE, NAME, MODEL
//! i createobject("YTlb", "$RAWCODE$")
//! i makechange(current, "bfxr", 180.00)
//! i makechange(current, "bfil", "$MODEL$")
//! i makechange(current, "boch", 0.00)
//! i makechange(current, "bshd", "")
//! i makechange(current, "btar", "")
//! i makechange(current, "bcpr", 0)
//! i makechange(current, "bmas", 10.0)
//! i makechange(current, "bmis", 0.10)
//! i makechange(current, "bcpd", 0)
//! i makechange(current, "buch", 0)
//! i makechange(current, "bptx", none)
//! i makechange(current, "bsuf", "$NAME$")
//! i makechange(current, "bnam", " ")
//! endtextmacro
//! textmacro CI_GEN_SLOT takes RAWCODE, NAME, TEXTURE
//! i createobject("YTlb", "$RAWCODE$")
//! i makechange(current, "bfxr", 180.00)
//! i makechange(current, "bfil", "CustomWindow\\IconBase.mdl")
//! i makechange(current, "boch", 0.00)
//! i makechange(current, "btxf", "$TEXTURE$")
//! i makechange(current, "btxi", 32)
//! i makechange(current, "bshd", "")
//! i makechange(current, "btar", "")
//! i makechange(current, "bcpr", 0)
//! i makechange(current, "bmas", 10.0)
//! i makechange(current, "bmis", 0.10)
//! i makechange(current, "bcpd", 0)
//! i makechange(current, "buch", 0)
//! i makechange(current, "bptx", none)
//! i makechange(current, "bsuf", "$NAME$")
//! i makechange(current, "bnam", " ")
//! endtextmacro
//! textmacro CI_GEN_BORDER takes RAWCODE, NAME, MODEL
//! i createobject("YTlb", "$RAWCODE$")
//! i makechange(current, "bfxr", 0.00)
//! i makechange(current, "bfil", "$MODEL$")
//! i makechange(current, "boch", 0.00)
//! i makechange(current, "btxf", "UI\\Widgets\\EscMenu\\Human\\human-options-menu-border.blp")
//! i makechange(current, "btxi", 32)
//! i makechange(current, "bshd", "")
//! i makechange(current, "btar", "")
//! i makechange(current, "bcpr", 0)
//! i makechange(current, "bmas", 10.0)
//! i makechange(current, "bmis", 0.10)
//! i makechange(current, "bcpd", 0)
//! i makechange(current, "buch", 0)
//! i makechange(current, "bptx", none)
//! i makechange(current, "bsuf", "$NAME$")
//! i makechange(current, "bnam", " ")
//! endtextmacro
endscope
//TESH.scrollpos=18
//TESH.alwaysfold=0
library Items initializer init requires CustomInventory
private function test takes CustomItem ciObj, unit ciUnit returns boolean
return GetUnitTypeId(ciUnit) == 'Hmkg'
endfunction
private function init takes nothing returns nothing
local CustomItem ci = 0
local CIForgeItem fi = 0
local CISet is = 0
local trigger itemDrop = CreateTrigger()
set ci = CreateCustomItem('I001')
set ci.class = ITEM_CLASS_TWOHANDER
set ci.dmg = 35
set ci.str = 7
set ci.dest = 'it03'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNShamanMaster.blp"
set ci.name = "Shaman Claw"
set ci.desc = "Twohander item."
call ci.addSfx("Abilities\\Spells\\Human\\InnerFire\\InnerFireTarget.mdl", "overhead")
set ci = CreateCustomItem('hcun')
set ci.class = ITEM_CLASS_HELMET
set ci.as = 35
set ci.agy = 12
set ci.dest = 'it04'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNHoodOfCunning.blp"
set ci.name = "Hood of Cunning"
set ci.desc = "Increases attasckspeed by 35%\n and agility by 12."
set ci = CreateCustomItem('ratf')
set ci.class = ITEM_CLASS_HAND
set ci.dmg = 15
set ci.dest = 'coat'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNClawsOfAttack.blp"
set ci.name = "Clawns of Attack +15"
set ci.desc = "This item increases your damage \nby 15 if carried."
set ci = CreateCustomItem('rat3')
set ci.class = ITEM_CLASS_HAND
set ci.dmg = 3
set ci.dest = 'coat'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNClawsOfAttack.blp"
set ci.name = "Clawns of Attack +3"
set ci.desc = "This item increases your damage \nby 3 if carried."
set ci = CreateCustomItem('rat6')
set ci.link = 'I000'
set ci.class = ITEM_CLASS_HAND
set ci.dmg = 6
set ci.dest = 'coat'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNClawsOfAttack.blp"
set ci.name = "Clawns of Attack +6"
set ci.desc = "This item increases your damage \nby 6 if carried."
set ci = CreateCustomItem('rat9')
set ci.class = ITEM_CLASS_HAND
set ci.dmg = 9
set ci.dest = 'coat'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNClawsOfAttack.blp"
set ci.name = "Clawns of Attack +9"
set ci.desc = "This item increases your damage \nby 9 if carried."
set ci = CreateCustomItem('phea')
set ci.class = ITEM_CLASS_POTION
set ci.dest = 'it01'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNPotionGreenSmall.blp"
set ci.name = "Healing Potion (Small)"
set ci.desc = "Use this potion to heal 250 hitpoints."
set ci.stack = 10
set ci = CreateCustomItem('pclr')
set ci.class = ITEM_CLASS_POTION
set ci.dest = 'it02'
set ci.icon = "ReplaceableTextures\\CommandButtons\\BTNPotionOfClarity.blp"
set ci.name = "Clarity Potion"
set ci.desc = "Use this potion to heal 150 \nmana over 20 seconds."
set ci.stack = 10
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope test initializer init
private function init takes nothing returns nothing
local unit fakeInv = null
local unit hero = null
local integer i = 0
loop
exitwhen i >= 12
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
set fakeInv = CreateInventoryUnit(Player(i), 'h000')
set hero = CreateUnit(Player(i), 'Hpal', 0., 0., 0.)
call CreateInventoryUI(hero, fakeInv)
endif
set i = i +1
endloop
endfunction
endscope