mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
154 lines
4.4 KiB
C++
154 lines
4.4 KiB
C++
/*
|
|
* sfall
|
|
* Copyright (C) 2008-2016 The sfall team
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "..\..\..\FalloutEngine\Fallout2.h"
|
|
#include "..\..\Explosions.h"
|
|
#include "..\..\ScriptExtender.h"
|
|
|
|
#include "Anims.h"
|
|
|
|
namespace sfall
|
|
{
|
|
namespace script
|
|
{
|
|
|
|
static char regAnimCombatCheck = 1;
|
|
|
|
void RegAnimCombatCheck(DWORD newValue) {
|
|
char oldValue = regAnimCombatCheck;
|
|
regAnimCombatCheck = (newValue > 0);
|
|
if (oldValue != regAnimCombatCheck) {
|
|
SafeWrite8(0x459C97, regAnimCombatCheck); // reg_anim_func
|
|
SafeWrite8(0x459D4B, regAnimCombatCheck); // reg_anim_animate
|
|
SafeWrite8(0x459E3B, regAnimCombatCheck); // reg_anim_animate_reverse
|
|
SafeWrite8(0x459EEB, regAnimCombatCheck); // reg_anim_obj_move_to_obj
|
|
SafeWrite8(0x459F9F, regAnimCombatCheck); // reg_anim_obj_run_to_obj
|
|
SafeWrite8(0x45A053, regAnimCombatCheck); // reg_anim_obj_move_to_tile
|
|
SafeWrite8(0x45A10B, regAnimCombatCheck); // reg_anim_obj_run_to_tile
|
|
SafeWrite8(0x45AE53, regAnimCombatCheck); // reg_anim_animate_forever
|
|
}
|
|
}
|
|
|
|
// true if combat mode is active and combat check was not disabled
|
|
bool checkCombatMode() {
|
|
return (regAnimCombatCheck & fo::var::combat_state) != 0;
|
|
}
|
|
|
|
void op_reg_anim_combat_check(OpcodeContext& ctx) {
|
|
RegAnimCombatCheck(ctx.arg(0).rawValue());
|
|
}
|
|
|
|
void op_reg_anim_destroy(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
fo::func::register_object_must_erase(obj);
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_animate_and_hide(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
int animId = ctx.arg(1).rawValue(),
|
|
delay = ctx.arg(2).rawValue();
|
|
|
|
fo::func::register_object_animate_and_hide(obj, animId, delay);
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_light(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
int radius = ctx.arg(1).rawValue(),
|
|
delay = ctx.arg(2).rawValue();
|
|
|
|
if (radius < 0) {
|
|
radius = 0;
|
|
} else if (radius > 8) {
|
|
radius = 8;
|
|
}
|
|
fo::func::register_object_light(obj, radius, delay);
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_change_fid(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
int fid = ctx.arg(1).rawValue(),
|
|
delay = ctx.arg(2).rawValue();
|
|
|
|
fo::func::register_object_change_fid(obj, fid, delay);
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_take_out(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
int holdFrame = ctx.arg(1).rawValue(),
|
|
nothing = ctx.arg(2).rawValue(); // not used by engine
|
|
|
|
fo::func::register_object_take_out(obj, holdFrame, nothing);
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_turn_towards(OpcodeContext& ctx) {
|
|
if (!checkCombatMode()) {
|
|
auto obj = ctx.arg(0).object();
|
|
int tile = ctx.arg(1).rawValue(),
|
|
nothing = ctx.arg(2).rawValue();
|
|
|
|
fo::func::register_object_turn_towards(obj, tile, nothing);
|
|
}
|
|
}
|
|
|
|
static void __declspec(naked) ExecuteCallback() {
|
|
__asm {
|
|
call fo::funcoffs::executeProcedure_;
|
|
jmp ScriptExtender::GetResetScriptReturnValue; // return callback result from scr_return script function: -1 - break registered sequence
|
|
}
|
|
}
|
|
|
|
void op_reg_anim_callback(OpcodeContext& ctx) {
|
|
fo::func::register_object_call(
|
|
reinterpret_cast<long*>(ctx.program()),
|
|
reinterpret_cast<long*>(ctx.arg(0).rawValue()), // callback procedure
|
|
reinterpret_cast<void*>(ExecuteCallback),
|
|
-1
|
|
);
|
|
}
|
|
|
|
void op_explosions_metarule(OpcodeContext& ctx) {
|
|
int mode = ctx.arg(0).rawValue(),
|
|
result = ExplosionsMetaruleFunc(mode, ctx.arg(1).rawValue(), ctx.arg(2).rawValue());
|
|
|
|
if (result == -1) {
|
|
ctx.printOpcodeError("%s() - mode (%d) is not supported for the function.", ctx.getOpcodeName(), mode);
|
|
}
|
|
ctx.setReturn(result);
|
|
}
|
|
|
|
void op_art_exists(OpcodeContext& ctx) {
|
|
ctx.setReturn(fo::func::art_exists(ctx.arg(0).rawValue()));
|
|
}
|
|
|
|
void mf_art_cache_flush(OpcodeContext& ctx) {
|
|
__asm call fo::funcoffs::art_flush_;
|
|
}
|
|
|
|
}
|
|
}
|