Ok,
If I were to try something similar I would do it this way:
1. How many enemies do I need all together?
2. How many NPCs do I need all together?
3. Are there common characteristics that I will need to control or to test for?
4. How many of these characteristics total?
5. Since I'm using DBC, there is no TYPE or STRUCT definition, but I can get around this with MEMBLOCKS... do I need to account for multiple data types for a single object?
For my example, I've decided I need 5 enemies and 5 NPCs. I've also decided that I'm going to reserve object numbers 1-5 for enemies, and 6-10 for NPCs. With that decided, I can easily test if the object is enemy or npc with a conditional:
If you are numbering your character objects in the thousands, I would use the method you demonstrated to get at lower numbered array:
Quote: "(object#-1000,2)"
Assuming obj is the object number:
If obj <= 5 and obj >= 1
gosub enemy stuff
Endif
If obj <= 10 and obj >= 6
gosub npc stuff
Endif
Now, are there characteristics that I need to check for? Yes. I actually want to have the object and it's position closely related to each other. In this case I will need an array. An array is an allocation of memory to store data in. The dimensions of the array determine how that memory is configured. With this in mind, you can make some reasonable determinations about efficiency, depending on the size and how you manage the array. The more dimensions it has, the more memory it consumes (whether you populate the memory or not) - the larger the index, the more memory it consumes. A general formula in terms of resources is:
Type Bytes x index dimension 1+1 x index dimesion 2+1 x etc..
so a 2 dimensional array with 10 as the index numbers defined as a float: myfloat#(10,10) would roughly take up this much memory
4x11x11 = 484 bytes of memory.
Since I know I've reserved numbers 1-10 for character objects, that's going to be my first dimension. The other things I want to store are the x,y, and z position and the reputation. That means I need another dimension with an index number of 4. Since x,y, and z for an object are floats, and I as long as I don't use a decimal I can reference the object number with a float, I will dimension my array as a float:
dim character#(10,4)
NOTE: An array index actually starts at 0 so 10 actually means 11 elements and 4 actually means 5 elements... but there is such a small use of memory I'm not gonna worry about that level of efficiency and just use 10 and 4 for what they are.
The first dimension represents the character number. I don't have to keep track in the array as a separate data element if they are good or bad because that is tested for simply by the object number.
The second dimension holds x y z and reputation
1=x
2=y
3=z
4=reputation
If reputation doesn't apply to an enemy, it doesn't matter - you just won't test for it when there is interaction with an enemy. You will already have a subroutine specifically designed for the character type based on the object number.
So for example, obj = 5, and object 5 is located at (345,20,-45). Reputation = 2
character#(obj,1)=345
character#(obj,2)=20
character#(obj,3)=-45
character#(obj,4)=2
You could use a loop to assign all the values for all of the different characters.
In order to keep the number of characters from being cycled through in all of your loops, you have to find a way to skip some and include others. One way would be whether or not the appear on the screen. Another would be if they were in jail or in some situation where they couldn't be interacted with (unconsious). Another could be the distance from the main player.
to calculate the distance use the distance formula for the difference between the character (obj) and the main player (mp):
sqrt((character#(obj,1)- object position x(mp))^2 + (character#(obj,2)- object position y(mp))^2 + (character#(obj,3)- object position z(mp))^2)
To place objects randomly, you will need a check in your loop to determine if they are on the same spot as another object. If they are, then reposition them randomly and check again.
You would be randomizing x and z. Y would be the ground height of the matrix plus the distance to the objects center (in general). This test is a little inefficient, but you can use the general idea and improve upon it. You could streamline the test with collision detection, but I'm assuming this would be a one time placement of objects, so it can be run once before the action in the game starts and therefore won't detract from game play.
for obj = 1 to 10
x# = rnd(matrix size x)
z# = rnd(matrix size z)
y# = get ground height(x#,z#)+tallness
position object obj,x#,y#,z#
for test = 1 to allobjects
if test <> obj and object exists(test)=1
while x#=object position x(test) and z#=object position z(test)
x# = rnd(matrix size x)
z# = rnd(matrix size z)
y# = get ground height(x#,z#)+tallness
position object obj,x#,y#,z#
endwhile
endif
next test
next obj
Enjoy your day.