Name | Type | is_array | initial_value |
//TESH.scrollpos=60
//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("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
Ok so here is the phylosophy.
I will take the crap and try to explain.
I am going to place them in functions.
function 1. Adding an ability to the system.
// Not hard. You can do this without my system as well but I think I'm making some things easyer,
// especialy for mass-adding abilities.
// Just call this function:
call AddAbil( 'Item ID', 'Ability ID', "boolean wich establishes if the ability will be added either when the item is acquired-true or used-false" )
Example: call AddAbil( 'I000', 'A009', true )
// The item corresponding to the ability A009 is I000 and is triggered when acquired.
// 'I000' is the raw code of the item (ID), 'A009' is the raw code (ID) of the ability
// and true means the ability will be given when the item is acquired.
// For importing, check the next (number 2) piece of information.
endfunction
function 2. Importing the system.
// Not hard either. Just copy the whole "Abilities System" category to your map, save, close the
// map or exit the program and then open again and voila! You've got the system working.
// All we need now is the spellbooks! Just copy the abilities one by one, or import the
// abilities data if you don't have any ability in your map.
// Of course, you can make your own abilities spellbooks if you want and even not use spellbooks.
// If you don't use the spellbooks, the abilities don't have to be disabled.
// It's all your choice.
// For adding abilities and stuff, check the previous (number 1) piece of information.
endfunction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//^^^^^^^^^^^\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Other Stuff \\
_______________________________//_______________\\_____________________________________________________________________________________________________________________________________________________________________________________________________________
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Questions and answers, you can find them here.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you have a question and/or an answer, post at the forum!
~I get syntax errors when I save the map or paste the triggers!
//- You need JNGP for this system to work...
~Why did you place the pieces of information in functions?
//- It's easyer for people who read it to minimize and maximize that part of the trigger.
~Hey but this limits the number of abilities to 8192 for each type, used or acquired!
//- This is true, but aren't 8192 abilities enough for a map? 8192 is still very much!!
// Who the hell needs 8192 abilities?!
~Is there a way to add an ability without calling the custom function, in GUI?
//- I am not sure...
~Why does it lag when I pick an item for an ability?
//! It's fixed.
//- Because the trigger checks trough all the registered items for a fit.
// This may get fixed in future, maybe using some more variables or JASS, getting rid of stupid,
// infected BJ's!
~When I try to save, the WE says the function AddAbil is undeclared, what should I do?
//- Disable all triggers wich call the "AddAbil" function, save, close the map,
// re-open it and re-enable the triggers, save again and now the error should be gone.
// If the error is still there, I am not sure what to do...
~Why do I have to put my abilities in spellbooks and set their order ID to the one of the
coresponding category? Can you make the abilities be added directly to their spellbook?
//- No! Triggers cannot manipulate spellbooks, and triggers can't recognize your ability's
// element and stuff.
// You'll have to add the abilities manualy in spellbooks and change their order ID corresponding
// to their element. It's not hard!
// If you really want, you can just add the abilities to the hero without introducing them in
// spellbooks, but this way they must not be disabled!
~I have my own abilities in my map, and I cannot re-do them all!
//- This requires JNGP wich is also able to merge object editor datas!
// Before complaining, yes, this also includes units, buffs, upgrades, doodads, items, abilities
// and all the data related to the object editor.
// (Please do not confuse the Object Editor with the Object Manager! They are two different things!)
~Can the hero have the same ability twice at the same time?
//- No. Abilities don't stack like that.
~Does this support custom abilities?
//- Yes.
~What happends if I use the same order ID for more spellbooks?
//- They stack. The curent spellbooks "add" spells to the "categories" due
// to this stacking thing.
~What happends if a spellbook uses the same order ID as a spell of the owner?
//- Creates a conflict between them and one of them will be used when clicking.
// Doesn't matter wich one you click, the first one acquired will be used.
~Are those spells still learned if the hero/unit does not have the Abilities spellbook?
//- That might be interesting. Take a closer look at my triggers and you will see.
// It checks if the level of "Abilities" is greater than or equal to 1, so it's safe.
~But what should I do if I want more units with different spell categories?
For example, the unit X has Light and Darkness and the unit Y has Fire and Water.
How to do this?
//- Give the Abilities spellbook more levels, and give your unit(s) a certain level so they
// will have their own categories of spells.
// This is possible due to the triggers condition which checks if the picking/usiong
// unit's Abilities spellbook's level is bigger than or equal to 1.
//TESH.scrollpos=1
//TESH.alwaysfold=0
/***************************************************************************************************\
| Abilities System |
| by Vercas |
| |
| Requires: - Table |
| by Vexorian |
| |
| I made this system for my map, for making managing abilities easier but I thought other |
| people could use it as well so I uploaded it! |
| |
| Since version 2.01.a1, it has been completly rewritten and now the only reason to lag is...|
| ABILITIES PRELOADING!!! |
| You know, the crappy Warcraft 3 engine lags the first time it sees an ability on an unit... |
| So do not complain for the lag, I will fix it later! |
| |
| I've kept the old documentation trigger if you have any questions... |
| |
| |
| Application Programming Interface (API) : |
| |
| AddAbil( item ID, ability ID, boolean) -> nothing |
| This adds an item to the system; |
| Assigns an ability to an item! If the boolean is true, the ability is given when |
| the item is picked up, else when it's used. |
\***************************************************************************************************/
/**/library AbilitiesSystem initializer Init requires Table/***************************************/
globals
private constant integer SB_ABILITY = 'A000' // The ID of your main Spellbook. Please check the Object Editor for the ability.
private Table ItemAbility // Fastest way to get the ability assigned to an item
private Table ItemUsed // 0 is true ; anything else is false... Pretty useless...
private Table AbilityItem // To be used later for backwards compatibility
endglobals
function AddAbil takes integer it, integer abil, boolean c returns nothing
local integer i = 0
set it:ItemAbility = abil
if c then
set it:ItemUsed = 0
else
set it:ItemUsed = 1
endif
set abil:AbilityItem = it
loop
call SetPlayerAbilityAvailable( Player( i ), abil, false )
set i = i + 1
exitwhen i >= 16
endloop
endfunction
private function Action takes nothing returns nothing
local integer i = GetItemTypeId( GetManipulatedItem( ) )
call RemoveItem( GetManipulatedItem( ) )
call UnitAddAbility( GetTriggerUnit( ) , i:ItemAbility )
endfunction
private function Cond1 takes nothing returns boolean
local integer i = GetItemTypeId( GetManipulatedItem( ) )
return i:ItemAbility != 0 and i:ItemUsed == 0
endfunction
private function Cond2 takes nothing returns boolean
local integer i = GetItemTypeId( GetManipulatedItem( ) )
return i:ItemAbility != 0 and i:ItemUsed != 0
endfunction
private function Cond takes nothing returns boolean
return GetUnitAbilityLevel( GetFilterUnit(), SB_ABILITY ) > 0
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger ( )
local trigger t2 = CreateTrigger ( )
local boolexpr BX= Condition ( function Cond )
local integer i = 0
set ItemAbility = Table.create ( )
set ItemUsed = Table.create ( )
set AbilityItem = Table.create ( )
loop
call TriggerRegisterPlayerUnitEvent( t , Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, BX )
call TriggerRegisterPlayerUnitEvent( t2, Player(i), EVENT_PLAYER_UNIT_USE_ITEM , BX )
set i = i + 1
exitwhen i >= 16
endloop
call TriggerAddCondition ( t , Condition( function Cond1 ) )
call TriggerAddCondition ( t2, Condition( function Cond2 ) )
call TriggerAddAction ( t , function Action )
call TriggerAddAction ( t2, function Action )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Mouse_over_trackable_Actions takes nothing returns nothing
call ClearTextMessages()
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " |cffcc20ccQuests avaible!|r " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, "|cffdddd20-|r Don't forget to check the quests window! " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " |cffcc20ccLearner!|r " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, "|cffdddd20-|r This person is willing to learn as many abilities as there are!" )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, "|cffdddd20-|r Get some Tomes to get your abilities! " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, "|cffdddd20-|r Check his Abilities spellbook for categories! " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " |cffcc20ccMaster of Abilities|r " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, " " )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0.00 ,0.00, 30000.00, "|cffdddd20-|r He is selling you tomes wich give you abilities! " )
endfunction
//===========================================================================
function InitTrig_Mouse_over_trackable takes nothing returns nothing
set gg_trg_Mouse_over_trackable = CreateTrigger( )
call TriggerRegisterTrackableTrackEvent( gg_trg_Mouse_over_trackable, CreateTrackable( "Objects\\RandomObject\\RandomObject.mdl", 30.00, 360.00, 270.00) )
call TriggerAddAction( gg_trg_Mouse_over_trackable, function Trig_Mouse_over_trackable_Actions )
endfunction