mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b7fc0b6a3 | ||
|
|
2e4bef0d09 | ||
|
|
172952cb0f | ||
|
|
72c27bdbe8 | ||
|
|
bd4de16007 | ||
|
|
2e560f2ddb | ||
|
|
d35d3d25f8 | ||
|
|
2d5111f14b | ||
|
|
d95754d6b4 | ||
|
|
5e3d4c6cfd | ||
|
|
deca820c9e | ||
|
|
21c298271b |
No files matched your search
+1050
-21
File diff suppressed because it is too large.
Load diff
@@ -18,6 +18,7 @@ void hud_init_missile_lock();
|
||||
void hud_calculate_lock_position(float frametime);
|
||||
void hud_calculate_lock_start_pos();
|
||||
void hud_do_lock_indicator(float frametime);
|
||||
void hud_do_lock_indicators(float frametime);
|
||||
void hud_stop_looped_locking_sounds();
|
||||
void hud_lock_reset(float lock_time_scale=1.0f);
|
||||
|
||||
@@ -54,7 +55,9 @@ public:
|
||||
void initLoopLockedAnim(bool loop);
|
||||
|
||||
void render(float frametime) override;
|
||||
void renderOld(float frametime);
|
||||
void renderLockTriangles(int center_x, int center_y, float frametime);
|
||||
void renderLockTrianglesNew(int center_x, int center_y, int start_timestamp);
|
||||
void renderLockTrianglesOld(int center_x, int center_y, int radius);
|
||||
void pageIn() override;
|
||||
void initialize() override;
|
||||
|
||||
@@ -3431,6 +3431,7 @@ void hud_show_targeting_gauges(float frametime)
|
||||
vec3d target_pos;
|
||||
|
||||
hud_show_hostile_triangle();
|
||||
hud_do_lock_indicators(frametime);
|
||||
|
||||
if (Player_ai->target_objnum == -1)
|
||||
return;
|
||||
@@ -3480,8 +3481,6 @@ void hud_show_targeting_gauges(float frametime)
|
||||
|
||||
// display the lock indicator
|
||||
if (!Player->target_is_dying) {
|
||||
hud_do_lock_indicator(frametime);
|
||||
|
||||
// update and render artillery
|
||||
hud_artillery_update();
|
||||
hud_artillery_render();
|
||||
|
||||
@@ -781,10 +781,16 @@ void obj_player_fire_stuff( object *objp, control_info ci )
|
||||
// single player and multiplayer masters do all of the following
|
||||
if ( !MULTIPLAYER_CLIENT ) {
|
||||
if ( ci.fire_secondary_count ) {
|
||||
ship_fire_secondary( objp );
|
||||
if ( !ship_start_secondary_fire(objp) ) {
|
||||
ship_fire_secondary( objp );
|
||||
}
|
||||
|
||||
// kill the secondary count
|
||||
ci.fire_secondary_count = 0;
|
||||
} else {
|
||||
if ( ship_stop_secondary_fire(objp) ) {
|
||||
ship_fire_secondary( objp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+185
-17
@@ -11844,33 +11844,34 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
|
||||
// Ensure if this is a "require-lock" missile, that a lock actually exists
|
||||
if ( wip->wi_flags[Weapon::Info_Flags::No_dumbfire] ) {
|
||||
if ( aip->current_target_is_locked <= 0 ) {
|
||||
if ( obj == Player_obj ) {
|
||||
if ( !Weapon_energy_cheat ) {
|
||||
if (!aip->current_target_is_locked && !ship_lock_present(shipp) && !(shipp->missile_locks_firing.size() > 0)) {
|
||||
if (obj == Player_obj) {
|
||||
if (!Weapon_energy_cheat) {
|
||||
float max_dist;
|
||||
|
||||
max_dist = wip->lifetime * wip->max_speed;
|
||||
if (wip->wi_flags[Weapon::Info_Flags::Local_ssm]){
|
||||
max_dist= wip->lssm_lock_range;
|
||||
if (wip->wi_flags[Weapon::Info_Flags::Local_ssm]) {
|
||||
max_dist = wip->lssm_lock_range;
|
||||
}
|
||||
|
||||
if ((aip->target_objnum != -1) && (vm_vec_dist_quick(&obj->pos, &Objects[aip->target_objnum].pos) > max_dist)) {
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR( "Too far from target to acquire lock", 487));
|
||||
if ((aip->target_objnum != -1) &&
|
||||
(vm_vec_dist_quick(&obj->pos, &Objects[aip->target_objnum].pos) > max_dist)) {
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR("Too far from target to acquire lock", 487));
|
||||
} else {
|
||||
char missile_name[NAME_LENGTH];
|
||||
strcpy_s(missile_name, wip->get_display_string());
|
||||
end_string_at_first_hash_symbol(missile_name);
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Cannot fire %s without a lock", 488), missile_name);
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR("Cannot fire %s without a lock", 488), missile_name);
|
||||
}
|
||||
|
||||
snd_play( gamesnd_get_game_sound(ship_get_sound(Player_obj, GameSounds::OUT_OF_MISSLES)) );
|
||||
swp->next_secondary_fire_stamp[bank] = timestamp(800); // to avoid repeating messages
|
||||
snd_play(gamesnd_get_game_sound(ship_get_sound(Player_obj, GameSounds::OUT_OF_MISSLES)));
|
||||
swp->next_secondary_fire_stamp[bank] = timestamp(800); // to avoid repeating messages
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// multiplayer clients should always fire the weapon here, so return only if not
|
||||
// a multiplayer client.
|
||||
if ( !MULTIPLAYER_CLIENT ) {
|
||||
if (!MULTIPLAYER_CLIENT) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -11901,16 +11902,21 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !allow_swarm && obj == Player_obj ) {
|
||||
ship_queue_missile_locks(shipp);
|
||||
}
|
||||
|
||||
// if trying to fire a swarm missile, make sure being called from right place
|
||||
if ( (wip->wi_flags[Weapon::Info_Flags::Swarm]) && !allow_swarm ) {
|
||||
Assert(wip->swarm_count > 0);
|
||||
if(wip->swarm_count <= 0){
|
||||
if (wip->multi_lock && obj == Player_obj) {
|
||||
shipp->num_swarm_missiles_to_fire = (int)shipp->missile_locks_firing.size();
|
||||
} else if(wip->swarm_count <= 0){
|
||||
shipp->num_swarm_missiles_to_fire = SWARM_DEFAULT_NUM_MISSILES_FIRED;
|
||||
} else {
|
||||
shipp->num_swarm_missiles_to_fire = wip->swarm_count;
|
||||
}
|
||||
|
||||
shipp->swarm_missile_bank = bank;
|
||||
return 1; // Note: Missiles didn't get fired, but the frame interval code will fire them.
|
||||
}
|
||||
@@ -11919,7 +11925,11 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
if ( (wip->wi_flags[Weapon::Info_Flags::Corkscrew]) && !allow_swarm ) {
|
||||
//phreak 11-9-02
|
||||
//changed this from 4 to custom number defined in tables
|
||||
shipp->num_corkscrew_to_fire = (ubyte)(shipp->num_corkscrew_to_fire + (ubyte)wip->cs_num_fired);
|
||||
if (wip->multi_lock && obj == Player_obj) {
|
||||
shipp->num_corkscrew_to_fire = (ubyte)shipp->missile_locks_firing.size();
|
||||
} else {
|
||||
shipp->num_corkscrew_to_fire = (ubyte)(shipp->num_corkscrew_to_fire + (ubyte)wip->cs_num_fired);
|
||||
}
|
||||
shipp->corkscrew_missile_bank = bank;
|
||||
return 1; // Note: Missiles didn't get fired, but the frame interval code will fire them.
|
||||
}
|
||||
@@ -11933,7 +11943,7 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
t = Weapon_info[weapon_idx].fire_wait; // They can fire 5 times a second
|
||||
swp->burst_counter[bank_adjusted] = 0;
|
||||
}
|
||||
swp->next_secondary_fire_stamp[bank] = timestamp((int) (t * 1000.0f));
|
||||
swp->next_secondary_fire_stamp[bank] = timestamp((int)(t * 1000.0f));
|
||||
swp->last_secondary_fire_stamp[bank] = timestamp();
|
||||
|
||||
// Here is where we check if weapons subsystem is capable of firing the weapon.
|
||||
@@ -11961,6 +11971,33 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
return 0; // we can make a quick out here!!!
|
||||
}
|
||||
|
||||
int target_objnum;
|
||||
ship_subsys *target_subsys;
|
||||
int locked;
|
||||
|
||||
if ( obj == Player_obj ) {
|
||||
// use missile lock slots
|
||||
if ( shipp->missile_locks_firing.size() > 0 ) {
|
||||
lock_info lock_data = shipp->missile_locks_firing.back();
|
||||
|
||||
if ( wip->multi_lock ) {
|
||||
shipp->missile_locks_firing.pop_back();
|
||||
}
|
||||
|
||||
target_objnum = OBJ_INDEX(lock_data.obj);
|
||||
target_subsys = lock_data.subsys;
|
||||
locked = 1;
|
||||
} else {
|
||||
target_objnum = -1;
|
||||
target_subsys = nullptr;
|
||||
locked = 0;
|
||||
}
|
||||
} else {
|
||||
target_objnum = aip->target_objnum;
|
||||
target_subsys = aip->targeted_subsys;
|
||||
locked = aip->current_target_is_locked;
|
||||
}
|
||||
|
||||
num_slots = pm->missile_banks[bank].num_slots;
|
||||
|
||||
// determine if there is enough ammo left to fire weapons on this bank. As with primary
|
||||
@@ -12071,7 +12108,7 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
|
||||
// create the weapon -- for multiplayer, the net_signature is assigned inside
|
||||
// of weapon_create
|
||||
weapon_num = weapon_create( &firing_pos, &firing_orient, weapon_idx, OBJ_INDEX(obj), -1, aip->current_target_is_locked);
|
||||
weapon_num = weapon_create( &firing_pos, &firing_orient, weapon_idx, OBJ_INDEX(obj), -1, locked);
|
||||
|
||||
if (weapon_num == -1) {
|
||||
// Weapon most likely failed to fire
|
||||
@@ -12083,7 +12120,7 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
|
||||
if (weapon_num >= 0) {
|
||||
weapon_idx = Weapons[Objects[weapon_num].instance].weapon_info_index;
|
||||
weapon_set_tracking_info(weapon_num, OBJ_INDEX(obj), aip->target_objnum, aip->current_target_is_locked, aip->targeted_subsys);
|
||||
weapon_set_tracking_info(weapon_num, OBJ_INDEX(obj), target_objnum, locked, target_subsys);
|
||||
has_fired = true;
|
||||
|
||||
// create the muzzle flash effect
|
||||
@@ -19228,3 +19265,134 @@ bool ship::is_arriving(ship::warpstage stage, bool dock_leader_or_single)
|
||||
Assertion(false, "ship::is_arriving didn't handle all possible states; get a coder!");
|
||||
return false;
|
||||
}
|
||||
|
||||
void ship_clear_lock(lock_info *slot) {
|
||||
vec3d zero_vec = ZERO_VECTOR;
|
||||
|
||||
slot->accumulated_x_pixels = 0;
|
||||
slot->accumulated_y_pixels = 0;
|
||||
|
||||
slot->catch_up_distance = 0.0f;
|
||||
|
||||
slot->catching_up = 0;
|
||||
|
||||
slot->current_target_sx = -1;
|
||||
slot->current_target_sy = -1;
|
||||
|
||||
slot->dist_to_lock = 0.0f;
|
||||
|
||||
slot->indicator_start_x = -1;
|
||||
slot->indicator_start_y = -1;
|
||||
|
||||
slot->indicator_visible = false;
|
||||
|
||||
slot->indicator_x = -1;
|
||||
slot->indicator_y = -1;
|
||||
|
||||
slot->last_dist_to_target = 0.0f;
|
||||
|
||||
slot->locked_timestamp = 0;
|
||||
|
||||
slot->maintain_lock_count = 0;
|
||||
|
||||
slot->need_new_start_pos = false;
|
||||
|
||||
slot->target_in_lock_cone = false;
|
||||
|
||||
slot->world_pos = zero_vec;
|
||||
|
||||
slot->locked = false;
|
||||
|
||||
slot->obj = nullptr;
|
||||
slot->subsys = nullptr;
|
||||
|
||||
|
||||
slot->time_to_lock = -1.0f;
|
||||
}
|
||||
|
||||
void ship_queue_missile_locks(ship *shipp)
|
||||
{
|
||||
shipp->missile_locks_firing.clear();
|
||||
|
||||
// queue up valid missile locks
|
||||
std::copy_if(shipp->missile_locks.begin(), shipp->missile_locks.end(), std::back_inserter(shipp->missile_locks_firing), [](lock_info lock) { return lock.locked; });
|
||||
}
|
||||
|
||||
bool ship_lock_present(ship *shipp)
|
||||
{
|
||||
return std::any_of(shipp->missile_locks.begin(), shipp->missile_locks.end(), [](lock_info lock) { return lock.locked; });
|
||||
}
|
||||
|
||||
bool ship_start_secondary_fire(object* objp)
|
||||
{
|
||||
Assert( objp != nullptr);
|
||||
|
||||
if ( objp->type != OBJ_SHIP ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = objp->instance;
|
||||
|
||||
Assert( n >= 0 && n < MAX_SHIPS );
|
||||
Assert( Ships[n].objnum == OBJ_INDEX(objp) );
|
||||
|
||||
ship *shipp = &Ships[n];
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
ship_weapon* swp = &shipp->weapons;
|
||||
|
||||
int bank = swp->current_secondary_bank;
|
||||
|
||||
if ( bank < 0 || bank >= sip->num_secondary_banks ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert( (swp->secondary_bank_weapons[bank] >= 0) && (swp->secondary_bank_weapons[bank] < weapon_info_size()) );
|
||||
|
||||
weapon_info *wip = &Weapon_info[swp->secondary_bank_weapons[bank]];
|
||||
|
||||
if ( wip->trigger_lock ) {
|
||||
swp->flags.set(Ship::Weapon_Flags::Trigger_Lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ship_stop_secondary_fire(object* objp)
|
||||
{
|
||||
Assert( objp != nullptr);
|
||||
|
||||
if ( objp->type != OBJ_SHIP ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = objp->instance;
|
||||
|
||||
if ( n < 0 || n >= MAX_SHIPS ) {
|
||||
return false;
|
||||
}
|
||||
Assert( Ships[n].objnum == OBJ_INDEX(objp) );
|
||||
|
||||
ship *shipp = &Ships[n];
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
ship_weapon *swp = &shipp->weapons;
|
||||
|
||||
int bank = swp->current_secondary_bank;
|
||||
|
||||
if ( bank < 0 || bank >= sip->num_secondary_banks ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert( (swp->secondary_bank_weapons[bank] >= 0) && (swp->secondary_bank_weapons[bank] < weapon_info_size()) );
|
||||
|
||||
weapon_info *wip = &Weapon_info[swp->secondary_bank_weapons[bank]];
|
||||
|
||||
if ( wip->trigger_lock && swp->flags[Ship::Weapon_Flags::Trigger_Lock]) {
|
||||
swp->flags.remove(Ship::Weapon_Flags::Trigger_Lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "weapon/trails.h"
|
||||
#include "ship/ship_flags.h"
|
||||
#include "weapon/weapon_flags.h"
|
||||
#include "ai/ai.h"
|
||||
|
||||
#include <string>
|
||||
#include <particle/ParticleManager.h>
|
||||
@@ -283,6 +284,36 @@ typedef struct cockpit_display_info {
|
||||
int size[2];
|
||||
} cockpit_display_info;
|
||||
|
||||
// structure to keep track of ship locks
|
||||
typedef struct lock_info {
|
||||
object *obj;
|
||||
ship_subsys *subsys;
|
||||
|
||||
vec3d world_pos;
|
||||
|
||||
int current_target_sx;
|
||||
int current_target_sy;
|
||||
|
||||
bool locked;
|
||||
int maintain_lock_count;
|
||||
int indicator_x;
|
||||
int indicator_y;
|
||||
int indicator_start_x;
|
||||
int indicator_start_y;
|
||||
bool indicator_visible;
|
||||
float time_to_lock;
|
||||
float dist_to_lock;
|
||||
int catching_up;
|
||||
float catch_up_distance;
|
||||
float last_dist_to_target;
|
||||
double accumulated_x_pixels;
|
||||
double accumulated_y_pixels;
|
||||
bool need_new_start_pos;
|
||||
bool target_in_lock_cone;
|
||||
|
||||
int locked_timestamp;
|
||||
} lock_info;
|
||||
|
||||
// structure definition for a linked list of subsystems for a ship. Each subsystem has a pointer
|
||||
// to the static data for the subsystem. The obj_subsystem data is defined and read in the model
|
||||
// code. Other dynamic data (such as current_hits) should remain in this structure.
|
||||
@@ -560,6 +591,9 @@ public:
|
||||
vec3d wash_rot_axis;
|
||||
int wash_timestamp;
|
||||
|
||||
SCP_vector<lock_info> missile_locks;
|
||||
SCP_vector<lock_info> missile_locks_firing;
|
||||
|
||||
int num_swarm_missiles_to_fire; // number of swarm missiles that need to be launched
|
||||
int next_swarm_fire; // timestamp of next swarm missile to fire
|
||||
int next_swarm_path; // next path number for swarm missile to take
|
||||
@@ -1409,6 +1443,9 @@ extern bool in_autoaim_fov(ship *shipp, int bank_to_fire, object *obj);
|
||||
extern int ship_stop_fire_primary(object * obj);
|
||||
extern int ship_fire_primary(object * objp, int stream_weapons, int force = 0);
|
||||
extern int ship_fire_secondary(object * objp, int allow_swarm = 0 );
|
||||
bool ship_start_secondary_fire(object* objp);
|
||||
bool ship_stop_secondary_fire(object* objp);
|
||||
|
||||
extern int ship_launch_countermeasure(object *objp, int rand_val = -1);
|
||||
|
||||
// for special targeting lasers
|
||||
@@ -1800,4 +1837,13 @@ extern void toggle_ignore_list_flag(Ship::Ship_Flags flag);
|
||||
|
||||
ship_subsys* ship_get_subsys_for_submodel(ship* shipp, int submodel);
|
||||
|
||||
// Clears a lock_info struct with defaults
|
||||
void ship_clear_lock(lock_info *slot);
|
||||
|
||||
// queues up locks
|
||||
void ship_queue_missile_locks(ship *shipp);
|
||||
|
||||
// snoops missile locks to see if any are ready to fire.
|
||||
bool ship_lock_present(ship *shipp);
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@ namespace Ship {
|
||||
Beam_Free = 0, // if this is a beam weapon, its free to fire
|
||||
Turret_Lock, // is this turret is free to fire or locked
|
||||
Tagged_Only, // only fire if target is tagged
|
||||
Trigger_Lock, // // indicates that the trigger is held down
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
+30
-1
@@ -38,6 +38,15 @@ extern int Num_weapon_subtypes;
|
||||
#define WRT_LASER 1
|
||||
#define WRT_POF 2
|
||||
|
||||
// constants for weapon lock acquire methods
|
||||
#define WLOCK_PIXEL 0
|
||||
#define WLOCK_TIMER 1
|
||||
|
||||
// constants for weapon lock restrictions
|
||||
#define LR_CURRENT_TARGET 0 // Only lock current target and subsystem
|
||||
#define LR_CURRENT_TARGET_SUBSYS 1 //
|
||||
#define LR_ANY_TARGETS 2
|
||||
|
||||
//particle names go here -nuke
|
||||
#define PSPEW_NONE -1 //used to disable a spew, useful for xmts
|
||||
#define PSPEW_DEFAULT 0 //std fs2 pspew
|
||||
@@ -315,11 +324,24 @@ struct weapon_info
|
||||
short swarm_count; // how many swarm missiles are fired for this weapon
|
||||
int SwarmWait; // *Swarm firewait, default is 150 -Et1
|
||||
|
||||
int target_restrict;
|
||||
bool multi_lock;
|
||||
int max_seeking; // how many seekers can be active at a time if multilock is enabled. A value of one will lock stuff up one by one.
|
||||
int max_seekers_per_target; // how many seekers can be attached to a target.
|
||||
|
||||
SCP_vector<int> ship_type_restrict;
|
||||
SCP_vector<SCP_string> ship_type_restrict_temp;
|
||||
|
||||
bool trigger_lock; // Trigger must be held down and released to lock and fire.
|
||||
bool launch_reset_locks; // Lock indicators reset after firing
|
||||
|
||||
// Specific to ASPECT homing missiles.
|
||||
int acquire_method;
|
||||
float min_lock_time; // minimum time (in seconds) to achieve lock
|
||||
int lock_pixels_per_sec; // pixels/sec moved while locking
|
||||
int catchup_pixels_per_sec; // pixels/sec moved while catching-up for a lock
|
||||
int catchup_pixel_penalty; // number of extra pixels to move while locking as a penalty for catching up for a lock
|
||||
int catchup_pixel_penalty; // number of extra pixels to move while locking as a penalty for catching up for a lock
|
||||
float lock_fov;
|
||||
|
||||
// Specific to HEAT homing missiles.
|
||||
float fov;
|
||||
@@ -629,4 +651,11 @@ void validate_SSM_entries();
|
||||
|
||||
void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx);
|
||||
|
||||
// Swifty - return number of max simultaneous locks
|
||||
int weapon_get_max_missile_seekers(weapon_info *wip);
|
||||
|
||||
// return if this weapon can lock on this ship type
|
||||
bool weapon_can_lock_on_ship_type(weapon_info *wip, int ship_type);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1398,6 +1398,56 @@ int parse_weapon(int subtype, bool replace, const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("+Target Lock Restriction:")) {
|
||||
if (optional_string("current target, any subsystem")) {
|
||||
wip->target_restrict = LR_CURRENT_TARGET_SUBSYS;
|
||||
|
||||
}
|
||||
else if (optional_string("any target")) {
|
||||
wip->target_restrict = LR_ANY_TARGETS;
|
||||
|
||||
}
|
||||
else if (optional_string("current target only")) {
|
||||
wip->target_restrict = LR_CURRENT_TARGET;
|
||||
|
||||
}
|
||||
else {
|
||||
wip->target_restrict = LR_CURRENT_TARGET;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Independent Seekers:")) {
|
||||
stuff_boolean(&wip->multi_lock);
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Trigger Hold:")) {
|
||||
stuff_boolean(&wip->trigger_lock);
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Reset On Launch:")) {
|
||||
stuff_boolean(&wip->launch_reset_locks);
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Max Seekers Per Target:")) {
|
||||
stuff_int(&wip->max_seekers_per_target);
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Max Active Seekers:")) {
|
||||
stuff_int(&wip->max_seeking);
|
||||
|
||||
}
|
||||
|
||||
if (optional_string("+Ship Types:")) {
|
||||
stuff_string_list(wip->ship_type_restrict_temp);
|
||||
|
||||
}
|
||||
|
||||
if (wip->is_locked_homing()) {
|
||||
// locked homing missiles have a much longer lifespan than the AI think they do
|
||||
wip->max_lifetime = wip->lifetime * LOCKED_HOMING_EXTENDED_LIFE_FACTOR;
|
||||
@@ -3599,6 +3649,7 @@ void weapon_close()
|
||||
void weapon_level_init()
|
||||
{
|
||||
int i;
|
||||
extern int ships_inited;
|
||||
|
||||
// Reset everything between levels
|
||||
Num_weapons = 0;
|
||||
@@ -3610,6 +3661,19 @@ void weapon_level_init()
|
||||
for (i = 0; i < weapon_info_size(); i++) {
|
||||
Weapon_info[i].damage_type_idx = Weapon_info[i].damage_type_idx_sav;
|
||||
Weapon_info[i].shockwave.damage_type_idx = Weapon_info[i].shockwave.damage_type_idx_sav;
|
||||
|
||||
if ( ships_inited ) {
|
||||
// populate ship type lock restrictions
|
||||
for ( int j = 0; j < (int)Weapon_info[i].ship_type_restrict_temp.size(); ++j ) {
|
||||
int idx = ship_type_name_lookup((char*)Weapon_info[i].ship_type_restrict_temp[j].c_str());
|
||||
|
||||
if ( idx >= 0 ) {
|
||||
Weapon_info[i].ship_type_restrict.push_back(idx);
|
||||
}
|
||||
}
|
||||
|
||||
Weapon_info[i].ship_type_restrict_temp.clear();
|
||||
}
|
||||
}
|
||||
|
||||
trail_level_init(); // reset all missile trails
|
||||
@@ -7700,12 +7764,25 @@ void weapon_info::reset()
|
||||
// *Default is 150 -Et1
|
||||
this->SwarmWait = SWARM_MISSILE_DELAY;
|
||||
|
||||
this->target_restrict = LR_CURRENT_TARGET;
|
||||
this->multi_lock = false;
|
||||
this->trigger_lock = false;
|
||||
this->launch_reset_locks = false;
|
||||
|
||||
this->max_seeking = 1;
|
||||
this->max_seekers_per_target = 1;
|
||||
this->ship_type_restrict.clear();
|
||||
this->ship_type_restrict_temp.clear();
|
||||
|
||||
this->acquire_method = WLOCK_PIXEL;
|
||||
|
||||
this->min_lock_time = 0.0f;
|
||||
this->lock_pixels_per_sec = 50;
|
||||
this->catchup_pixels_per_sec = 50;
|
||||
this->catchup_pixel_penalty = 50;
|
||||
this->fov = 0; //should be cos(pi), not pi
|
||||
this->seeker_strength = 1.0f;
|
||||
this->lock_fov = 0.85f;
|
||||
|
||||
this->pre_launch_snd = gamesnd_id();
|
||||
this->pre_launch_snd_min_interval = 0;
|
||||
@@ -8094,3 +8171,30 @@ void weapon_spew_stats()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Given a weapon, figure out how many independent locks we can have with it.
|
||||
int weapon_get_max_missile_seekers(weapon_info *wip)
|
||||
{
|
||||
int max_target_locks;
|
||||
|
||||
if ( wip->multi_lock ) {
|
||||
if ( wip->wi_flags[Weapon::Info_Flags::Swarm] ) {
|
||||
max_target_locks = wip->swarm_count;
|
||||
} else if ( wip->wi_flags[Weapon::Info_Flags::Corkscrew] ) {
|
||||
max_target_locks = wip->cs_num_fired;
|
||||
} else {
|
||||
max_target_locks = 1;
|
||||
}
|
||||
} else {
|
||||
max_target_locks = 1;
|
||||
}
|
||||
|
||||
return max_target_locks;
|
||||
}
|
||||
|
||||
bool weapon_can_lock_on_ship_type(weapon_info *wip, int ship_type)
|
||||
{
|
||||
// Determine if there are any restrictions, treating an empty list as true
|
||||
return (wip->ship_type_restrict.size() == 0) ||
|
||||
std::any_of(wip->ship_type_restrict.begin(), wip->ship_type_restrict.end(), [ship_type](int type) { return type == ship_type; });
|
||||
}
|
||||
Reference in new issue
Block a user