use std::{collections::HashMap, error::Error, ffi::CStr};
use serde::{Deserialize, Serialize};
use crate::{
ai_interface::{
callback::{
resource::Resource,
weapon_def::{
bounce::{WeaponBounce, WeaponBounceAll},
shield::{WeaponShield, WeaponShieldAll},
},
},
AIInterface,
},
get_callback,
};
pub mod bounce;
pub mod shield;
#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct WeaponDef {
pub ai_id: i32,
pub weapon_def_id: i32,
}
#[derive(Debug, Clone)]
pub struct WeaponDefInterface {
pub ai_id: i32,
}
#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub enum Trajectory {
Low,
High,
Unit,
}
#[derive(Debug, Clone)]
pub struct WeaponDefAll {
name: String,
description: String,
range: f32,
spray_angle: f32,
moving_accuracy: f32,
target_move_error: f32,
lead_limit: f32,
lead_bonus: f32,
predict_boost: f32,
paralyze_damage_time: i32,
impulse_factor: f32,
impulse_boost: f32,
crater_multiplier: f32,
crater_boost: f32,
area_of_effect: f32,
self_damage: bool,
fire_starter: f32,
edge_effectivness: f32,
size: f32,
size_growth: f32,
collision_size: f32,
salvo_size: i32,
salvo_delay: f32,
reload: f32,
beam_time: f32,
beam_burst: bool,
bounce: WeaponBounceAll,
max_angle: f32,
up_time: f32,
flight_time: i32,
cost: HashMap<Resource, f32>,
projectiles_per_shot: i32,
turret: bool,
only_forward: bool,
fixed_launcher: bool,
water_weapon: bool,
fire_submersed: bool,
sub_missile: bool,
tracks: bool,
dropped: bool,
paralyzer: bool,
impact_only: bool,
auto_target: bool,
manual_fire: bool,
interceptor: bool,
targetable: bool,
stockpileable: bool,
stockpile_time: f32,
interceptor_coverage_range: f32,
fall_off_rate: f32,
sound_trigger: bool,
self_explode: bool,
gravity_affected: bool,
trajectory: Trajectory,
trajectory_height: f32,
gravity: f32,
explode: bool,
start_velocity: f32,
max_velocity: f32,
weapon_acceleration: f32,
turn_rate: f32,
projectile_speed: f32,
explosion_speed: f32,
wobble: f32,
dance: f32,
large_beam_laser: bool,
shield: Option<WeaponShieldAll>,
avoid_friendly: bool,
avoid_feature: bool,
avoid_neutral: bool,
target_border: f32,
cylinder_targetting: f32,
minimum_intensity: f32,
height_boost_factor: f32,
proximity_priority: f32,
sweep_fire: bool,
able_to_attack_ground: bool,
dynamic_damage_exponent: f32,
dynamic_damage_minimum: f32,
dynamic_damage_range: f32,
dynamic_damage_inverted: bool,
}
impl AIInterface {
pub fn weapon_def_interface(&self) -> WeaponDefInterface {
WeaponDefInterface { ai_id: self.ai_id }
}
}
const MAX_WEAPON_DEFS: usize = 128;
impl WeaponDefInterface {
pub fn get_weapon_defs(&self) -> Result<Vec<WeaponDef>, Box<dyn Error>> {
let get_weapon_defs_func = get_callback!(self.ai_id, getWeaponDefs)?;
Ok((0..unsafe { get_weapon_defs_func(self.ai_id) })
.map(|i| WeaponDef {
ai_id: self.ai_id,
weapon_def_id: i,
})
.collect())
}
}
impl WeaponDef {
pub fn name(&self) -> Result<String, Box<dyn Error>> {
let get_name = get_callback!(self.ai_id, WeaponDef_getName)?;
Ok(String::from(
unsafe { CStr::from_ptr(get_name(self.ai_id, self.weapon_def_id)) }.to_str()?,
))
}
pub fn description(&self) -> Result<String, Box<dyn Error>> {
let get_description = get_callback!(self.ai_id, WeaponDef_getDescription)?;
Ok(String::from(
unsafe { CStr::from_ptr(get_description(self.ai_id, self.weapon_def_id)) }.to_str()?,
))
}
pub fn range(&self) -> Result<f32, Box<dyn Error>> {
let get_range = get_callback!(self.ai_id, WeaponDef_getRange)?;
Ok(unsafe { get_range(self.ai_id, self.weapon_def_id) })
}
pub fn spray_angle(&self) -> Result<f32, Box<dyn Error>> {
let get_spray_angle = get_callback!(self.ai_id, WeaponDef_getSprayAngle)?;
Ok(unsafe { get_spray_angle(self.ai_id, self.weapon_def_id) })
}
pub fn moving_accuracy(&self) -> Result<f32, Box<dyn Error>> {
let get_moving_accuracy = get_callback!(self.ai_id, WeaponDef_getMovingAccuracy)?;
Ok(unsafe { get_moving_accuracy(self.ai_id, self.weapon_def_id) })
}
pub fn target_move_error(&self) -> Result<f32, Box<dyn Error>> {
let get_target_move_error = get_callback!(self.ai_id, WeaponDef_getTargetMoveError)?;
Ok(unsafe { get_target_move_error(self.ai_id, self.weapon_def_id) })
}
pub fn lead_limit(&self) -> Result<f32, Box<dyn Error>> {
let get_lead_limit = get_callback!(self.ai_id, WeaponDef_getLeadLimit)?;
Ok(unsafe { get_lead_limit(self.ai_id, self.weapon_def_id) })
}
pub fn lead_bonus(&self) -> Result<f32, Box<dyn Error>> {
let get_lead_bonus = get_callback!(self.ai_id, WeaponDef_getLeadBonus)?;
Ok(unsafe { get_lead_bonus(self.ai_id, self.weapon_def_id) })
}
pub fn predict_boost(&self) -> Result<f32, Box<dyn Error>> {
let get_predict_boost = get_callback!(self.ai_id, WeaponDef_getPredictBoost)?;
Ok(unsafe { get_predict_boost(self.ai_id, self.weapon_def_id) })
}
pub fn paralyze_damage_time(&self) -> Result<i32, Box<dyn Error>> {
let get_paralyze_damage_time =
get_callback!(self.ai_id, WeaponDef_Damage_getParalyzeDamageTime)?;
Ok(unsafe { get_paralyze_damage_time(self.ai_id, self.weapon_def_id) })
}
pub fn impulse_factor(&self) -> Result<f32, Box<dyn Error>> {
let get_impulse_factor = get_callback!(self.ai_id, WeaponDef_Damage_getImpulseFactor)?;
Ok(unsafe { get_impulse_factor(self.ai_id, self.weapon_def_id) })
}
pub fn impulse_boost(&self) -> Result<f32, Box<dyn Error>> {
let get_impulse_boost = get_callback!(self.ai_id, WeaponDef_Damage_getImpulseBoost)?;
Ok(unsafe { get_impulse_boost(self.ai_id, self.weapon_def_id) })
}
pub fn crater_multiplier(&self) -> Result<f32, Box<dyn Error>> {
let get_crater_multiplier = get_callback!(self.ai_id, WeaponDef_Damage_getCraterMult)?;
Ok(unsafe { get_crater_multiplier(self.ai_id, self.weapon_def_id) })
}
pub fn crater_boost(&self) -> Result<f32, Box<dyn Error>> {
let get_crater_boost = get_callback!(self.ai_id, WeaponDef_Damage_getCraterBoost)?;
Ok(unsafe { get_crater_boost(self.ai_id, self.weapon_def_id) })
}
pub fn area_of_effect(&self) -> Result<f32, Box<dyn Error>> {
let get_area_of_effect = get_callback!(self.ai_id, WeaponDef_getAreaOfEffect)?;
Ok(unsafe { get_area_of_effect(self.ai_id, self.weapon_def_id) })
}
pub fn self_damage(&self) -> Result<bool, Box<dyn Error>> {
let get_no_self_damage = get_callback!(self.ai_id, WeaponDef_isNoSelfDamage)?;
Ok(!unsafe { get_no_self_damage(self.ai_id, self.weapon_def_id) })
}
pub fn fire_starter(&self) -> Result<f32, Box<dyn Error>> {
let get_fire_starter = get_callback!(self.ai_id, WeaponDef_getFireStarter)?;
Ok(unsafe { get_fire_starter(self.ai_id, self.weapon_def_id) })
}
pub fn edge_effectivness(&self) -> Result<f32, Box<dyn Error>> {
let get_edge_effectivness = get_callback!(self.ai_id, WeaponDef_getEdgeEffectiveness)?;
Ok(unsafe { get_edge_effectivness(self.ai_id, self.weapon_def_id) })
}
pub fn size(&self) -> Result<f32, Box<dyn Error>> {
let get_size = get_callback!(self.ai_id, WeaponDef_getSize)?;
Ok(unsafe { get_size(self.ai_id, self.weapon_def_id) })
}
pub fn size_growth(&self) -> Result<f32, Box<dyn Error>> {
let get_size_growth = get_callback!(self.ai_id, WeaponDef_getSizeGrowth)?;
Ok(unsafe { get_size_growth(self.ai_id, self.weapon_def_id) })
}
pub fn collision_size(&self) -> Result<f32, Box<dyn Error>> {
let get_collision_size = get_callback!(self.ai_id, WeaponDef_getCollisionSize)?;
Ok(unsafe { get_collision_size(self.ai_id, self.weapon_def_id) })
}
pub fn salvo_size(&self) -> Result<i32, Box<dyn Error>> {
let get_salvo_size = get_callback!(self.ai_id, WeaponDef_getSalvoSize)?;
Ok(unsafe { get_salvo_size(self.ai_id, self.weapon_def_id) })
}
pub fn salvo_delay(&self) -> Result<f32, Box<dyn Error>> {
let get_salvo_delay = get_callback!(self.ai_id, WeaponDef_getSalvoDelay)?;
Ok(unsafe { get_salvo_delay(self.ai_id, self.weapon_def_id) })
}
pub fn reload(&self) -> Result<f32, Box<dyn Error>> {
let get_reload = get_callback!(self.ai_id, WeaponDef_getReload)?;
Ok(unsafe { get_reload(self.ai_id, self.weapon_def_id) })
}
pub fn beam_time(&self) -> Result<f32, Box<dyn Error>> {
let get_beam_time = get_callback!(self.ai_id, WeaponDef_getBeamTime)?;
Ok(unsafe { get_beam_time(self.ai_id, self.weapon_def_id) })
}
pub fn beam_burst(&self) -> Result<bool, Box<dyn Error>> {
let get_beam_burst = get_callback!(self.ai_id, WeaponDef_isBeamBurst)?;
Ok(unsafe { get_beam_burst(self.ai_id, self.weapon_def_id) })
}
pub fn bounce(&self) -> WeaponBounce {
WeaponBounce {
ai_id: self.ai_id,
weapon_def_id: self.weapon_def_id,
}
}
pub fn max_angle(&self) -> Result<f32, Box<dyn Error>> {
let get_max_angle = get_callback!(self.ai_id, WeaponDef_getMaxAngle)?;
Ok(unsafe { get_max_angle(self.ai_id, self.weapon_def_id) })
}
pub fn up_time(&self) -> Result<f32, Box<dyn Error>> {
let get_up_time = get_callback!(self.ai_id, WeaponDef_getUpTime)?;
Ok(unsafe { get_up_time(self.ai_id, self.weapon_def_id) })
}
pub fn flight_time(&self) -> Result<i32, Box<dyn Error>> {
let get_flight_time = get_callback!(self.ai_id, WeaponDef_getFlightTime)?;
Ok(unsafe { get_flight_time(self.ai_id, self.weapon_def_id) })
}
pub fn cost(&self, resource: Resource) -> Result<f32, Box<dyn Error>> {
let get_cost_func = get_callback!(self.ai_id, WeaponDef_getCost)?;
Ok(unsafe { get_cost_func(self.ai_id, self.weapon_def_id, resource.resource_id) })
}
pub fn projectiles_per_shot(&self) -> Result<i32, Box<dyn Error>> {
let get_projectiles_per_shot_func =
get_callback!(self.ai_id, WeaponDef_getProjectilesPerShot)?;
Ok(unsafe { get_projectiles_per_shot_func(self.ai_id, self.weapon_def_id) })
}
pub fn turret(&self) -> Result<bool, Box<dyn Error>> {
let get_is_turret_func = get_callback!(self.ai_id, WeaponDef_isTurret)?;
Ok(unsafe { get_is_turret_func(self.ai_id, self.weapon_def_id) })
}
pub fn only_forward(&self) -> Result<bool, Box<dyn Error>> {
let get_only_forward_func = get_callback!(self.ai_id, WeaponDef_isOnlyForward)?;
Ok(unsafe { get_only_forward_func(self.ai_id, self.weapon_def_id) })
}
pub fn fixed_launcher(&self) -> Result<bool, Box<dyn Error>> {
let get_fixed_launcher_func = get_callback!(self.ai_id, WeaponDef_isFixedLauncher)?;
Ok(unsafe { get_fixed_launcher_func(self.ai_id, self.weapon_def_id) })
}
pub fn water_weapon(&self) -> Result<bool, Box<dyn Error>> {
let get_water_weapon_func = get_callback!(self.ai_id, WeaponDef_isWaterWeapon)?;
Ok(unsafe { get_water_weapon_func(self.ai_id, self.weapon_def_id) })
}
pub fn fire_submersed(&self) -> Result<bool, Box<dyn Error>> {
let get_fire_submersed_func = get_callback!(self.ai_id, WeaponDef_isFireSubmersed)?;
Ok(unsafe { get_fire_submersed_func(self.ai_id, self.weapon_def_id) })
}
pub fn sub_missile(&self) -> Result<bool, Box<dyn Error>> {
let get_sub_missile_func = get_callback!(self.ai_id, WeaponDef_isSubMissile)?;
Ok(unsafe { get_sub_missile_func(self.ai_id, self.weapon_def_id) })
}
pub fn tracks(&self) -> Result<bool, Box<dyn Error>> {
let get_tracks_func = get_callback!(self.ai_id, WeaponDef_isTracks)?;
Ok(unsafe { get_tracks_func(self.ai_id, self.weapon_def_id) })
}
pub fn dropped(&self) -> Result<bool, Box<dyn Error>> {
let get_dropped_func = get_callback!(self.ai_id, WeaponDef_isDropped)?;
Ok(unsafe { get_dropped_func(self.ai_id, self.weapon_def_id) })
}
pub fn paralyzer(&self) -> Result<bool, Box<dyn Error>> {
let get_paralyzer_func = get_callback!(self.ai_id, WeaponDef_isParalyzer)?;
Ok(unsafe { get_paralyzer_func(self.ai_id, self.weapon_def_id) })
}
pub fn impact_only(&self) -> Result<bool, Box<dyn Error>> {
let get_impact_only_func = get_callback!(self.ai_id, WeaponDef_isImpactOnly)?;
Ok(unsafe { get_impact_only_func(self.ai_id, self.weapon_def_id) })
}
pub fn auto_target(&self) -> Result<bool, Box<dyn Error>> {
let get_no_auto_target_func = get_callback!(self.ai_id, WeaponDef_isNoAutoTarget)?;
Ok(!unsafe { get_no_auto_target_func(self.ai_id, self.weapon_def_id) })
}
pub fn manual_fire(&self) -> Result<bool, Box<dyn Error>> {
let get_manual_fire_func = get_callback!(self.ai_id, WeaponDef_isManualFire)?;
Ok(unsafe { get_manual_fire_func(self.ai_id, self.weapon_def_id) })
}
pub fn interceptor(&self) -> Result<bool, Box<dyn Error>> {
let get_interceptor_func = get_callback!(self.ai_id, WeaponDef_getInterceptor)?;
let ret = unsafe { get_interceptor_func(self.ai_id, self.weapon_def_id) };
if ret == 1 {
Ok(true)
} else if ret == 0 {
Ok(false)
} else {
Err("Interceptor not 0 or 1".into())
}
}
pub fn targetable(&self) -> Result<bool, Box<dyn Error>> {
let get_targetable_func = get_callback!(self.ai_id, WeaponDef_getTargetable)?;
let ret = unsafe { get_targetable_func(self.ai_id, self.weapon_def_id) };
if ret == 1 {
Ok(true)
} else if ret == 0 {
Ok(false)
} else {
Err("Targetable not 0 or 1".into())
}
}
pub fn stockpileable(&self) -> Result<bool, Box<dyn Error>> {
let get_stockpileable_func = get_callback!(self.ai_id, WeaponDef_isStockpileable)?;
Ok(unsafe { get_stockpileable_func(self.ai_id, self.weapon_def_id) })
}
pub fn stockpile_time(&self) -> Result<f32, Box<dyn Error>> {
let get_stockpile_time_func = get_callback!(self.ai_id, WeaponDef_getStockpileTime)?;
Ok(unsafe { get_stockpile_time_func(self.ai_id, self.weapon_def_id) })
}
pub fn interceptor_coverage_range(&self) -> Result<f32, Box<dyn Error>> {
let get_coverage_range_func = get_callback!(self.ai_id, WeaponDef_getCoverageRange)?;
Ok(unsafe { get_coverage_range_func(self.ai_id, self.weapon_def_id) })
}
pub fn intensity(&self) -> Result<f32, Box<dyn Error>> {
let get_intensity_func = get_callback!(self.ai_id, WeaponDef_getIntensity)?;
Ok(unsafe { get_intensity_func(self.ai_id, self.weapon_def_id) })
}
pub fn duration(&self) -> Result<f32, Box<dyn Error>> {
let get_duration_func = get_callback!(self.ai_id, WeaponDef_getDuration)?;
Ok(unsafe { get_duration_func(self.ai_id, self.weapon_def_id) })
}
pub fn fall_off_rate(&self) -> Result<f32, Box<dyn Error>> {
let get_fall_off_rate_func = get_callback!(self.ai_id, WeaponDef_getFalloffRate)?;
Ok(unsafe { get_fall_off_rate_func(self.ai_id, self.weapon_def_id) })
}
pub fn sound_trigger(&self) -> Result<bool, Box<dyn Error>> {
let get_sound_trigger_func = get_callback!(self.ai_id, WeaponDef_isSoundTrigger)?;
Ok(unsafe { get_sound_trigger_func(self.ai_id, self.weapon_def_id) })
}
pub fn self_explode(&self) -> Result<bool, Box<dyn Error>> {
let get_self_explode_func = get_callback!(self.ai_id, WeaponDef_isSelfExplode)?;
Ok(unsafe { get_self_explode_func(self.ai_id, self.weapon_def_id) })
}
pub fn gravity_affected(&self) -> Result<bool, Box<dyn Error>> {
let get_gravity_affected_func = get_callback!(self.ai_id, WeaponDef_isGravityAffected)?;
Ok(unsafe { get_gravity_affected_func(self.ai_id, self.weapon_def_id) })
}
pub fn trajectory_height(&self) -> Result<f32, Box<dyn Error>> {
let get_trajectory_height_func = get_callback!(self.ai_id, WeaponDef_getTrajectoryHeight)?;
Ok(unsafe { get_trajectory_height_func(self.ai_id, self.weapon_def_id) })
}
pub fn trajectory(&self) -> Result<Trajectory, Box<dyn Error>> {
let get_high_trajectory_func = get_callback!(self.ai_id, WeaponDef_getHighTrajectory)?;
match unsafe { get_high_trajectory_func(self.ai_id, self.weapon_def_id) } {
0 => Ok(Trajectory::Low),
1 => Ok(Trajectory::High),
2 => Ok(Trajectory::Unit),
_ => Err("Trajectory not 0, 1, or 2".into()),
}
}
pub fn gravity(&self) -> Result<f32, Box<dyn Error>> {
let get_gravity_func = get_callback!(self.ai_id, WeaponDef_getMyGravity)?;
Ok(unsafe { get_gravity_func(self.ai_id, self.weapon_def_id) })
}
pub fn explode(&self) -> Result<bool, Box<dyn Error>> {
let get_no_explode_func = get_callback!(self.ai_id, WeaponDef_isNoExplode)?;
Ok(!unsafe { get_no_explode_func(self.ai_id, self.weapon_def_id) })
}
pub fn start_velocity(&self) -> Result<f32, Box<dyn Error>> {
let get_start_velocity_func = get_callback!(self.ai_id, WeaponDef_getStartVelocity)?;
Ok(unsafe { get_start_velocity_func(self.ai_id, self.weapon_def_id) })
}
pub fn max_velocity(&self) -> Result<f32, Box<dyn Error>> {
let get_max_velocity_func = get_callback!(self.ai_id, WeaponDef_getMaxVelocity)?;
Ok(unsafe { get_max_velocity_func(self.ai_id, self.weapon_def_id) })
}
pub fn weapon_acceleration(&self) -> Result<f32, Box<dyn Error>> {
let get_weapon_acceleration_func =
get_callback!(self.ai_id, WeaponDef_getWeaponAcceleration)?;
Ok(unsafe { get_weapon_acceleration_func(self.ai_id, self.weapon_def_id) })
}
pub fn turn_rate(&self) -> Result<f32, Box<dyn Error>> {
let get_turn_rate_func = get_callback!(self.ai_id, WeaponDef_getTurnRate)?;
Ok(unsafe { get_turn_rate_func(self.ai_id, self.weapon_def_id) })
}
pub fn projectile_speed(&self) -> Result<f32, Box<dyn Error>> {
let get_projectile_speed_func = get_callback!(self.ai_id, WeaponDef_getProjectileSpeed)?;
Ok(unsafe { get_projectile_speed_func(self.ai_id, self.weapon_def_id) })
}
pub fn explosion_speed(&self) -> Result<f32, Box<dyn Error>> {
let get_explosion_speed_func = get_callback!(self.ai_id, WeaponDef_getExplosionSpeed)?;
Ok(unsafe { get_explosion_speed_func(self.ai_id, self.weapon_def_id) })
}
pub fn wobble(&self) -> Result<f32, Box<dyn Error>> {
let get_wobble_func = get_callback!(self.ai_id, WeaponDef_getWobble)?;
Ok(unsafe { get_wobble_func(self.ai_id, self.weapon_def_id) })
}
pub fn dance(&self) -> Result<f32, Box<dyn Error>> {
let get_dance_func = get_callback!(self.ai_id, WeaponDef_getDance)?;
Ok(unsafe { get_dance_func(self.ai_id, self.weapon_def_id) })
}
pub fn large_beam_laser(&self) -> Result<bool, Box<dyn Error>> {
let get_large_beam_laser_func = get_callback!(self.ai_id, WeaponDef_isLargeBeamLaser)?;
Ok(unsafe { get_large_beam_laser_func(self.ai_id, self.weapon_def_id) })
}
pub fn shield(&self) -> Result<Option<WeaponShield>, Box<dyn Error>> {
let get_shield_func = get_callback!(self.ai_id, WeaponDef_isShield)?;
let has_shield = unsafe { get_shield_func(self.ai_id, self.weapon_def_id) };
Ok(if has_shield {
Some(WeaponShield {
ai_id: self.ai_id,
weapon_def_id: self.weapon_def_id,
})
} else {
None
})
}
pub fn avoid_friendly(&self) -> Result<bool, Box<dyn Error>> {
let get_avoid_friendly_func = get_callback!(self.ai_id, WeaponDef_isAvoidFriendly)?;
Ok(unsafe { get_avoid_friendly_func(self.ai_id, self.weapon_def_id) })
}
pub fn avoid_feature(&self) -> Result<bool, Box<dyn Error>> {
let get_avoid_feature_func = get_callback!(self.ai_id, WeaponDef_isAvoidFeature)?;
Ok(unsafe { get_avoid_feature_func(self.ai_id, self.weapon_def_id) })
}
pub fn avoid_neutral(&self) -> Result<bool, Box<dyn Error>> {
let get_avoid_neutral_func = get_callback!(self.ai_id, WeaponDef_isAvoidNeutral)?;
Ok(unsafe { get_avoid_neutral_func(self.ai_id, self.weapon_def_id) })
}
pub fn target_border(&self) -> Result<f32, Box<dyn Error>> {
let get_target_border_func = get_callback!(self.ai_id, WeaponDef_getTargetBorder)?;
Ok(unsafe { get_target_border_func(self.ai_id, self.weapon_def_id) })
}
pub fn cylinder_targetting(&self) -> Result<f32, Box<dyn Error>> {
let get_cylinder_targetting_func =
get_callback!(self.ai_id, WeaponDef_getCylinderTargetting)?;
Ok(unsafe { get_cylinder_targetting_func(self.ai_id, self.weapon_def_id) })
}
pub fn minimum_intensity(&self) -> Result<f32, Box<dyn Error>> {
let get_minimum_intensity_func = get_callback!(self.ai_id, WeaponDef_getMinIntensity)?;
Ok(unsafe { get_minimum_intensity_func(self.ai_id, self.weapon_def_id) })
}
pub fn height_boost_factor(&self) -> Result<f32, Box<dyn Error>> {
let get_height_boost_factor_func =
get_callback!(self.ai_id, WeaponDef_getHeightBoostFactor)?;
Ok(unsafe { get_height_boost_factor_func(self.ai_id, self.weapon_def_id) })
}
pub fn proximity_priority(&self) -> Result<f32, Box<dyn Error>> {
let get_proximity_priority_func =
get_callback!(self.ai_id, WeaponDef_getProximityPriority)?;
Ok(unsafe { get_proximity_priority_func(self.ai_id, self.weapon_def_id) })
}
pub fn sweep_fire(&self) -> Result<bool, Box<dyn Error>> {
let get_sweep_fire_func = get_callback!(self.ai_id, WeaponDef_isSweepFire)?;
Ok(unsafe { get_sweep_fire_func(self.ai_id, self.weapon_def_id) })
}
pub fn able_to_attack_ground(&self) -> Result<bool, Box<dyn Error>> {
let get_able_to_attack_ground_func =
get_callback!(self.ai_id, WeaponDef_isAbleToAttackGround)?;
Ok(unsafe { get_able_to_attack_ground_func(self.ai_id, self.weapon_def_id) })
}
pub fn dynamic_damage_exponent(&self) -> Result<f32, Box<dyn Error>> {
let get_dynamic_damage_exponent_func =
get_callback!(self.ai_id, WeaponDef_getDynDamageExp)?;
Ok(unsafe { get_dynamic_damage_exponent_func(self.ai_id, self.weapon_def_id) })
}
pub fn dynamic_damage_minimum(&self) -> Result<f32, Box<dyn Error>> {
let get_dynamic_damage_min_func = get_callback!(self.ai_id, WeaponDef_getDynDamageMin)?;
Ok(unsafe { get_dynamic_damage_min_func(self.ai_id, self.weapon_def_id) })
}
pub fn dynamic_damage_range(&self) -> Result<f32, Box<dyn Error>> {
let get_dynamic_damage_range_func = get_callback!(self.ai_id, WeaponDef_getDynDamageRange)?;
Ok(unsafe { get_dynamic_damage_range_func(self.ai_id, self.weapon_def_id) })
}
pub fn dynamic_damage_inverted(&self) -> Result<bool, Box<dyn Error>> {
let get_dynamic_damage_inverted_func =
get_callback!(self.ai_id, WeaponDef_isDynDamageInverted)?;
Ok(unsafe { get_dynamic_damage_inverted_func(self.ai_id, self.weapon_def_id) })
}
pub fn all(&self) -> Result<WeaponDefAll, Box<dyn Error>> {
Ok(WeaponDefAll {
name: self.name()?,
description: self.description()?,
range: self.range()?,
spray_angle: self.spray_angle()?,
moving_accuracy: self.moving_accuracy()?,
target_move_error: self.target_move_error()?,
lead_limit: self.lead_limit()?,
lead_bonus: self.lead_bonus()?,
predict_boost: self.predict_boost()?,
paralyze_damage_time: self.paralyze_damage_time()?,
impulse_factor: self.impulse_factor()?,
impulse_boost: self.impulse_boost()?,
crater_multiplier: self.crater_multiplier()?,
crater_boost: self.crater_boost()?,
area_of_effect: self.area_of_effect()?,
self_damage: self.self_damage()?,
fire_starter: self.fire_starter()?,
edge_effectivness: self.edge_effectivness()?,
size: self.size()?,
size_growth: self.size_growth()?,
collision_size: self.collision_size()?,
salvo_size: self.salvo_size()?,
salvo_delay: self.salvo_delay()?,
reload: self.reload()?,
beam_time: self.beam_time()?,
beam_burst: self.beam_burst()?,
bounce: self.bounce().all()?,
max_angle: self.max_angle()?,
up_time: self.up_time()?,
flight_time: self.flight_time()?,
cost: AIInterface::new(self.ai_id)
.resource_interface()
.get_resources()?
.into_iter()
.filter_map(|resource| {
if let Ok(res) = self.cost(resource) {
Some((resource, res))
} else {
None
}
})
.collect(),
projectiles_per_shot: self.projectiles_per_shot()?,
turret: self.turret()?,
only_forward: self.only_forward()?,
fixed_launcher: self.fixed_launcher()?,
water_weapon: self.water_weapon()?,
fire_submersed: self.fire_submersed()?,
sub_missile: self.sub_missile()?,
tracks: self.tracks()?,
dropped: self.dropped()?,
paralyzer: self.paralyzer()?,
impact_only: self.impact_only()?,
auto_target: self.auto_target()?,
manual_fire: self.manual_fire()?,
interceptor: self.interceptor()?,
targetable: self.targetable()?,
stockpileable: self.stockpileable()?,
stockpile_time: self.stockpile_time()?,
interceptor_coverage_range: self.interceptor_coverage_range()?,
fall_off_rate: self.fall_off_rate()?,
sound_trigger: self.sound_trigger()?,
self_explode: self.self_explode()?,
gravity_affected: self.gravity_affected()?,
trajectory: self.trajectory()?,
trajectory_height: self.trajectory_height()?,
gravity: self.gravity()?,
explode: self.explode()?,
start_velocity: self.start_velocity()?,
max_velocity: self.max_velocity()?,
weapon_acceleration: self.weapon_acceleration()?,
turn_rate: self.turn_rate()?,
projectile_speed: self.projectile_speed()?,
explosion_speed: self.explosion_speed()?,
wobble: self.wobble()?,
dance: self.dance()?,
large_beam_laser: self.large_beam_laser()?,
shield: match self.shield()? {
Some(s) => Some(s.all()?),
None => None,
},
avoid_friendly: self.avoid_friendly()?,
avoid_feature: self.avoid_feature()?,
avoid_neutral: self.avoid_neutral()?,
target_border: self.target_border()?,
cylinder_targetting: self.cylinder_targetting()?,
minimum_intensity: self.minimum_intensity()?,
height_boost_factor: self.height_boost_factor()?,
proximity_priority: self.proximity_priority()?,
sweep_fire: self.sweep_fire()?,
able_to_attack_ground: self.able_to_attack_ground()?,
dynamic_damage_exponent: self.dynamic_damage_exponent()?,
dynamic_damage_minimum: self.dynamic_damage_minimum()?,
dynamic_damage_range: self.dynamic_damage_range()?,
dynamic_damage_inverted: self.dynamic_damage_inverted()?,
})
}
}