mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19ca467c41 | ||
|
|
73736280f9 | ||
|
|
d5546f95e8 | ||
|
|
29edfeedea | ||
|
|
8cf20b0175 | ||
|
|
c85040efc4 | ||
|
|
a16be863f3 | ||
|
|
de80c254ae | ||
|
|
d703fcacc3 | ||
|
|
ddef6ea377 | ||
|
|
2b2333f692 | ||
|
|
4a819d7b20 | ||
|
|
a79dd70138 | ||
|
|
d5af6b5775 | ||
|
|
e3b24ea9e2 | ||
|
|
8645210c0a | ||
|
|
8c39bf54d4 | ||
|
|
bb43411bb1 | ||
|
|
622ae3ef2c | ||
|
|
ab7a1d8fd7 | ||
|
|
a246ef21aa | ||
|
|
e8d379a91c | ||
|
|
45862e06a9 | ||
|
|
c9dd97d223 | ||
|
|
25a6bf2b87 |
No files matched your search
+55
-33
@@ -10015,12 +10015,26 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
|
||||
aip->submode = SM_ATTACK;
|
||||
aip->submode_start_time = Missiontime;
|
||||
aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC;
|
||||
} else if (Objects[aip->target_objnum].type == OBJ_SHIP) {
|
||||
int num_attacking_cur, num_attacking_new;
|
||||
} else {
|
||||
// This section used to be a lot simpler, but some "invalid" object types were probably getting into num_ships_attacking
|
||||
// below, so we have to manually return for some object types and make sure to assert for other object types
|
||||
// that are symptomatic of a larger problem with the engine.
|
||||
|
||||
// This just checks to see that the target was a valid type. If it is not one of these, something really
|
||||
// could be drastically wrong in the engine.
|
||||
Assertion(Objects[aip->target_objnum].type == OBJ_SHIP || Objects[aip->target_objnum].type == OBJ_WEAPON || Objects[aip->target_objnum].type == OBJ_DEBRIS || Objects[aip->target_objnum].type == OBJ_ASTEROID || Objects[aip->target_objnum].type == OBJ_WAYPOINT,
|
||||
"This function just discovered that %s has an invalid target object type of %d. This is bad. Please report!",
|
||||
Ships[aip->shipnum].ship_name, Objects[aip->target_objnum].type);
|
||||
|
||||
if (!(Objects[aip->target_objnum].type == OBJ_SHIP || Objects[aip->target_objnum].type == OBJ_WEAPON || Objects[aip->target_objnum].type == OBJ_ASTEROID || Objects[aip->target_objnum].type == OBJ_DEBRIS)){
|
||||
// it's probably a valid target, but retail would not count those cases, so just return.
|
||||
return;
|
||||
}
|
||||
|
||||
int num_attacking_cur = num_ships_attacking(aip->target_objnum);
|
||||
|
||||
num_attacking_cur = num_ships_attacking(aip->target_objnum);
|
||||
if (num_attacking_cur > 1) {
|
||||
num_attacking_new = num_ships_attacking(hitter_objnum);
|
||||
int num_attacking_new = num_ships_attacking(hitter_objnum);
|
||||
|
||||
if (num_attacking_new < num_attacking_cur) {
|
||||
|
||||
@@ -10037,8 +10051,6 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
|
||||
aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE("The AI previously had a guard goal to guard something besides a ship, specifically an object of type %d. As we understand it, this should not happen. Please report!", Objects[aip->target_objnum].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14710,7 +14722,8 @@ void ai_frame(int objnum)
|
||||
}
|
||||
}
|
||||
|
||||
static void ai_control_info_check(ai_info *aip, ship_info *sip, physics_info *pi)
|
||||
// set and removes any maneuver flags for ai maneuver overrides
|
||||
static void ai_control_info_flags_upkeep(ai_info* aip, ship_info* sip, physics_info* pi)
|
||||
{
|
||||
if (aip->ai_override_flags.none_set())
|
||||
return;
|
||||
@@ -14741,6 +14754,37 @@ static void ai_control_info_check(ai_info *aip, ship_info *sip, physics_info *pi
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_bank_when_turning] || sip->flags[Ship::Info_Flags::Dont_bank_when_turning])
|
||||
AI_ci.control_flags |= CIF_DONT_BANK_WHEN_TURNING;
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_clamp_max_velocity] || sip->flags[Ship::Info_Flags::Dont_clamp_max_velocity])
|
||||
AI_ci.control_flags |= CIF_DONT_CLAMP_MAX_VELOCITY;
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Instantaneous_acceleration] || sip->flags[Ship::Info_Flags::Instantaneous_acceleration])
|
||||
AI_ci.control_flags |= CIF_INSTANTANEOUS_ACCELERATION;
|
||||
}
|
||||
|
||||
// set physics flag according to whether we are instantaneously accelerating
|
||||
if (AI_ci.control_flags & CIF_INSTANTANEOUS_ACCELERATION)
|
||||
pi->flags |= PF_MANEUVER_NO_DAMP;
|
||||
else
|
||||
pi->flags &= ~PF_MANEUVER_NO_DAMP;
|
||||
}
|
||||
|
||||
// applies any rotational or lateral maneuver values to the AI's CI
|
||||
static void ai_control_info_apply(ai_info *aip)
|
||||
{
|
||||
if (aip->ai_override_flags.none_set())
|
||||
return;
|
||||
|
||||
bool lateral_maneuver = false;
|
||||
bool rotational_maneuver = false;
|
||||
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Lateral_never_expire] || !timestamp_elapsed(aip->ai_override_lat_timestamp))
|
||||
lateral_maneuver = true;
|
||||
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Rotational_never_expire] || timestamp_elapsed(aip->ai_override_rot_timestamp))
|
||||
rotational_maneuver = true;
|
||||
|
||||
if (lateral_maneuver || rotational_maneuver) {
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Full_rot])
|
||||
{
|
||||
AI_ci.pitch = aip->ai_override_ci.pitch;
|
||||
@@ -14750,17 +14794,11 @@ static void ai_control_info_check(ai_info *aip, ship_info *sip, physics_info *pi
|
||||
else
|
||||
{
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Pitch])
|
||||
{
|
||||
AI_ci.pitch = aip->ai_override_ci.pitch;
|
||||
}
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Heading])
|
||||
{
|
||||
AI_ci.heading = aip->ai_override_ci.heading;
|
||||
}
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Roll])
|
||||
{
|
||||
AI_ci.bank = aip->ai_override_ci.bank;
|
||||
}
|
||||
}
|
||||
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Full_lat])
|
||||
@@ -14772,32 +14810,13 @@ static void ai_control_info_check(ai_info *aip, ship_info *sip, physics_info *pi
|
||||
else
|
||||
{
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Up])
|
||||
{
|
||||
AI_ci.vertical = aip->ai_override_ci.vertical;
|
||||
}
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Sideways])
|
||||
{
|
||||
AI_ci.sideways = aip->ai_override_ci.sideways;
|
||||
}
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Forward])
|
||||
{
|
||||
AI_ci.forward = aip->ai_override_ci.forward;
|
||||
}
|
||||
}
|
||||
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_bank_when_turning] || sip->flags[Ship::Info_Flags::Dont_bank_when_turning])
|
||||
AI_ci.control_flags |= CIF_DONT_BANK_WHEN_TURNING;
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_clamp_max_velocity] || sip->flags[Ship::Info_Flags::Dont_clamp_max_velocity])
|
||||
AI_ci.control_flags |= CIF_DONT_CLAMP_MAX_VELOCITY;
|
||||
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Instantaneous_acceleration] || sip->flags[Ship::Info_Flags::Instantaneous_acceleration])
|
||||
AI_ci.control_flags |= CIF_INSTANTANEOUS_ACCELERATION;
|
||||
}
|
||||
|
||||
// set physics flag according to whether we are instantaneously accelerating
|
||||
if (AI_ci.control_flags & CIF_INSTANTANEOUS_ACCELERATION)
|
||||
pi->flags |= PF_NO_DAMP;
|
||||
else
|
||||
pi->flags &= ~PF_NO_DAMP;
|
||||
}
|
||||
|
||||
int Last_ai_obj = -1;
|
||||
@@ -14857,9 +14876,12 @@ void ai_process( object * obj, int ai_index, float frametime )
|
||||
if (shipp->flags[Ship::Ship_Flags::Dying] && sip->flags[Ship::Info_Flags::Large_ship_deathroll])
|
||||
rfc = false;
|
||||
|
||||
// regardless if we're acting on them, upkeep maneuver flags
|
||||
ai_control_info_flags_upkeep(aip, sip, &obj->phys_info);
|
||||
|
||||
if (rfc) {
|
||||
// Wanderer - sexp based override goes here - only if rfc is valid though
|
||||
ai_control_info_check(aip, sip, &obj->phys_info);
|
||||
ai_control_info_apply(aip);
|
||||
physics_read_flying_controls( &obj->orient, &obj->phys_info, &AI_ci, frametime);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ void processEvents()
|
||||
{
|
||||
io::mouse::CursorManager::get()->showCursor(false);
|
||||
|
||||
os_remove_deferred_cutscene_key_events();
|
||||
os_poll();
|
||||
}
|
||||
|
||||
|
||||
@@ -1294,7 +1294,7 @@ void parse_soundtrack()
|
||||
continue;
|
||||
|
||||
// check for file
|
||||
if (!cf_exists_full(Soundtracks[strack_idx].patterns[i].fname, CF_TYPE_MUSIC))
|
||||
if (!cf_exists_full_ext(Soundtracks[strack_idx].patterns[i].fname, CF_TYPE_MUSIC, NUM_AUDIO_EXT, audio_ext_list))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,23 +31,23 @@
|
||||
#define GM_CAMPAIGN_MODE (1 << 10) // are we currently in a campaign.
|
||||
#define GM_LAB (1 << 11) // We are currently in the F3 lab
|
||||
|
||||
#define VM_EXTERNAL (1 << 0) // Set if not viewing from player position.
|
||||
#define VM_TRACK (1 << 1) // Set if viewer is tracking target.
|
||||
#define VM_DEAD_VIEW (1 << 2) // Set if viewer is watching from dead view.
|
||||
#define VM_CHASE (1 << 3) // Chase view.
|
||||
#define VM_OTHER_SHIP (1 << 4) // View from another ship.
|
||||
#define VM_CAMERA_LOCKED (1 << 5) // Set if player does not have control of the camera
|
||||
#define VM_WARP_CHASE (1 << 6) // View while warping out (form normal view mode)
|
||||
#define VM_PADLOCK_UP (1 << 7)
|
||||
#define VM_PADLOCK_REAR (1 << 8)
|
||||
#define VM_PADLOCK_LEFT (1 << 9)
|
||||
#define VM_PADLOCK_RIGHT (1 << 10)
|
||||
#define VM_WARPIN_ANCHOR (1 << 11) // special warpin camera mode
|
||||
#define VM_TOPDOWN (1 << 12) //Camera is looking down on ship
|
||||
#define VM_FREECAMERA (1 << 13) //Camera is not attached to any particular object, probably under SEXP control
|
||||
#define VM_CENTERING (1 << 14) // View is springing to center
|
||||
#define VM_EXTERNAL (1 << 0) // Set if not viewing from player position.
|
||||
#define VM_TRACK (1 << 1) // Set if viewer is tracking target.
|
||||
#define VM_DEAD_VIEW (1 << 2) // Set if viewer is watching from dead view.
|
||||
#define VM_CHASE (1 << 3) // Chase view.
|
||||
#define VM_OTHER_SHIP (1 << 4) // View from another ship.
|
||||
#define VM_CAMERA_LOCKED (1 << 5) // Set if player does not have control of the camera
|
||||
#define VM_WARP_CHASE (1 << 6) // View while warping out (form normal view mode)
|
||||
#define VM_PADLOCK_UP (1 << 7) // Set when player is looking up
|
||||
#define VM_PADLOCK_REAR (1 << 8) // Set when player is looking behind
|
||||
#define VM_PADLOCK_LEFT (1 << 9) // Set when player is looking left
|
||||
#define VM_PADLOCK_RIGHT (1 << 10) // Set when player is looking right
|
||||
#define VM_WARPIN_ANCHOR (1 << 11) // special warpin camera mode
|
||||
#define VM_TOPDOWN (1 << 12) // Camera is looking down on ship
|
||||
#define VM_FREECAMERA (1 << 13) // Camera is not attached to any particular object, probably under SEXP control
|
||||
#define VM_CENTERING (1 << 14) // View is springing to center
|
||||
|
||||
#define VM_PADLOCK_ANY (VM_PADLOCK_UP|VM_PADLOCK_REAR|VM_PADLOCK_LEFT|VM_PADLOCK_RIGHT)
|
||||
#define VM_PADLOCK_ANY (VM_PADLOCK_UP | VM_PADLOCK_REAR | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)
|
||||
|
||||
//-----Cutscene stuff
|
||||
//No bars
|
||||
|
||||
@@ -642,3 +642,8 @@ fix timestamp_get_mission_time()
|
||||
|
||||
return static_cast<fix>(time / MICROSECONDS_PER_SECOND);
|
||||
}
|
||||
|
||||
uint64_t timestamp_get_mission_time_in_microseconds()
|
||||
{
|
||||
return timestamp_get_microseconds() - Timestamp_microseconds_at_mission_start;
|
||||
}
|
||||
@@ -106,6 +106,7 @@ extern int timer_get_seconds(); // seconds since program started... not accur
|
||||
constexpr int MILLISECONDS_PER_SECOND = 1000;
|
||||
constexpr uint64_t MICROSECONDS_PER_SECOND = 1000000;
|
||||
constexpr uint64_t NANOSECONDS_PER_SECOND = 1000000000;
|
||||
constexpr uint64_t NANOSECONDS_PER_MICROSECOND = 1000;
|
||||
|
||||
// use this call to get the current counter value (which represents the time at the time
|
||||
// this function is called). I.e. it doesn't return a count that would be in the future,
|
||||
@@ -225,5 +226,6 @@ void timestamp_start_mission();
|
||||
|
||||
// Calculate the current mission time using the timestamps
|
||||
fix timestamp_get_mission_time();
|
||||
uint64_t timestamp_get_mission_time_in_microseconds();
|
||||
|
||||
#endif
|
||||
@@ -2070,6 +2070,7 @@ void vm_angular_move_forward_vec(const vec3d* goal_f, const matrix* orient, cons
|
||||
|
||||
// handle bank separately, simpler, since its just a target velocity
|
||||
{
|
||||
CLAMP(bank_vel, -vel_limit->xyz.z, vel_limit->xyz.z);
|
||||
float delta_bank_vel = bank_vel - w_in->xyz.z;
|
||||
float delta_bank_accel = fl_abs(delta_bank_vel) / delta_t; // the accel required to reach the target vel this frame
|
||||
float accel = (delta_bank_accel > acc_limit->xyz.z) ? acc_limit->xyz.z : delta_bank_accel;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "scripting/scripting.h"
|
||||
#include "ship/ship.h"
|
||||
#include "ship/subsysdamage.h"
|
||||
#include "sound/audiostr.h"
|
||||
#include "sound/fsspeech.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "utils/Random.h"
|
||||
@@ -1735,7 +1736,7 @@ void message_queue_message( int message_num, int priority, int timing, const cha
|
||||
if (message_filename_has_fs1_wingman_prefix(filename)) {
|
||||
char converted[MAX_FILENAME_LEN];
|
||||
message_filename_convert_to_command(converted, filename);
|
||||
if (cf_exists_full(converted, CF_TYPE_VOICE_SPECIAL)) {
|
||||
if (cf_exists_full_ext(converted, CF_TYPE_VOICE_SPECIAL, NUM_AUDIO_EXT, audio_ext_list)) {
|
||||
convert_to_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,7 +926,7 @@ void debrief_choose_voice(char *voice_dest, size_t buf_size, char *voice_base, i
|
||||
if (snprintf(voice_dest, buf_size, NOX("%d_%s"), persona_index, voice_base) < static_cast<int>(buf_size))
|
||||
{
|
||||
// if it exists, we're done
|
||||
if (cf_exists_full(voice_dest, CF_TYPE_VOICE_DEBRIEFINGS))
|
||||
if (cf_exists_full_ext(voice_dest, CF_TYPE_VOICE_DEBRIEFINGS, NUM_AUDIO_EXT, audio_ext_list))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1368,9 +1368,10 @@ int multi_oo_pack_data(net_player *pl, object *objp, ushort oo_flags, ubyte *dat
|
||||
|
||||
// Check that we are not sending too much data, if so, don't actually send.
|
||||
if (packet_size + ret <= OO_MAX_DATA_SIZE) {
|
||||
nprintf(("Network","Had to remove subsystems section from data packet for %s\n", shipp->ship_name));
|
||||
oo_flags |= OO_SUBSYSTEMS_NEW;
|
||||
packet_size += ret;
|
||||
} else {
|
||||
nprintf(("Network","Had to remove subsystems section from data packet for %s\n", shipp->ship_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-8
@@ -300,7 +300,7 @@ static char szWinTitle[128];
|
||||
static char szWinClass[128];
|
||||
static int Os_inited = 0;
|
||||
|
||||
static SCP_vector<SDL_Event> buffered_events;
|
||||
static SCP_vector<SDL_Event> deferred_events;
|
||||
|
||||
int Os_debugger_running = 0;
|
||||
|
||||
@@ -713,11 +713,11 @@ namespace os
|
||||
}
|
||||
}
|
||||
|
||||
void os_ignore_events() {
|
||||
void os_defer_events_on_load_screen() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
// Add event to buffer
|
||||
buffered_events.push_back(event);
|
||||
// Add event to be handled later
|
||||
deferred_events.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,14 +745,28 @@ static void handle_sdl_event(const SDL_Event& event) {
|
||||
}
|
||||
}
|
||||
|
||||
void os_remove_deferred_cutscene_key_events() {
|
||||
deferred_events.erase(
|
||||
std::remove_if(deferred_events.begin(), deferred_events.end(), [](const SDL_Event &event)
|
||||
{
|
||||
return (event.type == SDL_KEYUP) && (
|
||||
event.key.keysym.sym == SDLK_KP_ENTER ||
|
||||
event.key.keysym.sym == SDLK_RETURN ||
|
||||
event.key.keysym.sym == SDLK_SPACE
|
||||
);
|
||||
}),
|
||||
deferred_events.end()
|
||||
);
|
||||
}
|
||||
|
||||
void os_poll()
|
||||
{
|
||||
// Replay the buffered events
|
||||
auto end = buffered_events.end();
|
||||
for (auto it = buffered_events.begin(); it != end; ++it) {
|
||||
// Replay the deferred events
|
||||
auto end = deferred_events.end();
|
||||
for (auto it = deferred_events.begin(); it != end; ++it) {
|
||||
handle_sdl_event(*it);
|
||||
}
|
||||
buffered_events.clear();
|
||||
deferred_events.clear();
|
||||
|
||||
SDL_Event event;
|
||||
|
||||
|
||||
+5
-2
@@ -64,9 +64,12 @@ int os_foreground();
|
||||
// process management --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Removes all pending events and ignores them
|
||||
* @brief Defers all pending events to be handled later
|
||||
*/
|
||||
void os_ignore_events();
|
||||
void os_defer_events_on_load_screen();
|
||||
|
||||
// removes key events that may unintentionally skip the cutscene
|
||||
void os_remove_deferred_cutscene_key_events();
|
||||
|
||||
// call to process windows messages. only does something in non THREADED mode
|
||||
void os_poll();
|
||||
|
||||
+48
-4
@@ -2125,6 +2125,12 @@ int check_sexp_syntax(int node, int return_type, int recursive, int *bad_node, i
|
||||
|
||||
} else if (Sexp_nodes[node].subtype == SEXP_ATOM_CONTAINER_DATA) {
|
||||
// this is an instance of "Replace Container Data"
|
||||
|
||||
// can't be used in special argument list
|
||||
if (type == OPF_ANYTHING || type == OPF_DATA_OR_STR_CONTAINER) {
|
||||
return SEXP_CHECK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
const int modifier_node = Sexp_nodes[node].first;
|
||||
if (modifier_node == -1) {
|
||||
return SEXP_CHECK_MISSING_CONTAINER_MODIFIER;
|
||||
@@ -11029,6 +11035,13 @@ void sexp_change_argument_validity(int n, bool invalidate)
|
||||
// first we must check if the arg_handler marks a selection. At the moment random-of is the only one that does this
|
||||
arg_n = CDR(arg_handler);
|
||||
while (invalidate && (arg_n != -1)) {
|
||||
Assertion(Sexp_nodes[arg_n].subtype != SEXP_ATOM_CONTAINER_NAME,
|
||||
"Attempt to use invalidate-argument with container %s. Please report!",
|
||||
Sexp_nodes[arg_n].text);
|
||||
Assertion(Sexp_nodes[arg_n].subtype != SEXP_ATOM_CONTAINER_DATA,
|
||||
"Attempt to use invalidate-argument with data from container %s. Please report!",
|
||||
Sexp_nodes[arg_n].text);
|
||||
|
||||
if (Sexp_nodes[arg_n].flags & SNF_ARGUMENT_SELECT) {
|
||||
// now check if the selected argument matches the one we want to invalidate
|
||||
if (!strcmp(CTEXT(n), CTEXT(arg_n))) {
|
||||
@@ -11047,6 +11060,13 @@ void sexp_change_argument_validity(int n, bool invalidate)
|
||||
arg_n = CDR(arg_handler);
|
||||
while (arg_n != -1)
|
||||
{
|
||||
Assertion(Sexp_nodes[arg_n].subtype != SEXP_ATOM_CONTAINER_NAME,
|
||||
"Attempt to change argument validity of container %s. Please report!",
|
||||
Sexp_nodes[arg_n].text);
|
||||
Assertion(Sexp_nodes[arg_n].subtype != SEXP_ATOM_CONTAINER_DATA,
|
||||
"Attempt to change argument validity of data from container %s. Please report!",
|
||||
Sexp_nodes[arg_n].text);
|
||||
|
||||
// match?
|
||||
if (!strcmp(CTEXT(n), CTEXT(arg_n)))
|
||||
{
|
||||
@@ -11826,7 +11846,7 @@ void sexp_clear_goals(int n)
|
||||
if (ship_entry)
|
||||
{
|
||||
if (ship_entry->status != ShipStatus::PRESENT)
|
||||
return; // ship not around anymore???? then forget it!
|
||||
continue; // ship not around anymore???? then forget it!
|
||||
|
||||
ai_clear_ship_goals(&(Ai_info[ship_entry->shipp->ai_index]));
|
||||
continue;
|
||||
@@ -11836,7 +11856,7 @@ void sexp_clear_goals(int n)
|
||||
if (wingp)
|
||||
{
|
||||
if (wingp->flags[Ship::Wing_Flags::Gone])
|
||||
return; // wing not around anymore???? then forget it!
|
||||
continue; // wing not around anymore???? then forget it!
|
||||
|
||||
ai_clear_wing_goals(wingp);
|
||||
}
|
||||
@@ -12208,6 +12228,11 @@ void multi_sexp_hud_display_gauge()
|
||||
void sexp_player_use_ai(int flag)
|
||||
{
|
||||
Player_use_ai = flag ? 1 : 0;
|
||||
|
||||
if (!flag) {
|
||||
Player_ai->ai_override_flags.reset();
|
||||
Player_obj->phys_info.flags &= ~PF_MANEUVER_NO_DAMP;
|
||||
}
|
||||
}
|
||||
|
||||
// Karajorma
|
||||
@@ -32293,6 +32318,21 @@ int get_category(int sexp_id)
|
||||
return category;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
const char *get_category_name(int category_id)
|
||||
{
|
||||
if (category_id == OP_CATEGORY_CHANGE2)
|
||||
category_id = OP_CATEGORY_CHANGE;
|
||||
|
||||
for (auto &category : op_menu)
|
||||
{
|
||||
if (category.id == category_id)
|
||||
return category.name.c_str();
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int category_of_subcategory(int subcategory_id)
|
||||
{
|
||||
@@ -33887,7 +33927,8 @@ SCP_vector<sexp_help_struct> Sexp_help = {
|
||||
// Goober5000
|
||||
{ OP_INVALIDATE_ARGUMENT, "Invalidate-argument (Conditional operator)\r\n"
|
||||
"\tRemoves an argument from future consideration as a " SEXP_ARGUMENT_STRING " special data item.\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, the retrieved arguments can't be individually invalidated.\r\n\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, the retrieved arguments can't be individually invalidated.\r\n"
|
||||
"\tAdditionally, you can't invalidate individual container arguments.\r\n\r\n"
|
||||
"Takes 1 or more arguments...\r\n"
|
||||
"\tAll:\tThe argument to remove from the preceding argument list." },
|
||||
|
||||
@@ -33895,19 +33936,22 @@ SCP_vector<sexp_help_struct> Sexp_help = {
|
||||
{ OP_VALIDATE_ARGUMENT, "Validate-argument (Conditional operator)\r\n"
|
||||
"\tRestores an argument for future consideration as a " SEXP_ARGUMENT_STRING " special data item.\r\n"
|
||||
"\tIf the argument hasn't been previously invalidated, it will do nothing.\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, the retrieved arguments can't be individually validated.\r\n\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, the retrieved arguments can't be individually validated.\r\n"
|
||||
"\tAdditionally, you can't validate individual container arguments.\r\n\r\n"
|
||||
"Takes 1 or more arguments...\r\n"
|
||||
"\tAll:\tThe argument to restore to the preceding argument list." },
|
||||
|
||||
// Karajorma
|
||||
{ OP_INVALIDATE_ALL_ARGUMENTS, "Invalidate-all-arguments (Conditional operator)\r\n"
|
||||
"\tRemoves all argument from future consideration as " SEXP_ARGUMENT_STRING " special data items.\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, container arguments will also be invalidated, but they can't be indvidiually validated.\r\n\r\n"
|
||||
"Takes no arguments." },
|
||||
|
||||
// Karajorma
|
||||
{ OP_VALIDATE_ALL_ARGUMENTS, "Validate-all-arguments (Conditional operator)\r\n"
|
||||
"\tRestores all arguments for future consideration as " SEXP_ARGUMENT_STRING " special data items.\r\n"
|
||||
"\tIf the argument hasn't been previously invalidated, it will do nothing.\r\n"
|
||||
"\tFor argument-related SEXPs that accept containers as arguments, container arguments will also be validated, but they can't be indvidiually invalidated.\r\n\r\n"
|
||||
"Takes no arguments." },
|
||||
|
||||
// Goober5000 - added wing capability
|
||||
|
||||
@@ -1359,6 +1359,7 @@ void set_turret_secondary_ammo(ship_subsys *turret, int requested_bank, int requ
|
||||
extern int get_category(int sexp_id);
|
||||
extern int category_of_subcategory(int subcategory_id);
|
||||
extern int get_subcategory(int sexp_id);
|
||||
extern const char *get_category_name(int category_id);
|
||||
|
||||
// Goober5000
|
||||
extern void sexp_music_close();
|
||||
|
||||
@@ -125,8 +125,10 @@ void parse_sexp_table(const char* filename) {
|
||||
luaSexp->parseTable();
|
||||
|
||||
int op = add_dynamic_sexp(std::move(instance), SEXP_GOAL_OPERATOR);
|
||||
luaSexp->registerAIMode(op);
|
||||
luaSexp->maybeRegisterPlayerOrder(op);
|
||||
if (op >= 0) {
|
||||
luaSexp->registerAIMode(op);
|
||||
luaSexp->maybeRegisterPlayerOrder(op);
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
@@ -177,8 +179,19 @@ int add_dynamic_sexp(std::unique_ptr<DynamicSEXP>&& sexp, int type)
|
||||
new_op.min = sexp->getMinimumArguments();
|
||||
new_op.max = sexp->getMaximumArguments();
|
||||
|
||||
int free_op_index = get_next_free_operator(sexp->getCategory());
|
||||
if (free_op_index >= 256) {
|
||||
Warning(LOCATION, "There are too many SEXPs in the %s category. The SEXP %s will not be added.", get_category_name(sexp->getCategory()), sexp->getName().c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Operators.size() >= FIRST_OP) {
|
||||
Warning(LOCATION, "There are too many total SEXPs. The SEXP %s will not be added.", sexp->getName().c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// For now, all dynamic SEXPS are only valid in missions
|
||||
new_op.value = get_next_free_operator(sexp->getCategory()) | sexp->getCategory() | OP_NONCAMPAIGN_FLAG;
|
||||
new_op.value = free_op_index | sexp->getCategory() | OP_NONCAMPAIGN_FLAG;
|
||||
new_op.type = type;
|
||||
|
||||
global.operator_const_mapping.insert(std::make_pair(new_op.value, std::move(sexp)));
|
||||
|
||||
@@ -168,7 +168,7 @@ void physics_sim_rot(matrix * orient, physics_info * pi, float sim_time )
|
||||
shock_amplitude = pi->shockwave_shake_amp * shock_fraction_time_left;
|
||||
}
|
||||
}
|
||||
else if (pi->flags & PF_NO_DAMP) {
|
||||
else if (pi->flags & PF_MANEUVER_NO_DAMP) {
|
||||
rotdamp = 0.0f;
|
||||
}
|
||||
else {
|
||||
@@ -305,7 +305,7 @@ void physics_sim_vel(vec3d * position, physics_info * pi, float sim_time, matrix
|
||||
}
|
||||
}
|
||||
// no damping at all
|
||||
else if (pi->flags & PF_NO_DAMP) {
|
||||
else if (pi->flags & PF_MANEUVER_NO_DAMP) {
|
||||
damp = vmd_zero_vector;
|
||||
}
|
||||
// newtonian
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define PF_GLIDING (1 << 14)
|
||||
#define PF_FORCE_GLIDE (1 << 15)
|
||||
#define PF_NEWTONIAN_DAMP (1 << 16) // SUSHI: Whether or not to use newtonian dampening
|
||||
#define PF_NO_DAMP (1 << 17) // Goober5000 - don't damp velocity changes in physics; used for instantaneous acceleration
|
||||
#define PF_MANEUVER_NO_DAMP (1 << 17) // Goober5000 - don't damp velocity changes in physics; used for instantaneous acceleration
|
||||
|
||||
//information for physics sim for an object
|
||||
typedef struct physics_info {
|
||||
|
||||
@@ -510,16 +510,6 @@ void do_view_external()
|
||||
Viewer_external_info.angles.h = PI2 + Viewer_external_info.angles.h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Separate out the reading of thrust keys, so we can call this from external view as well as from normal view
|
||||
*/
|
||||
void do_thrust_keys(control_info *ci)
|
||||
{
|
||||
ci->forward = check_control_timef(FORWARD_THRUST) - check_control_timef(REVERSE_THRUST);
|
||||
ci->sideways = (check_control_timef(RIGHT_SLIDE_THRUST) - check_control_timef(LEFT_SLIDE_THRUST));//for slideing-Bobboau
|
||||
ci->vertical = (check_control_timef(UP_SLIDE_THRUST) - check_control_timef(DOWN_SLIDE_THRUST));//for slideing-Bobboau
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by single and multiplayer modes to reset information inside of control info structure
|
||||
*/
|
||||
@@ -552,12 +542,12 @@ void read_keyboard_controls( control_info * ci, float frame_time, physics_info *
|
||||
|
||||
// Camera & View controls
|
||||
if ( Viewer_mode & VM_EXTERNAL ) {
|
||||
// External mode
|
||||
control_used(VIEW_EXTERNAL);
|
||||
|
||||
do_view_external();
|
||||
do_thrust_keys(ci);
|
||||
|
||||
} else if ( Viewer_mode & VM_CHASE ) {
|
||||
// Chase mode
|
||||
do_view_chase();
|
||||
|
||||
} else {
|
||||
@@ -570,7 +560,6 @@ void read_keyboard_controls( control_info * ci, float frame_time, physics_info *
|
||||
// Ship controls
|
||||
if (Viewer_mode & VM_CAMERA_LOCKED) {
|
||||
// From keyboard...
|
||||
do_thrust_keys(ci);
|
||||
if ( check_control(BANK_WHEN_PRESSED) ) {
|
||||
ci->bank = check_control_timef(BANK_LEFT) + check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT) - check_control_timef(BANK_RIGHT);
|
||||
ci->heading = 0.0f;
|
||||
@@ -609,6 +598,12 @@ void read_keyboard_controls( control_info * ci, float frame_time, physics_info *
|
||||
}
|
||||
|
||||
if (!(Game_mode & GM_DEAD)) {
|
||||
// Thrust controls
|
||||
ci->forward = check_control_timef(FORWARD_THRUST) - check_control_timef(REVERSE_THRUST);
|
||||
ci->sideways = (check_control_timef(RIGHT_SLIDE_THRUST) - check_control_timef(LEFT_SLIDE_THRUST)); // for slideing-Bobboau
|
||||
ci->vertical = (check_control_timef(UP_SLIDE_THRUST) - check_control_timef(DOWN_SLIDE_THRUST)); // for slideing-Bobboau
|
||||
|
||||
// Throttle controls
|
||||
if ( button_info_query(&Player->bi, ONE_THIRD_THROTTLE) ) {
|
||||
control_used(ONE_THIRD_THROTTLE);
|
||||
player_clear_speed_matching();
|
||||
|
||||
@@ -10,10 +10,15 @@ namespace api {
|
||||
|
||||
ADE_LIB(l_Time, "Time", "time", "Real-Time library");
|
||||
|
||||
ADE_FUNC(getCurrentTime, l_Time, nullptr, "Gets the current real-time timestamp.", "timestamp", "The current time")
|
||||
ADE_FUNC(getCurrentTime, l_Time, nullptr, "Gets the current real-time timestamp, i.e. the actual elapsed time, regardless of whether the game has changed time compression or been paused.", "timestamp", "The current time")
|
||||
{
|
||||
return ade_set_args(L, "o", l_Timestamp.Set(timer_get_nanoseconds()));
|
||||
}
|
||||
|
||||
ADE_FUNC(getCurrentMissionTime, l_Time, nullptr, "Gets the current mission-time timestamp, which can be affected by time compression and paused.", "timestamp", "The current mission time")
|
||||
{
|
||||
return ade_set_args(L, "o", l_Timestamp.Set(timestamp_get_mission_time_in_microseconds() * NANOSECONDS_PER_MICROSECOND));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
@@ -63,7 +63,7 @@ ADE_VIRTVAR(FPS, l_MoviePlayer, "number", "Determines the frames per second of t
|
||||
LuaError(L, "Tried to modify read-only member!");
|
||||
}
|
||||
|
||||
return ade_set_args(L, "f", (int)ph->player()->getMovieProperties().fps);
|
||||
return ade_set_args(L, "f", ph->player()->getMovieProperties().fps);
|
||||
}
|
||||
|
||||
ADE_FUNC(update, l_MoviePlayer, "timespan step_time",
|
||||
|
||||
@@ -31,7 +31,7 @@ ADE_FUNC(getSeconds, l_TimeSpan, nullptr, "Gets the value of this timestamp in s
|
||||
}
|
||||
|
||||
// Timestamps and spans are stored in nanoseconds
|
||||
return ade_set_args(L, "f", (float)value / 1000000000.f);
|
||||
return ade_set_args(L, "f", (float)((long double)value / (long double)NANOSECONDS_PER_SECOND));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -172,12 +172,15 @@ LuaValueList LuaFunction::call(lua_State* L, const LuaValueList& args) const {
|
||||
stackTop = lua_gettop(L);
|
||||
}
|
||||
|
||||
if(!lua_checkstack(L, (int)args.size() + 1))
|
||||
throw LuaException("Lua Stack Overflow!");
|
||||
|
||||
// Push the function onto the stack
|
||||
this->pushValue(L);
|
||||
this->pushValue(L, true);
|
||||
|
||||
// Push the arguments onto the stack
|
||||
for (const auto& arg : args) {
|
||||
arg.pushValue(L);
|
||||
arg.pushValue(L, true);
|
||||
}
|
||||
|
||||
// actually call the function now!
|
||||
|
||||
@@ -80,10 +80,14 @@ bool UniqueLuaReference::isValid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void UniqueLuaReference::pushValue(lua_State* thread) const
|
||||
void UniqueLuaReference::pushValue(lua_State* thread, bool manualStackAllocation) const
|
||||
{
|
||||
Assertion(thread != nullptr, "Valid thread state must be specified!");
|
||||
|
||||
if (!manualStackAllocation) {
|
||||
lua_checkstack(thread, 1);
|
||||
}
|
||||
|
||||
if (this->isValid()) {
|
||||
lua_rawgeti(thread, LUA_REGISTRYINDEX, this->getReference());
|
||||
}
|
||||
|
||||
@@ -100,8 +100,9 @@ class UniqueLuaReference {
|
||||
/**
|
||||
* @brief Pushes the referenced value onto the stack.
|
||||
* @param thread A specific thread state to push the value to. nullptr for the default state of this reference
|
||||
* @param manualStackAllocation Set to true if you manually allocate sufficient stack size before calling this function. Keep false unless you know what you are doing.
|
||||
*/
|
||||
void pushValue(lua_State* thread) const;
|
||||
void pushValue(lua_State* thread, bool manualStackAllocation = false) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -88,10 +88,10 @@ bool LuaValue::isValid() const {
|
||||
return _reference && _reference->isValid();
|
||||
}
|
||||
|
||||
bool LuaValue::pushValue(lua_State* thread) const
|
||||
bool LuaValue::pushValue(lua_State* thread, bool manualStackAllocation) const
|
||||
{
|
||||
if (this->_reference->isValid()) {
|
||||
this->_reference->pushValue(thread);
|
||||
this->_reference->pushValue(thread, manualStackAllocation);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -185,8 +185,9 @@ class LuaValue {
|
||||
* @brief Pushes this lua value onto the stack.
|
||||
* @param thread The thread stack onto which this value should be pushed. May be nullptr for the default state of
|
||||
* this value
|
||||
* @param manualStackAllocation Set to true if you manually allocate sufficient stack size before calling this function. Keep false unless you know what you are doing.
|
||||
*/
|
||||
bool pushValue(lua_State* thread) const;
|
||||
bool pushValue(lua_State* thread, bool manualStackAllocation = false) const;
|
||||
|
||||
lua_State* getLuaState() const;
|
||||
|
||||
|
||||
@@ -337,14 +337,20 @@ bool script_state::EvalStringWithReturn(const char* string, const char* format,
|
||||
scripting::ade_get_args(LuaState, format, rtn);
|
||||
}
|
||||
} catch (const LuaException&) {
|
||||
lua_pop(LuaState, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (const LuaException& e) {
|
||||
LuaError(GetLuaSession(), "%s", e.what());
|
||||
|
||||
lua_pop(LuaState, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
lua_pop(LuaState, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+15
-16
@@ -1193,7 +1193,7 @@ void game_loading_callback(int count)
|
||||
|
||||
Script_system.RemHookVar("Progress");
|
||||
|
||||
os_ignore_events();
|
||||
os_defer_events_on_load_screen();
|
||||
|
||||
if (do_flip)
|
||||
gr_flip();
|
||||
@@ -6683,17 +6683,7 @@ void game_shutdown(void)
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
// Free the scripting resources of the new UI first
|
||||
scpui::shutdown_scripting();
|
||||
|
||||
// Everything after this should be done without scripting so we can free those resources here
|
||||
Script_system.Clear();
|
||||
|
||||
// Deinitialize the new UI system, needs to be done after scripting shutdown to make sure the resources were
|
||||
// released properly
|
||||
scpui::shutdown();
|
||||
|
||||
|
||||
// if the player has left the "player select" screen and quit the game without actually choosing
|
||||
// a player, Player will be nullptr, in which case we shouldn't write the player file out!
|
||||
if (!(Game_mode & GM_STANDALONE_SERVER) && (Player!=nullptr) && !Is_standalone){
|
||||
@@ -6729,9 +6719,6 @@ void game_shutdown(void)
|
||||
|
||||
scoring_close();
|
||||
|
||||
// Free SEXP resources
|
||||
sexp_shutdown();
|
||||
|
||||
stars_close(); // clean out anything used by stars code
|
||||
|
||||
// the menu close functions will unload the bitmaps if they were displayed during the game
|
||||
@@ -6741,6 +6728,19 @@ void game_shutdown(void)
|
||||
// free left over memory from table parsing
|
||||
player_tips_close();
|
||||
|
||||
|
||||
// more fundamental shutdowns begin here ----------
|
||||
|
||||
sexp_shutdown(); // Free SEXP resources
|
||||
|
||||
scpui::shutdown_scripting(); // Free the scripting resources of the new UI first
|
||||
|
||||
Script_system.Clear(); // Everything after this should be done without scripting so we can free those resources here.
|
||||
// By this point, all things that hold Lua References must be destroyed (such as Lua SEXPs)
|
||||
|
||||
scpui::shutdown(); // Deinitialize the new UI system, needs to be done after scripting shutdown to make sure the resources were released properly
|
||||
|
||||
|
||||
control_config_common_close();
|
||||
io::joystick::shutdown();
|
||||
|
||||
@@ -6779,7 +6779,6 @@ void game_shutdown(void)
|
||||
}
|
||||
|
||||
lcl_xstr_close();
|
||||
|
||||
}
|
||||
|
||||
// game_stop_looped_sounds()
|
||||
|
||||
Reference in new issue
Block a user