mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "objects_in_radius" and "tile_by_position" script functions
This commit is contained in:
@@ -259,6 +259,7 @@
|
||||
#define metarule_exist(metaruleName) sfall_func1("metarule_exist", metaruleName)
|
||||
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
|
||||
#define obj_under_cursor(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude)
|
||||
#define objects_in_radius(tile, radius, elev, type) sfall_func4("objects_in_radius", tile, radius, elev, type)
|
||||
#define outlined_object sfall_func0("outlined_object")
|
||||
#define real_dude_obj sfall_func0("real_dude_obj")
|
||||
#define remove_all_timer_events sfall_func0("remove_timer_event")
|
||||
@@ -278,6 +279,7 @@
|
||||
#define string_compare(str1, str2) sfall_func2("string_compare", str1, str2)
|
||||
#define string_compare_locale(str1, str2, codePage) sfall_func3("string_compare", str1, str2, codePage)
|
||||
#define string_format(format, a1, a2) sfall_func3("string_format", format, a1, a2)
|
||||
#define tile_by_position(x, y) sfall_func2("tile_by_position", x, y)
|
||||
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
||||
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
|
||||
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
|
||||
|
||||
@@ -591,7 +591,17 @@ optional arguments:
|
||||
|
||||
> string sfall_func3("string_format", string format, any val1, any val2, ...)
|
||||
- formats given value using standard syntax of C printf function (google "printf" for format details). However it is limited to formatting up to 4 values
|
||||
- formatting is only supported for %s and %d. The format string is limited to 1024 characters
|
||||
- formatting is only supported for %s and %d, and the format string is limited to 1024 characters
|
||||
|
||||
> array sfall_func3("objects_in_radius", int tile, int radius, int elevation)
|
||||
> array sfall_func4("objects_in_radius", int tile, int radius, int elevation, int type)
|
||||
- returns an array of objects of a type (see OBJ_TYPE_* constants in define_extra.h) within the specified radius from the given tile
|
||||
- The radius is limited to 50 hexes
|
||||
- passing -1 to the type argument or not specifying it will return all types of objects
|
||||
|
||||
> int sfall_func2("tile_by_position", int x, int y)
|
||||
- returns the tile number at the x/y position relative to the top-left corner of the screen
|
||||
- returns -1 if the position is outside of the screen
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
|
||||
@@ -672,6 +672,7 @@ const DWORD text_font_ = 0x4D58DC;
|
||||
const DWORD text_object_create_ = 0x4B036C;
|
||||
const DWORD tile_coord_ = 0x4B1674;
|
||||
const DWORD tile_dir_ = 0x4B1ABC;
|
||||
const DWORD tile_dist_ = 0x4B185C;
|
||||
const DWORD tile_num_ = 0x4B1754;
|
||||
const DWORD tile_num_in_direction_ = 0x4B1A6C;
|
||||
const DWORD tile_refresh_display_ = 0x4B12D8;
|
||||
@@ -927,6 +928,22 @@ long __fastcall GetTopWindowID(long xPos, long yPos) {
|
||||
return win->wID;
|
||||
}
|
||||
|
||||
// Returns an array of objects within the specified radius from the source tile
|
||||
void GetObjectsTileRadius(std::vector<TGameObj*> &objs, long sourceTile, long radius, long elev, long type = -1) {
|
||||
for (long tile = 0; tile < 40000; tile++) {
|
||||
TGameObj* obj = ObjFindFirstAtTile(elev, tile);
|
||||
while (obj) {
|
||||
if (type == -1 || type == obj->pid >> 24) {
|
||||
bool multiHex = (obj->flags & 0x800) ? true : false;
|
||||
if (TileDist(sourceTile, obj->tile) <= (radius + multiHex)) {
|
||||
objs.push_back(obj);
|
||||
}
|
||||
}
|
||||
obj = ObjFindNextAtTile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall RegisterObjectCall(long* target, long* source, void* func, long delay) {
|
||||
__asm {
|
||||
mov eax, ecx;
|
||||
@@ -1330,6 +1347,15 @@ long __fastcall ObjNewSidInst(TGameObj* object, long sType, long scriptIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall TileNum(long x, long y) {
|
||||
__asm {
|
||||
push ebx; // don't delete (bug in tile_num_)
|
||||
mov eax, ecx;
|
||||
call tile_num_;
|
||||
pop ebx;
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall TileNumInDirection(long tile, long rotation, long distance) {
|
||||
__asm {
|
||||
mov ebx, distance;
|
||||
@@ -1338,6 +1364,14 @@ long __fastcall TileNumInDirection(long tile, long rotation, long distance) {
|
||||
}
|
||||
}
|
||||
|
||||
long __stdcall TileDist(long scrTile, long dstTile) {
|
||||
__asm {
|
||||
mov edx, dstTile;
|
||||
mov eax, scrTile;
|
||||
call tile_dist_;
|
||||
}
|
||||
}
|
||||
|
||||
long __stdcall TileDir(long scrTile, long dstTile) {
|
||||
__asm {
|
||||
mov edx, dstTile;
|
||||
|
||||
@@ -917,6 +917,7 @@ extern const DWORD text_font_;
|
||||
extern const DWORD text_object_create_;
|
||||
extern const DWORD tile_coord_; // eax - tilenum, edx (int*) - x, ebx (int*) - y
|
||||
extern const DWORD tile_dir_;
|
||||
extern const DWORD tile_dist_;
|
||||
extern const DWORD tile_num_;
|
||||
extern const DWORD tile_num_in_direction_;
|
||||
extern const DWORD tile_refresh_display_;
|
||||
@@ -1057,6 +1058,8 @@ long GetScriptLocalVars(long sid);
|
||||
|
||||
long __fastcall GetTopWindowID(long xPos, long yPos);
|
||||
|
||||
void GetObjectsTileRadius(std::vector<TGameObj*> &objs, long sourceTile, long radius, long elev, long type);
|
||||
|
||||
void __fastcall RegisterObjectCall(long* target, long* source, void* func, long delay);
|
||||
|
||||
long __fastcall ScrGetLocalVar(long sid, long varId, long* value);
|
||||
@@ -1164,8 +1167,12 @@ TGameObj* __fastcall ObjBlockingAt(TGameObj* object, long tile, long elevation);
|
||||
|
||||
long __fastcall ObjNewSidInst(TGameObj* object, long sType, long scriptIndex);
|
||||
|
||||
long __fastcall TileNum(long x, long y);
|
||||
|
||||
long __fastcall TileNumInDirection(long tile, long rotation, long distance);
|
||||
|
||||
long __stdcall TileDist(long scrTile, long dstTile);
|
||||
|
||||
long __stdcall TileDir(long scrTile, long dstTile);
|
||||
|
||||
// for the backported AmmoCostHook from 4.x
|
||||
|
||||
@@ -433,6 +433,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||
{sf_set_unjam_locks_time, "set_unjam_locks_time", {DATATYPE_MASK_INT}},
|
||||
{sf_set_window_flag, "set_window_flag", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_show_window, "show_window", {DATATYPE_MASK_STR}},
|
||||
{sf_tile_by_position, "tile_by_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}},
|
||||
{sf_unwield_slot, "unwield_slot", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||
#ifndef NDEBUG
|
||||
|
||||
@@ -152,7 +152,8 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"loot_obj", sf_get_loot_object, 0, 0},
|
||||
{"metarule_exist", sf_metarule_exist, 1, 1},
|
||||
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1},
|
||||
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2},
|
||||
{"obj_under_cursor", sf_obj_under_cursor, 2, 2},
|
||||
{"objects_in_radius", sf_objects_in_radius, 3, 4},
|
||||
{"outlined_object", sf_outlined_object, 0, 0},
|
||||
{"real_dude_obj", sf_real_dude_obj, 0, 0},
|
||||
{"remove_timer_event", sf_remove_timer_event, 0, 1},
|
||||
@@ -170,6 +171,7 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"spatial_radius", sf_spatial_radius, 1, 1},
|
||||
{"string_compare", sf_string_compare, 2, 3},
|
||||
{"string_format", sf_string_format, 2, 5},
|
||||
{"tile_by_position", sf_tile_by_position, 2, 2},
|
||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||
{"unjam_lock", sf_unjam_lock, 1, 1},
|
||||
{"unwield_slot", sf_unwield_slot, 2, 2},
|
||||
|
||||
@@ -609,7 +609,7 @@ static void sf_get_dialog_object() {
|
||||
opHandler.setReturn(InDialog() ? *ptr_dialog_target : 0);
|
||||
}
|
||||
|
||||
static void sf_get_obj_under_cursor() {
|
||||
static void sf_obj_under_cursor() {
|
||||
const ScriptValue &crSwitchArg = opHandler.arg(0),
|
||||
&inclDudeArg = opHandler.arg(1);
|
||||
|
||||
@@ -740,3 +740,36 @@ static void sf_set_unique_id() {
|
||||
}
|
||||
opHandler.setReturn(id);
|
||||
}
|
||||
|
||||
void sf_objects_in_radius() {
|
||||
const ScriptValue &tileArg = opHandler.arg(0),
|
||||
&radiusArg = opHandler.arg(1),
|
||||
&elevArg = opHandler.arg(2);
|
||||
|
||||
DWORD id = 0;
|
||||
if (tileArg.isInt() && radiusArg.isInt() && elevArg.isInt()) {
|
||||
long type = -1;
|
||||
if (opHandler.numArgs() > 3) {
|
||||
const ScriptValue &typeArg = opHandler.arg(3);
|
||||
if (!typeArg.isInt()) goto invalidArgs;
|
||||
type = typeArg.rawValue();
|
||||
}
|
||||
long radius = radiusArg.rawValue();
|
||||
if (radius <= 0) radius = 1; else if (radius > 50) radius = 50;
|
||||
long elev = elevArg.rawValue();
|
||||
if (elev < 0) elev = 0; else if (elev > 2) elev = 2;
|
||||
|
||||
std::vector<TGameObj*> objects;
|
||||
objects.reserve(25);
|
||||
GetObjectsTileRadius(objects, tileArg.rawValue(), radius, elev, type);
|
||||
size_t sz = objects.size();
|
||||
id = TempArray(sz, 0);
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
arrays[id].val[i].set((long)objects[i]);
|
||||
}
|
||||
} else {
|
||||
invalidArgs:
|
||||
OpcodeInvalidArgs("get_objects_at_radius");
|
||||
}
|
||||
opHandler.setReturn(id);
|
||||
}
|
||||
|
||||
@@ -223,3 +223,7 @@ static void sf_get_map_enter_position() {
|
||||
arrays[id].val[2].set((long)*ptr_rotation);
|
||||
opHandler.setReturn(id);
|
||||
}
|
||||
|
||||
static void sf_tile_by_position() {
|
||||
opHandler.setReturn(TileNum(opHandler.arg(0).rawValue(), opHandler.arg(1).rawValue()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user