Jump to content

Unit Locations


Danial

Recommended Posts

Facing is in unitref.dat. Column 10 if you start counting from from 0. Otherwise, it'll be row 11. Turret facing for tanks is in the unit's 'throwing accuracy' in row 24 (from zero) or 25 (From one).

 

Positions are in unitpos.dat

 

X, Y and Z coordinates are the first three bytes in each entry.

 

Note, all the large unit quarters are counted as four separate entities in this file, but they will all refer to a single line in the unitref.dat file. So if you have a tank in the first slot, the first soldier in unitref will be in the second slot, but in unitpos, the first soldier starts from fifth slot. All four tank parts in unitpos will refer to the first line in unitref, and the soldier will get the second, and so on.

 

Identifying tanks in unitpos.dat and which quarter they belong to can be done by examining the unit information flag in row 11 of the unitpos file - or 12, if you start from 1. It's a bit flag, and I can't remember what bits affect what functions at the moment.

 

edit:

 

Here we go, to identify if it's a large unit, do a bit-wise AND of 4 (or 100 in binary or 0x4 in hex) and then right shift the bits to the right by 2. 1 = large unit, 0 = normal unit

 

To identify which quarter it is:

 

Do a bitwise AND on it with the value of 24 (or 11000 in binary or 0x18 in hex). Right shift the whole value by 3 to get the quarter. 0 = upper left(the primary quarter that does most of the up-down collision detection), 1 = upper right, 2 = lower right, 3 = lower left.

 

- NKF

Link to comment
Share on other sites

Thanks, Guys!

 

unitpos[10] - Unit info flags. Bits (from left to right, 87654321):

(  1) 1: 0 = Invisible, 1 = visible.

(  2) 2: 0 = Dead, 1 = alive.

(  4) 3: 0 = Small unit, 1 = big unit.

(  8) 4: 0 = Left section of unit, 1 = right side of unit.

( 16) 5: 0 = Upper side of unit, 1 = lower side of unit.

( 32) 6: Only seems to flag for certain tank parts. Could be where tank will fire from?

( 64) 7: 0 = Normal, 1 = under mind control.

(128) 8: Unused?

I'm not quite sure what you mean here ;)

 

Do you mean that if a unit were visible, alive, and small, byte 10 would be 00000011... so a value of 3??

 

(  8) 4: ??? Seems to flag if the unit has been selected this turn.

That's a negative on that one...

 

The only unit with that bit flagged in my file is my 1st hovertank... I just selected 3 of my soldiers and re-saved, and the hovertank is still the only one with it :D

 

Maybe it's a "select this unit first" flag??

 

On the subject of viewing files, can anyone suggest a windows-based viewer so i don't have to keep opening MS Edit?

 

Numerous posts merged by BB

Link to comment
Share on other sites

Do you mean that if a unit were visible, alive, and small, byte 10 would be 00000011... so a value of 3??

 

Yup. :D

 

The only unit with that bit flagged in my file is my 1st hovertank... I just selected 3 of my soldiers and re-saved, and the hovertank is still the only one with it  ;)

 

Maybe it's a "select this unit first" flag??

 

You're more or less right. By memory, the unit which has that flagged is the one that was selected when you save the game. If you reload the game, the next unit will be selected. I never updated my notes on that one, though, as I felt I hadn't tested it enough.

Link to comment
Share on other sites

On the subject of viewing files, can anyone suggest a windows-based viewer so i don't have to keep opening MS Edit?

I've found several Hex editing programs, but they all start the offsets from the beginning of the file, rather than the beginning of the line ;) This makes it rather hard to figure out which offset you're viewing once you're off the first unit :D

Link to comment
Share on other sites

Speaking of unitref and unitpos, I've got a bit of a problem, and I'm sure we've got some brilliant minds here who can bodge something together.

 

I have a problem that has an answer I'm sure is staring me right in the face, but because I spent most of the weekend untangling the spaghetti that is my effort at C++ programming, my mind is somewhat exhausted and isn't coming up with any reasonable solutions.

 

Unitref.dat stores a substantial amount of information about every respective unit in the map.

 

Unitpos stores position data on all of the actual physical units (including dummy units for the large units) on the map and a few of their status flags that are equally as important as the unitref's themselves.

 

obpos.dat (the battlescape object position file), uses unitpos references to determine ownership, not unitref, which would've made things a bit easier, but things are never that easy.

 

The problem here is I want to be able to load unitref and unitpos into an easy to manage data structure so that I can easily work with unitref and unitpos information as one whole unit, oh and effortlessly work with obpos information as well. There's no trouble when all the units in the map are small as the indexes in both tables will be the same, but the moment large 2x2 units are introduced, that's when the indexing for units in unitref and unitpos start to go pear shaped.

 

A large unit in unitpos uses 4 slots while a large unit in unitref only uses 1 slot. I'm sure you see right away how messed up the numbering system will be.

 

My first thought was to make two referencing mapping tables, then make a few functions that, when I pass a value from one table, I'll get pointed to the right index for the other table. But this is quite a fiddly solution and may end up being more work than is necessary, if not at the moment, but for future revisions of the program. In any case, it's going to involve a heap of effort when moving (within the table itself, not physically), deleting or inserting units and their equipment(if any).

 

Any thoughts (that is to say, if you understood a single word of the rubbish I've written above :D )? As I said before, the answer's probably staring me right in the face, but I just can't see it at the moment due to numbness of the mind.

 

- NKF

Link to comment
Share on other sites

I ran into that one too, with my mapviewer.

 

Now, calculating where a given unitpos reference ends up in the unitref file (or vice versa) is simple enough to do, but there's no direct formula to do it, so your code is going to be long winded. Thus it's best to do all the needed calculations at load time, and don't ever bother with them again.

 

Thus, you must fill a 2x80 array with the links. I called my array, 'linky', for want of a better word.

 

Don't look at me like that. I used to use such terms as 'mumbo' and 'jumbo', or 'spoon' and 'nospoon'. I'm improving.

 

Now, the first 80 values should stand for each unit in unitpos. If you reference linky[30][0] (where 30 is a record in unitpos), it'll return the relevant record number in unitref. The next 80 vlaues stand for each unit in unitref, so if you reference linky[30][1] (where 30 is a record in unitref), it'll return the FIRST relevant record number in unitpos.

 

All unitpos references *will* map to a single, but not always unique, unitref record.

 

All unitref references *could* map to a multiple records in unitpos. Luckily, you don't NEED any more then the first record. If the worst comes to worst, you can easily calculate where the others are at run time, given that once you have the first one you know straight away where the other three should be.

 

When you've got this array filled, you don't need any functions. You can just use the array directly to jump from unitref to unitpos, or vice versa.

 

I don't know how clear that is... But I can't think of a simpler way to do things.

 

The below is a code extract which creates my array. It also records unitref/pos into arrays for use later in the program, and generates a string table containing the unit names.

 

It doesn't do anything overly fancy, so I reckon it should translate to your knowledge of C without too much trouble, even if it is long-winded and I lack the urge to write frequent comments. ;)

 

The FileRead object is a custom one, though:

 

FileRead.read( , , );

 

That means that the 'working' array end up with 124 elements, each being a single byte read from unitref... Meh, I'm sure you can work out the rest from there.

 

"if (working[0] == 3 || working[0] == 12 || working[0] == 13 || working[0] == 14)" is a long winded way of saying "if it's a big unit"....

 

int linkycount = 0, linkycount2 = 0;

int[] working, working2;

FileRead data = new FileRead("../game_"+savenum+"/unitref.dat"),data2 = new FileRead("../game_"+savenum+"/unitpos.dat");

 

for (int i=0; i

{

working = data.read(i*124,124,1);

working2 = data2.read(i*14,14,1);

 

if (working[0] != 255)

{

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...