diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index e1c7376b..2d5a4174 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -213,7 +213,7 @@ #define exec_map_update_scripts sfall_func0("exec_map_update_scripts") #define set_outline(obj, color) sfall_func2("set_outline", obj, color) #define get_outline(obj) sfall_func1("get_outline", obj) -#define set_flags(obj, color) sfall_func2("set_flags", obj, color) +#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags) #define get_flags(obj) sfall_func1("get_flags", obj) #define tile_refresh_display sfall_func0("tile_refresh_display") #define outlined_object sfall_func0("outlined_object") diff --git a/sfall/FalloutEngine/Functions_def.h b/sfall/FalloutEngine/Functions_def.h index abecb3e2..8616096e 100644 --- a/sfall/FalloutEngine/Functions_def.h +++ b/sfall/FalloutEngine/Functions_def.h @@ -32,6 +32,7 @@ WRAP_WATCOM_FUNC2(long, db_fwriteByte, DbFile*, file, long, value) WRAP_WATCOM_FUNC2(long, db_fwriteInt, DbFile*, file, long, value) // perform combat turn for a given critter WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn) +WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter) WRAP_WATCOM_FUNC1(long, gmouse_set_cursor, long, picNum) WRAP_WATCOM_FUNC1(Window*, GNW_find, long, winRef) WRAP_WATCOM_FUNC0(long, intface_is_item_right_hand) @@ -45,6 +46,8 @@ WRAP_WATCOM_FUNC2(long, light_get_tile, long, elevation, long, tileNum) WRAP_WATCOM_FUNC2(void, mouse_get_position, long*, outX, long*, outY) WRAP_WATCOM_FUNC0(void, mouse_show) WRAP_WATCOM_FUNC0(void, mouse_hide) +// calculates path and returns it's length +WRAP_WATCOM_FUNC6(long, make_path_func, GameObject*, objectFrom, long, tileFrom, long, tileTo, char*, pathDataBuffer, long, arg5, void*, blockingFunc) // calculates bounding box (rectangle) for a given object WRAP_WATCOM_FUNC2(void, obj_bound, GameObject*, object, BoundRect*, boundRect) WRAP_WATCOM_FUNC3(long, register_object_animate, GameObject*, object, long, anim, long, delay) diff --git a/sfall/Modules/Scripting/Handlers/Objects.cpp b/sfall/Modules/Scripting/Handlers/Objects.cpp index f211cff4..05d1fd6e 100644 --- a/sfall/Modules/Scripting/Handlers/Objects.cpp +++ b/sfall/Modules/Scripting/Handlers/Objects.cpp @@ -217,7 +217,7 @@ static DWORD _stdcall obj_blocking_at_wrapper(DWORD obj, DWORD tile, DWORD eleva } } -static DWORD _stdcall make_straight_path_func_wrapper(DWORD obj, DWORD tileFrom, DWORD a3, DWORD tileTo, DWORD* result, DWORD a6, DWORD func) { +static DWORD _stdcall make_straight_path_func_wrapper(fo::GameObject* obj, DWORD tileFrom, DWORD a3, DWORD tileTo, DWORD* result, DWORD a6, DWORD func) { __asm { mov eax, obj; mov edx, tileFrom; @@ -253,45 +253,28 @@ static DWORD getBlockingFunc(DWORD type) { } void sf_make_straight_path(OpcodeContext& ctx) { - DWORD objFrom = ctx.arg(0).asInt(), - tileTo = ctx.arg(1).asInt(), + auto objFrom = ctx.arg(0).asObject(); + DWORD tileTo = ctx.arg(1).asInt(), type = ctx.arg(2).asInt(), resultObj, arg6; arg6 = (type == BLOCKING_TYPE_SHOOT) ? 32 : 0; - make_straight_path_func_wrapper(objFrom, *(DWORD*)(objFrom + 4), 0, tileTo, &resultObj, arg6, getBlockingFunc(type)); + make_straight_path_func_wrapper(objFrom, objFrom->tile, 0, tileTo, &resultObj, arg6, getBlockingFunc(type)); ctx.setReturn(resultObj, DataType::INT); } void sf_make_path(OpcodeContext& ctx) { - DWORD objFrom = ctx.arg(0).asInt(), - tileFrom = 0, - tileTo = ctx.arg(1).asInt(), - type = ctx.arg(2).asInt(), - func = getBlockingFunc(type), - arr; + auto objFrom = ctx.arg(0).asObject(); + auto tileTo = ctx.arg(1).asInt(), + type = ctx.arg(2).asInt(); + auto func = getBlockingFunc(type); long pathLength, a5 = 1; - if (!objFrom) { - ctx.setReturn(0, DataType::INT); - return; - } - tileFrom = *(DWORD*)(objFrom + 4); char pathData[800]; - char* pathDataPtr = pathData; - __asm { - mov eax, objFrom; - mov edx, tileFrom; - mov ecx, pathDataPtr; - mov ebx, tileTo; - push func; - push a5; - call fo::funcoffs::make_path_func_; - mov pathLength, eax; - } - arr = TempArray(pathLength, 0); + pathLength = fo::func::make_path_func(objFrom, objFrom->tile, tileTo, pathData, a5, (void*)func); + auto arrayId = TempArray(pathLength, 0); for (int i = 0; i < pathLength; i++) { - arrays[arr].val[i].set((long)pathData[i]); + arrays[arrayId].val[i].set((long)pathData[i]); } - ctx.setReturn(arr, DataType::INT); + ctx.setReturn(arrayId, DataType::INT); } void sf_obj_blocking_at(OpcodeContext& ctx) { @@ -309,46 +292,26 @@ void sf_obj_blocking_at(OpcodeContext& ctx) { void sf_tile_get_objects(OpcodeContext& ctx) { DWORD tile = ctx.arg(0).asInt(), - elevation = ctx.arg(1).asInt(), - obj; + elevation = ctx.arg(1).asInt(); DWORD arrayId = TempArray(0, 4); - __asm { - mov eax, elevation; - mov edx, tile; - call fo::funcoffs::obj_find_first_at_tile_; - mov obj, eax; - } + auto obj = fo::func::obj_find_first_at_tile(elevation, tile); while (obj) { - arrays[arrayId].push_back((long)obj); - __asm { - call fo::funcoffs::obj_find_next_at_tile_; - mov obj, eax; - } + arrays[arrayId].push_back(reinterpret_cast(obj)); + obj = fo::func::obj_find_next_at_tile(); } ctx.setReturn(arrayId, DataType::INT); } void sf_get_party_members(OpcodeContext& ctx) { - DWORD obj, mode = ctx.arg(0).asInt(), isDead; - int i, actualCount = fo::var::partyMemberCount; + auto includeHidden = ctx.arg(0).asInt(); + int actualCount = fo::var::partyMemberCount; DWORD arrayId = TempArray(0, 4); - DWORD* partyMemberList = fo::var::partyMemberList; - for (i = 0; i < actualCount; i++) { - obj = partyMemberList[i * 4]; - if (mode == 0) { // mode 0 will act just like op_party_member_count in fallout2 - if ((*(DWORD*)(obj + 100) >> 24) != fo::OBJ_TYPE_CRITTER) // obj type != critter - continue; - __asm { - mov eax, obj; - call fo::funcoffs::critter_is_dead_; - mov isDead, eax; - } - if (isDead) - continue; - if (*(DWORD*)(obj + 36) & 1) // no idea.. - continue; + auto partyMemberList = fo::var::partyMemberList; + for (int i = 0; i < actualCount; i++) { + auto obj = reinterpret_cast(partyMemberList[i * 4]); + if (includeHidden || (obj->type() == fo::OBJ_TYPE_CRITTER && !fo::func::critter_is_dead(obj) && !(obj->flags & fo::ObjectFlag::Mouse_3d))) { + arrays[arrayId].push_back((long)obj); } - arrays[arrayId].push_back((long)obj); } ctx.setReturn(arrayId, DataType::INT); } diff --git a/sfall/Modules/Scripting/Opcodes.cpp b/sfall/Modules/Scripting/Opcodes.cpp index e784083e..4ccf7527 100644 --- a/sfall/Modules/Scripting/Opcodes.cpp +++ b/sfall/Modules/Scripting/Opcodes.cpp @@ -130,14 +130,14 @@ static SfallOpcodeInfo opcodeInfoArray[] = { {0x26b, "message_str_game", sf_message_str_game, 2, true, {ARG_INT, ARG_INT}}, {0x26c, "sneak_success", sf_sneak_success, 0, true}, {0x26d, "tile_light", sf_tile_light, 2, true, {ARG_INT, ARG_INT}}, - {0x26e, "obj_blocking_line", sf_make_straight_path, 3, true}, - {0x26f, "obj_blocking_tile", sf_obj_blocking_at, 3, true}, - {0x270, "tile_get_objs", sf_tile_get_objects, 2, true}, - {0x271, "party_member_list", sf_get_party_members, 1, true}, - {0x272, "path_find_to", sf_make_path, 3, true}, - {0x273, "create_spatial", sf_create_spatial, 4, true}, - {0x274, "art_exists", sf_art_exists, 1, true}, - {0x275, "obj_is_carrying_obj", sf_obj_is_carrying_obj, 2, true}, + {0x26e, "obj_blocking_line", sf_make_straight_path, 3, true, {ARG_OBJECT, ARG_INT, ARG_INT}}, + {0x26f, "obj_blocking_tile", sf_obj_blocking_at, 3, true, {ARG_INT, ARG_INT, ARG_INT}}, + {0x270, "tile_get_objs", sf_tile_get_objects, 2, true, {ARG_INT, ARG_INT}}, + {0x271, "party_member_list", sf_get_party_members, 1, true, {ARG_INT}}, + {0x272, "path_find_to", sf_make_path, 3, true, {ARG_OBJECT, ARG_INT, ARG_INT}}, + {0x273, "create_spatial", sf_create_spatial, 4, true, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}}, + {0x274, "art_exists", sf_art_exists, 1, true, {ARG_INT}}, + {0x275, "obj_is_carrying_obj", sf_obj_is_carrying_obj, 2, true, {ARG_OBJECT, ARG_OBJECT}}, // universal opcodes: {0x276, "sfall_func0", HandleMetarule, 1, true},