If you want a billion functions to automate your object cycling.
This version has one array. In that array are groups. As you make objects you wish to recycle to assign them to a group (it's fine to just use one group). Whenever you need a reusable object you call a function, it'll activate and return an object if one's free. Whenever you've finished with an object call one of the kill functions. There are off-screen and time-based kill tools too.
I suspect as long as your numbers remain reasonable this is quick enough. The next version will have multiple arrays, each with groups. That should speed things, not that this seems laggy. Smaller arrays are quicker to search than large ones, and not all groups might be active at once; or you might want a very large but infrequently needed group, etc.
REMSTART
O-CYCLE
Object-Cycling System
by viberunner
Copyright: Public Domain. Have as your own. Enjoy.
As-ever, the documentation appears to confuse the subject.
Using the system will clarify everything, as should
the demonstration program.
These functions are elegant and thus roboust, I hope.
It is a poor idea to create, instance, or delete, objects
during a game's action loop. Fine during loading screens
or menus, quite another during the game cycle. Object
management causes texture rewrites on the graphics card,
a bad thing if you want a smooth game. Or so the DBP
documentation asserts.
The best idea is to create, clone, or instance all objects required
ahead of time; then use and re-use them as required in the game.
These functions automate that task.
Objects are placed into category groups. Objects in those
groups are either active, or not active. There are functions
to find inactive objects of a group and active them; and
others to deactivate them.
Once an object is placed into to the OCycle system, it cannot
be removed. It can be switched into a different group though,
so it could be moved to an ignored group.
Moving groups is an effective way of managing anything capacity
related; like inventory slots, or rate-of-fire.
The system uses one array of a USER DEFINED TYPE:
OCycle() OF OCycle_TYPE
You can add your own labels to the TYPE, but leave the system ones:
.object DWORD
.time DWORD
.group BYTE
.active BOOLEAN
The demo program below adds .speed, but this is just for the demo program,
it is not required by the OCYCLE system.
LIST OF FUNCTIONS
SETUP FUNCTION
This is the ONE-TIME function that adds objects to the system.
It is called once for EACH and every object added to the OCycle system.
FUNCTION OCycleAdd
PARAMETERS object AS DWORD, activation state AS BOOLEAN, group AS BYTE
RETURNS success 1, failure 0
DOCUMENTATION:
Adds an object to the O-Cycle system. Sets default group, and activation state.
MAIN FUNCTIONS
Finds a free object id, activating it. One returns object number, the other the index.
FUNCTION OCycleActivateObject
PARAMETERS group
RETURNS object, or zero if failed to find
DOCUMENTATION:
Finds an inactive object; of a group; activates it; and returns it.
FUNCTION OCycleGetActivateIndex
PARAMETERS group
RETURNS index, or zero if failed to find
DOCUMENTATION:
Finds an inactive object; of a group; activates it; and returns it.
MOVE GROUP FUNCTIONS
Handy for group management; for inventory, density, rates-of-fire, etc.!
FUNCTION OCycleMoveGroup
PARAMETERS from group, destination group, amount AS DWORD
RETURNS success 1, failure 0
DOCUMENTATION:
Moves 'amount' number of inactive objects between groups.
DIRECT ACTIVATION/DEACTIVATION FUNCTONS
These functions activate/deactivate in batches.
FUNCTION OCycleActivateAll
PARAMETERS none
RETURNS success 1, failure 0
DOCUMENTATION:
Activate all objects.
FUNCTION OCycleActivateAllGroup
PARAMETERS group
RETURNS success 1, failure 0
DOCUMENTATION:
Activate all objects of a group.
FUNCTION OCycleActivate
PARAMETERS object
RETURNS success 1, failure 0
DOCUMENTATION:
Activates an object; "OCycleActivateObject()" is probably more useful.
FUNCTION OCycleKillAll
PARAMETERS none
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivates all objects.
FUNCTION OCycleKillAllGroup
PARAMETERS group
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivates all objects of a group.
FUNCTION OCycleKill
PARAMETERS object
RETURNS success 1, failure 0
DOCUMENTATION:
Makes specified object inactive.
SPECIAL DEACTIVATION FUNCTIONS
These might be handy, else are ideal as templates for your own needs.
DeActivate those not visible on the screen:
FUNCTION OCycleOffScreenKillGroup
PARAMETERS group
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivate all active objects of a group that are not visible on-screen.
FUNCTION OCycleOffScreenKillAll
PARAMETERS none
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivate all active objects that are not visible on-screen.
DeActivate those over a certain age:
FUNCTION OCycleKillTimerGroup
PARAMETERS microseconds, group
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivates all objects of a group of specified microseconds.
FUNCTION OCycleKillTimerAll
PARAMETERS microseconds
RETURNS success 1, failure 0
DOCUMENTATION:
Deactivates all objects of specified microseconds.
COUNTING FUNCTIONS
These functions are for knowing how many objects are in a group, and how
many objects of a particular activiation state there are in a group.
FUNCTION OCycleCountGroup
PARAMETERS group, activation state
RETURNS object count
DOCUMENTATION:
Returns a count of all objects of a group, of particular activation state.
FUNCTION OCycleCountGroupAll
PARAMETERS group
RETURNS object count
DOCUMENTATION:
Returns a count of all objects of a group.
FUNCTION OCycleCount
PARAMETERS activation state
RETURNS object count
DOCUMENTATION:
Returns a count of all of particular activation state.
FUNCTION OCycleCountAll
PARAMETERS none
RETURNS object count
DOCUMENTATION:
Returns a count of all objects in system.
TECHNICAL FUNCTIONS FOR GAME WRITER
** THESE FUNCTIONS ARE INTENDED TO CONTAIN YOUR CODE FOR YOUR OBJECTS **
Examine these functions for more detail, but these are internal 'engine'
functions. You do not call them directly, hence no documentation on
parameters/return. These functions are called from the various user-focused
functions above.
They are useful for implementing your own activation, update, and
deactivation routines.
OCycleObjectActivation For when object activates
OCycleObjectDeActivation For when object deactivates
OCycleObjectUpdate Maintain active objects of a group
INDEX FUNCTIONS
Find an idex from an object, or object from an index. You are far better off
finding an object if you know the index; avoid finding the index if you can.
Thus if you need to know the index, use "OCycleGetActivateIndex()", and find
the object with "OCycleFindObject()".
FUNCTION OCycleFindIndex
PARAMETERS object
RETURNS index
DOCUMENTATION:
Returns the INDEX number of the OCycle array of a specified object.
FUNCTION OCycleFindObject
PARAMETERS index
RETURNS object
DOCUMENTATION:
Returns the object of a given OCycle array index.
RESET FUNCTION
FUNCTION OCycleReset
PARAMETERS delete AS BOOLEAN
RETURNS success 1, failure 0
DOCUMENTATION:
Clears the O-Cycle system arrays; nullifies all previous uses of OCycleAdd()
ALSO: If delete is set to 1, all objects in all groups are deleted.
BONUS FUNCTION
FIND_FREE_OBJECT A lithe little slip of a bitch.
REMEND
` ###### USER DEFINED TYPE ######
` ###### INFORMATION STORE ######
` ###### USER DEFINED TYPE ######
TYPE OCycle_TYPE
` ENGINE ATTRIBUTES
object AS DWORD
active AS BOOLEAN
group AS DWORD
time AS DWORD
` YOUR STUFF, avoid strings
speed AS BYTE
ENDTYPE
` ###### DEMO PROGRAM ######
` ###### START ######
` ###### DEMO PROGRAM ######
#CONSTANT AMMO_RED 1
#CONSTANT AMMO_RED_STORE 2
#CONSTANT AMMO_GREEN 3
#CONSTANT AMMO_GREEN_STORE 4
` These constants used in the demo example only,
` not the functions!
#CONSTANT OBJECT_ACTIVE 1
#CONSTANT OBJECT_INACTIVE 0
AUTOCAM OFF
HIDE MOUSE
SYNC RATE 60 : SYNC ON
BACKDROP ON
COLOR BACKDROP 0
XMAX=SCREEN WIDTH()
YMAX=SCREEN HEIGHT()
XHALF=XMAX/2
YHALF=YMAX/2
XBIT=XHALF/2
YBIT=YHALF/2
POSITION CAMERA 0,400,-400
POINT CAMERA XHALF,YHALF,0
` RED SPHERE TEMPLANT OBJECT
S1 = FIND_FREE_OBJECT()
MAKE OBJECT SPHERE S1,20
COLOR OBJECT S1,RGB(255,0,0)
POSITION OBJECT S1,XBIT,YHALF,0
s1x = OBJECT POSITION X(S1)
s1y = OBJECT POSITION Y(s1)
s1z = OBJECT POSITION Z(S1)
` GREEN SPHERE TEMPLANT OBJECT
S2 = FIND_FREE_OBJECT()
MAKE OBJECT SPHERE S2,8
COLOR OBJECT S2,RGB(0,255,0)
POSITION OBJECT S2,XHALF+XBIT,YHALF,0
s2x = OBJECT POSITION X(S2)
s2y = OBJECT POSITION Y(S2)
s2z = OBJECT POSITION Z(S2)
` Create instances, place into OCycle Groups
` BULLETS
FOR i = 1 TO 20
` Free object ID is found
` Object is instanced from Red or Green ball
` It is added to the OCycle system; in an inactive object; in a group
` RED BULLETS
o = FIND_FREE_OBJECT()
CLONE OBJECT o,S1
OCycleAdd(o, OBJECT_INACTIVE, AMMO_RED)
` GREEN BULLETS
o = FIND_FREE_OBJECT()
INSTANCE OBJECT o,S2
OCycleAdd(o, OBJECT_INACTIVE, AMMO_GREEN)
NEXT i
` BACKUP BULLETS
FOR i = 1 TO 300
` Spare Red Bullets
o = FIND_FREE_OBJECT()
CLONE OBJECT o,S1
OCycleAdd(o, OBJECT_INACTIVE, AMMO_RED_STORE)
` Spare Green Bullets
o = FIND_FREE_OBJECT()
INSTANCE OBJECT o,S2
OCycleAdd(o, OBJECT_INACTIVE, AMMO_GREEN_STORE)
NEXT i
` ### MAIN LOOP START
` ### MAIN LOOP START
` ### MAIN LOOP START
` NOTE: the major parts of this program (fire, update, deactivate, shift, count)
` could have been done in any order.
DO
` ### USE O-CYCLE SYSTEM TO FIND FREE INSTANCES OF AN OBJECT
` FIRE A RED BALL
IF MOUSECLICK()=1 OR MOUSECLICK()=3
` We only need the object number, so OCycleActivateObject is enough.
` We do not need the index because we are not looking at
` the datatype, the speed of these objects will be hardcoded.
o = OCycleActivateObject(AMMO_RED)
` Zero is returned if no free objects, so test
IF o <> 0
POSITION OBJECT o,s1x,s1y,s1z
XROTATE OBJECT o,RND(360)
YROTATE OBJECT o,RND(360)
ZROTATE OBJECT o,RND(360)
` Rescale, just for a bit of fun
s = RND(250) + 50
SCALE OBJECT o,s,s,s
ENDIF
ENDIF
` ### USE O-CYCLE SYSTEM TO FIND FREE INSTANCES OF AN OBJECT
` FIRE SEVERAL GREEN BALLS
IF MOUSECLICK()=2 OR MOUSECLICK()=3
amount = RND(10) + 1
FOR c = 1 TO amount
` We need the index, so find it, and use it to find the object.
` We do not need the index because we are looking at the
` array datatype, our speed setting is stored there
i = OCycleActivateIndex(AMMO_GREEN)
o = OCycleFindObject(i)
` Zero is returned if no free objects, so test
IF i <> 0
POSITION OBJECT o,s2x,s2y,s2z
XROTATE OBJECT o,RND(360)
YROTATE OBJECT o,RND(360)
ZROTATE OBJECT o,RND(360)
` Update the user-made part of the typed array
OCycle(i).speed = 3 + RND(5)
ENDIF
NEXT c
ENDIF
` ### UPDATE OBJECTS
` ### UPDATE OBJECTS
` ### UPDATE OBJECTS
` RED
` This updates objects with USER-WRITTEN code inside the function.
OCycleObjectUpdate(AMMO_RED)
` GREEN
` Example of updating using a loop.
` Just be wary about messing the array up.
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).active = 1
` You could case all your active groups, including
` just issuing a whizz-bang function with an object id,
` or array index.
SELECT OCycle(c).group
CASE 3 : ` AMMO_GREEN
MOVE OBJECT OCycle(c).object, OCycle(c).speed
ENDCASE
ENDSELECT
ENDIF
NEXT c
` ### DEACTIVATE OBJECTS
` ### DEACTIVATE OBJECTS
` ### DEACTIVATE OBJECTS
` Red - timer based
` Since KillTimer only works with a whole group,
` what do you do if you wish to put timers on just
` one object of a group?
` One method is to have a "timeout AS BOOLEAN" variable
` on the typed array, and set it to 1 and the existing ".time"
` to HITIMER() + countdown amount (in microseconds).
` Then in the UPDATE section check for timeout=1, and if
` set check .time as < HITIMER(), if so deactivate that
` object and perform your game logic.
OCycleKillTimerGroup(2000,AMMO_RED)
` Green - off-screen
OCycleOffScreenKillGroup(AMMO_GREEN)
` Spacebar - kill all
IF INKEY$()=" "
OCycleKillAll()
ENDIF
` ### SHIFT OBJECTS BETWEEN GROUPS, AVAILABLE AND STORAGE
` ### SHIFT OBJECTS BETWEEN GROUPS, AVAILABLE AND STORAGE
` ### SHIFT OBJECTS BETWEEN GROUPS, AVAILABLE AND STORAGE
` Move red, from storage bucket to ammo bucket
IF INKEY$()="1"
OCycleMoveGroup(AMMO_RED_STORE, AMMO_RED,5)
ENDIF
` Move red, from ammo bucket to storage bucket
IF INKEY$()="2"
OCycleMoveGroup(AMMO_RED, AMMO_RED_STORE,10)
ENDIF
` Same for Green
IF INKEY$()="3"
OCycleMoveGroup(AMMO_GREEN_STORE, AMMO_GREEN,5)
ENDIF
IF INKEY$()="4"
OCycleMoveGroup(AMMO_GREEN, AMMO_GREEN_STORE,10)
ENDIF
` ### COUNT OBJECTS
` ### COUNT OBJECTS
` ### COUNT OBJECTS
` Various tallies for demo display.
` RED COUNTS
` Count all of a Group; active, OR not active
used_red = OCycleCountGroup(AMMO_RED, OBJECT_ACTIVE)
unused_red = OCycleCountGroup(AMMO_RED, OBJECT_INACTIVE)
` Count all of a Group; active AND not active
total_red = OCycleCountGroupAll(AMMO_RED)
total_red_store = OCycleCountGroupAll(AMMO_RED_STORE)
` GREEN COUNTS
` Count all of a Group; active, OR not active
used_green = OCycleCountGroup(AMMO_GREEN, OBJECT_ACTIVE)
unused_green = OCycleCountGroup(AMMO_GREEN, OBJECT_INACTIVE)
` Count all of a Group; active AND not active
total_green = OCycleCountGroupAll(AMMO_GREEN)
total_green_store = OCycleCountGroupAll(AMMO_GREEN_STORE)
` SYSTEM COUNTS
all_active = OCycleCount(OBJECT_ACTIVE)
all_inactive = OCycleCount(OBJECT_INACTIVE)
all_total = OCycleCountAll()
` Display the counts
text 20,0, "RED EMITTER"
text 20,20, "Left-Mouse"
text 20,40, "Keys 1 and 2"
text 20,60, "active " + str$(used_red)
text 20,80, "free " + str$(unused_red)
text 20,100,"total available " + str$(total_red)
text 20,120,"extra in storage " + str$(total_red_store)
text 20,140,"TIMER CLEARED (2 secs)"
text 220,0, "GREEN EMITTER"
text 220,20, "Right-Mouse"
text 220,40, "Keys 3 and 4"
text 220,60, "active " + str$(used_green)
text 220,80, "free " + str$(unused_green)
text 220,100,"total available " + str$(total_green)
text 220,120,"extra in storage " + str$(total_green_store)
text 220,140,"CLEARED WHEN NO LONGER VISIBLE"
text 420,0, "SPACEBAR = CLEAR ALL"
text 420,40, "SYSTEM TOTALS"
text 420,60, "active " + str$(all_active)
text 420,80, "inactive " + str$(all_inactive)
text 420,100,"total " + str$(all_total)
` Peek-a-boo!
FASTSYNC
LOOP
END
` ###### DEMO PROGRAM ######
` ###### END ######
` ###### DEMO PROGRAM ######
REM ** ******************* **
REM ** ******************* **
REM ** O-CYCLE FUNCTIONS **
REM ** ******************* **
REM ** ******************* **
` local variables and parameters follow the standard:
` i array index
` o object
` g group
` a active state
` c counter (loop)
` r report counter
` t time counter
REM ** SPECIAL USER-INPUT FUNCTIONS **
REM These functions are for tailoring to your system, each
REM time an object of a Group is activated or deactivated,
REM ** DO NOT CALL these functions DIRECTLY **
REM ** DO NOT CALL these functions DIRECTLY **
REM ** DO NOT CALL these functions DIRECTLY **
REM They take an index parameter, this is done for speed.
REM Well, call them if you know the index number. =)
REM However, they are called from all of the MANY Activate
REM and Kill functions.
FUNCTION OCycleObjectActivation(i AS DWORD)
OCycle(i).active = 0
` Sanity Checks
IF OCycle(i).object = 0
EXITFUNCTION 0
ENDIF
IF OBJECT EXIST(OCycle(i).object) = 0
EXITFUNCTION 0
ENDIF
` Only valid objects can be activated
OCycle(i).active = 1
OCycle(i).time = TIMER()
` ****************************************************************************
` **** USER CODE START ****
` ****************************************************************************
` example code. remember you have access to OCycle(i)
SHOW OBJECT OCycle(i).object
` ****************************************************************************
` **** USER CODE END ****
` ****************************************************************************
` Success
ENDFUNCTION 1
FUNCTION OCycleObjectDeActivation(i AS DWORD)
OCycle(i).active = 0
OCycle(i).time = 0
` Sanity Checks
IF OCycle(i).object = 0
EXITFUNCTION 0
ENDIF
IF OBJECT EXIST(OCycle(i).object) = 0
EXITFUNCTION 0
ENDIF
` ****************************************************************************
` **** USER CODE START ****
` ****************************************************************************
` example code. remember you have access to OCycle(i)
HIDE OBJECT OCycle(i).object
` ****************************************************************************
` **** USER CODE END ****
` ****************************************************************************
` Success
ENDFUNCTION 1
FUNCTION OCycleObjectUpdate(g AS BYTE)
FOR i = 1 TO ARRAY COUNT(OCycle(0))
` For All Objects of Our Group
IF OCycle(i).group = g
` If Object is Active
IF OCycle(i).active = 1
` Sanity Checks
IF OCycle(i).object = 0
EXITFUNCTION 0
ENDIF
IF OBJECT EXIST(OCycle(i).object) = 0
EXITFUNCTION 0
ENDIF
` ****************************************************************************
` **** USER CODE START ****
` ****************************************************************************
` example code. remember you have access to OCycle(i)
IF g = ammo_red
MOVE OBJECT OCycle(i).object,3.0
ENDIF
` ****************************************************************************
` **** USER CODE END ****
` ****************************************************************************
ENDIF
ENDIF
NEXT i
` Success
ENDFUNCTION 1
REM ** ****************** **
REM ** ****************** **
REM ** ENGINE FUNCTIONS **
REM ** ****************** **
REM ** ****************** **
REM ** OCYCLE ADD
` ** MAIN ENGINE FUNCTION **
` Parameters: Object number , object Activation state , Group number
` Returns: SUCCESS STATUS CODE
` Description: Adds an object into the OCycle system.
FUNCTION OCycleAdd(o AS DWORD, a AS BOOLEAN, g AS BYTE)
` Sanity Checks, fail if no object
IF o = 0 : EXITFUNCTION 0 : ENDIF
IF OBJECT EXIST(o) = 0 : EXITFUNCTION 0 : ENDIF
` Check object not already in system
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).object = o : : EXITFUNCTION 0 : ENDIF
NEXT c
GLOBAL DIM OCycle(c) AS OCycle_TYPE
OCycle(c).object = o
OCycle(c).active = a
OCycle(c).group = g
OCycle(c).time = TIMER()
IF a = 1
OCycleObjectActivation(c)
ELSE
OCycleObjectDeActivation(c)
ENDIF
` Success
ENDFUNCTION 1
REM ** OCYCLE ACTIVATE - RETURN OBJECT
` Returns: freed OBJECT, or zero on a fail-to-find
FUNCTION OCycleActivateObject(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
IF OCycle(c).active = 0
o = OCycle(c).object
OCycleObjectActivation(c)
` Success, return object
EXITFUNCTION o
ENDIF
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE ACTIVATE - RETURN INDEX
` Returns: INDEX of freed OBJECT, or zero on a fail-to-find
FUNCTION OCycleActivateIndex(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
IF OCycle(c).active = 0
o = OCycle(c).object
OCycleObjectActivation(c)
` Success, return object
EXITFUNCTION c
ENDIF
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE MOVE OBJECT GROUP, from Group to Group, num 0 = all
` Returns: SUCCESS STATUS CODE
` WILL ONLY MOVE INACTIVE GROUPS
FUNCTION OCycleMoveGroup(g1 AS BYTE, g2 AS BYTE, num AS DWORD)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g1
IF OCycle(c).active = 0
OCycle(c).group = g2
INC no
IF no >= num
` Success
EXITFUNCTION 1
ENDIF
ENDIF
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE FIND INDEX
` Returns: INDEX, OR FAIL
FUNCTION OCycleFindIndex(o AS DWORD)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).object = o
` Success
EXITFUNCTION c
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE FIND OBJECT
` Returns: OBJECT, OR FAIL
FUNCTION OCycleFindObject(i AS DWORD)
IF i <= ARRAY COUNT(OCycle(0))
` Success
o = OCycle(i).object
EXITFUNCTION o
ENDIF
` Fail
ENDFUNCTION 0
REM ** OCYCLE KILL OBJECT
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleKill(o AS DWORD)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).object = o
OCycleObjectDeActivation(c)
` Success, return object
EXITFUNCTION 1
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE KILL GROUP
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleKillAllGroup(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF g = OCycle(c).group
OCycleObjectDeActivation(c)
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE KILL ALL
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleKillAll()
FOR c = 1 TO ARRAY COUNT(OCycle(0))
OCycleObjectDeActivation(c)
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE ACTIVATE
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleActivate(o AS DWORD)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).object = o
OCycleObjectActivation(c)
` Success
EXITFUNCTION 1
ENDIF
NEXT c
` Fail
ENDFUNCTION 0
REM ** OCYCLE ACTIVATE GROUP
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleActivateAllGroup(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF g = OCycle(c).group
OCycleObjectActivation(c)
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE ACTIVATE ALL
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleActivateAll()
FOR c = 1 TO ARRAY COUNT(OCycle(0))
OCycleObjectActivation(c)
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE RESET
` Clear the OCycles out; d AS BOOLEAN - DELETE OBJECTS
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleReset(d AS BOOLEAN)
IF d = 1
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).object > 0
IF OBJECT EXIST(OCycle(c).object) = 1
DELETE OBJECT OCycle(c).object
ENDIF
ENDIF
NEXT c
ENDIF
GLOBAL DIM OCycle(0) AS OCycle_TYPE
` Success
ENDFUNCTION 1
REM ** OCYCLE COUNT GROUP
` Returns: Count of Group, of specified activation
FUNCTION OCycleCountGroup(g AS BYTE, a AS BOOLEAN)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
IF OCycle(c).active = a
INC r
ENDIF
ENDIF
NEXT c
` Report
ENDFUNCTION r
REM ** OCYCLE COUNT GROUP
` Returns: Count of Group, of all activations
FUNCTION OCycleCountGroupAll(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
INC r
ENDIF
NEXT c
` Report
ENDFUNCTION r
REM ** OCYCLE COUNT ALL
` Returns: Count of of specified activation
FUNCTION OCycleCount(a AS BOOLEAN)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).active = a
INC r
ENDIF
NEXT c
` Report
ENDFUNCTION r
REM ** OCYCLE COUNT ALL
` Returns: System Count
FUNCTION OCycleCountAll()
FOR c = 1 TO ARRAY COUNT(OCycle(0))
INC r
NEXT c
` Report
ENDFUNCTION r
REM ** OCYCLE OFF-SCREEN KILL, GROUPED
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleOffScreenKillGroup(g AS BYTE)
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
IF OCycle(c).active = 1
IF OBJECT IN SCREEN(OCycle(c).object) = 0
OCycleObjectDeActivation(c)
ENDIF
ENDIF
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE OFF-SCREEN KILL, ALL
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleOffScreenKillAll()
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).active = 1
IF OBJECT IN SCREEN(OCycle(c).object) = 0
OCycleObjectDeActivation(c)
ENDIF
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE TIMER KILL, GROUP
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleKillTimerGroup(t AS DWORD, g AS BYTE)
t = TIMER() - t
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).group = g
IF OCycle(c).active = 1
IF OCycle(c).time < t
OCycleObjectDeActivation(c)
ENDIF
ENDIF
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** OCYCLE TIMER KILL, ALL
` Returns: SUCCESS STATUS CODE
FUNCTION OCycleKillTimerAll(t AS DWORD)
t = TIMER() - t
FOR c = 1 TO ARRAY COUNT(OCycle(0))
IF OCycle(c).active = 1
IF OCycle(c).time < t
OCycleObjectDeActivation(c)
ENDIF
ENDIF
NEXT c
` Success
ENDFUNCTION 1
REM ** BONUS ** ** BONUS **
REM ** FIND_FREE_OBJECT() **
REM ** XXX-EDITION-XXX **
FUNCTION FIND_FREE_OBJECT()
REPEAT : INC o : UNTIL NOT OBJECT EXIST(o)
ENDFUNCTION o
ta.