- Joined
- Nov 18, 2007
- Messages
- 1,084
So I created a dummy recycling system, and I would like feedback on it before I actually try submitting it.
The main reason I'm not submitting this yet is because I'm not sure if this can be useful or if it's doing something more complicated than it should be.
Hopefully the documentation should be enough to explain what it does.
I have also attached a test map which has a simple spell using the system.
I hope I'm not offending baassee with this because he already submitted his own system. :O I had worked on this system before I saw his.
Credits:
The main reason I'm not submitting this yet is because I'm not sure if this can be useful or if it's doing something more complicated than it should be.
Hopefully the documentation should be enough to explain what it does.
JASS:
//==========================================================================================
// DummyReuser by watermelon_1234
//******************************************************************************************
// A system designed to reuse/recycle dummy units of any type.
// This is mostly aimed for resusing dummy units that can be treated like special effects,
// except that they can play a specific animation.
//******************************************************************************************
// Libraries required: (Libraries with * are optional)
// - Table
// - TimerUtils
//##########################################################################################
// API:
// *reuser object*
// Dummy units are reused by creating a reuser object. The best way to use this sytem is
// have a global variable of type reuser.
//
// *static method create takes integer id,boolean hasLocust returns thistype*
// Create a reuser object with this method. id is the unit type id of the dummy unit you wnat
// to recycle. hasLocust is used to determine if a dummy unit should have locust or not.
// Once created, the struct has access to the following methods:
//
// *method giveDummy takes player owner, real x, real y, real facing returns unit*
// Gives a dummy unit by means of getting one in storage or by creating a new unit.
// Note that a dummy unit can not be reused with this method if DEFAULT_MAX_DUMMY_LIMIT
// is reached.
//
// *method reuseDummy takes unit dummy, real reuseDelay returns boolean*
// Attempts to reuse a dummy unit if it can. Dummy units can be used in reuseDelay seconds.
// If reuserDelay is equal or less than 0, the unit will be recycled instantly.
// Returns false if the unit cannot be recycled.
//
// *method canReuse takes unit dummy returns boolean*
// Returns true if a dummy unit can be recycled by the struct.
//
// *method destroy takes nothing returns nothing*
// Use when you no longer need a reuser. Note that all dummy units in the struct's
// storage will get removed.
//
// Struct Members:
// *boolean removeDummiesOnDestroy*
// Set to false if you don't want dummy units to be removed when a reuser object is destroyed.
//
// ~readonly integer unitID~
// ~readonly boolean hasLocust~
// ~readonly integer numberDummies~
// These members should not be changed outside of the system's code. They're only intended
// to be there so that you can check the value.
//##########################################################################################
// Importing:
// 1. Copy this trigger.
// 2. Implement the required libraries.
// 3. Configure the system to your liking
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Notes:
// - Dummy units should not be able to die.
// - Having a higher DEFAULT_MAX_DUMMY_LIMIT will limit how many reuser objects you can have.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Credits:
// - Vexorian for Table and TimerUtils.
//==========================================================================================
library DummyReuser requires Table, TimerUtils
globals
// The maximum amount of dummies that would be stored by any reuser.
private constant integer DEFAULT_MAX_DUMMY_LIMIT = 15
// The player for the dummy unit when it's in storage
private constant player DUMMY_STORAGE_OWNER = Player(15)
// Coordinates for the storage of the dummy
private constant real DUMMY_STORAGE_X = 0
private constant real DUMMY_STORAGE_Y = 0
endglobals
//==========================================================================================
// END OF CONFIGURATION
//==========================================================================================
private keyword data
globals
private constant integer ARRAY_LIMIT = DEFAULT_MAX_DUMMY_LIMIT-1 // Don't know why this won't work by using the value directly.
endglobals
struct reuser
readonly integer unitID // Unit id of the dummy unit you want reused
readonly boolean hasLocust // Should the dummy units initially have locust or not?
readonly integer numberDummies = 0 // The amount of dummies currently in storage
boolean removeDummiesOnDestroy = true // Whether or not to remove the dummy units when a reuser object gets destroyed.
readonly unit array curDummies[ARRAY_LIMIT] // Stores all the dummy units currently used.
readonly boolean array inUse[ARRAY_LIMIT] // Determines whether or not a unit can be used at the moment.
private static HandleTable DummyID // To get the dummy's id assigned in the array
private method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .numberDummies
if .removeDummiesOnDestroy then
call RemoveUnit(.curDummies[i])
endif
set .curDummies[i] = null
set .inUse[i] = false
set i = i + 1
endloop
endmethod
method canReuse takes unit dummy returns boolean
return thistype.DummyID.exists(dummy)
endmethod
method giveDummy takes player owner, real x, real y, real facing returns unit
local integer i = 0
// Search for any available dummy unit
loop
exitwhen i >= .numberDummies
if .curDummies[i] != null and not .inUse[i] then
// Make sure the dummy unit is properly set up to be used.
call SetUnitOwner(.curDummies[i],owner,true)
call SetUnitFacing(.curDummies[i],facing)
call SetUnitX(.curDummies[i],x)
call SetUnitY(.curDummies[i],y)
call ShowUnit(.curDummies[i],true)
if .hasLocust and UnitRemoveAbility(.curDummies[i],'Aloc') then
call UnitAddAbility(.curDummies[i],'Aloc')
endif
set .inUse[i] = true
return .curDummies[i]
endif
set i = i + 1
endloop
// If the max limit has not been reached, create a dummy unit and allow it to be reused.
// Else, just do a CreateUnit call
if .numberDummies < DEFAULT_MAX_DUMMY_LIMIT then
set .curDummies[.numberDummies] = CreateUnit(owner,.unitID,x,y,facing)
set thistype.DummyID[.curDummies[.numberDummies]] = .numberDummies
set .inUse[.numberDummies] = true
set .numberDummies = .numberDummies + 1
return .curDummies[.numberDummies-1]
else
debug call BJDebugMsg(SCOPE_PREFIX + ": Exceeded dummy limit, new unit was created.")
return CreateUnit(owner,.unitID,x,y,facing)
endif
endmethod
method reuseDummy takes unit dummy, real reuseDelay returns boolean
if .canReuse(dummy) then
if .inUse[thistype.DummyID[dummy]] then
if reuseDelay > 0 then
call data.create(this,thistype.DummyID[dummy],reuseDelay)
else
call ShowUnit(.curDummies[thistype.DummyID[dummy]],false)
call SetUnitOwner(.curDummies[thistype.DummyID[dummy]],DUMMY_STORAGE_OWNER,false)
call SetUnitX(.curDummies[thistype.DummyID[dummy]],DUMMY_STORAGE_X)
call SetUnitY(.curDummies[thistype.DummyID[dummy]],DUMMY_STORAGE_Y)
set .inUse[thistype.DummyID[dummy]] = false
endif
return true
debug else
debug call BJDebugMsg(SCOPE_PREFIX + ": Dummy unit is not in use.")
endif
debug else
debug call BJDebugMsg(SCOPE_PREFIX + ": An invalid unit given to be reused.")
endif
return false
endmethod
static method create takes integer id,boolean hasLocust returns thistype
local thistype this = thistype.allocate()
set .unitID = id
set .hasLocust = hasLocust
return this
endmethod
private static method onInit takes nothing returns nothing
set thistype.DummyID = HandleTable.create()
endmethod
endstruct
// Struct used to reuse dummy units later
private struct data
reuser r
integer id
timer tim
static method onExpire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
call ShowUnit(.r.curDummies[.id],false)
call SetUnitOwner(.r.curDummies[.id],DUMMY_STORAGE_OWNER,false)
call SetUnitX(.r.curDummies[.id],DUMMY_STORAGE_X)
call SetUnitY(.r.curDummies[.id],DUMMY_STORAGE_Y)
set .r.inUse[.id] = false
call ReleaseTimer(.tim)
call .destroy()
endmethod
static method create takes reuser r, integer id, real delay returns thistype
local thistype this = thistype.allocate()
set .r = r
set .id = id
set .tim = NewTimer()
call SetTimerData(.tim,this)
call TimerStart(.tim,delay,false,function thistype.onExpire)
return this
endmethod
endstruct
endlibrary
I hope I'm not offending baassee with this because he already submitted his own system. :O I had worked on this system before I saw his.
Credits:
- Vexorian for libraries used in test-map
- aznricepuff for xeprojectile
Attachments
Last edited: