Fallout 1 Scripting

Ragfox

First time out of the vault
I'm working on the Italian translation of Fallout 1 (I've already published the translations of Fallout 2 and Tactics - Progetto TIFONE) and I've to modify some scripts to get the "feminine version" of some dialogs (e.g. in English "You see a farmer" works for both male and female characters, but in Italian you must use "Vedi un contadino" and "Vedi una contadina").
Decompiling .INT files was not a problem, but compiling them sure is!
After precompilating the file, both p.bat and Jargo's FSE give me errors like "Undefined symbol op_critter_add_trait" and won't create the modded .int file.
And this happens even with original .ssl files (extracted from Fallout 1 master.dat). I think it's linked to lines beginning with op_* commands (?).
I've successfully modified Fallout 2 scripts in the past, but Fallout 1 files must be somehow different and I cannot find dedicated compilers.
Any suggestions?

Here is one of the .ssl files (Pleasant.ssl) - notice the red line:

procedure start;
procedure combat_p_proc;
procedure critter_p_proc;
procedure damage_p_proc;
procedure destroy_p_proc;
procedure look_at_p_proc;
procedure pickup_p_proc;
procedure talk_p_proc;
procedure timed_event_p_proc;
procedure flee_dude;

variable hostile := 0;
variable initialized := 0;
variable round_counter := 0;
variable PsstTime := 0;

procedure start
begin
if (not initialized) then
begin
op_critter_add_trait(op_self_obj(), 1, 6, 2);
op_critter_add_trait(op_self_obj(), 1, 5, 6);
op_add_timer_event(op_self_obj(), op_game_ticks(op_random(15, 60)), 1);
op_add_timer_event(op_self_obj(), op_game_ticks(op_random(3, 5)), 1);
initialized := 1;
end
else if (op_script_action() == 13) then
call combat_p_proc();
else if (op_script_action() == 12) then
call critter_p_proc();
else if (op_script_action() == 18) then
call destroy_p_proc();
else if (op_script_action() == 21) then
call look_at_p_proc();
else if (op_script_action() == 4) then
call pickup_p_proc();
else if (op_script_action() == 11) then
call talk_p_proc();
end

procedure combat_p_proc
begin
if (op_fixed_param() == 4) then
begin
round_counter := round_counter + 1;
if (round_counter > 3) then
begin
if ((op_global_var(246) == 0) and ((op_cur_map_index() == 26) or (op_cur_map_index() == 25))) then
begin
op_set_global_var(246, 1);
op_set_global_var(155, op_global_var(155) - 5);
end
end
end
end

procedure critter_p_proc
begin
variable LVar1 := 0;

if (op_obj_can_see_obj(op_self_obj(), op_dude_obj())) then
begin
if ((op_global_var(246) == 1) and ((op_cur_map_index() == 26) or (op_cur_map_index() == 25))) then
hostile := 1;
end
if (hostile) then
begin
hostile := 0;
op_attack(op_dude_obj(), 0, 1, 0, 0, 30000, 0, 0);
end
else if (op_local_var(0)) then
begin
if (op_tile_distance_objs(op_self_obj(), op_dude_obj()) < 8) then
call flee_dude();
end
LVar1 := op_global_var(343);
if ((((op_game_time() / 10) - LVar1) >= 10) and (op_tile_distance_objs(op_self_obj(), op_dude_obj()) <= 4) and (op_global_var(246) == 0) and ((op_cur_map_index() == 26) or (op_cur_map_index() == 25))) then
begin
op_float_msg(op_self_obj(), op_msg_string(115, op_random(110, 114)), 0);
LVar1 := op_game_time() / 10;
op_set_global_var(343, LVar1);
end
end

procedure damage_p_proc
begin
if (op_source_obj() == op_dude_obj()) then
op_set_local_var(0, 1);
end

procedure destroy_p_proc
begin
if ((op_source_obj() == op_dude_obj()) and ((op_cur_map_index() == 26) or (op_cur_map_index() == 25))) then
op_set_global_var(246, 1);
if (op_source_obj() == op_dude_obj()) then
begin
if (((op_global_var(160) + op_global_var(159)) >= 25) and ((op_global_var(159) > (2 * op_global_var(160))) or (op_global_var(156) == 1))) then
begin
op_set_global_var(156, 1);
op_set_global_var(157, 0);
end
if (((op_global_var(160) + op_global_var(159)) >= 25) and ((op_global_var(160) > (3 * op_global_var(159))) or (op_global_var(157) == 1))) then
begin
op_set_global_var(157, 1);
op_set_global_var(156, 0);
end
op_set_global_var(159, op_global_var(159) + 1);
if ((op_global_var(159) % 2) == 0) then
op_set_global_var(155, op_global_var(155) - 1);
end
end

procedure look_at_p_proc
begin
op_script_overrides();
if (critter_is_male) then
op_display_msg(op_msg_string(9, 100));
else
op_display_msg(op_msg_string(9, 1100));
end

procedure pickup_p_proc
begin
hostile := 1;
end

procedure talk_p_proc
begin
if (op_local_var(0) or op_global_var(246)) then
op_float_msg(op_self_obj(), op_msg_string(669, op_random(100, 105)), 0);
else if (op_global_var(43) == 2) then
op_float_msg(op_self_obj(), op_msg_string(9, op_random(101, 104)), 0);
else
op_float_msg(op_self_obj(), op_msg_string(9, op_random(101, 107)), 0);
end

procedure timed_event_p_proc
begin
if (op_obj_on_screen(op_self_obj())) then
op_animate_move_obj_to_tile(op_self_obj(), op_tile_num_in_direction(op_tile_num(op_self_obj()), op_random(0, 5), op_random(1, 5)), 0);
op_add_timer_event(op_self_obj(), op_game_ticks(op_random(6, 10)), 1);
end

procedure flee_dude
begin
variable LVar1 := 0;
variable LVar2 := 0;
variable LVar3 := 0;

while (LVar2 < 5) do
begin
if (op_tile_distance(op_tile_num(op_dude_obj()), op_tile_num_in_direction(op_tile_num(op_self_obj()), LVar2, 3)) > LVar3) then
begin
LVar1 := op_tile_num_in_direction(op_tile_num(op_self_obj()), LVar2, 3);
LVar3 := op_tile_distance(op_tile_num(op_dude_obj()), LVar1);
end
LVar2 := LVar2 + 1;
end
op_animate_move_obj_to_tile(op_self_obj(), LVar1, 1);
end
 
Problems with compiling this script (and any other decompiled) is that Noid decompiller have a little different syntax than Interply compiler. Download latest FSE version 1.5, in script menu of FSE you find Convert script Noid -> Iply option.
FSE will convert actual script to interplay format (like delete "()" "op_" etc) there are 2 steps:

First is just converting to correct syntax

Second (if you click yes) will convert it to use macros.

If you plan to make heavy changes to script you may use both steps but, second step can sometimes change to much so you need to make some corrections by hand to make it compile(first step is 100% if decompiler goes ok)
 
I've followed your instructions and I got the compilation done... but only sometimes. Many times (and totally at random, it seems) I get errors like "expected 'begin' block" or "Error! ',' expected" (even with the original files).
Moreover, the compiled .int file doesn't seem to work like it should (maybe F1 doesn't accept the "critter_is_male" parameter, but I really don't know).
I'll leave the .int alone and I'll continue to work on .msg files only.

Thank you anyway.
 
Back
Top