1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1999-2000 Revolution Software Ltd.
9 * This code is based on source code created by Revolution Software,
10 * used with permission.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 *
26 */
27
28 #include "engines/icb/common/px_common.h"
29 #include "engines/icb/common/ptr_util.h"
30 #include "engines/icb/icb.h"
31 #include "engines/icb/p4_generic.h"
32 #include "engines/icb/debug.h"
33 #include "engines/icb/mission.h"
34 #include "engines/icb/global_objects.h"
35 #include "engines/icb/global_switches.h"
36 #include "engines/icb/floors.h"
37 #include "engines/icb/fn_routines.h"
38 #include "engines/icb/p4_generic.h"
39 #include "engines/icb/sound.h" // to get PauseSounds()
40 #include "engines/icb/common/px_scriptengine.h"
41 #include "engines/icb/common/px_floor_map.h"
42 #include "engines/icb/common/px_features.h"
43 #include "engines/icb/direct_input.h"
44 #include "engines/icb/actor.h"
45 #include "engines/icb/remora.h"
46
47 #include "common/keyboard.h"
48
49 namespace ICB {
50
fn_set_voxel_image_path(int32 & result,int32 * params)51 mcodeFunctionReturnCodes fn_set_voxel_image_path(int32 &result, int32 *params) { return (g_mission->session->fn_set_voxel_image_path(result, params)); }
52
fn_test(int32 & result,int32 * params)53 mcodeFunctionReturnCodes fn_test(int32 &result, int32 *params) { return (g_mission->session->fn_test(result, params)); }
54
fn_create_mega(int32 & result,int32 * params)55 mcodeFunctionReturnCodes fn_create_mega(int32 &result, int32 *params) { return (g_mission->session->fn_create_mega(result, params)); }
56
fn_set_xyz(int32 & result,int32 * params)57 mcodeFunctionReturnCodes fn_set_xyz(int32 &result, int32 *params) { return (g_mission->session->fn_set_xyz(result, params)); }
58
fn_set_to_floor(int32 & result,int32 * params)59 mcodeFunctionReturnCodes fn_set_to_floor(int32 &result, int32 *params) { return (g_mission->session->fn_set_to_floor(result, params)); }
60
fn_init_from_nico_file(int32 & result,int32 * params)61 mcodeFunctionReturnCodes fn_init_from_nico_file(int32 &result, int32 *params) { return (g_mission->session->fn_init_from_nico_file(result, params)); }
62
fn_init_from_marker_file(int32 & result,int32 * params)63 mcodeFunctionReturnCodes fn_init_from_marker_file(int32 &result, int32 *params) { return (MS->fn_init_from_marker_file(result, params)); }
64
fn_set_player_can_interact(int32 & result,int32 * params)65 mcodeFunctionReturnCodes fn_set_player_can_interact(int32 &result, int32 *params) { return (MS->fn_set_player_can_interact(result, params)); }
66
fn_set_player_cannot_interact(int32 & result,int32 * params)67 mcodeFunctionReturnCodes fn_set_player_cannot_interact(int32 &result, int32 *params) { return (MS->fn_set_player_cannot_interact(result, params)); }
68
fn_call_socket(int32 & result,int32 * params)69 mcodeFunctionReturnCodes fn_call_socket(int32 &result, int32 *params) { return (MS->fn_call_socket(result, params)); }
70
fn_prop_near_a_mega(int32 & result,int32 * params)71 mcodeFunctionReturnCodes fn_prop_near_a_mega(int32 &result, int32 *params) { return (MS->fn_prop_near_a_mega(result, params)); }
72
socket_force_new_logic(int32 & result,int32 * params)73 mcodeFunctionReturnCodes socket_force_new_logic(int32 &result, int32 *params) { return (MS->socket_force_new_logic(result, params)); }
74
fn_reset_player(int32 & result,int32 * params)75 mcodeFunctionReturnCodes fn_reset_player(int32 &result, int32 *params) { return (MS->fn_reset_player(result, params)); }
76
fn_rig_test(int32 & result,int32 * params)77 mcodeFunctionReturnCodes fn_rig_test(int32 &result, int32 *params) { return (MS->fn_rig_test(result, params)); }
78
fn_teleport(int32 & result,int32 * params)79 mcodeFunctionReturnCodes fn_teleport(int32 &result, int32 *params) { return (MS->fn_teleport(result, params)); }
80
fn_teleport_to_nico(int32 & result,int32 * params)81 mcodeFunctionReturnCodes fn_teleport_to_nico(int32 &result, int32 *params) { return (MS->fn_teleport_to_nico(result, params)); }
82
fn_get_pan_from_nico(int32 & result,int32 * params)83 mcodeFunctionReturnCodes fn_get_pan_from_nico(int32 &result, int32 *params) { return (MS->fn_get_pan_from_nico(result, params)); }
84
fn_are_we_on_this_floor(int32 & result,int32 * params)85 mcodeFunctionReturnCodes fn_are_we_on_this_floor(int32 &result, int32 *params) { return (MS->fn_are_we_on_this_floor(result, params)); }
86
fn_is_object_on_our_floor(int32 & result,int32 * params)87 mcodeFunctionReturnCodes fn_is_object_on_our_floor(int32 &result, int32 *params) { return (MS->fn_is_object_on_our_floor(result, params)); }
88
fn_is_object_on_screen(int32 & result,int32 * params)89 mcodeFunctionReturnCodes fn_is_object_on_screen(int32 &result, int32 *params) { return (MS->fn_is_object_on_screen(result, params)); }
90
fn_is_object_dead(int32 & result,int32 * params)91 mcodeFunctionReturnCodes fn_is_object_dead(int32 &result, int32 *params) { return (MS->fn_is_object_dead(result, params)); }
92
fn_set_weapon(int32 & result,int32 * params)93 mcodeFunctionReturnCodes fn_set_weapon(int32 &result, int32 *params) { return (g_mission->session->fn_set_weapon(result, params)); }
94
fn_set_custom(int32 & result,int32 * params)95 mcodeFunctionReturnCodes fn_set_custom(int32 &result, int32 *params) { return (g_mission->session->fn_set_custom(result, params)); }
96
fn_message(int32 & result,int32 * params)97 mcodeFunctionReturnCodes fn_message(int32 &result, int32 *params) { return (g_mission->session->fn_message(result, params)); }
98
fn_message_var(int32 & result,int32 * params)99 mcodeFunctionReturnCodes fn_message_var(int32 &result, int32 *params) { return (g_mission->session->fn_message_var(result, params)); }
100
fn_get_state_flag(int32 & result,int32 * params)101 mcodeFunctionReturnCodes fn_get_state_flag(int32 &result, int32 *params) { return (g_mission->session->fn_get_state_flag(result, params)); }
102
fn_near(int32 & result,int32 * params)103 mcodeFunctionReturnCodes fn_near(int32 &result, int32 *params) { return (g_mission->session->fn_near(result, params)); }
104
fn_teleport_z(int32 & result,int32 * params)105 mcodeFunctionReturnCodes fn_teleport_z(int32 &result, int32 *params) { return (MS->fn_teleport_z(result, params)); }
106
fn_on_screen(int32 & result,int32 * params)107 mcodeFunctionReturnCodes fn_on_screen(int32 &result, int32 *params) { return (MS->fn_on_screen(result, params)); }
108
fn_hold_if_off_screen(int32 & result,int32 * params)109 mcodeFunctionReturnCodes fn_hold_if_off_screen(int32 &result, int32 *params) { return (MS->fn_hold_if_off_screen(result, params)); }
110
fn_object_near_nico(int32 & result,int32 * params)111 mcodeFunctionReturnCodes fn_object_near_nico(int32 &result, int32 *params) { return (MS->fn_object_near_nico(result, params)); }
112
fn_teleport_y_to_id(int32 & result,int32 * params)113 mcodeFunctionReturnCodes fn_teleport_y_to_id(int32 &result, int32 *params) { return (MS->fn_teleport_y_to_id(result, params)); }
114
fn_call_socket_id(int32 & result,int32 * params)115 mcodeFunctionReturnCodes fn_call_socket_id(int32 &result, int32 *params) { return (MS->fn_call_socket_id(result, params)); }
116
fn_lift_process_list(int32 & result,int32 * params)117 mcodeFunctionReturnCodes fn_lift_process_list(int32 &result, int32 *params) { return (MS->fn_lift_process_list(result, params)); }
118
fn_add_object_id_to_list(int32 & result,int32 * params)119 mcodeFunctionReturnCodes fn_add_object_id_to_list(int32 &result, int32 *params) { return (MS->fn_add_object_id_to_list(result, params)); }
120
fn_add_object_name_to_list(int32 & result,int32 * params)121 mcodeFunctionReturnCodes fn_add_object_name_to_list(int32 &result, int32 *params) { return (MS->fn_add_object_name_to_list(result, params)); }
122
fn_hold_while_list_near_nico(int32 & result,int32 * params)123 mcodeFunctionReturnCodes fn_hold_while_list_near_nico(int32 &result, int32 *params) { return (MS->fn_hold_while_list_near_nico(result, params)); }
124
fn_set_watch(int32 & result,int32 * params)125 mcodeFunctionReturnCodes fn_set_watch(int32 &result, int32 *params) { return (MS->fn_set_watch(result, params)); }
126
fn_three_sixty_interact(int32 & result,int32 * params)127 mcodeFunctionReturnCodes fn_three_sixty_interact(int32 &result, int32 *params) { return (MS->fn_three_sixty_interact(result, params)); }
128
fn_near_list(int32 & result,int32 * params)129 mcodeFunctionReturnCodes fn_near_list(int32 &result, int32 *params) { return (MS->fn_near_list(result, params)); }
130
fn_get_list_result(int32 & result,int32 * params)131 mcodeFunctionReturnCodes fn_get_list_result(int32 &result, int32 *params) { return (MS->fn_get_list_result(result, params)); }
132
fn_random(int32 & result,int32 * params)133 mcodeFunctionReturnCodes fn_random(int32 &result, int32 *params) { return (MS->fn_random(result, params)); }
134
fn_change_session(int32 & result,int32 * params)135 mcodeFunctionReturnCodes fn_change_session(int32 &result, int32 *params) { return (MS->fn_change_session(result, params)); }
136
fn_changed_sessions(int32 & result,int32 * params)137 mcodeFunctionReturnCodes fn_changed_sessions(int32 &result, int32 *params) { return (MS->fn_changed_sessions(result, params)); }
138
fn_is_object_adjacent(int32 & result,int32 * params)139 mcodeFunctionReturnCodes fn_is_object_adjacent(int32 &result, int32 *params) { return (MS->fn_is_object_adjacent(result, params)); }
140
fn_is_object_on_this_floor(int32 & result,int32 * params)141 mcodeFunctionReturnCodes fn_is_object_on_this_floor(int32 &result, int32 *params) { return (MS->fn_is_object_on_this_floor(result, params)); }
142
fn_get_objects_lvar_value(int32 & result,int32 * params)143 mcodeFunctionReturnCodes fn_get_objects_lvar_value(int32 &result, int32 *params) { return (MS->fn_get_objects_lvar_value(result, params)); }
144
fn_set_objects_lvar_value(int32 & result,int32 * params)145 mcodeFunctionReturnCodes fn_set_objects_lvar_value(int32 &result, int32 *params) { return (MS->fn_set_objects_lvar_value(result, params)); }
146
fn_switch_on_the_really_neat_and_special_script_debugging_facility(int32 & result,int32 * params)147 mcodeFunctionReturnCodes fn_switch_on_the_really_neat_and_special_script_debugging_facility(int32 &result, int32 *params) {
148 return (MS->fn_switch_on_the_really_neat_and_special_script_debugging_facility(result, params));
149 }
150
fn_switch_off_the_really_neat_and_special_script_debugging_facility(int32 & result,int32 * params)151 mcodeFunctionReturnCodes fn_switch_off_the_really_neat_and_special_script_debugging_facility(int32 &result, int32 *params) {
152 return (MS->fn_switch_off_the_really_neat_and_special_script_debugging_facility(result, params));
153 }
154
fn_no_logic(int32 & result,int32 * params)155 mcodeFunctionReturnCodes fn_no_logic(int32 &result, int32 *params) { return (MS->fn_no_logic(result, params)); }
156
fn_lift2_process(int32 & result,int32 * params)157 mcodeFunctionReturnCodes fn_lift2_process(int32 &result, int32 *params) { return (MS->fn_lift2_process(result, params)); }
158
fn_preload_custom_mega_anim(int32 & result,int32 * params)159 mcodeFunctionReturnCodes fn_preload_custom_mega_anim(int32 &result, int32 *params) { return (MS->fn_preload_custom_mega_anim(result, params)); }
160
fn_init_mega_from_nico(int32 & result,int32 * params)161 mcodeFunctionReturnCodes fn_init_mega_from_nico(int32 &result, int32 *params) { return (MS->fn_init_mega_from_nico(result, params)); }
162
fn_mega_use_lift(int32 & result,int32 * params)163 mcodeFunctionReturnCodes fn_mega_use_lift(int32 &result, int32 *params) { return (MS->fn_mega_use_lift(result, params)); }
164
fn_snap_to_nico_y(int32 & result,int32 * params)165 mcodeFunctionReturnCodes fn_snap_to_nico_y(int32 &result, int32 *params) { return (MS->fn_snap_to_nico_y(result, params)); }
166
fn_lib_lift_chord_and_chi(int32 & result,int32 * params)167 mcodeFunctionReturnCodes fn_lib_lift_chord_and_chi(int32 &result, int32 *params) { return (MS->fn_lib_lift_chord_and_chi(result, params)); }
168
fn_set_interacting(int32 & result,int32 * params)169 mcodeFunctionReturnCodes fn_set_interacting(int32 &result, int32 *params) { return (MS->fn_set_interacting(result, params)); }
170
fn_clear_interacting(int32 & result,int32 * params)171 mcodeFunctionReturnCodes fn_clear_interacting(int32 &result, int32 *params) { return (MS->fn_clear_interacting(result, params)); }
172
fn_check_for_nico(int32 & result,int32 * params)173 mcodeFunctionReturnCodes fn_check_for_nico(int32 &result, int32 *params) { return (MS->fn_check_for_nico(result, params)); }
174
fn_set_ids_lvar_value(int32 & result,int32 * params)175 mcodeFunctionReturnCodes fn_set_ids_lvar_value(int32 &result, int32 *params) { return (MS->fn_set_ids_lvar_value(result, params)); }
176
fn_teleport_to_nico_y(int32 & result,int32 * params)177 mcodeFunctionReturnCodes fn_teleport_to_nico_y(int32 &result, int32 *params) { return (MS->fn_teleport_to_nico_y(result, params)); }
178
fn_set_evil(int32 & result,int32 * params)179 mcodeFunctionReturnCodes fn_set_evil(int32 &result, int32 *params) { return (MS->fn_set_evil(result, params)); }
180
fn_changed_via_this_shaft(int32 & result,int32 * params)181 mcodeFunctionReturnCodes fn_changed_via_this_shaft(int32 &result, int32 *params) { return (MS->fn_changed_via_this_shaft(result, params)); }
182
fn_get_objects_x(int32 & result,int32 * params)183 mcodeFunctionReturnCodes fn_get_objects_x(int32 &result, int32 *params) { return (MS->fn_get_objects_x(result, params)); }
184
fn_get_objects_y(int32 & result,int32 * params)185 mcodeFunctionReturnCodes fn_get_objects_y(int32 &result, int32 *params) { return (MS->fn_get_objects_y(result, params)); }
186
fn_get_objects_z(int32 & result,int32 * params)187 mcodeFunctionReturnCodes fn_get_objects_z(int32 &result, int32 *params) { return (MS->fn_get_objects_z(result, params)); }
188
fn_are_we_on_screen(int32 & result,int32 * params)189 mcodeFunctionReturnCodes fn_are_we_on_screen(int32 &result, int32 *params) { return (MS->fn_are_we_on_screen(result, params)); }
190
fn_is_mega_within_area(int32 & result,int32 * params)191 mcodeFunctionReturnCodes fn_is_mega_within_area(int32 &result, int32 *params) { return (MS->fn_is_mega_within_area(result, params)); }
192
fn_end_mission(int32 & result,int32 * params)193 mcodeFunctionReturnCodes fn_end_mission(int32 &result, int32 *params) { return (MS->fn_end_mission(result, params)); }
194
fn_set_pose(int32 & result,int32 * params)195 mcodeFunctionReturnCodes fn_set_pose(int32 &result, int32 *params) { return (MS->fn_set_pose(result, params)); }
196
fn_is_crouching(int32 & result,int32 * params)197 mcodeFunctionReturnCodes fn_is_crouching(int32 &result, int32 *params) { return (MS->fn_is_crouching(result, params)); }
198
fn_is_armed(int32 & result,int32 * params)199 mcodeFunctionReturnCodes fn_is_armed(int32 &result, int32 *params) { return (MS->fn_is_armed(result, params)); }
200
fn_am_i_player(int32 & result,int32 * params)201 mcodeFunctionReturnCodes fn_am_i_player(int32 &result, int32 *params) { return (MS->fn_am_i_player(result, params)); }
202
fn_start_conveyor(int32 & result,int32 * params)203 mcodeFunctionReturnCodes fn_start_conveyor(int32 &result, int32 *params) { return (MS->fn_start_conveyor(result, params)); }
204
fn_stop_conveyor(int32 & result,int32 * params)205 mcodeFunctionReturnCodes fn_stop_conveyor(int32 &result, int32 *params) { return (MS->fn_stop_conveyor(result, params)); }
206
fn_register_stairway(int32 & result,int32 * params)207 mcodeFunctionReturnCodes fn_register_stairway(int32 &result, int32 *params) { return (MS->fn_register_stairway(result, params)); }
208
fn_set_object_type(int32 & result,int32 * params)209 mcodeFunctionReturnCodes fn_set_object_type(int32 &result, int32 *params) { return (MS->fn_set_object_type(result, params)); }
210
fn_register_ladder(int32 & result,int32 * params)211 mcodeFunctionReturnCodes fn_register_ladder(int32 &result, int32 *params) { return (MS->fn_register_ladder(result, params)); }
212
fn_is_an_object_crouching(int32 & result,int32 * params)213 mcodeFunctionReturnCodes fn_is_an_object_crouching(int32 &result, int32 *params) { return (MS->fn_is_an_object_crouching(result, params)); }
214
fn_align_with_floor(int32 & result,int32 * params)215 mcodeFunctionReturnCodes fn_align_with_floor(int32 &result, int32 *params) { return (MS->fn_align_with_floor(result, params)); }
216
fn_load_players_gun(int32 & result,int32 * params)217 mcodeFunctionReturnCodes fn_load_players_gun(int32 &result, int32 *params) { return (MS->fn_load_players_gun(result, params)); }
218
fn_flash_health(int32 & result,int32 * params)219 mcodeFunctionReturnCodes fn_flash_health(int32 &result, int32 *params) { return (MS->fn_flash_health(result, params)); }
220
fn_set_player_pose(int32 & result,int32 * params)221 mcodeFunctionReturnCodes fn_set_player_pose(int32 &result, int32 *params) { return (MS->fn_set_player_pose(result, params)); }
222
fn_set_anim_speed(int32 & result,int32 * params)223 mcodeFunctionReturnCodes fn_set_anim_speed(int32 &result, int32 *params) { return (MS->fn_set_anim_speed(result, params)); }
224
fn_push_coords(int32 & result,int32 * params)225 mcodeFunctionReturnCodes fn_push_coords(int32 &result, int32 *params) { return (MS->fn_push_coords(result, params)); }
226
fn_pop_coords(int32 & result,int32 * params)227 mcodeFunctionReturnCodes fn_pop_coords(int32 &result, int32 *params) { return (MS->fn_pop_coords(result, params)); }
228
fn_set_texture(int32 & result,int32 * params)229 mcodeFunctionReturnCodes fn_set_texture(int32 &result, int32 *params) { return (MS->fn_set_texture(result, params)); }
230
fn_set_palette(int32 & result,int32 * params)231 mcodeFunctionReturnCodes fn_set_palette(int32 &result, int32 *params) { return (MS->fn_set_palette(result, params)); }
232
fn_restart_gamescript(int32 & result,int32 * params)233 mcodeFunctionReturnCodes fn_restart_gamescript(int32 &result, int32 *params) { return (MS->fn_restart_gamescript(result, params)); }
234
fn_quick_restart(int32 & result,int32 * params)235 mcodeFunctionReturnCodes fn_quick_restart(int32 &result, int32 *params) { return (MS->fn_quick_restart(result, params)); }
236
fn_is_mega_near_mega(int32 & result,int32 * params)237 mcodeFunctionReturnCodes fn_is_mega_near_mega(int32 &result, int32 *params) { return (MS->fn_is_mega_near_mega(result, params)); }
238
fn_make_remora_beep(int32 & result,int32 * params)239 mcodeFunctionReturnCodes fn_make_remora_beep(int32 &result, int32 *params) { return (MS->fn_make_remora_beep(result, params)); }
240
fn_shadows_on(int32 & result,int32 * params)241 mcodeFunctionReturnCodes fn_shadows_on(int32 &result, int32 *params) { return (MS->fn_shadows_on(result, params)); }
242
fn_shadows_off(int32 & result,int32 * params)243 mcodeFunctionReturnCodes fn_shadows_off(int32 &result, int32 *params) { return (MS->fn_shadows_off(result, params)); }
244
fn_panless_teleport_to_nico(int32 & result,int32 * params)245 mcodeFunctionReturnCodes fn_panless_teleport_to_nico(int32 &result, int32 *params) { return (MS->fn_panless_teleport_to_nico(result, params)); }
246
fn_can_mega_see_dead_megas(int32 & result,int32 * params)247 mcodeFunctionReturnCodes fn_can_mega_see_dead_megas(int32 &result, int32 *params) { return (MS->fn_can_mega_see_dead_megas(result, params)); }
248
fn_set_shade_percentage(int32 & result,int32 * params)249 mcodeFunctionReturnCodes fn_set_shade_percentage(int32 &result, int32 *params) { return (MS->fn_set_shade_percentage(result, params)); }
250
fn_do_not_disturb(int32 & result,int32 * params)251 mcodeFunctionReturnCodes fn_do_not_disturb(int32 &result, int32 *params) { return (MS->fn_do_not_disturb(result, params)); }
252
fn_has_mega_our_height(int32 & result,int32 * params)253 mcodeFunctionReturnCodes fn_has_mega_our_height(int32 &result, int32 *params) { return (MS->fn_has_mega_our_height(result, params)); }
254
fn_register_platform_coords(int32 & result,int32 * params)255 mcodeFunctionReturnCodes fn_register_platform_coords(int32 &result, int32 *params) { return (MS->fn_register_platform_coords(result, params)); }
256
fn_activate_stair_or_ladder(int32 & result,int32 * params)257 mcodeFunctionReturnCodes fn_activate_stair_or_ladder(int32 &result, int32 *params) { return (MS->fn_activate_stair_or_ladder(result, params)); }
258
fn_deactivate_stair_or_ladder(int32 & result,int32 * params)259 mcodeFunctionReturnCodes fn_deactivate_stair_or_ladder(int32 &result, int32 *params) { return (MS->fn_deactivate_stair_or_ladder(result, params)); }
260
fn_set_half_character_width(int32 & result,int32 * params)261 mcodeFunctionReturnCodes fn_set_half_character_width(int32 &result, int32 *params) { return (MS->fn_set_half_character_width(result, params)); }
262
fn_set_interact_look_height(int32 & result,int32 * params)263 mcodeFunctionReturnCodes fn_set_interact_look_height(int32 &result, int32 *params) { return (MS->fn_set_interact_look_height(result, params)); }
264
fn_set_visible(int32 & result,int32 * params)265 mcodeFunctionReturnCodes fn_set_visible(int32 &result, int32 *params) { return (MS->fn_set_visible(result, params)); }
266
fn_set_object_visible(int32 & result,int32 * params)267 mcodeFunctionReturnCodes fn_set_object_visible(int32 &result, int32 *params) { return (MS->fn_set_object_visible(result, params)); }
268
fn_set_to_dead(int32 & result,int32 * params)269 mcodeFunctionReturnCodes fn_set_to_dead(int32 &result, int32 *params) { return (MS->fn_set_to_dead(result, params)); }
270
fn_set_camera_hold(int32 & result,int32 * params)271 mcodeFunctionReturnCodes fn_set_camera_hold(int32 &result, int32 *params) { return (MS->fn_set_camera_hold(result, params)); }
272
fn_set_mega_wait_for_player(int32 & result,int32 * params)273 mcodeFunctionReturnCodes fn_set_mega_wait_for_player(int32 &result, int32 *params) { return (MS->fn_set_mega_wait_for_player(result, params)); }
274
fn_set_mega_off_camera_hold(int32 & result,int32 * params)275 mcodeFunctionReturnCodes fn_set_mega_off_camera_hold(int32 &result, int32 *params) { return (MS->fn_set_mega_off_camera_hold(result, params)); }
276
fn_set_mega_slice_hold(int32 & result,int32 * params)277 mcodeFunctionReturnCodes fn_set_mega_slice_hold(int32 &result, int32 *params) { return (MS->fn_set_mega_slice_hold(result, params)); }
278
fn_set_mesh(int32 & result,int32 * params)279 mcodeFunctionReturnCodes fn_set_mesh(int32 &result, int32 *params) { return (MS->fn_set_mesh(result, params)); }
280
fn_prop_crouch_interact(int32 & result,int32 * params)281 mcodeFunctionReturnCodes fn_prop_crouch_interact(int32 &result, int32 *params) { return (MS->fn_prop_crouch_interact(result, params)); }
282
fn_set_sleep(int32 & result,int32 * params)283 mcodeFunctionReturnCodes fn_set_sleep(int32 &result, int32 *params) { return (MS->fn_set_sleep(result, params)); }
284
fn_wait_for_button(int32 & result,int32 * params)285 mcodeFunctionReturnCodes fn_wait_for_button(int32 &result, int32 *params) { return (MS->fn_wait_for_button(result, params)); }
286
fn_trace(int32 & result,int32 * params)287 mcodeFunctionReturnCodes fn_trace(int32 &result, int32 *params) { return (MS->fn_trace(result, params)); }
288
fn_lock_y(int32 & result,int32 * params)289 mcodeFunctionReturnCodes fn_lock_y(int32 &result, int32 *params) { return (MS->fn_lock_y(result, params)); }
290
fn_unlock_y(int32 & result,int32 * params)291 mcodeFunctionReturnCodes fn_unlock_y(int32 &result, int32 *params) { return (MS->fn_unlock_y(result, params)); }
292
fn_flip_pan(int32 & result,int32 * params)293 mcodeFunctionReturnCodes fn_flip_pan(int32 &result, int32 *params) { return (MS->fn_flip_pan(result, params)); }
294
fn_snap_to_ladder_bottom(int32 & result,int32 * params)295 mcodeFunctionReturnCodes fn_snap_to_ladder_bottom(int32 &result, int32 *params) { return (MS->fn_snap_to_ladder_bottom(result, params)); }
296
fn_snap_to_ladder_top(int32 & result,int32 * params)297 mcodeFunctionReturnCodes fn_snap_to_ladder_top(int32 &result, int32 *params) { return (MS->fn_snap_to_ladder_top(result, params)); }
298
fn_PLEASE_REUSE_THIS_SLOT_2(int32 &,int32 *)299 mcodeFunctionReturnCodes fn_PLEASE_REUSE_THIS_SLOT_2(int32 &, int32 *) { return IR_CONT; }
300
fn_PLEASE_REUSE_THIS_SLOT_3(int32 &,int32 *)301 mcodeFunctionReturnCodes fn_PLEASE_REUSE_THIS_SLOT_3(int32 &, int32 *) { return IR_CONT; }
302
fn_swordfight(int32 & result,int32 * params)303 mcodeFunctionReturnCodes fn_swordfight(int32 &result, int32 *params) { return (MS->fn_swordfight(result, params)); }
304
fn_swordfight(int32 &,int32 *)305 mcodeFunctionReturnCodes _game_session::fn_swordfight(int32 &, int32 *) { return (IR_CONT); }
306
fn_set_as_player(int32 & result,int32 * params)307 mcodeFunctionReturnCodes fn_set_as_player(int32 &result, int32 *params) { return (MS->fn_set_as_player(result, params)); }
308
fn_set_as_player(int32 &,int32 *)309 mcodeFunctionReturnCodes _game_session::fn_set_as_player(int32 &, int32 *) { return (IR_CONT); }
310
fn_rig_test(int32 &,int32 *)311 mcodeFunctionReturnCodes _game_session::fn_rig_test(int32 &, int32 *) {
312 // no params
313
314 if (!MS->prev_save_state)
315 return IR_REPEAT;
316
317 return IR_CONT;
318 }
319
fn_test(int32 &,int32 *)320 mcodeFunctionReturnCodes _game_session::fn_test(int32 & /*result*/, int32 * /*params*/) {
321 #if 0
322 char buf[256];
323
324 sprintf(buf, "z_%s.txt", object->GetName());
325
326 if (params[0] < 256)
327 Tdebug(buf, "%d", params[0]);
328 else
329 Tdebug(buf, "%s", params[0]);
330
331 result = TRUE8;
332 #endif
333 return IR_CONT;
334 }
335
fn_create_mega(int32 &,int32 *)336 mcodeFunctionReturnCodes _game_session::fn_create_mega(int32 &, int32 *) {
337 Zdebug("FN_create_mega");
338
339 // assign _mega object
340 logic_structs[cur_id]->mega = g_megas[num_megas];
341
342 logic_structs[cur_id]->mega->___init();
343
344 // set the view state to off camera for this cycle and last cycle
345 logic_structs[cur_id]->mega->viewState = OFF_OFF_CAMERA;
346
347 num_megas++;
348
349 if (num_megas == MAX_voxel_list)
350 Fatal_error("fn_create_mega - too many megas!");
351
352 return IR_CONT;
353 }
354
socket_force_new_logic(int32 &,int32 * params)355 mcodeFunctionReturnCodes _game_session::socket_force_new_logic(int32 &, int32 *params) {
356 // force in a new logic script mega who owns the socket script
357 // IGNORES if already running
358
359 // params [0] extension part of script name
360
361 char *ad;
362 uint32 script_hash;
363 const char *script_name = (const char *)MemoryUtil::resolvePtr(params[0]);
364
365 script_hash = HashString(script_name);
366
367 if (g_px->socket_watch)
368 Message_box("socket_force_new_logic - obj %s, script %s", socket_object->GetName(), script_name);
369
370 // now try and find a script with the passed extention i.e. ???::looping
371 for (uint32 k = 0; k < socket_object->GetNoScripts(); k++) {
372 // now check for actual script name
373 if (script_hash == socket_object->GetScriptNamePartHash(k)) {
374 Zdebug("script %d matches", k);
375 // script k is the one to run
376 // get the address of the script we want to run
377 ad = (char *)scripts->Try_fetch_item_by_hash(socket_object->GetScriptNameFullHash(k));
378
379 if (g_px->socket_watch)
380 Message_box("replacing logic");
381
382 // write actual offset
383 logic_structs[socket_id]->logic[1] = ad;
384
385 // write reference for change script checks later - i.e. FN_context_chosen_script
386 logic_structs[socket_id]->logic_ref[1] = ad;
387
388 logic_structs[socket_id]->logic_level = 1; // reset to level 1
389
390 logic_structs[socket_id]->looping = 0; // reset logic
391
392 // if a mega then cancel interacting
393 if (logic_structs[socket_id]->image_type == VOXEL)
394 logic_structs[socket_id]->mega->interacting = 0;
395
396 logic_structs[socket_id]->do_not_disturb = 3; // object will not be caught by events this cycle - events pending will be cleared
397 return (IR_CONT);
398 }
399 }
400
401 // didnt find the script in the target
402 // shut that object down as its full of holes!
403
404 Fatal_error("socket_force_new_logic cant find script - obj %s, script %s", socket_object->GetName(), script_name);
405
406 return (IR_TERMINATE);
407 }
408
409 const char *default_palette = "default";
410 const char *default_texture = "material";
411 const char *default_mesh = "mesh";
412
fn_set_voxel_image_path(int32 &,int32 * params)413 mcodeFunctionReturnCodes _game_session::fn_set_voxel_image_path(int32 &, int32 *params) {
414 // set image_type to VOXEL and create the _vox_image object which inits all the animation set filenames and caps
415 // we are passed the character name AND the graphic set
416 // for example, cord, wetsuit
417
418 // **this routine inits an object as a voxel object**
419 // **more precisely, a mega character\actor with either voxel or polygon image to be sent to stage_draw**
420
421 // enforce this convention
422 if (!logic_structs[cur_id]->mega)
423 Fatal_error("fn_set_voxel_image_path %s is not a mega", object->GetName());
424
425 const char *param0Str = (const char *)MemoryUtil::resolvePtr(params[0]);
426 const char *param1Str = (const char *)MemoryUtil::resolvePtr(params[1]);
427
428 // set 'cord'
429 Set_string(const_cast<char *>(param0Str), logic_structs[cur_id]->mega->chr_name, MAX_CHAR_NAME_LENGTH);
430
431 // set 'casual_wear'
432 Set_string(const_cast<char *>(param1Str), logic_structs[cur_id]->mega->anim_set, MAX_OUTFIT_NAME_LENGTH);
433
434 // create _vox_image object
435 if (!logic_structs[cur_id]->voxel_info) {
436 // assign a struct
437 logic_structs[cur_id]->voxel_info = g_vox_images[num_vox_images];
438 num_vox_images++;
439 }
440
441 logic_structs[cur_id]->voxel_info->___init(param0Str, param1Str, logic_structs[cur_id]->mega->Fetch_pose());
442
443 // Set the default texture & palette
444 logic_structs[cur_id]->voxel_info->Set_palette(default_palette);
445 logic_structs[cur_id]->voxel_info->Set_texture(default_texture);
446 logic_structs[cur_id]->voxel_info->Set_mesh(default_mesh);
447
448 // set type while here
449 logic_structs[cur_id]->image_type = VOXEL;
450
451 // script continues
452 return IR_CONT;
453 }
454
fn_set_xyz(int32 &,int32 *)455 mcodeFunctionReturnCodes _game_session::fn_set_xyz(int32 &, int32 *) {
456 // set a game objects x,y,z worldspace coords
457
458 Fatal_error("[%s] fn_set_xyz - not supported", object->GetName());
459
460 return IR_CONT;
461 }
462
fn_set_pan(int32 & result,int32 * params)463 mcodeFunctionReturnCodes fn_set_pan(int32 &result, int32 *params) {
464 // set a game objects pan value
465 return (g_mission->session->fn_set_pan(result, params));
466 }
467
fn_set_pan(int32 &,int32 *)468 mcodeFunctionReturnCodes _game_session::fn_set_pan(int32 &, int32 *) {
469 // params[0] pan value
470
471 Fatal_error("fn_set_pan - not supported");
472 return IR_CONT;
473 }
474
fn_init_from_nico_file(int32 &,int32 *)475 mcodeFunctionReturnCodes _game_session::fn_init_from_nico_file(int32 &, int32 * /*params*/) {
476 // **this is for props - non mega actors**
477 // set the object position and pan
478 // if the object does not have a corresponding entry in the positions file then we may ULTIMATELY shut the game object down
479 // ** we may need to make this a status option via linc **
480
481 // no params
482
483 _feature_info *start_pos;
484
485 Zdebug("fn_init_from_nico_file - %s (cur_id %d)", object->GetName(), cur_id);
486
487 if (L->image_type == VOXEL)
488 Fatal_error("fn_init_from_nico_file called by a mega! [%s] - use fn_init_mega_from_nico", object->GetName());
489
490 // fetch tag file for this item
491 start_pos = (_feature_info *)features->Try_fetch_item_by_name(object->GetName());
492
493 if (!start_pos) {
494 Message_box("fn_init_from_nico_file - missing nico for item %s", object->GetName());
495 Shut_down_object("fn_init_from_nico_file - missing nico for item");
496 return IR_STOP;
497 }
498
499 // set coordinates
500 logic_structs[cur_id]->prop_xyz.x = start_pos->x;
501
502 if (start_pos->y < start_pos->floor_y) // nico is under the floor!
503 logic_structs[cur_id]->prop_xyz.y = start_pos->floor_y;
504
505 else
506 logic_structs[cur_id]->prop_xyz.y = start_pos->y;
507
508 logic_structs[cur_id]->prop_xyz.z = start_pos->z;
509
510 // set pan
511 logic_structs[cur_id]->pan = start_pos->direction; // is this right?
512
513 logic_structs[cur_id]->prop_interact_pan = start_pos->direction; // this might be more sensible
514
515 // set owner floor for things lile fn_on_screen
516 logic_structs[cur_id]->owner_floor_rect = floor_def->Return_floor_rect(start_pos->x, start_pos->z, start_pos->floor_y, 0);
517
518 if (logic_structs[cur_id]->owner_floor_rect == PXNULL) {
519 Message_box("fn_init_from_nico_file - %s nico not on a legal floor position - object has been shutdown", object->GetName());
520 Shut_down_object("fn_init_from_nico_file");
521 return IR_STOP;
522 }
523
524 // prop has coords
525 logic_structs[cur_id]->prop_coords_set = TRUE8;
526
527 return IR_CONT;
528 }
529
fn_check_for_nico(int32 & result,int32 *)530 mcodeFunctionReturnCodes _game_session::fn_check_for_nico(int32 &result, int32 *) {
531 // check to see if there is a nico in this objects name
532
533 _feature_info *start_pos;
534
535 start_pos = (_feature_info *)features->Try_fetch_item_by_name(object->GetName());
536
537 if (!start_pos)
538 result = FALSE8;
539 else
540 result = TRUE8;
541
542 return IR_CONT;
543 }
544
fn_init_from_marker_file(int32 &,int32 *)545 mcodeFunctionReturnCodes _game_session::fn_init_from_marker_file(int32 &, int32 *) {
546 // set the object position and pan from an engine created map-marker file
547
548 // if the object does not have a corresponding entry in the positions file then we may ULTIMATELY shut the game object down
549 // ** we may need to make this a status option via linc **
550
551 // no params
552
553 _map_marker *start_pos;
554
555 Zdebug("fn_init_from_marker_file - %s (cur_id %d)", object->GetName(), cur_id);
556
557 // if this object does not have a voxel_info struct then we're done here!
558 if (!logic_structs[cur_id]->voxel_info)
559 Fatal_error("FN_INIT_FROM_MARKER_FILE fails because object is not registered as a mega.");
560
561 // fetch tag file for this item
562 start_pos = (_map_marker *)markers.Fetch_marker_by_object_name(const_cast<char *>(object->GetName()));
563
564 if (!start_pos) {
565 Message_box("fn_init_from_marker_file missing map marker file entry for item %s. You must edit the markers - dont play the game.", object->GetName());
566 Shut_down_object("fn_init_from_marker_file");
567 return IR_STOP;
568 }
569
570 logic_structs[cur_id]->mega->actor_xyz.x = start_pos->x;
571 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->y;
572 logic_structs[cur_id]->mega->actor_xyz.z = start_pos->z;
573
574 // set pan
575 logic_structs[cur_id]->pan = start_pos->pan;
576
577 // has coords
578 logic_structs[cur_id]->prop_coords_set = TRUE8;
579
580 return IR_CONT;
581 }
582
fn_init_mega_from_nico(int32 &,int32 *)583 mcodeFunctionReturnCodes _game_session::fn_init_mega_from_nico(int32 &, int32 *) {
584 // set the object position and pan from a MAX NICO marker
585
586 // no params
587
588 _feature_info *start_pos;
589
590 Zdebug("fn_init_mega_from_nico - %s (cur_id %d)", object->GetName(), cur_id);
591
592 // if this object does not have a voxel_info struct then we're done here!
593 if (!logic_structs[cur_id]->voxel_info)
594 Fatal_error("fn_init_mega_from_nico fails because object is not registered as a mega");
595
596 // fetch tag file for this item
597 start_pos = (_feature_info *)features->Try_fetch_item_by_name(object->GetName());
598
599 if (!start_pos) {
600 Message_box("fn_init_mega_from_nico missing nico for item %s", object->GetName());
601 Shut_down_object("fn_init_mega_from_nico missing nico for item");
602 return IR_STOP;
603 }
604
605 // set coordinates
606 logic_structs[cur_id]->mega->actor_xyz.x = start_pos->x;
607 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->floor_y;
608 logic_structs[cur_id]->mega->actor_xyz.z = start_pos->z;
609
610 // set pan
611 logic_structs[cur_id]->pan = start_pos->direction;
612
613 // has coords
614 logic_structs[cur_id]->prop_coords_set = TRUE8;
615
616 return IR_CONT;
617 }
618
fn_teleport_to_nico(int32 &,int32 * params)619 mcodeFunctionReturnCodes _game_session::fn_teleport_to_nico(int32 &, int32 *params) {
620 // set the object position and pan from a MAX NICO marker
621
622 // params 0 name of nico
623
624 _feature_info *start_pos;
625
626 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
627
628 Zdebug("fn_teleport_to_nico - %s (to %s)", object->GetName(), nico_name);
629
630 // if this object does not have a voxel_info struct then we're done here!
631 if (!logic_structs[cur_id]->voxel_info)
632 Fatal_error("fn_teleport_to_nico fails because object is not registered as a mega");
633
634 // fetch tag file for this item
635 start_pos = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
636 if (!start_pos)
637 Fatal_error("no NICO marker (fn_teleport_to_nico) ob %s, nico %s", object->GetName(), nico_name);
638
639 // set coordinates
640 logic_structs[cur_id]->mega->actor_xyz.x = start_pos->x;
641 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->floor_y; // Gravitise_y(start_pos->y);
642 logic_structs[cur_id]->mega->actor_xyz.z = start_pos->z;
643
644 // set pan
645 logic_structs[cur_id]->pan = start_pos->direction;
646
647 // for safety
648 logic_structs[cur_id]->cur_anim_type = __STAND;
649 logic_structs[cur_id]->anim_pc = 0;
650
651 return IR_CONT;
652 }
653
fn_panless_teleport_to_nico(int32 &,int32 * params)654 mcodeFunctionReturnCodes _game_session::fn_panless_teleport_to_nico(int32 &, int32 *params) {
655 // set the object position from a MAX NICO marker
656
657 // params 0 name of nico
658
659 _feature_info *start_pos;
660
661 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
662
663 Zdebug("fn_panless_teleport_to_nico");
664
665 // if this object does not have a voxel_info struct then we're done here!
666 if (!logic_structs[cur_id]->voxel_info)
667 Fatal_error("fn_panless_teleport_to_nico_ fails because object is not registered as a mega");
668
669 // fetch tag file for this item
670 start_pos = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
671 if (!start_pos)
672 Fatal_error("no NICO marker (fn_panless_teleport_to_nico_) ob %s, nico %s", object->GetName(), nico_name);
673
674 // set coordinates
675 logic_structs[cur_id]->mega->actor_xyz.x = start_pos->x;
676 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->floor_y; // Gravitise_y(start_pos->y);
677 logic_structs[cur_id]->mega->actor_xyz.z = start_pos->z;
678
679 // for safety
680 logic_structs[cur_id]->cur_anim_type = __STAND;
681 logic_structs[cur_id]->anim_pc = 0;
682
683 return IR_CONT;
684 }
685
fn_teleport_to_nico_y(int32 &,int32 * params)686 mcodeFunctionReturnCodes _game_session::fn_teleport_to_nico_y(int32 &, int32 *params) {
687 // get y coord from a nico
688
689 // params 0 name of nico
690
691 _feature_info *start_pos;
692
693 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
694
695 Zdebug("fn_teleport_to_nico_y - %s (to %s)", object->GetName(), nico_name);
696
697 // if this object does not have a voxel_info struct then we're done here!
698 if (!logic_structs[cur_id]->voxel_info)
699 Fatal_error("fn_teleport_to_nico_y fails because object is not registered as a mega");
700
701 // fetch tag file for this item
702 start_pos = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
703 if (!start_pos)
704 Fatal_error("no NICO marker (fn_teleport_to_nico_y) ob %s, nico %s", object->GetName(), nico_name);
705
706 // set coordinates
707 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->floor_y; // Gravitise_y(start_pos->y);
708
709 // for safety
710 logic_structs[cur_id]->cur_anim_type = __STAND;
711 logic_structs[cur_id]->anim_pc = 0;
712
713 if (cur_id == player.Fetch_player_id())
714 Prepare_megas_route_barriers(TRUE8); // update barriers
715
716 return IR_CONT;
717 }
718
fn_snap_to_nico_y(int32 &,int32 * params)719 mcodeFunctionReturnCodes _game_session::fn_snap_to_nico_y(int32 &, int32 *params) {
720 // get y from nico
721
722 // params 0 name of nico
723
724 _feature_info *start_pos;
725
726 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
727
728 Zdebug("fn_snap_to_nico_y - %s (to %s)", object->GetName(), nico_name);
729
730 // if this object does not have a voxel_info struct then we're done here!
731 if (!logic_structs[cur_id]->voxel_info)
732 Fatal_error("fn_snap_to_nico_y fails because object is not registered as a mega");
733
734 // fetch tag file for this item
735 start_pos = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
736 if (!start_pos)
737 Fatal_error("no NICO marker (fn_snap_to_nico_y) ob %s, nico %s", object->GetName(), nico_name);
738
739 // set coordinates
740 logic_structs[cur_id]->mega->actor_xyz.y = start_pos->floor_y;
741
742 return IR_CONT;
743 }
744
fn_get_pan_from_nico(int32 &,int32 * params)745 mcodeFunctionReturnCodes _game_session::fn_get_pan_from_nico(int32 &, int32 *params) {
746 // set the object pan from a MAX NICO marker
747 // prop or mega
748
749 // params 0 name of nico
750
751 _feature_info *start_pos;
752
753 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
754
755 Zdebug("fn_get_pan_from_nico - %s (nico %s)", object->GetName(), nico_name);
756
757 // fetch tag file for this item
758 start_pos = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
759
760 if (!start_pos) {
761 // item does not have an entry but clearly expects one
762 // for now, just carry on and log a warning
763 Zdebug("WARNING missing feature file entry for item %s", object->GetName());
764 Fatal_error("no NICO marker (fn_get_pan_from_nico) %s", object->GetName());
765 }
766
767 // set pan
768 logic_structs[cur_id]->pan = start_pos->direction;
769
770 return IR_CONT;
771 }
772
fn_set_player_can_interact(int32 &,int32 *)773 mcodeFunctionReturnCodes _game_session::fn_set_player_can_interact(int32 &, int32 *) {
774 Zdebug("set interact");
775
776 L->player_can_interact = TRUE8;
777
778 return (IR_CONT);
779 }
780
fn_set_player_cannot_interact(int32 &,int32 *)781 mcodeFunctionReturnCodes _game_session::fn_set_player_cannot_interact(int32 &, int32 *) {
782 Zdebug("stop interact");
783
784 L->player_can_interact = FALSE8;
785
786 return (IR_CONT);
787 }
788
fn_call_socket(int32 & result,int32 * params)789 mcodeFunctionReturnCodes _game_session::fn_call_socket(int32 &result, int32 *params) {
790 // call a script of another object
791 // the script must be of a run-once and terminate nature
792
793 // params 0 ascii name of target object
794 // 1 ascii name of socket script
795
796 int32 retval;
797 uint32 script_hash;
798
799 const char *target_object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
800 const char *socket_script_name = (const char *)MemoryUtil::resolvePtr(params[1]);
801
802 Zdebug("fn_call_socket - obj %s, script %s", target_object_name, socket_script_name);
803
804 if (g_px->socket_watch)
805 Message_box("%s fn_call_socket - obj %s, script %s", object->GetName(), target_object_name, socket_script_name);
806
807 script_hash = HashString(socket_script_name);
808
809 // get target object
810 socket_object = (c_game_object *)MS->objects->Try_fetch_item_by_name(target_object_name);
811 if (!socket_object)
812 Fatal_error("%s call to fn_call_socket - object %s doesnt exist", object->GetName(), target_object_name);
813
814 // set socket_id ready for any special socket functions
815 socket_id = MS->objects->Fetch_item_number_by_name(target_object_name);
816 if (socket_id == 0xffffffff)
817 Fatal_error("fn_call_socket couldnt find object [%s]", target_object_name);
818
819 // now try and find a script with the passed extention i.e. ???::looping
820 for (uint32 k = 0; k < socket_object->GetNoScripts(); k++) {
821 // now check for actual script name
822 if (script_hash == socket_object->GetScriptNamePartHash(k)) {
823 Zdebug("calling socket %d", k);
824 // script k is the one to run
825 // get the address of the script we want to run
826
827 const char *pc = (const char *)scripts->Try_fetch_item_by_hash(socket_object->GetScriptNameFullHash(k));
828
829 // run the script - pass its object so vars can be accessed
830 RunScript(pc, socket_object, &retval);
831
832 Zdebug("return val = %d", retval);
833
834 result = retval; // pass return value of socket call into result flag
835
836 return (IR_CONT);
837 }
838 }
839
840 Fatal_error("fn_call_socket couldnt find script %s", socket_script_name);
841
842 return (IR_CONT);
843 }
844
fn_call_socket_id(int32 & result,int32 * params)845 mcodeFunctionReturnCodes _game_session::fn_call_socket_id(int32 &result, int32 *params) {
846 // call a script of another object
847 // the script must be of a run-once and terminate nature
848
849 // params 0 ID of target object
850 // 1 ascii name of socket script
851
852 int32 ret;
853
854 Zdebug("fn_call_socket_id id=%d", params[0]);
855
856 const char *socket_script_name = (const char *)MemoryUtil::resolvePtr(params[1]);
857
858 Call_socket(params[0], socket_script_name, &ret);
859
860 result = ret;
861
862 return (IR_CONT);
863 }
864
Call_socket(uint32 id,const char * script,int32 * retval)865 bool8 _game_session::Call_socket(uint32 id, const char *script, int32 *retval) {
866 // call a script of an object
867 // the script must be of a run-once and terminate nature
868 // this routine kept in here as its closely related to fn-call-socket
869 // we pass id and script name
870
871 // engine uses this
872
873 uint32 script_hash;
874
875 script_hash = HashString(script);
876
877 // get target object
878 socket_object = (c_game_object *)MS->objects->Fetch_item_by_number(id);
879 if (!socket_object)
880 Fatal_error("internal Call_socket - named object dont exist");
881
882 Zdebug("\nCall_socket - obj %s, script %s", socket_object->GetName(), script);
883
884 // set this for socket fn_ functions
885 socket_id = id;
886
887 // now try and find a script with the passed extention i.e. ???::looping
888 for (uint32 k = 0; k < socket_object->GetNoScripts(); k++) {
889 // skip past the object:: aspect
890
891 // now check for actual script name
892 if (script_hash == socket_object->GetScriptNamePartHash(k)) {
893 Zdebug("calling socket %d", k);
894 // script k is the one to run
895 // get the address of the script we want to run
896 const char *pc = (const char *)scripts->Try_fetch_item_by_hash(socket_object->GetScriptNameFullHash(k));
897
898 int32 result = static_cast<int>(*retval);
899
900 // run the script - pass its object so vars can be accessed
901 RunScript(pc, socket_object, &result);
902
903 *retval = result;
904
905 return (TRUE8);
906 }
907 }
908
909 Tdebug("Call_socket_fails.txt", "[%s] couldnt find script [%s] in [%s]", object->GetName(), script, socket_object->GetName());
910
911 return (FALSE8);
912 }
913
fn_prop_near_a_mega(int32 & result,int32 * params)914 mcodeFunctionReturnCodes _game_session::fn_prop_near_a_mega(int32 &result, int32 *params) {
915 // check all live megas against the coordinate of this prop for rough distance of param passed
916
917 // params 0 address of result variable
918 // 1 distance away value
919
920 uint32 j;
921
922 // run through all the objects calling their logic
923 for (j = 0; j < total_objects; j++) { // object 0 is used
924 // object must be alive and interactable and a mega
925 if ((logic_structs[j]->image_type == VOXEL) && (logic_structs[j]->ob_status != OB_STATUS_HELD)) { // not if the object has been manually switched out
926 if (PXfabs(L->prop_xyz.y - logic_structs[j]->mega->actor_xyz.y) < (200 * REAL_ONE)) { // slack for height calc
927 if ((PXfabs(L->prop_xyz.x - logic_structs[j]->mega->actor_xyz.x) < (PXreal)params[0]) &&
928 (PXfabs(L->prop_xyz.z - logic_structs[j]->mega->actor_xyz.z) < (PXreal)params[0])) {
929 // yes
930 result = TRUE8;
931 return (IR_CONT);
932 }
933 }
934 }
935 }
936
937 // no
938 result = FALSE8;
939 return (IR_CONT);
940 }
941
fn_reset_player(int32 &,int32 *)942 mcodeFunctionReturnCodes _game_session::fn_reset_player(int32 &, int32 *) {
943 // reset the player to standing - useful for after he's been interupted - perhaps after being shot...
944
945 player.Reset_player();
946
947 return (IR_CONT);
948 }
949
fn_teleport(int32 &,int32 * params)950 mcodeFunctionReturnCodes _game_session::fn_teleport(int32 &, int32 *params) {
951 // move the player to another objects coordinate
952
953 // params 0 name of target object
954 // 1 xoff
955 // 2 zoff
956
957 const char *target_object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
958
959 Zdebug("\nfn_teleport to %s x%d z%d", target_object_name, params[1], params[2]);
960 Zdebug("cur_id %d [%s]", cur_id, object->GetName());
961
962 // Made this so it takes a special name "from_origin" to indicate that the offset is to be applied
963 // from 0,0.
964 if (strcmp(target_object_name, "from_origin") != 0) {
965 uint32 tar = MS->objects->Fetch_item_number_by_name(target_object_name);
966
967 if (tar == 0xffffffff)
968 Fatal_error("'destination' teleport object [%s] does not exist", target_object_name);
969
970 if (!logic_structs[tar]->prop_coords_set)
971 Fatal_error("fn_teleport by [%s] finds object [%s] is not yet initialised :O - i.e. its not run its init script yet", object->GetName(),
972 target_object_name);
973
974 if (logic_structs[tar]->image_type == PROP) {
975 Tdebug("teleport.txt", "target prop y=%3.1f - our y=%3.1f", logic_structs[tar]->prop_xyz.y, logic_structs[cur_id]->mega->actor_xyz.y);
976 Zdebug("y=%3.1f , grav y =%3.1f", logic_structs[tar]->prop_xyz.y, floor_def->Gravitise_y(logic_structs[tar]->prop_xyz.y));
977 logic_structs[cur_id]->mega->actor_xyz.x = logic_structs[tar]->prop_xyz.x;
978 logic_structs[cur_id]->mega->actor_xyz.y = floor_def->Gravitise_y(logic_structs[tar]->prop_xyz.y); // logic_structs[tar]->prop_xyz.y;
979 logic_structs[cur_id]->mega->actor_xyz.z = logic_structs[tar]->prop_xyz.z;
980 } else { // mega
981 logic_structs[cur_id]->mega->actor_xyz.x = logic_structs[tar]->mega->actor_xyz.x;
982 logic_structs[cur_id]->mega->actor_xyz.y = logic_structs[tar]->mega->actor_xyz.y;
983 logic_structs[cur_id]->mega->actor_xyz.z = logic_structs[tar]->mega->actor_xyz.z;
984 }
985
986 // add offset
987 logic_structs[cur_id]->mega->actor_xyz.x += (PXfloat)params[1];
988 logic_structs[cur_id]->mega->actor_xyz.z += (PXfloat)params[2];
989 } else {
990 // Absolute jump has been requested, so just set the new x,z for the object to the given values.
991 logic_structs[cur_id]->mega->actor_xyz.x = (PXfloat)params[1];
992 logic_structs[cur_id]->mega->actor_xyz.z = (PXfloat)params[2];
993 }
994
995 // set floor rect value - used by stage draw to find indexed camera name
996 // gotta keep this bang up to date for player history system
997 floor_def->Set_floor_rect_flag(L);
998
999 return (IR_CONT);
1000 }
1001
fn_teleport_z(int32 &,int32 * params)1002 mcodeFunctionReturnCodes _game_session::fn_teleport_z(int32 &, int32 *params) {
1003 // move the player to another objects Y coordinate
1004
1005 // params 0 name of target object
1006
1007 const char *target_object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1008
1009 Zdebug("fn_teleport_z to %s", target_object_name);
1010
1011 uint32 tar = MS->objects->Fetch_item_number_by_name(target_object_name);
1012
1013 if (tar == 0xffffffff)
1014 Fatal_error("'destination' teleport object [%s] does not exist", target_object_name);
1015 if (!logic_structs[tar]->prop_coords_set)
1016 Fatal_error("fn_teleport by [%s] finds object [%s] is not yet initialised :O - i.e. its not run its init script yet", object->GetName(), target_object_name);
1017
1018 if (logic_structs[tar]->image_type == PROP) {
1019 logic_structs[cur_id]->mega->actor_xyz.y = floor_def->Gravitise_y(logic_structs[tar]->prop_xyz.y); // logic_structs[tar]->prop_xyz.y;
1020 } else { // mega
1021 logic_structs[cur_id]->mega->actor_xyz.y = logic_structs[tar]->mega->actor_xyz.y;
1022 }
1023
1024 // set floor rect value - used by stage draw to find indexed camera name
1025 // gotta keep this bang up to date for player history system
1026 floor_def->Set_floor_rect_flag(L);
1027
1028 return (IR_CONT);
1029 }
1030
fn_teleport_y_to_id(int32 &,int32 * params)1031 mcodeFunctionReturnCodes _game_session::fn_teleport_y_to_id(int32 &, int32 *params) {
1032 // move the player to another objects Y coordinate
1033
1034 // params 0 ID of target object
1035
1036 Zdebug("fn_teleport_y_to_id to %d", params[0]);
1037
1038 assert((uint32)params[0] < total_objects);
1039
1040 if (logic_structs[params[0]]->image_type == PROP) {
1041 logic_structs[cur_id]->mega->actor_xyz.y = floor_def->Gravitise_y(logic_structs[params[0]]->prop_xyz.y); // logic_structs[tar]->prop_xyz.y;
1042 } else { // mega
1043 logic_structs[cur_id]->mega->actor_xyz.y = logic_structs[params[0]]->mega->actor_xyz.y;
1044 }
1045
1046 // set floor rect value - used by stage draw to find indexed camera name
1047 // gotta keep this bang up to date for player history system
1048 floor_def->Set_floor_rect_flag(L);
1049
1050 return (IR_CONT);
1051 }
1052
fn_are_we_on_this_floor(int32 & result,int32 * params)1053 mcodeFunctionReturnCodes _game_session::fn_are_we_on_this_floor(int32 &result, int32 *params) {
1054 // check to see if object is on the floor passed
1055
1056 // params 0 name of floor
1057
1058 uint32 floor_id;
1059
1060 result = FALSE8;
1061
1062 const char *floor_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1063
1064 if (first_session_cycle)
1065 return IR_CONT;
1066
1067 uint32 hash = HashString(floor_name);
1068 floor_id = floor_def->floors->Fetch_item_number_by_hash(hash);
1069
1070 if (floor_id == 0xffffffff)
1071 Fatal_error("fn_are_we_on_this_floor cant locate floor [%s]", floor_name);
1072
1073 if (floor_id == L->owner_floor_rect)
1074 result = TRUE8;
1075
1076 return IR_CONT;
1077 }
1078
fn_is_object_on_our_floor(int32 & result,int32 * params)1079 mcodeFunctionReturnCodes _game_session::fn_is_object_on_our_floor(int32 &result, int32 *params) {
1080 // check to see if object is on the floor passed
1081
1082 // params 0 name of object
1083
1084 uint32 id, num_extra, j, cam;
1085
1086 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1087
1088 result = FALSE8;
1089
1090 if (first_session_cycle)
1091 return IR_CONT;
1092
1093 id = objects->Fetch_item_number_by_name(object_name);
1094 if (id == 0xffffffff)
1095 Fatal_error("fn_is_object_on_our_floor - illegal object [%s]", object_name);
1096
1097 // same camera means same floor
1098 if (floor_to_camera_index[L->owner_floor_rect] == floor_to_camera_index[logic_structs[id]->owner_floor_rect]) {
1099 result = TRUE8;
1100 } else {
1101 // ok, but is our floor linked to theirs?
1102 cam = floor_to_camera_index[L->owner_floor_rect]; // the camera associated with calling objects (my) floor
1103 num_extra = cam_floor_list[cam].num_extra_floors;
1104
1105 for (j = 0; j < num_extra; j++) {
1106 if (cam_floor_list[cam].extra_floors[j] == logic_structs[id]->owner_floor_rect) {
1107 result = TRUE8; // yes - the floors are linked
1108 return IR_CONT;
1109 }
1110 }
1111 }
1112
1113 return (IR_CONT);
1114 }
1115
fn_can_mega_see_dead_megas(int32 & result,int32 *)1116 mcodeFunctionReturnCodes _game_session::fn_can_mega_see_dead_megas(int32 &result, int32 *) {
1117 // are there dead megas on this megas floor?
1118
1119 uint32 j, cam, num_extra;
1120
1121 for (j = 0; j < number_of_voxel_ids; j++) {
1122 if (cur_id != voxel_id_list[j]) {
1123 if ((logic_structs[voxel_id_list[j]]->mega->dead) && // dead
1124 (logic_structs[voxel_id_list[j]]->ob_status != OB_STATUS_HELD)) { // not held
1125 // found a dead mega who isnt us - is it on our floor?
1126
1127 // same camera means same floor
1128 if (floor_to_camera_index[L->owner_floor_rect] == floor_to_camera_index[logic_structs[voxel_id_list[j]]->owner_floor_rect]) {
1129 result = TRUE8; //
1130 return IR_CONT; // cor, found one
1131 }
1132
1133 // otherwise do a check to see if our camera is linked to others floor
1134 cam = floor_to_camera_index[L->owner_floor_rect];
1135 num_extra = cam_floor_list[cam].num_extra_floors;
1136
1137 for (uint32 k = 0; k < num_extra; k++) {
1138 if (cam_floor_list[cam].extra_floors[k] == logic_structs[voxel_id_list[j]]->owner_floor_rect) {
1139 result = TRUE8; // yes - the floors are linked
1140 return IR_CONT;
1141 }
1142 }
1143 }
1144 }
1145 }
1146
1147 result = FALSE8;
1148 return IR_CONT;
1149 }
1150
fn_is_object_on_screen(int32 & result,int32 * params)1151 mcodeFunctionReturnCodes _game_session::fn_is_object_on_screen(int32 &result, int32 *params) {
1152 // check to see if object is in current camera space - i.e. will be drawn by actor-draw
1153
1154 // params 0 name of object
1155
1156 uint32 id;
1157 PXvector pos;
1158 bool8 resu = FALSE8;
1159 PXvector filmpos;
1160
1161 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1162
1163 Zdebug("fn_is_object_on_screen [%s]", object_name);
1164
1165 if (!SetOK()) {
1166 result = FALSE8; // no camera as yet
1167 return (IR_CONT);
1168 }
1169
1170 // get object to check
1171 id = objects->Fetch_item_number_by_name(object_name);
1172 if (id == 0xffffffff)
1173 Fatal_error("fn_is_object_on_screen - illegal object [%s]", object_name);
1174
1175 Zdebug(" id = %d", id);
1176
1177 // mega or prop
1178 if (logic_structs[id]->image_type == PROP) {
1179 Zdebug(" prop");
1180 pos.x = logic_structs[id]->prop_xyz.x;
1181 pos.y = logic_structs[id]->prop_xyz.y; // talks over head rather than from the feet
1182 pos.z = logic_structs[id]->prop_xyz.z;
1183 } else {
1184 Zdebug(" mega");
1185 pos.x = logic_structs[id]->mega->actor_xyz.x;
1186 pos.y = logic_structs[id]->mega->actor_xyz.y; // talks over head rather than from the feet
1187 pos.z = logic_structs[id]->mega->actor_xyz.z;
1188 }
1189
1190 // setup camera
1191 PXcamera &camera = GetCamera();
1192
1193 // compute screen coord
1194 Zdebug(" PXWorldToFilm");
1195 PXWorldToFilm(pos, camera, resu, filmpos);
1196 result = (int32)resu;
1197 Zdebug(" ~PXWorldToFilm");
1198
1199 // Ignore actors who are on the wrong side of the hither plane
1200 if (filmpos.z > -g_actor_hither_plane)
1201 result = 0;
1202
1203 return (IR_CONT);
1204 }
1205
fn_are_we_on_screen(int32 & result,int32 *)1206 mcodeFunctionReturnCodes _game_session::fn_are_we_on_screen(int32 &result, int32 *) {
1207 // Similar to the above function but does the check just for the object calling the function, which
1208 // must be a mega character.
1209
1210 // No params.
1211
1212 // Write the call in the debug file.
1213 Zdebug("fn_are_we_on_screen() - object id = %d", cur_id);
1214
1215 // Check if we have a camera set up.
1216 if (!SetOK()) {
1217 result = FALSE8;
1218 return (IR_CONT);
1219 }
1220
1221 // Caller must be a mega. (We can change this if we find we need to.)
1222 if (logic_structs[cur_id]->image_type != VOXEL)
1223 Fatal_error("Non mega object (id=%d) called fn_are_we_on_screen()", cur_id);
1224
1225 result = 0;
1226
1227 if (Object_visible_to_camera(cur_id)) {
1228 bool8 aresult = TRUE8;
1229 PXvector filmPosition;
1230 PXWorldToFilm(M->actor_xyz, set.GetCamera(), aresult, filmPosition);
1231
1232 if (filmPosition.z < -g_actor_hither_plane) {
1233 VECTOR v;
1234 v.vx = (int32)M->actor_xyz.x;
1235 v.vy = (int32)M->actor_xyz.y;
1236 v.vz = (int32)M->actor_xyz.z;
1237
1238 SVECTOR orient;
1239 orient.vx = 0;
1240 orient.vy = 0;
1241 orient.vz = 0;
1242
1243 // finally if this is true then we are okay so on_screen is true
1244 if (QuickActorCull((psxCamera *)&(set.GetCamera()), &v, &orient) != 1)
1245 result = 1;
1246 }
1247 }
1248
1249 return (IR_CONT);
1250 }
1251
fn_get_objects_lvar_value(int32 & result,int32 * params)1252 mcodeFunctionReturnCodes _game_session::fn_get_objects_lvar_value(int32 &result, int32 *params) {
1253 // params 0 name of object
1254 // 1 name of lvar
1255
1256 int32 ret;
1257 c_game_object *ob;
1258 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1259 const char *lvar_name = (const char *)MemoryUtil::resolvePtr(params[1]);
1260
1261 Zdebug("fn_get_objects_lvar_value - [%s] [%s]", object_name, lvar_name);
1262
1263 uint32 hash = HashString(object_name);
1264 ob = (c_game_object *)objects->Try_fetch_item_by_hash(hash);
1265 if (!ob)
1266 Fatal_error("fn_get_objects_lvar_value - illegal object [%s]", object_name);
1267
1268 ret = ob->GetVariable(lvar_name);
1269 if (ret == -1)
1270 Fatal_error("%s finds fn_get_objects_lvar_value - target object [%s] doesnt have [%s] lvar", object->GetName(), object_name, lvar_name);
1271
1272 result = ob->GetIntegerVariable(ret);
1273
1274 Zdebug(" var==%d", result);
1275
1276 return (IR_CONT);
1277 }
1278
fn_set_objects_lvar_value(int32 &,int32 * params)1279 mcodeFunctionReturnCodes _game_session::fn_set_objects_lvar_value(int32 &, int32 *params) {
1280 // params 0 name of object
1281 // 1 name of lvar
1282 // 2 new value of lvar
1283
1284 int32 var_num;
1285 c_game_object *ob;
1286 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1287 const char *lvar_name = (const char *)MemoryUtil::resolvePtr(params[1]);
1288
1289 Zdebug("[%s] calls fn_set_objects_lvar_value - [%s] [%s, %d]", object->GetName(), object_name, lvar_name, params[2]);
1290
1291 ob = (c_game_object *)objects->Fetch_item_by_name(object_name);
1292 if (!ob)
1293 Fatal_error("fn_set_objects_lvar_value - illegal object [%s]", object_name);
1294
1295 var_num = ob->GetVariable(lvar_name);
1296 if (var_num == -1)
1297 Fatal_error("[%s] fn_set_objects_lvar_value - object [%s] doesnt have [%s] lvar", object->GetName(), object_name, lvar_name);
1298
1299 ob->SetIntegerVariable(var_num, params[2]);
1300
1301 Zdebug(" var==%d", params[2]);
1302
1303 return (IR_CONT);
1304 }
1305
fn_set_ids_lvar_value(int32 &,int32 * params)1306 mcodeFunctionReturnCodes _game_session::fn_set_ids_lvar_value(int32 &, int32 *params) {
1307 // params 0 id of object
1308 // 1 name of lvar
1309 // 2 new value of lvar
1310
1311 int32 var_num;
1312 c_game_object *ob;
1313 const char *lvar_name = (const char *)MemoryUtil::resolvePtr(params[1]);
1314
1315 Zdebug("fn_set_ids_lvar_value - [%s] [%s]", objects->Fetch_items_name_by_number(params[0]), lvar_name);
1316
1317 ob = (c_game_object *)objects->Fetch_item_by_number(params[0]);
1318 if (!ob)
1319 Fatal_error("fn_set_ids_lvar_value - illegal object [%d]", params[0]);
1320
1321 var_num = ob->GetVariable(lvar_name);
1322 if (var_num == -1)
1323 Fatal_error("fn_set_ids_lvar_value - object [%d] doesnt have [%s] lvar", params[0], lvar_name);
1324
1325 ob->SetIntegerVariable(var_num, params[2]);
1326
1327 Zdebug(" var==%d", params[2]);
1328
1329 return (IR_CONT);
1330 }
1331
fn_get_state_flag(int32 & result,int32 * params)1332 mcodeFunctionReturnCodes _game_session::fn_get_state_flag(int32 &result, int32 *params) {
1333 // params 0 name of object
1334
1335 int32 ret;
1336 c_game_object *ob;
1337 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1338
1339 ob = (c_game_object *)objects->Fetch_item_by_name(object_name);
1340 if (!ob)
1341 Fatal_error("fn_get_state_flag - illegal object [%s]", object_name);
1342 ret = ob->GetVariable("state");
1343 if (ret == -1)
1344 Fatal_error("fn_get_state_flag - object [%s] doesnt have 'state' lvar", object_name);
1345 result = ob->GetIntegerVariable(ret);
1346
1347 return (IR_CONT);
1348 }
1349
fn_is_object_dead(int32 & result,int32 * params)1350 mcodeFunctionReturnCodes _game_session::fn_is_object_dead(int32 &result, int32 *params) {
1351 // params 0 name of object
1352
1353 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1354 uint32 id = objects->Fetch_item_number_by_name(object_name);
1355
1356 if (!logic_structs[id]->mega)
1357 Fatal_error("fn_get_state_flag - object [%s] not mega", object_name);
1358
1359 result = logic_structs[id]->mega->dead;
1360
1361 return (IR_CONT);
1362 }
1363
fn_set_weapon(int32 &,int32 * params)1364 mcodeFunctionReturnCodes _game_session::fn_set_weapon(int32 &, int32 *params) {
1365 // change/set the weapon type
1366 // if the new one is not the current then an anim must be played...
1367
1368 // params 0 ascii name of weapon - should be compatible with weapon_text
1369
1370 const char *weapon_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1371
1372 // search the weapon set table
1373
1374 uint32 j;
1375
1376 Zdebug("fn-set-weapon [%s]", weapon_name);
1377
1378 for (j = 0; j < __TOTAL_WEAPONS; j++) {
1379 Zdebug("test [%s]", weapon_text[j]);
1380 if (!strcmp(weapon_name, weapon_text[j])) {
1381 Zdebug("found %d", j);
1382 L->mega->weapon = (__weapon)j;
1383 return (IR_CONT);
1384 }
1385 }
1386
1387 Fatal_error("WARNING - %s specified weapon does not exist [%s]", object->GetName(), weapon_name);
1388
1389 return (IR_STOP);
1390 }
1391
fn_is_crouching(int32 & result,int32 *)1392 mcodeFunctionReturnCodes _game_session::fn_is_crouching(int32 &result, int32 *) {
1393 // are we crouching yes or no
1394
1395 result = M->Is_crouched();
1396
1397 return IR_CONT;
1398 }
1399
fn_is_an_object_crouching(int32 & result,int32 * params)1400 mcodeFunctionReturnCodes _game_session::fn_is_an_object_crouching(int32 &result, int32 *params) {
1401 // is an object crouching yes or no
1402
1403 // params 0 name
1404
1405 uint32 id;
1406
1407 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1408
1409 id = objects->Fetch_item_number_by_name(object_name);
1410 if (id == 0xffffffff)
1411 Fatal_error("fn_is_an_object_crouching - illegal object [%s]", object_name);
1412
1413 // Make sure it is a mega.
1414 if (!logic_structs[id]->mega)
1415 Fatal_error("fn_is_an_object_crouching - object [%s] not a mega", object_name);
1416
1417 result = logic_structs[id]->mega->Is_crouched();
1418
1419 return IR_CONT;
1420 }
1421
fn_is_armed(int32 & result,int32 *)1422 mcodeFunctionReturnCodes _game_session::fn_is_armed(int32 &result, int32 *) {
1423 // are we armed yes or no
1424
1425 result = Fetch_cur_megas_armed_status();
1426
1427 return IR_CONT;
1428 }
1429
1430 extern _player_stat player_stat_table[__TOTAL_WEAPONS];
fn_set_pose(int32 &,int32 * params)1431 mcodeFunctionReturnCodes _game_session::fn_set_pose(int32 &, int32 *params) {
1432 // change/set the weapon type
1433 // set instantly - i.e. init the _vox_image
1434
1435 // params 0 ascii name of pose - should be compatible with weapon_text
1436
1437 // search the weapon set table
1438
1439 uint32 j;
1440 const char *pose_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1441
1442 Zdebug("fn-set-weapon [%s]", pose_name);
1443
1444 for (j = 0; j < __TOTAL_WEAPONS; j++) {
1445 Zdebug("test [%s]", weapon_text[j]);
1446 if (!strcmp(pose_name, weapon_text[j])) {
1447 Zdebug("found %d", j);
1448 L->mega->weapon = (__weapon)j;
1449
1450 // do this here as well as in fn-set-player-pose as its safer in-case of misuse
1451 if (player.Player_exists())
1452 if (cur_id == player.Fetch_player_id())
1453 player.Set_player_status(player_stat_table[j]);
1454
1455 I->___init(M->chr_name, M->anim_set, (__weapon)j); // we pass the person, set names through
1456
1457 return (IR_CONT);
1458 }
1459 }
1460
1461 Fatal_error("WARNING - %s specified weapon does not exist [%s]", object->GetName(), pose_name);
1462
1463 return (IR_STOP);
1464 }
1465
fn_set_texture(int32 &,int32 * params)1466 mcodeFunctionReturnCodes _game_session::fn_set_texture(int32 &, int32 *params) {
1467 // fn_set_texture(text)
1468
1469 const char *texture_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1470
1471 L->voxel_info->Set_texture(texture_name);
1472
1473 return (IR_CONT);
1474 }
1475
fn_set_palette(int32 &,int32 * params)1476 mcodeFunctionReturnCodes _game_session::fn_set_palette(int32 &, int32 *params) {
1477 const char *palette = (const char *)MemoryUtil::resolvePtr(params[0]);
1478
1479 L->voxel_info->Set_palette(palette);
1480
1481 return (IR_CONT);
1482 }
1483
fn_set_mesh(int32 &,int32 * params)1484 mcodeFunctionReturnCodes _game_session::fn_set_mesh(int32 &, int32 *params) {
1485 // fn_set_mesh(text)
1486
1487 const char *mesh = (const char *)MemoryUtil::resolvePtr(params[0]);
1488
1489 L->voxel_info->Set_mesh(mesh);
1490
1491 return (IR_CONT);
1492 }
1493
1494 extern _player_stat player_stat_table[__TOTAL_WEAPONS];
1495
fn_set_player_pose(int32 &,int32 * params)1496 mcodeFunctionReturnCodes _game_session::fn_set_player_pose(int32 &, int32 *params) {
1497 // change/set the weapon type
1498 // set instantly - i.e. init the _vox_image
1499 // sets players status to equivelent mode
1500
1501 // params 0 ascii name of pose - should be compatible with weapon_text
1502
1503 // search the weapon set table
1504 uint32 j;
1505 const char *pose_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1506
1507 Zdebug("fn_set_player_pose [%s]", pose_name);
1508
1509 for (j = 0; j < __TOTAL_WEAPONS; j++) {
1510 Zdebug("test [%s]", weapon_text[j]);
1511 if (!strcmp(pose_name, weapon_text[j])) {
1512 Zdebug("found %d", j);
1513 L->mega->weapon = (__weapon)j;
1514 player.Set_player_status(player_stat_table[j]);
1515
1516 player.Push_player_stat(); // because its popped on return from a conversation - hmmm
1517
1518 I->___init(M->chr_name, M->anim_set, (__weapon)j); // we pass the person, set names through
1519
1520 return (IR_CONT);
1521 }
1522 }
1523
1524 Fatal_error("WARNING - fn_set_player_pose %s specified weapon does not exist [%s]", object->GetName(), pose_name);
1525
1526 return (IR_STOP);
1527 }
1528
fn_set_custom(int32 &,int32 * params)1529 mcodeFunctionReturnCodes _game_session::fn_set_custom(int32 &, int32 *params) {
1530 // change/set the custom anim type
1531 // if the new one is not the current then an anim must be played...
1532
1533 // params 0 ascii name of custom
1534
1535 const char *custom_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1536
1537 Zdebug("fn_set_custom [%s]", custom_name);
1538
1539 if (!M)
1540 Fatal_error("fn_set_custom finds [%s] is not a mega", object->GetName());
1541
1542 Set_string(custom_name, M->custom_set, MAX_CUSTOM_NAME_LENGTH);
1543 M->custom = TRUE8;
1544
1545 return (IR_CONT);
1546 }
1547
fn_message(int32 &,int32 * params)1548 mcodeFunctionReturnCodes _game_session::fn_message(int32 &, int32 *params) {
1549 const char *message = (const char *)MemoryUtil::resolvePtr(params[0]);
1550
1551 // pc has to muck around to clear sticky ctrl key
1552 // hold until ctrl key released
1553 if ((Read_DI_keys(Common::KEYCODE_LCTRL)) && (!first_session_cycle))
1554 return (IR_REPEAT);
1555
1556 if (params[0] < 256) {
1557 Message_box("%d", params[0]);
1558 } else {
1559 Message_box("%s - %s", object->GetName(), message);
1560 }
1561 return IR_CONT;
1562 }
1563
fn_message_var(int32 &,int32 * params)1564 mcodeFunctionReturnCodes _game_session::fn_message_var(int32 &, int32 *params) {
1565 const char *var_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1566
1567 uint32 var = object->GetVariable(var_name);
1568 if (var == 0xffffffff)
1569 Fatal_error("fn_message_var - object %s has no var %s", object->GetName(), var_name);
1570
1571 // pc has to muck around to clear sticky ctrl key
1572 // hold until ctrl key released
1573 if (Read_DI_keys(Common::KEYCODE_LCTRL))
1574 return (IR_REPEAT);
1575
1576 char txt[100];
1577
1578 if (object->IsVariableString(var))
1579 sprintf(txt, "%s=\"%s\"", var_name, object->GetStringVariable(var));
1580 else
1581 sprintf(txt, "%s=%d", var_name, object->GetIntegerVariable(var));
1582
1583 Message_box(txt);
1584
1585 return IR_CONT;
1586 }
1587
fn_trace(int32 &,int32 *)1588 mcodeFunctionReturnCodes _game_session::fn_trace(int32 &, int32 *) { return (IR_CONT); }
1589
fn_get_objects_x(int32 & result,int32 * params)1590 mcodeFunctionReturnCodes _game_session::fn_get_objects_x(int32 &result, int32 *params) {
1591 // return objects x coord
1592
1593 // params 0 name of object
1594
1595 uint32 id;
1596
1597 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1598
1599 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1600 if (id == 0xffffffff)
1601 Fatal_error("fn_get_objects_x - illegal object [%s]", object_name);
1602
1603 if (logic_structs[id]->image_type == PROP) {
1604 result = (uint32)logic_structs[id]->prop_xyz.x;
1605 } else {
1606 result = (uint32)logic_structs[id]->mega->actor_xyz.x;
1607 }
1608
1609 return IR_CONT;
1610 }
1611
fn_get_objects_y(int32 & result,int32 * params)1612 mcodeFunctionReturnCodes _game_session::fn_get_objects_y(int32 &result, int32 *params) {
1613 // return objects y coord
1614
1615 // params 0 name of object
1616
1617 uint32 id;
1618
1619 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1620
1621 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1622 if (id == 0xffffffff)
1623 Fatal_error("fn_get_objects_y - illegal object [%s]", object_name);
1624
1625 if (logic_structs[id]->image_type == PROP) {
1626 result = (uint32)logic_structs[id]->prop_xyz.y;
1627 } else {
1628 result = (uint32)logic_structs[id]->mega->actor_xyz.y;
1629 }
1630
1631 return IR_CONT;
1632 }
1633
fn_get_objects_z(int32 & result,int32 * params)1634 mcodeFunctionReturnCodes _game_session::fn_get_objects_z(int32 &result, int32 *params) {
1635 // return objects z coord
1636
1637 // params 0 name of object
1638
1639 uint32 id;
1640
1641 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1642
1643 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1644 if (id == 0xffffffff)
1645 Fatal_error("fn_get_objects_z - illegal object [%s]", object_name);
1646
1647 if (logic_structs[id]->image_type == PROP) {
1648 result = (uint32)logic_structs[id]->prop_xyz.z;
1649 } else {
1650 result = (uint32)logic_structs[id]->mega->actor_xyz.z;
1651 }
1652
1653 return IR_CONT;
1654 }
1655
fn_has_mega_our_height(int32 & result,int32 * params)1656 mcodeFunctionReturnCodes _game_session::fn_has_mega_our_height(int32 &result, int32 *params) {
1657 // params 0 name of object
1658
1659 uint32 id;
1660
1661 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1662
1663 // get target
1664 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1665 if (id == 0xffffffff)
1666 Fatal_error("fn_has_mega_our_height - illegal object [%s]", object_name);
1667
1668 // check its a mega
1669 if (logic_structs[id]->image_type == PROP)
1670 Fatal_error("fn_has_mega_our_height - [%s] not a mega", object_name);
1671
1672 // same y?
1673 if (logic_structs[id]->mega->actor_xyz.y == M->actor_xyz.y)
1674 result = 1; // yes!
1675 else
1676 result = 0; // no
1677
1678 return IR_CONT;
1679 }
1680
fn_near(int32 & result,int32 * params)1681 mcodeFunctionReturnCodes _game_session::fn_near(int32 &result, int32 *params) {
1682 // params 0 name of object
1683 // 1 dist
1684
1685 uint32 id;
1686 PXreal sub1, sub2, len;
1687 PXreal ourx, oury, ourz;
1688 PXreal itsx, itsy, itsz;
1689
1690 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1691
1692 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1693 if (id == 0xffffffff)
1694 Fatal_error("fn_is_object_dead - illegal object [%s]", object_name);
1695
1696 if (L->image_type == PROP) {
1697 ourx = L->prop_xyz.x;
1698 oury = L->prop_xyz.y;
1699 ourz = L->prop_xyz.z;
1700 } else {
1701 ourx = M->actor_xyz.x;
1702 oury = M->actor_xyz.y;
1703 ourz = M->actor_xyz.z;
1704 }
1705
1706 if (logic_structs[id]->image_type == PROP) {
1707 itsx = logic_structs[id]->prop_xyz.x;
1708 itsy = logic_structs[id]->prop_xyz.y;
1709 itsz = logic_structs[id]->prop_xyz.z;
1710 } else {
1711 itsx = logic_structs[id]->mega->actor_xyz.x;
1712 itsy = logic_structs[id]->mega->actor_xyz.y;
1713 itsz = logic_structs[id]->mega->actor_xyz.z;
1714 }
1715
1716 if (PXfabs(itsy - oury) < (200 * REAL_ONE)) { // slack for height calc
1717 sub1 = itsx - ourx;
1718 sub2 = itsz - ourz;
1719
1720 // dist
1721 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
1722
1723 if (len < (PXreal)(params[1] * params[1])) {
1724 result = TRUE8;
1725 } else {
1726 result = FALSE8;
1727 }
1728 return (IR_CONT);
1729 } else {
1730 result = FALSE8;
1731 return (IR_CONT);
1732 }
1733 }
1734
fn_is_mega_near_mega(int32 & result,int32 * params)1735 mcodeFunctionReturnCodes _game_session::fn_is_mega_near_mega(int32 &result, int32 *params) {
1736 // params 0 name of object
1737 // 1 name of other
1738 // 2 dist
1739
1740 uint32 id, id2;
1741 PXreal sub1, sub2, len;
1742 PXreal ourx, oury, ourz;
1743 PXreal itsx, itsy, itsz;
1744 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1745 const char *other_object_name = (const char *)MemoryUtil::resolvePtr(params[1]);
1746
1747 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1748 if (id == 0xffffffff)
1749 Fatal_error("fn_is_mega_near_mega - illegal object [%s]", object_name);
1750 id2 = (uint32)objects->Fetch_item_number_by_name(other_object_name);
1751 if (id2 == 0xffffffff)
1752 Fatal_error("fn_is_mega_near_mega - illegal object [%s]", other_object_name);
1753
1754 if (logic_structs[id]->image_type == PROP)
1755 Fatal_error("fn_is_mega_near_mega %s not a mega", object_name);
1756 if (logic_structs[id2]->image_type == PROP)
1757 Fatal_error("fn_is_mega_near_mega %s not a mega", other_object_name);
1758
1759 itsx = logic_structs[id]->mega->actor_xyz.x;
1760 itsy = logic_structs[id]->mega->actor_xyz.y;
1761 itsz = logic_structs[id]->mega->actor_xyz.z;
1762
1763 ourx = logic_structs[id2]->mega->actor_xyz.x;
1764 oury = logic_structs[id2]->mega->actor_xyz.y;
1765 ourz = logic_structs[id2]->mega->actor_xyz.z;
1766
1767 if (PXfabs(itsy - oury) < (200 * REAL_ONE)) { // slack for height calc
1768 sub1 = itsx - ourx;
1769 sub2 = itsz - ourz;
1770
1771 // dist
1772 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
1773
1774 if (len < (PXreal)(params[2] * params[2]))
1775 result = TRUE8;
1776 else
1777 result = FALSE8;
1778
1779 return IR_CONT;
1780 } else { // failed on height
1781 result = FALSE8;
1782 return IR_CONT;
1783 }
1784 }
1785
fn_on_screen(int32 & result,int32 *)1786 mcodeFunctionReturnCodes _game_session::fn_on_screen(int32 &result, int32 * /* params */) {
1787 // no params
1788
1789 result = Object_visible_to_camera(cur_id);
1790
1791 return (IR_CONT);
1792 }
1793
fn_hold_if_off_screen(int32 &,int32 *)1794 mcodeFunctionReturnCodes _game_session::fn_hold_if_off_screen(int32 &, int32 *) {
1795 // no params
1796
1797 if (L->image_type != VOXEL)
1798 Fatal_error("fn_hold_if_off_screen only works with megas [%s]", object->GetName());
1799
1800 if (!Object_visible_to_camera(cur_id)) {
1801 return (IR_REPEAT);
1802 }
1803
1804 return (IR_CONT);
1805 }
1806
fn_object_near_nico(int32 & result,int32 * params)1807 mcodeFunctionReturnCodes _game_session::fn_object_near_nico(int32 &result, int32 *params) {
1808 // params 0 object name
1809 // 1 nico name
1810 // 2 dist
1811
1812 uint32 id;
1813 _feature_info *nico;
1814 PXreal sub1, sub2, len;
1815 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1816 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[1]);
1817
1818 id = (uint32)objects->Fetch_item_number_by_name(object_name);
1819
1820 if (id == 0xffffffff)
1821 Fatal_error("fn_object_near_nico - illegal object [%s]", object_name);
1822
1823 if (logic_structs[id]->image_type == PROP)
1824 Fatal_error("fn_object_near_nico object [%s] is not a mega!", object_name);
1825
1826 // fetch tag file for this item
1827 nico = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
1828
1829 if (!nico)
1830 Fatal_error("fn_object_near_nico cant find nico [%s]", nico_name);
1831
1832 if (PXfabs(logic_structs[id]->mega->actor_xyz.y - nico->y) < (200 * REAL_ONE)) { // slack for height calc
1833 sub1 = logic_structs[id]->mega->actor_xyz.x - nico->x;
1834 sub2 = logic_structs[id]->mega->actor_xyz.z - nico->z;
1835
1836 // dist
1837 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
1838
1839 if (len < (PXreal)(params[2] * params[2])) {
1840 // near
1841 result = TRUE8;
1842 } else {
1843 result = FALSE8;
1844 }
1845 } else
1846 result = FALSE8; // failed on y
1847
1848 return (IR_CONT);
1849 }
1850
fn_add_object_name_to_list(int32 &,int32 * params)1851 mcodeFunctionReturnCodes _game_session::fn_add_object_name_to_list(int32 &, int32 *params) {
1852 // params 0 object name
1853
1854 int32 id;
1855 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1856
1857 // check for list overflow
1858 if (L->total_list == MAX_list)
1859 Fatal_error("fn_object_name_to_list [%s] has exceeded list size of %d", object->GetName(), MAX_list);
1860
1861 id = objects->Fetch_item_number_by_name(object_name);
1862
1863 if (id == -1)
1864 Fatal_error("[%s] callling fn_add_object_name_to_list finds [%s] is not a legal object", object->GetName(), object_name);
1865
1866 L->list[L->total_list++] = (uint32)id;
1867
1868 return (IR_CONT);
1869 }
1870
fn_add_object_id_to_list(int32 &,int32 * params)1871 mcodeFunctionReturnCodes _game_session::fn_add_object_id_to_list(int32 &, int32 *params) {
1872 // params 0 object id
1873
1874 // check for list overflow
1875 if (L->total_list == MAX_list)
1876 Fatal_error("fn_object_id_to_list [%s] has exceeded list size of %d", object->GetName(), MAX_list);
1877
1878 assert((uint32)params[0] < total_objects);
1879
1880 L->list[L->total_list++] = params[0];
1881
1882 return (IR_CONT);
1883 }
1884
fn_lift_process_list(int32 & result,int32 * params)1885 mcodeFunctionReturnCodes _game_session::fn_lift_process_list(int32 &result, int32 *params) {
1886 // special lift logic function - checks all megas in the lift against named nico
1887
1888 // params 0 name of nico
1889 // 1 distance
1890 // 2 0 top, 1 bottom
1891
1892 // returns FALSE8 did nothing
1893 // TRUE8 someone used lift - ascend or descend
1894
1895 uint32 j;
1896 _feature_info *monica; // or nico to you and i
1897 PXreal sub1, sub2, len;
1898
1899 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1900
1901 // check for no people in list! Could be redefined as an error in-fact
1902 if (!L->total_list) {
1903 result = FALSE8; // did nothing
1904 return (IR_CONT);
1905 }
1906
1907 monica = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
1908 if (!monica)
1909 Fatal_error("fn_lift_process_list cant find nico [%s]", nico_name);
1910
1911 for (j = 0; j < L->total_list; j++) {
1912 if (logic_structs[L->list[j]]->image_type != VOXEL)
1913 Fatal_error("fn_lift_process_list finds [%s] is not a mega", (const char *)logic_structs[L->list[j]]->GetName());
1914
1915 if (PXfabs(logic_structs[L->list[j]]->mega->actor_xyz.y - monica->y) < (200 * REAL_ONE)) { // slack for height calc
1916 sub1 = logic_structs[L->list[j]]->mega->actor_xyz.x - monica->x;
1917 sub2 = logic_structs[L->list[j]]->mega->actor_xyz.z - monica->z;
1918
1919 // dist
1920 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
1921
1922 if (len < (PXreal)(params[1] * params[1])) {
1923 // near
1924
1925 result = TRUE8; // did something
1926
1927 if (params[2]) { // bottom
1928
1929 // Call the function that does the work in the event manager.
1930 g_oEventManager->PostNamedEventToObject(EVENT_LIFT_ASCEND, L->list[j], cur_id);
1931 return (IR_CONT);
1932 } else { // top
1933 g_oEventManager->PostNamedEventToObject(EVENT_LIFT_DESCEND, L->list[j], cur_id);
1934 return (IR_CONT);
1935 }
1936 }
1937 }
1938 }
1939
1940 result = FALSE8; // no action
1941 return (IR_CONT);
1942 }
1943
fn_lib_lift_chord_and_chi(int32 & result,int32 * params)1944 mcodeFunctionReturnCodes _game_session::fn_lib_lift_chord_and_chi(int32 &result, int32 *params) {
1945 // special lift platform handler for cord and chi
1946
1947 // look for player being on the lift
1948
1949 // params 0 name of nico (if not using platform coords)
1950 // 1 distance
1951 // 2 0 top, 1 bottom
1952
1953 // returns FALSE8 did nothing
1954 // TRUE8 someone used lift - ascend or descend
1955
1956 _feature_info *monica; // or nico to you and i
1957 PXreal sub1, sub2, len;
1958 PXreal lifty = REAL_ZERO;
1959 bool8 has_platform = FALSE8;
1960 uint32 lift = 0; // lift number in platform list
1961 bool8 hit = FALSE8;
1962 uint32 j = 0;
1963 static int32 issued_warning = FALSE8;
1964 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
1965
1966 if (!prev_save_state) { // could not save last go - then cant operate lift either. Player is in a private script
1967 result = FALSE8;
1968 return IR_CONT;
1969 }
1970
1971 monica = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
1972 if (!monica)
1973 Fatal_error("fn_lift_process_list cant find nico [%s]", nico_name);
1974 lifty = monica->y;
1975
1976 // see if the lift has registered a coordinate platform - if so, we use that
1977 for (j = 0; j < num_lifts; j++) {
1978 if (cur_id == lifts[j].id) {
1979 has_platform = TRUE8;
1980 lift = j;
1981 break; // yup - found a platform
1982 }
1983 }
1984
1985 // issue one warning at a time
1986 if ((!has_platform) && (!issued_warning)) {
1987 issued_warning = TRUE8;
1988 Message_box("lift [%s] says please can i have proper platform coords?", object->GetName());
1989 }
1990
1991 if (PXfabs(logic_structs[player.Fetch_player_id()]->mega->actor_xyz.y - lifty) < (200 * REAL_ONE)) { // slack for height calc
1992 if (!has_platform) {
1993 sub1 = logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x - monica->x;
1994 sub2 = logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z - monica->z;
1995 // dist
1996 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
1997 if (len < (PXreal)(params[1] * params[1]))
1998 hit = TRUE8;
1999 } else { // has a registered platform
2000 if ((logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x >= lifts[lift].x) && // area box method
2001 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x <= lifts[lift].x1) &&
2002 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z >= lifts[lift].z) &&
2003 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z <= lifts[lift].z1))
2004 hit = TRUE8;
2005 }
2006
2007 if (hit) {
2008 // tell player logic - stop ability to interact with anything else
2009 player.stood_on_lift = TRUE8;
2010
2011 if ((player.cur_state.IsButtonSet(__INTERACT)) && (!player.interact_lock) && (player.player_status == STOOD)) {
2012 player.interact_lock = TRUE8;
2013
2014 result = TRUE8; // did something
2015
2016 if (params[2]) { // bottom
2017 // Call the function that does the work in the event manager.
2018 g_oEventManager->PostNamedEventToObject(EVENT_LIFT_ASCEND, player.Fetch_player_id(), cur_id);
2019 return (IR_CONT);
2020 } else { // top
2021 g_oEventManager->PostNamedEventToObject(EVENT_LIFT_DESCEND, player.Fetch_player_id(), cur_id);
2022 return (IR_CONT);
2023 }
2024 }
2025 }
2026 }
2027
2028 result = FALSE8; // no action
2029 return IR_CONT;
2030 }
2031
2032 typedef struct {
2033 uint32 init;
2034 int32 params[4];
2035 } _lift_verify;
2036
2037 _lift_verify lift2s[MAX_session_objects];
2038
fn_lift2_process(int32 & result,int32 * params)2039 mcodeFunctionReturnCodes _game_session::fn_lift2_process(int32 &result, int32 *params) {
2040 // special lift logic function - checks all megas in the lift against named nico
2041 // if no one is here we IR_CONT
2042 // of someone hits the spot we teleport them
2043
2044 // params 0 name of nico
2045 // 1 catch distance
2046 // 2 0 top, 1 bottom
2047 // 3 release distance
2048
2049 // returns FALSE8 did nothing
2050 // TRUE8 someone used lift - ascend or descend
2051
2052 uint32 j = 0;
2053 _feature_info *monica; // or nico to you and i
2054 PXreal sub1, sub2, len;
2055 bool8 hit = FALSE8;
2056 bool8 has_platform = FALSE8;
2057 PXreal lifty = REAL_ZERO;
2058 uint32 lift = 0; // lift number in platform list
2059 static int32 issued_warning = FALSE8;
2060 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2061
2062 static int32 inited = FALSE8;
2063 if (!inited) {
2064 for (j = 0; j < MAX_session_objects; j++)
2065 lift2s[j].init = 0;
2066 inited = TRUE8;
2067 }
2068
2069 if (!lift2s[cur_id].init) {
2070 lift2s[cur_id].init = TRUE8;
2071 lift2s[cur_id].params[0] = params[0];
2072 lift2s[cur_id].params[1] = params[1];
2073 lift2s[cur_id].params[2] = params[2];
2074 lift2s[cur_id].params[3] = params[3];
2075 }
2076
2077 if (lift2s[cur_id].params[0] != params[0])
2078 Message_box("%s param 0 changed from %d to %d", object->GetName(), lift2s[cur_id].params[0], params[0]);
2079 if (lift2s[cur_id].params[1] != params[1])
2080 Message_box("%s param 1 changed from %d to %d", object->GetName(), lift2s[cur_id].params[1], params[1]);
2081 if (lift2s[cur_id].params[2] != params[2])
2082 Message_box("%s param 2 changed from %d to %d", object->GetName(), lift2s[cur_id].params[2], params[2]);
2083 if (lift2s[cur_id].params[3] != params[3])
2084 Message_box("%s param 3 changed from %d to %d", object->GetName(), lift2s[cur_id].params[3], params[3]);
2085
2086 // check for no people in list! Could be redefined as an error in-fact
2087 if (!L->total_list) {
2088 if (!issued_warning) {
2089 Message_box("lift [%s] says no items in list", object->GetName());
2090 issued_warning = TRUE8;
2091 }
2092
2093 result = FALSE8; // did nothing
2094 return (IR_CONT);
2095 }
2096
2097 // get nico
2098 monica = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
2099 if (!monica)
2100 Fatal_error("fn_lift_process_list cant find nico [%s]", nico_name);
2101 lifty = monica->y;
2102
2103 // see if the lift has registered a coordinate platform - if so, we use that
2104 for (j = 0; j < num_lifts; j++)
2105 if (cur_id == lifts[j].id) {
2106 has_platform = TRUE8;
2107 lift = j;
2108 break; // yup - found a platform
2109 }
2110
2111 // issue one warning at a time
2112 if ((!has_platform) && (!issued_warning)) {
2113 issued_warning = TRUE8;
2114 Message_box("lift [%s] says please can i have proper platform coords?", object->GetName());
2115 }
2116
2117 for (j = 0; j < L->total_list; j++) {
2118 if (logic_structs[L->list[j]]->image_type != VOXEL)
2119 Fatal_error("fn_lift_process_list finds [%s] is not a mega", (const char *)logic_structs[L->list[j]]->GetName());
2120
2121 if (logic_structs[L->list[j]]->mega->dead)
2122 continue;
2123
2124 if (PXfabs(logic_structs[L->list[j]]->mega->actor_xyz.y - lifty) < (200 * REAL_ONE)) { // slack for height calc
2125
2126 sub1 = logic_structs[L->list[j]]->mega->actor_xyz.x - monica->x;
2127 sub2 = logic_structs[L->list[j]]->mega->actor_xyz.z - monica->z;
2128
2129 // dist
2130 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
2131
2132 // are we inside release distance
2133 if (len < (PXreal)(params[3] * params[3])) {
2134 hit = TRUE8; // hurray, we found someone inside the release distance
2135 }
2136
2137 if (((!has_platform) && (len < (PXreal)(params[1] * params[1]))) || // crude inner nico method, or
2138 ((logic_structs[L->list[j]]->mega->actor_xyz.x >= lifts[lift].x) && // area box method
2139 (logic_structs[L->list[j]]->mega->actor_xyz.x <= lifts[lift].x1) && (logic_structs[L->list[j]]->mega->actor_xyz.z >= lifts[lift].z) &&
2140 (logic_structs[L->list[j]]->mega->actor_xyz.z <= lifts[lift].z1))) {
2141 if (L->list[j] == player.Fetch_player_id()) {
2142 // tell player logic - stop ability to interact with anything else
2143 player.stood_on_lift = TRUE8;
2144
2145 if ((player.cur_state.IsButtonSet(__INTERACT)) && (!player.interact_lock) && (player.player_status == STOOD)) {
2146 player.interact_lock = TRUE8;
2147
2148 L->list_result = L->list[j]; // save id for later retrieval
2149
2150 // near
2151 Zdebug("%s hits lift", (const char *)logic_structs[L->list[j]]->GetName());
2152
2153 result = TRUE8;
2154
2155 return (IR_CONT);
2156 }
2157 } else { // other megas
2158 L->list_result = L->list[j]; // save id for later retrieval
2159
2160 // near
2161 Zdebug("mega %s hits lift", (const char *)logic_structs[L->list[j]]->GetName());
2162
2163 result = TRUE8;
2164
2165 return (IR_CONT);
2166 }
2167 }
2168 }
2169 }
2170
2171 // someone was within release range so hold
2172 if (hit) {
2173 Zdebug("repeating");
2174 return (IR_REPEAT);
2175 }
2176
2177 L->list_result = 999; // means no one - release
2178
2179 // detected no one so continue in script - which means doors will close
2180 return IR_CONT;
2181 }
2182
fn_wait_for_button(int32 &,int32 * params)2183 mcodeFunctionReturnCodes _game_session::fn_wait_for_button(int32 &, int32 *params) {
2184 // wait for specified button
2185 // params 0 button number
2186 // 0 interact
2187 // 1 punch
2188 // 2 forward
2189 // 3 backward
2190 // 4 right
2191 // 5 left
2192
2193 player.Update_input_state();
2194
2195 if ((params[0] == 0) && (player.cur_state.IsButtonSet(__INTERACT)))
2196 return IR_CONT;
2197 if ((params[0] == 1) && (player.cur_state.IsButtonSet(__ATTACK)))
2198 return IR_CONT;
2199 if ((params[0] == 2) && (player.cur_state.momentum == __FORWARD_1))
2200 return IR_CONT;
2201 if ((params[0] == 3) && (player.cur_state.momentum == __BACKWARD_1))
2202 return IR_CONT;
2203 if ((params[0] == 4) && ((player.cur_state.turn == __RIGHT) || (player.cur_state.turn == __HARD_RIGHT)))
2204 return IR_CONT;
2205 if ((params[0] == 5) && ((player.cur_state.turn == __LEFT) || (player.cur_state.turn == __HARD_LEFT)))
2206 return IR_CONT;
2207
2208 return IR_REPEAT;
2209 }
2210
fn_register_platform_coords(int32 &,int32 * params)2211 mcodeFunctionReturnCodes _game_session::fn_register_platform_coords(int32 &, int32 *params) {
2212 // register coords of a lift platform
2213
2214 // params 0 x
2215 // 1 z
2216 // 2 x1
2217 // 3 z1
2218
2219 // we'll still take the y from the nico
2220
2221 // safety
2222 if (num_lifts == MAX_lift_platforms)
2223 Fatal_error("too many lifts - max = %d", MAX_lift_platforms);
2224
2225 lifts[num_lifts].id = cur_id; // our id
2226 lifts[num_lifts].x = (PXreal)params[0]; // x
2227 lifts[num_lifts].z = (PXreal)params[1]; // z
2228 lifts[num_lifts].x1 = (PXreal)params[2]; // x1
2229 lifts[num_lifts].z1 = (PXreal)params[3]; // z1
2230
2231 num_lifts++;
2232
2233 return IR_CONT;
2234 }
2235
fn_near_list(int32 & result,int32 * params)2236 mcodeFunctionReturnCodes _game_session::fn_near_list(int32 &result, int32 *params) {
2237 // works from our coordiate
2238 // we can be prop or mega
2239 // targets much be mega
2240
2241 // params 0 dist
2242
2243 uint32 j;
2244 PXreal sub1, sub2, len;
2245 PXreal ourx, oury, ourz;
2246
2247 if (L->image_type == PROP) {
2248 ourx = L->prop_xyz.x;
2249 oury = L->prop_xyz.y;
2250 ourz = L->prop_xyz.z;
2251 } else {
2252 ourx = M->actor_xyz.x;
2253 oury = M->actor_xyz.y;
2254 ourz = M->actor_xyz.z;
2255 }
2256
2257 for (j = 0; j < L->total_list; j++) {
2258 if (logic_structs[L->list[j]]->image_type != VOXEL)
2259 Fatal_error("fn_near_list finds [%s] is not a mega", (const char *)logic_structs[L->list[j]]->GetName());
2260
2261 if (!logic_structs[L->list[j]]->mega->dead) { // alive
2262
2263 Zdebug("%3.2f %3.2f", logic_structs[L->list[j]]->mega->actor_xyz.y, oury);
2264
2265 if (PXfabs(logic_structs[L->list[j]]->mega->actor_xyz.y - oury) < (200 * REAL_ONE)) { // slack for height calc
2266 sub1 = logic_structs[L->list[j]]->mega->actor_xyz.x - ourx;
2267 sub2 = logic_structs[L->list[j]]->mega->actor_xyz.z - ourz;
2268
2269 // dist
2270 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
2271
2272 if (len < (PXreal)(params[0] * params[0])) {
2273 // near
2274
2275 L->list_result = L->list[j]; // save id for later retrieval
2276
2277 result = TRUE8; // did something
2278
2279 return (IR_CONT);
2280 }
2281 }
2282 }
2283 }
2284
2285 result = FALSE8; // no action
2286 return (IR_CONT);
2287 }
2288
fn_get_list_result(int32 & result,int32 *)2289 mcodeFunctionReturnCodes _game_session::fn_get_list_result(int32 &result, int32 *) {
2290 // returns the result of a previous list process based function such as fn_near_list
2291
2292 // no params
2293
2294 result = L->list_result;
2295
2296 return (IR_CONT);
2297 }
2298
fn_hold_while_list_near_nico(int32 & result,int32 * params)2299 mcodeFunctionReturnCodes _game_session::fn_hold_while_list_near_nico(int32 &result, int32 *params) {
2300 // function holds the script position while a mega from the list of megas registers as being near the named nico
2301
2302 // params 0 nico
2303 // 1 distance
2304
2305 uint32 j;
2306 _feature_info *monica; // or nico to you and i
2307 PXreal sub1, sub2, len;
2308 int32 ret, res;
2309 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2310
2311 // check for no people in list! Could be redefined as an error in-fact
2312 if (!L->total_list) {
2313 result = FALSE8; // did nothing
2314 return (IR_CONT);
2315 }
2316
2317 monica = (_feature_info *)features->Try_fetch_item_by_name(nico_name);
2318 if (!monica)
2319 Fatal_error("fn_lift_process_list cant find nico [%s]", nico_name);
2320
2321 for (j = 0; j < L->total_list; j++) {
2322 if (logic_structs[L->list[j]]->image_type != VOXEL)
2323 Fatal_error("fn_hold_while_list_near_nico finds [%s] is not a mega", (const char *)logic_structs[L->list[j]]->GetName());
2324
2325 // ignore people who are dead
2326 res = Call_socket(L->list[j], "give_state", &ret);
2327 if (!res)
2328 Fatal_error("fn_hold_while_list_near_nico - object doesnt have 'give_state' script. Perhaps its not a mega");
2329
2330 if ((!ret) && (PXfabs(logic_structs[L->list[j]]->mega->actor_xyz.y - monica->y) < (200 * REAL_ONE))) { // slack for height calc
2331 sub1 = logic_structs[L->list[j]]->mega->actor_xyz.x - monica->x;
2332 sub2 = logic_structs[L->list[j]]->mega->actor_xyz.z - monica->z;
2333
2334 // dist
2335 len = (PXreal)((sub1 * sub1) + (sub2 * sub2));
2336
2337 if (len < (PXreal)(params[1] * params[1])) {
2338 // near
2339 return (IR_REPEAT);
2340 }
2341 }
2342 }
2343
2344 // no one was near the nico
2345 return (IR_CONT);
2346 }
2347
fn_set_watch(int32 &,int32 * params)2348 mcodeFunctionReturnCodes _game_session::fn_set_watch(int32 &, int32 *params) {
2349 _input *psInputState;
2350 _input sInputState;
2351
2352 // set the camera to follow the named mega
2353
2354 // params 0 name of object
2355
2356 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2357 uint32 id = objects->Fetch_item_number_by_name(object_name);
2358
2359 if (id == 0xffffffff)
2360 Fatal_error("fn_set_watch - object [%s] does not exist", object_name);
2361
2362 if (logic_structs[id]->image_type != VOXEL)
2363 Fatal_error("fn_set_watch - object [%s] is not a person!", object_name);
2364
2365 // if setting back to player then cancel the camera overide
2366 if (id == player.Fetch_player_id())
2367 g_mission->camera_follow_id_overide = 0;
2368 else
2369 g_mission->camera_follow_id_overide = id;
2370
2371 // If we are switching back to the player then we need to put the Remora back up if
2372 // it was up when we switched to a manual watch (but only in 3D).
2373 if (g_px->display_mode == THREED) {
2374 // Check if switching to player.
2375 if (id == player.Fetch_player_id()) {
2376 // If the Remora was active, need to bring it back up.
2377 if (g_mission->remora_save_mode != -1) {
2378 MS->player.Push_control_mode(ACTOR_RELATIVE);
2379 g_oRemora->SetModeOverride((_remora::RemoraMode)g_mission->remora_save_mode);
2380 g_oRemora->ActivateRemora((_remora::RemoraMode)g_mission->remora_save_mode);
2381 MS->player.Set_player_status(REMORA);
2382 MS->player.Update_input_state();
2383 psInputState = MS->player.Fetch_input_state();
2384 g_oRemora->CycleRemoraLogic(*psInputState);
2385 g_mission->remora_save_mode = -1;
2386 }
2387 } else {
2388 // Not switching to player so flag whether or not the Remora is active.
2389 if (g_oRemora->IsActive()) {
2390 // Deactivate it and remember its mode.
2391 g_mission->remora_save_mode = (int32)g_oRemora->GetMode();
2392 g_oRemora->SetMode(_remora::MOTION_SCAN);
2393 g_oRemora->DeactivateRemora(TRUE8);
2394 sInputState.UnSetButton(__UNUSEDBUTTON);
2395 g_oRemora->CycleRemoraLogic(sInputState);
2396 MS->player.Pop_control_mode();
2397 MS->player.Set_player_status(STOOD);
2398 } else {
2399 g_mission->remora_save_mode = -1;
2400 }
2401 }
2402 }
2403
2404 // Deactivate the Remora.
2405
2406 return (IR_CONT);
2407 }
2408
fn_three_sixty_interact(int32 &,int32 *)2409 mcodeFunctionReturnCodes _game_session::fn_three_sixty_interact(int32 &, int32 *) {
2410 // set object to use the prop 360deg interaction type
2411
2412 if (L->image_type != PROP)
2413 Fatal_error("fn_three_sixty_interact - object [%s] is not a prop!", object->GetName());
2414
2415 L->three_sixty_interact |= THREE_SIXTY_INTERACT;
2416
2417 return (IR_CONT);
2418 }
2419
fn_prop_crouch_interact(int32 &,int32 *)2420 mcodeFunctionReturnCodes _game_session::fn_prop_crouch_interact(int32 &, int32 *) {
2421 // set object to use the prop 360deg interaction type
2422
2423 L->three_sixty_interact |= PROP_CROUCH_INTERACT;
2424
2425 return IR_CONT;
2426 }
2427
fn_random(int32 & result,int32 * params)2428 mcodeFunctionReturnCodes _game_session::fn_random(int32 &result, int32 *params) {
2429 // return a random number to script
2430
2431 // params 0 largest number possible from choice
2432
2433 result = g_icb->getRandomSource()->getRandomNumber(params[0] - 1);
2434
2435 return (IR_CONT);
2436 }
2437
fn_change_session(int32 &,int32 * params)2438 mcodeFunctionReturnCodes _game_session::fn_change_session(int32 &, int32 *params) {
2439 // change session within the current mission
2440
2441 // params 0 name of session
2442 // params 1 name of new nico
2443
2444 uint32 ret;
2445 const char *ses_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2446 const char *nico_name = (const char *)MemoryUtil::resolvePtr(params[1]);
2447
2448 Tdebug("session_log.txt", "fn_change_session changing to [%s]", ses_name);
2449
2450 g_mission->Set_new_session_name(ses_name);
2451 g_mission->Set_init_nico_name(nico_name);
2452
2453 // save the players 'hits' variable
2454 c_game_object *ob;
2455 ob = (c_game_object *)objects->Fetch_item_by_number(player.Fetch_player_id());
2456 ret = ob->GetVariable("hits");
2457 g_mission->old_hits_value = ob->GetIntegerVariable(ret);
2458
2459 return (IR_STOP); // do no more
2460 }
2461
fn_changed_sessions(int32 & result,int32 *)2462 mcodeFunctionReturnCodes _game_session::fn_changed_sessions(int32 &result, int32 *) {
2463 // look for nico name logged by fn_change_session
2464 // if found init there
2465 // return yes or no
2466
2467 _feature_info *nico;
2468 uint32 ret;
2469
2470 result = g_mission->Is_there_init_nico();
2471
2472 if (result) { // nico is waiting Removed explicit test against TRUE8 to get rid of VC5 warning
2473 nico = (_feature_info *)features->Try_fetch_item_by_name(g_mission->Return_init_nico_name());
2474 if (!nico)
2475 Fatal_error("fn_changed_sessions cant find nico [%s]", g_mission->Return_init_nico_name());
2476
2477 #define XX logic_structs[cur_id]->mega->actor_xyz.x
2478 #define ZZ logic_structs[cur_id]->mega->actor_xyz.z
2479
2480 logic_structs[cur_id]->mega->actor_xyz.x = nico->x;
2481 logic_structs[cur_id]->mega->actor_xyz.y = nico->floor_y;
2482 logic_structs[cur_id]->mega->actor_xyz.z = nico->z;
2483
2484 // set pan
2485 logic_structs[cur_id]->pan = nico->direction;
2486
2487 // reset current hits from previous session
2488 ret = object->GetVariable("hits");
2489 object->SetIntegerVariable(ret, g_mission->old_hits_value);
2490
2491 // has coords
2492 logic_structs[cur_id]->prop_coords_set = TRUE8;
2493
2494 // move player forwards a little
2495 if (cur_id == objects->Fetch_item_number_by_name("chi")) {
2496 // we are the player then jump player in-front of chi
2497
2498 PXfloat ang = nico->direction * TWO_PI;
2499 PXfloat cang = (PXfloat)PXcos(ang);
2500 PXfloat sang = (PXfloat)PXsin(ang);
2501
2502 XX += PXfloat2PXreal((75 * REAL_ONE) * sang);
2503 ZZ += PXfloat2PXreal((75 * REAL_ONE) * cang);
2504 }
2505 }
2506
2507 return (IR_CONT);
2508 }
2509
fn_changed_via_this_shaft(int32 & result,int32 * params)2510 mcodeFunctionReturnCodes _game_session::fn_changed_via_this_shaft(int32 &result, int32 *params) {
2511 // a lib_session_changer_lift checks to see if its marker was the one that the player started the session on
2512 // if so then the lift knows that it was the lift that has just arrived and therefore it is here and open
2513
2514 // params 0 name of our marker
2515
2516 const char *marker_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2517
2518 if (g_mission->Is_there_init_nico()) {
2519 // there is a nico
2520 // is it ours
2521
2522 if (!strcmp(marker_name, g_mission->Return_init_nico_name())) {
2523 // yes!
2524 result = 1;
2525 return IR_CONT;
2526 }
2527 }
2528
2529 result = 0; // no
2530 return IR_CONT;
2531 }
2532
fn_is_object_adjacent(int32 & result,int32 * params)2533 mcodeFunctionReturnCodes _game_session::fn_is_object_adjacent(int32 &result, int32 *params) {
2534 // is the name object on a floor adjacent to this objects floor
2535
2536 // params 0 name of object
2537
2538 _floor *our_floor;
2539 uint32 their_floor;
2540 uint32 id;
2541 uint32 j;
2542 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2543
2544 our_floor = floor_def->Fetch_floor_number(L->owner_floor_rect);
2545
2546 if (!our_floor->num_neighbours) {
2547 result = FALSE8; // cant be adjacent as there are non - which is impossible of course but hey
2548 return (IR_CONT);
2549 }
2550
2551 id = objects->Fetch_item_number_by_name(object_name);
2552 if (id == 0xffffffff)
2553 Fatal_error("fn_is_object_on_our_floor - illegal object [%s]", object_name);
2554
2555 their_floor = logic_structs[id]->owner_floor_rect;
2556
2557 // are they on our floor - haha
2558 if (their_floor == L->owner_floor_rect) { //
2559 result = FALSE8; //
2560 return (IR_CONT);
2561 }
2562
2563 // check each neighbour
2564 for (j = 0; j < our_floor->num_neighbours; j++) {
2565 if (our_floor->neighbour_map[j].neighbour == their_floor) {
2566 result = TRUE8;
2567 return (IR_CONT);
2568 }
2569 }
2570
2571 result = FALSE8;
2572
2573 return (IR_CONT);
2574 }
2575
fn_is_object_on_this_floor(int32 & result,int32 * params)2576 mcodeFunctionReturnCodes _game_session::fn_is_object_on_this_floor(int32 &result, int32 *params) {
2577 // check to see if object is on the floor passed
2578
2579 // params 0 name of object
2580 // 1 name of floor
2581
2582 uint32 floor_id;
2583 uint32 id;
2584 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2585 const char *floor_name = (const char *)MemoryUtil::resolvePtr(params[1]);
2586
2587 Zdebug("fn_is_object_on_this_floor [%s], [%s]", object_name, floor_name);
2588
2589 id = objects->Fetch_item_number_by_name(object_name);
2590 if (id == 0xffffffff)
2591 Fatal_error("fn_is_object_on_our_floor - illegal object [%s]", object_name);
2592
2593 floor_id = floor_def->floors->Fetch_item_number_by_name(floor_name);
2594 if (floor_id == 0xffffffff)
2595 Fatal_error("fn_are_we_on_this_floor cant locate floor [%s]", floor_name);
2596
2597 if (floor_id == logic_structs[id]->owner_floor_rect)
2598 result = TRUE8;
2599 else
2600 result = FALSE8;
2601
2602 return (IR_CONT);
2603 }
2604
fn_switch_on_the_really_neat_and_special_script_debugging_facility(int32 & result,int32 * params)2605 mcodeFunctionReturnCodes _game_session::fn_switch_on_the_really_neat_and_special_script_debugging_facility(int32 &result, int32 *params) {
2606 // switch on daves debugging
2607 bool8 flag = (params[0] == 0) ? FALSE8 : TRUE8;
2608
2609 Zdebug("\n\n****** switching ON script debugging *******\n\n");
2610
2611 SetScriptDebugging(flag);
2612
2613 result = 0;
2614
2615 return (IR_CONT);
2616 }
2617
fn_switch_off_the_really_neat_and_special_script_debugging_facility(int32 & result,int32 *)2618 mcodeFunctionReturnCodes _game_session::fn_switch_off_the_really_neat_and_special_script_debugging_facility(int32 &result, int32 *) {
2619 // switch off daves debugging
2620
2621 Zdebug("\n\n------ switching OFF script debugging ------\n\n");
2622
2623 SetScriptDebugging(FALSE8);
2624
2625 result = 0;
2626
2627 return (IR_CONT);
2628 }
2629
fn_preload_custom_mega_anim(int32 & result,int32 * params)2630 mcodeFunctionReturnCodes _game_session::fn_preload_custom_mega_anim(int32 &result, int32 *params) {
2631 // set a resource loading
2632 // we have devided fn_functions into types (i.e. mega animations) in-case there are cluster complications
2633
2634 // params 0 name of final anim
2635
2636 return (fn_prime_custom_anim(result, params));
2637 }
2638
fn_no_logic(int32 &,int32 *)2639 mcodeFunctionReturnCodes _game_session::fn_no_logic(int32 &, int32 *) {
2640 // set wait_status to no-logic which stops the script being invoked
2641
2642 Tdebug("logic_modes.txt", "fn_no_logic freezing [%s]", object->GetName());
2643
2644 L->big_mode = __NO_LOGIC;
2645 L->cycle_time = 0; // for mt display
2646
2647 return (IR_CONT);
2648 }
2649
fn_set_sleep(int32 &,int32 * params)2650 mcodeFunctionReturnCodes _game_session::fn_set_sleep(int32 &, int32 *params) {
2651 // add or remove no-logic
2652
2653 // params 0 name
2654 // 1 0 off, 1 on
2655
2656 uint32 id;
2657 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2658
2659 id = objects->Fetch_item_number_by_name(object_name);
2660 if (id == 0xffffffff)
2661 Fatal_error("fn_set_sleep - illegal object [%s]", object_name);
2662
2663 if (params[1]) {
2664 logic_structs[id]->big_mode = __NO_LOGIC;
2665 logic_structs[id]->cycle_time = 0; // for mt display
2666 } else {
2667 logic_structs[id]->big_mode = __SCRIPT;
2668 }
2669
2670 return IR_CONT;
2671 }
2672
fn_mega_use_lift(int32 &,int32 * params)2673 mcodeFunctionReturnCodes _game_session::fn_mega_use_lift(int32 &, int32 *params) {
2674 // trigger a lift - manually
2675 // no safety checking here - scripts must assure all is in right position, etc.
2676
2677 // just set a request flag - putting in function gives us scope for seamless future changes
2678
2679 // params 0 name of lift
2680
2681 c_game_object *ob;
2682 uint32 var_num;
2683 const char *lift_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2684
2685 ob = (c_game_object *)objects->Fetch_item_by_name(lift_name);
2686 if (!ob)
2687 Fatal_error("fn_use_lift - illegal object [%s]", lift_name);
2688
2689 var_num = ob->GetVariable("request");
2690 if (var_num == (uint32)-1)
2691 Fatal_error("fn_use_lift - object [%s] doesnt have REQUEST variable", lift_name);
2692
2693 ob->SetIntegerVariable(var_num, 2); // two is trigger value
2694
2695 return (IR_CONT);
2696 }
2697
2698 // fn_make_remora_beep(1) makes the remora beep notice us, 0 makes it not do...
fn_make_remora_beep(int32 &,int32 * params)2699 mcodeFunctionReturnCodes _game_session::fn_make_remora_beep(int32 &, int32 *params) {
2700 if (logic_structs[cur_id]->image_type != VOXEL)
2701 Fatal_error("fn_make_remora_beep - object %s is not a person! what is this?", object->GetName());
2702
2703 if (params[0] == 0) {
2704 L->mega->make_remora_beep = FALSE8;
2705 Zdebug("%s->fn_make_remora_beep(no beep)\n", object->GetName());
2706 } else if (params[0] == 1) {
2707 L->mega->make_remora_beep = TRUE8;
2708 Zdebug("%s->fn_make_remora_beep(beep)\n", object->GetName());
2709 } else
2710 Fatal_error("fn_make_remora_beep - object [%s] called with value %d", object->GetName(), params[0]);
2711
2712 return (IR_CONT);
2713 }
2714
2715 // fn_set_evil(1) sets us to evil mode for beeping and possibly scanner, fn_set_evil(0) sets us to harmless
fn_set_evil(int32 &,int32 * params)2716 mcodeFunctionReturnCodes _game_session::fn_set_evil(int32 &, int32 *params) {
2717 if (logic_structs[cur_id]->image_type != VOXEL)
2718 Fatal_error("fn_set_evil - object %s is not a person! what is this?", object->GetName());
2719
2720 if (params[0] == 0) {
2721 L->mega->is_evil = FALSE8;
2722 Zdebug("%s->fn_set_evil(NOT_EVIL!)\n", object->GetName());
2723 } else if (params[0] == 1) {
2724 L->mega->is_evil = TRUE8;
2725 Zdebug("%s->fn_set_evil(EVIL!)\n", object->GetName());
2726 } else
2727 Fatal_error("fn_set_evil - object [%s] called with value %d", object->GetName(), params[0]);
2728
2729 return (IR_CONT);
2730 }
2731
fn_set_object_type(int32 &,int32 * params)2732 mcodeFunctionReturnCodes _game_session::fn_set_object_type(int32 &, int32 *params) {
2733 // This allows an object to set its type variable. At the moment, this is picked up only by the
2734 // Remora, for the purposes of displaying a suitable symbol, but we may be able to add other
2735 // functionality on it if we require.
2736 logic_structs[cur_id]->object_type = (__object_type)params[0];
2737 return (IR_CONT);
2738 }
2739
fn_do_not_disturb(int32 &,int32 * params)2740 mcodeFunctionReturnCodes _game_session::fn_do_not_disturb(int32 &, int32 *params) {
2741 bool8 bDoNotDisturb;
2742
2743 Zdebug("fn_do_not_disturb( %d ) called by object %d", (uint32)params[0], cur_id);
2744
2745 // Typesafe convert the parameter.
2746 bDoNotDisturb = ((uint32)params[0] == 0) ? FALSE8 : TRUE8;
2747
2748 logic_structs[cur_id]->do_not_disturb = bDoNotDisturb;
2749
2750 // Calling script can continue.
2751 return (IR_CONT);
2752 }
2753
fn_is_mega_within_area(int32 & result,int32 * params)2754 mcodeFunctionReturnCodes _game_session::fn_is_mega_within_area(int32 &result, int32 *params) {
2755 // is the named object within the specified rect
2756
2757 // params 0 name of object
2758 // 1,2,3,4 x,z, x1,z1
2759
2760 // returns true/false
2761
2762 uint32 id;
2763 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2764
2765 id = (uint32)objects->Fetch_item_number_by_name(object_name);
2766
2767 if (id == 0xffffffff)
2768 Fatal_error("fn_is_mega_within_area - illegal object [%s]", object_name);
2769
2770 if (logic_structs[id]->image_type == PROP)
2771 Fatal_error("fn_is_mega_within_area - object [%s] not a mega", object_name);
2772
2773 if ((logic_structs[id]->mega->actor_xyz.x > (PXreal)params[1]) && (logic_structs[id]->mega->actor_xyz.x < (PXreal)params[3]) &&
2774 (logic_structs[id]->mega->actor_xyz.z > (PXreal)params[2]) && (logic_structs[id]->mega->actor_xyz.z < (PXreal)params[4])) {
2775 result = TRUE8;
2776 } else {
2777 result = FALSE8;
2778 }
2779
2780 return IR_CONT;
2781 }
2782
fn_end_mission(int32 &,int32 *)2783 mcodeFunctionReturnCodes _game_session::fn_end_mission(int32 &, int32 *) {
2784 // end the mission and drop back to console, or, the main script
2785
2786 // shhhhhh - make everything quiet
2787 PauseSounds();
2788
2789 g_mission->End_mission();
2790
2791 return IR_STOP;
2792 }
2793
fn_restart_gamescript(int32 &,int32 *)2794 mcodeFunctionReturnCodes _game_session::fn_restart_gamescript(int32 &, int32 *) {
2795 // reset gamescript so that game begins afresh
2796 // presumably first thing in GS will be Start new game/Restore previous screen
2797
2798 return IR_CONT;
2799 }
2800
fn_am_i_player(int32 & result,int32 *)2801 mcodeFunctionReturnCodes _game_session::fn_am_i_player(int32 &result, int32 *) {
2802 // This function returns true if the player calls it, false otherwise. Allows an interact
2803 // script to tell if the player is using it or another mega.
2804
2805 if (cur_id == player.Fetch_player_id())
2806 result = 1;
2807 else
2808 result = 0;
2809
2810 // Calling script can continue.
2811 return (IR_CONT);
2812 }
2813
fn_start_conveyor(int32 &,int32 * params)2814 mcodeFunctionReturnCodes _game_session::fn_start_conveyor(int32 &, int32 *params) {
2815 // start a conveyor belt
2816
2817 // params 0 x
2818 // 1 y
2819 // 2 z
2820 // 3 x1
2821 // 4 z1
2822 // 5 xm
2823 // 6 zm
2824
2825 uint32 j;
2826
2827 for (j = 0; j < MAX_conveyors; j++) {
2828 if (conveyors[j].moving == FALSE8) {
2829 // found a slot
2830 conveyors[j].x = (PXreal)params[0];
2831 conveyors[j].y = (PXreal)params[1];
2832 conveyors[j].z = (PXreal)params[2];
2833 conveyors[j].x1 = (PXreal)params[3];
2834 conveyors[j].z1 = (PXreal)params[4];
2835 conveyors[j].xm = (PXreal)params[5];
2836 conveyors[j].zm = (PXreal)params[6];
2837
2838 conveyors[j].moving = TRUE8;
2839
2840 Tdebug("conveyor.txt", "conveyor %d = %d,%d,%d %d,%d %d,%d", j, params[0], params[1], params[2], params[3], params[4], params[5], params[6]);
2841
2842 return IR_CONT;
2843 }
2844 }
2845
2846 Fatal_error("too many conveyors!");
2847 return IR_CONT;
2848 }
2849
fn_stop_conveyor(int32 &,int32 * params)2850 mcodeFunctionReturnCodes _game_session::fn_stop_conveyor(int32 &, int32 *params) {
2851 // stop a conveyor
2852
2853 uint32 j;
2854
2855 for (j = 0; j < MAX_conveyors; j++) {
2856 if (conveyors[j].moving == TRUE8) {
2857 if ((conveyors[j].x == (PXreal)params[0]) && (conveyors[j].z == (PXreal)params[1])) {
2858 Tdebug("conveyor.txt", "conveyor %d stopped", j);
2859 conveyors[j].moving = FALSE8;
2860 return IR_CONT;
2861 }
2862 }
2863 }
2864
2865 Fatal_error("no conveyor @ %d,%d", params[0], params[1]);
2866
2867 return IR_CONT;
2868 }
2869
Process_conveyors()2870 void _game_session::Process_conveyors() {
2871 uint32 j;
2872
2873 for (j = 0; j < MAX_conveyors; j++) {
2874 if (conveyors[j].moving == TRUE8) {
2875 if ((logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x > conveyors[j].x) &&
2876 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.y == conveyors[j].y) &&
2877 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x < conveyors[j].x1) &&
2878 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z > conveyors[j].z) &&
2879 (logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z < conveyors[j].z1)) {
2880 logic_structs[player.Fetch_player_id()]->mega->actor_xyz.x += conveyors[j].xm;
2881 logic_structs[player.Fetch_player_id()]->mega->actor_xyz.z += conveyors[j].zm;
2882 }
2883 }
2884 }
2885 }
2886
fn_register_ladder(int32 & result,int32 * params)2887 mcodeFunctionReturnCodes _game_session::fn_register_ladder(int32 &result, int32 *params) {
2888 // register a ladder
2889
2890 // params 0 target marker name
2891 // 1 1==top (else bottom)
2892 // 2 length
2893
2894 const char *marker_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2895
2896 result = Register_stair_or_ladder(marker_name, (bool8)params[1], params[2], FALSE8, 24);
2897
2898 return IR_CONT;
2899 }
2900
fn_register_stairway(int32 & result,int32 * params)2901 mcodeFunctionReturnCodes _game_session::fn_register_stairway(int32 &result, int32 *params) {
2902 // register a stairway
2903
2904 // params 0 target marker name
2905 // 1 1==top (else bottom)
2906 // 2 length
2907
2908 const char *marker_name = (const char *)MemoryUtil::resolvePtr(params[0]);
2909
2910 result = Register_stair_or_ladder(marker_name, (bool8)params[1], params[2], TRUE8, 18);
2911
2912 return IR_CONT;
2913 }
2914
fn_activate_stair_or_ladder(int32 &,int32 * params)2915 mcodeFunctionReturnCodes _game_session::fn_activate_stair_or_ladder(int32 &, int32 *params) {
2916 Set_state_of_stair_or_ladder((uint32)params[0], TRUE8);
2917
2918 return (IR_CONT);
2919 }
2920
fn_deactivate_stair_or_ladder(int32 &,int32 * params)2921 mcodeFunctionReturnCodes _game_session::fn_deactivate_stair_or_ladder(int32 &, int32 *params) {
2922 Set_state_of_stair_or_ladder((uint32)params[0], FALSE8);
2923
2924 return (IR_CONT);
2925 }
2926
Set_state_of_stair_or_ladder(uint32 nIndex,bool8 bState)2927 void _game_session::Set_state_of_stair_or_ladder(uint32 nIndex, bool8 bState) {
2928 if (nIndex > num_stairs)
2929 Fatal_error("Index %d out or range 0-%d in _game_session::Set_state_of_stair_or_ladder()", nIndex, num_stairs - 1);
2930
2931 stairs[nIndex].live = bState;
2932 // do the other end
2933 stairs[stairs[nIndex].opposite_number].live = bState;
2934 }
2935
Register_stair_or_ladder(const char * target,bool8 top,uint32 length,bool8 isstair,uint32 stepcms)2936 uint32 _game_session::Register_stair_or_ladder(const char *target, bool8 top, uint32 length, bool8 isstair, uint32 stepcms) {
2937 _feature_info *stair;
2938 _feature_info *dest_stair;
2939 PXreal x1, z1, x2, z2, x3, z3;
2940 uint32 dest_stair_id;
2941 uint8 j = 0;
2942
2943 if (!length)
2944 Fatal_error("%s has 0 length", object->GetName());
2945 if (length > 1000)
2946 Fatal_error("%s has illegal length %d", object->GetName(), length);
2947
2948 // get our nico
2949 stair = (_feature_info *)features->Try_fetch_item_by_name(const_cast<char *>(object->GetName()));
2950 // get other end
2951 dest_stair = (_feature_info *)features->Try_fetch_item_by_name(target);
2952 dest_stair_id = objects->Fetch_item_number_by_name(target);
2953
2954 if (!stair)
2955 Fatal_error("fn_register_stairway - cant find nico %s", object->GetName());
2956 if (!dest_stair)
2957 Fatal_error("fn_register_stairway - cant find nico %s", target);
2958 if (num_stairs == MAX_stairs)
2959 Fatal_error("too many stairs - max = %d", MAX_stairs);
2960
2961 stairs[num_stairs].pan = stair->direction;
2962 stairs[num_stairs].pan_ref = stair->direction;
2963 stairs[num_stairs].x = stair->x;
2964 stairs[num_stairs].z = stair->z;
2965
2966 // link up with other end
2967 for (j = 0; j < num_stairs; j++) {
2968 if (stairs[j].stair_id == dest_stair_id) { // found the target - its already set itself up
2969 stairs[j].opposite_number = (uint8)num_stairs; // its opposite is us
2970 stairs[num_stairs].opposite_number = j; // its our opposite number
2971 break;
2972 }
2973 }
2974
2975 PXfloat ang = stair->direction * TWO_PI;
2976 PXfloat cang = (PXfloat)PXcos(ang);
2977 PXfloat sang = (PXfloat)PXsin(ang);
2978 PXreal dx = PXfloat2PXreal((PXfloat)length * cang);
2979 PXreal dz = PXfloat2PXreal((PXfloat)length * sang);
2980
2981 #define STAIR_BARRIER_OFFSET 0
2982
2983 x1 = stair->x + PXfloat2PXreal(STAIR_BARRIER_OFFSET * sang);
2984 z1 = stair->z + PXfloat2PXreal(STAIR_BARRIER_OFFSET * cang);
2985
2986 x2 = x1 - dx;
2987 z2 = z1 + dz;
2988
2989 x3 = x1 + dx;
2990 z3 = z1 - dz;
2991
2992 // new constructor for barrier...
2993 stairs[num_stairs].bar = _route_barrier(x2, z2, x3, z3, stair->floor_y, (PXreal)0 /* dont care */, BRICK /* dont care */);
2994
2995 // create the BCM maths----------------------------------------------
2996 // The barrier has coordinates x2, z2 to x3, z3.
2997 // Fill in the structure that holds the extra collision maths.
2998
2999 stairs[num_stairs].bar.bcm().Generate(x2, z2, x3, z3);
3000 stairs[num_stairs].bar.Create_pan();
3001
3002 Tdebug("stairs.txt", "try this: %.4f, %g,%g,%g %g,%g %g,%g %g,%g\n", stairs[num_stairs].bar.pan(), stairs[num_stairs].bar.bcm().linedist(),
3003 stairs[num_stairs].bar.bcm().alinedist(), stairs[num_stairs].bar.bcm().blinedist(), stairs[num_stairs].bar.bcm().lpx(), stairs[num_stairs].bar.bcm().lpz(),
3004 stairs[num_stairs].bar.bcm().alpx(), stairs[num_stairs].bar.bcm().alpz(), stairs[num_stairs].bar.bcm().blpx(), stairs[num_stairs].bar.bcm().blpz());
3005
3006 // create the BCM maths----------------------------------------------
3007
3008 // work out unit height
3009 stairs[num_stairs].units = (uint8)((PXfabs(dest_stair->floor_y - stair->floor_y) + (stepcms / 2)) / stepcms);
3010
3011 // dir
3012 if (!top) // if not the top
3013 stairs[num_stairs].up = TRUE8; // then its the bottom which means we're going up
3014 else {
3015 stairs[num_stairs].up = FALSE8; // else down
3016
3017 // top of ladders have their pan adjusted
3018 if (!isstair)
3019 stairs[num_stairs].pan_ref = stair->direction + HALF_TURN;
3020 }
3021
3022 // set id
3023 stairs[num_stairs].stair_id = (uint8)cur_id;
3024
3025 // type
3026 stairs[num_stairs].is_stair = isstair;
3027
3028 // make stair active
3029 stairs[num_stairs].live = TRUE8;
3030
3031 // diagnostics
3032 if (isstair)
3033 Tdebug("stairs.txt", "\nInit stair %d", num_stairs);
3034 else
3035 Tdebug("stairs.txt", "\nInit ladder %d", num_stairs);
3036 Tdebug("stairs.txt", "marker %3.2f,%3.2f, %3.2f", stair->x, stair->floor_y, stair->z);
3037 Tdebug("stairs.txt", "point 1 = %3.2f, %3.2f", x2, z2);
3038 Tdebug("stairs.txt", "point 2 = %3.2f, %3.2f", x3, z3);
3039 Tdebug("stairs.txt", "units = %d", stairs[num_stairs].units);
3040 if (stairs[num_stairs].up)
3041 Tdebug("stairs.txt", "going up");
3042 else
3043 Tdebug("stairs.txt", "going down");
3044
3045 L->list_result = num_stairs; // script needs to get this
3046
3047 return stairs[num_stairs++].units; // set to uploop in object - instead of implementor!
3048 }
3049
fn_align_with_floor(int32 &,int32 *)3050 mcodeFunctionReturnCodes _game_session::fn_align_with_floor(int32 &, int32 *) {
3051 // mega climbing stairs and ladder calls this afterward to realign with artist misaligned floors
3052
3053 floor_def->Allign_with_floor(M);
3054
3055 return IR_CONT;
3056 }
3057
fn_load_players_gun(int32 &,int32 * params)3058 mcodeFunctionReturnCodes _game_session::fn_load_players_gun(int32 &, int32 *params) {
3059 // put bullets in the players gun
3060
3061 player.SetBullets(params[0]);
3062
3063 return IR_CONT;
3064 }
3065
fn_flash_health(int32 &,int32 *)3066 mcodeFunctionReturnCodes _game_session::fn_flash_health(int32 &, int32 *) {
3067 // flash the health when you get shot
3068
3069 health_time = 12;
3070
3071 return IR_CONT;
3072 }
fn_set_anim_speed(int32 &,int32 * params)3073 mcodeFunctionReturnCodes _game_session::fn_set_anim_speed(int32 &, int32 *params) {
3074 // set a megas animation playback rate
3075
3076 // params 0 rate
3077
3078 if (logic_structs[cur_id]->image_type != VOXEL)
3079 Fatal_error("fn_set_anim_speed says people only!");
3080
3081 M->anim_speed = (uint8)params[0];
3082
3083 return IR_CONT;
3084 }
3085
fn_push_coords(int32 &,int32 *)3086 mcodeFunctionReturnCodes _game_session::fn_push_coords(int32 &, int32 *) {
3087 // push coordinates - used before megas attempt to climb stairs or ladders - for save games
3088
3089 M->pushed = TRUE8;
3090
3091 memcpy(&M->pushed_actor_xyz, &M->actor_xyz, sizeof(PXvector));
3092
3093 return IR_CONT;
3094 }
3095
fn_pop_coords(int32 &,int32 *)3096 mcodeFunctionReturnCodes _game_session::fn_pop_coords(int32 &, int32 *) {
3097 // remove previous pop
3098
3099 M->pushed = FALSE8;
3100
3101 return IR_CONT;
3102 }
3103
fn_quick_restart(int32 & result,int32 *)3104 mcodeFunctionReturnCodes _game_session::fn_quick_restart(int32 &result, int32 *) {
3105 // reset game now or not
3106 // if not then mission ends
3107 // if so then simply reset the player
3108
3109 // if ( MessageBox(windowHandle, "reset player?", "would you like to...", MB_YESNO | MB_DEFBUTTON2 ) == IDYES )
3110 {
3111 result = 1; // do
3112 MS->Restart_player();
3113 }
3114
3115 return IR_CONT;
3116 }
3117
fn_shadows_on(int32 &,int32 *)3118 mcodeFunctionReturnCodes _game_session::fn_shadows_on(int32 &, int32 *) {
3119 // shadows back on
3120
3121 if (logic_structs[cur_id]->image_type != VOXEL)
3122 Fatal_error("fn_shadows_on says people only!");
3123
3124 M->drawShadow = TRUE8; // shadows back on
3125
3126 return IR_CONT;
3127 }
3128
fn_shadows_off(int32 &,int32 *)3129 mcodeFunctionReturnCodes _game_session::fn_shadows_off(int32 &, int32 *) {
3130 // shadows back on
3131
3132 if (logic_structs[cur_id]->image_type != VOXEL)
3133 Fatal_error("fn_shadows_off says people only!");
3134
3135 M->drawShadow = FALSE8; // shadows back on
3136
3137 return IR_CONT;
3138 }
3139
fn_set_shade_percentage(int32 &,int32 * params)3140 mcodeFunctionReturnCodes _game_session::fn_set_shade_percentage(int32 &, int32 *params) {
3141 // set shade percentage figure for mega
3142
3143 if (L->image_type != VOXEL)
3144 Fatal_error("fn_set_shade_percentage [%s] says people only!", object->GetName());
3145 if (params[0] > 99)
3146 Fatal_error("fn_set_shade_percentage [%s] percentages usually go 0-99", object->GetName());
3147
3148 M->inShadePercentage = (uint8)params[0];
3149
3150 return IR_CONT;
3151 }
3152
fn_set_half_character_width(int32 &,int32 * params)3153 mcodeFunctionReturnCodes _game_session::fn_set_half_character_width(int32 &, int32 *params) {
3154 // adjust the default barrier extrapolation for route barriers - for people like spectre who is very big
3155
3156 if (!M)
3157 Fatal_error("fn_set_door_width only for megas [%s]", object->GetName());
3158
3159 M->extrap_size = (uint8)params[0];
3160
3161 return IR_CONT;
3162 }
3163
fn_set_visible(int32 &,int32 * params)3164 mcodeFunctionReturnCodes _game_session::fn_set_visible(int32 &, int32 *params) {
3165 // set high level on off clip
3166 // params 0 0 off 1 on
3167
3168 if (!M)
3169 Fatal_error("%s fn_set_visible is for megas only", object->GetName());
3170
3171 M->display_me = (bool8)params[0];
3172
3173 return IR_CONT;
3174 }
3175
fn_set_object_visible(int32 &,int32 * params)3176 mcodeFunctionReturnCodes _game_session::fn_set_object_visible(int32 &, int32 *params) {
3177 uint32 nObjectID;
3178
3179 const char *object_name = (const char *)MemoryUtil::resolvePtr(params[0]);
3180
3181 // Find the target object's ID.
3182 nObjectID = objects->Fetch_item_number_by_name(object_name);
3183
3184 // Make sure object is a mega character.
3185 if (!(logic_structs[nObjectID]->mega))
3186 Fatal_error("fn_set_object_visible is for megas only");
3187
3188 // Right it is a mega, so set its flag.
3189 logic_structs[nObjectID]->mega->display_me = ((int32)params[1] == 0) ? FALSE8 : TRUE8;
3190
3191 // Calling script can continue.
3192 return (IR_CONT);
3193 }
3194
3195 // fn_set_interact_look_height(h)
3196 // sets the height of an interact object for the looking around code
3197 // the units are cm above the floor...
fn_set_interact_look_height(int32 &,int32 * params)3198 mcodeFunctionReturnCodes _game_session::fn_set_interact_look_height(int32 &, int32 *params) {
3199 int32 h = params[0];
3200
3201 L->look_height = h;
3202
3203 return IR_CONT;
3204 }
3205
fn_set_to_dead(int32 &,int32 *)3206 mcodeFunctionReturnCodes _game_session::fn_set_to_dead(int32 &, int32 *) {
3207 // set the dead flag - we have a flag for speed of access
3208
3209 if (!L->mega)
3210 Fatal_error("fn_set_to_dead called for [%s] but not a mega", object->GetName());
3211
3212 L->mega->dead = TRUE8;
3213
3214 return IR_CONT;
3215 }
3216
fn_set_camera_hold(int32 &,int32 * params)3217 mcodeFunctionReturnCodes _game_session::fn_set_camera_hold(int32 &, int32 *params) {
3218 // switch camera hold mode on or off
3219
3220 if (M)
3221 Fatal_error("fn_set_camera_hold called for [%s] but this is for props only", object->GetName());
3222
3223 // find entry for this object via its name, which we find via its number :(
3224 if (!prop_anims->Try_fetch_item_by_name(object->GetName()))
3225 return IR_CONT; // item has no prop entry - so keep it live
3226
3227 if (params[0])
3228 L->hold_mode = prop_camera_hold;
3229 else
3230 L->hold_mode = none;
3231
3232 return IR_CONT;
3233 }
3234
fn_set_mega_wait_for_player(int32 &,int32 *)3235 mcodeFunctionReturnCodes _game_session::fn_set_mega_wait_for_player(int32 &, int32 *) {
3236 // mega will pause until the player arrives
3237
3238 if (!M)
3239 Fatal_error("fn_set_mega_wait_for_player called for [%s] but not a mega", object->GetName());
3240
3241 L->big_mode = __MEGA_INITIAL_FLOOR_HELD;
3242
3243 return IR_CONT;
3244 }
3245
fn_set_mega_off_camera_hold(int32 &,int32 *)3246 mcodeFunctionReturnCodes _game_session::fn_set_mega_off_camera_hold(int32 &, int32 *) {
3247 // mega will pause when not on_camera
3248
3249 if (!M)
3250 Fatal_error("fn_set_mega_off_camera_hold called for [%s] but not a mega", object->GetName());
3251
3252 L->big_mode = __MEGA_PLAYER_FLOOR_HELD;
3253 L->hold_mode = mega_player_floor_hold;
3254
3255 return IR_CONT;
3256 }
3257
fn_set_mega_slice_hold(int32 &,int32 * params)3258 mcodeFunctionReturnCodes _game_session::fn_set_mega_slice_hold(int32 &, int32 *params) {
3259 // mega will pause until the player arrives
3260
3261 // params 0 y distance to stray before character holds again
3262
3263 if (!M)
3264 Fatal_error("fn_set_mega_slice_hold called for [%s] but not a mega", object->GetName());
3265
3266 L->big_mode = __MEGA_SLICE_HELD;
3267 L->hold_mode = mega_slice_hold;
3268 M->slice_hold_tolerance = (uint32)params[0];
3269
3270 return IR_CONT;
3271 }
3272
fn_lock_y(int32 &,int32 * params)3273 mcodeFunctionReturnCodes _game_session::fn_lock_y(int32 &, int32 *params) {
3274 // lock a y coord of a named nico marker - the floor chooser will use this value. Good for lifts that cross multiple slices, etc
3275
3276 _feature_info *nico;
3277 const char *marker_name = (const char *)MemoryUtil::resolvePtr(params[0]);
3278
3279 nico = (_feature_info *)features->Try_fetch_item_by_name(marker_name);
3280 if (!nico)
3281 Fatal_error("fn_lock_y by [%s] for nico [%s] finds no such nico", object->GetName(), marker_name);
3282
3283 M->y_locked = TRUE8;
3284 M->y_lock = nico->y;
3285
3286 return IR_CONT;
3287 }
3288
fn_unlock_y(int32 &,int32 *)3289 mcodeFunctionReturnCodes _game_session::fn_unlock_y(int32 &, int32 *) {
3290 // cancel locked y
3291
3292 M->y_locked = FALSE8;
3293
3294 return IR_CONT;
3295 }
3296
fn_flip_pan(int32 &,int32 *)3297 mcodeFunctionReturnCodes _game_session::fn_flip_pan(int32 &, int32 *) {
3298 // flip the pan 180deg - used, for example, when megas get off the bottom of ladders
3299 // this is why we are going to engine code this type of logic next time
3300
3301 L->pan += HALF_TURN;
3302
3303 return IR_CONT;
3304 }
3305
fn_snap_to_ladder_bottom(int32 &,int32 *)3306 mcodeFunctionReturnCodes _game_session::fn_snap_to_ladder_bottom(int32 &, int32 *) {
3307 // used to position non player megas going up ladders
3308
3309 #define MEGA_SNAP_UP 40
3310
3311 for (uint8 j = 0; j < num_stairs; j++) {
3312 if (stairs[j].stair_id == M->target_id) { // found the target - its already set itself up
3313 Snap_to_ladder(&stairs[j], MEGA_SNAP_UP);
3314 return IR_CONT;
3315 }
3316 }
3317
3318 return IR_CONT;
3319 }
3320
fn_snap_to_ladder_top(int32 &,int32 *)3321 mcodeFunctionReturnCodes _game_session::fn_snap_to_ladder_top(int32 &, int32 *) {
3322 // used to position non player megas going down ladders
3323
3324 #define MEGA_SNAP_DOWN 85
3325
3326 for (uint8 j = 0; j < num_stairs; j++) {
3327 if (stairs[j].stair_id == M->target_id) { // found the target - its already set itself up
3328 Snap_to_ladder(&stairs[j], MEGA_SNAP_DOWN);
3329 return IR_CONT;
3330 }
3331 }
3332
3333 return IR_CONT;
3334 }
3335
fn_set_to_floor(int32 &,int32 * params)3336 mcodeFunctionReturnCodes _game_session::fn_set_to_floor(int32 &, int32 *params) {
3337 // locate a character onto a specified floor
3338 // crudely sticks the character in the middle of the first floor LRECT
3339
3340 // params[0] ascii name of floor
3341
3342 //const char *floor_name = (const char *)MemoryUtil::resolvePtr(params[0]);
3343
3344 // get the floor
3345 //_floor *floor = (_floor *)floor_def->Fetch_named_floor(floor_name);
3346
3347 return IR_CONT;
3348 }
3349
3350 } // End of namespace ICB
3351