PDA

View Full Version : ActionPoint problem



DragonsLover
April 26th, 2011, 16:44
Danrhan, a good old programmer friend on DK.net, has found something to be checked.

There's probably a mistake on the "range" of the Action Points which is an unsigned short.

In a standard AP file, the range is a value between 0 and 10. This value is multiplied by 32 in the game for the size of the tiles in the game. This gives a radius from 16 to 320.

In the level editor, we can adjust the range of the Action Point pixel by pixel, but if the two bytes are considered as a word, the range may become huge!
For example : if the range equals 5, this gives a radius of 160 pixels. No problem if the second byte is 0.
However, if the range equals 4.5... the second byte is not 0 and then, the radius is way larger. This may causes the action point to be triggered even if our creatures don't reach it.

Mefisto, could you confirm this?

Here's what Danrhan thinks it should be:
Area = (Range*32) - Minus;

Actually in KeeperFX:

struct InitActionPoint { // sizeof = 8
struct Coord2d mappos;
unsigned short range;
unsigned short num;
};Modified KeeperFX:

struct InitActionPoint { // sizeof = 8
struct Coord2d mappos;
byte range;
byte minus;
unsigned short num;
};

mefistotelis
May 3rd, 2011, 20:33
In DK, there are several ways to 'code' a map positiion. range/radius values are always connected with one of these ways.

The most popular ways are:
- unsigned short (word, uint16_t) - coded as cube*256+position_within_cube (or subtile*256+position_within_subtile).
- unsigned char (byte, uint8_t) - just the cube (subtile) number; used if exact position is irrelevant.
- unsigned short (word, uint16_t) - X and Y coordinates coded as single number - pos_y*256+pos_x.

Note that some ways are using subtile multiplication 256, which means lower 8 bits (one byte) are left for the other value. This means these values can be treated as two bytes, or one word - depending on what you want to achieve. Both approaches will work. This sometimes leads to confusion.

I'm pretty sure the range is just coded like all other lengths in the game, subtiles*256+fractional_part. Will check to be completely sure.

EDIT:

Checked - the code for action point activation is in "action_point_get_players_within()" (at .text:0041F0B0 in IDA Pro when viewing DK Gold executable).

The code only uses "HIBYTE(apt->range)", which means the lower byte is really ignored - it's a simplification to avoid computing precise distances for every thing object.

The apt is declared as "struct ActionPoint *apt;", which is made from "struct InitActionPoint" in function load_action_point_file().

DragonsLover
May 4th, 2011, 13:28
Thanks for the verification. :) Danrhan wants to show the action points range in a DKTools application and when he coded the formula to make them show, the AP ranges were sometimes very big, thus the reason for this topic.

mefistotelis
May 4th, 2011, 18:26
When I was working on ADiKtEd, I remember making some visualization for it too. I named it "ADiKtEd Library Examples", or something similar.