diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index ecb9a4c6..d9c43c79 100644 --- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -14,6 +14,7 @@ import net.psforever.objects.serverobject.pad.VehicleSpawnPadDefinition import net.psforever.objects.serverobject.terminals._ import net.psforever.objects.serverobject.tube.SpawnTubeDefinition import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition +import net.psforever.objects.ballistics.{DamageType, Projectiles} import net.psforever.objects.vehicles.{SeatArmorRestriction, UtilityType} import net.psforever.types.PlanetSideEmpire @@ -43,6 +44,286 @@ object GlobalDefinitions { val surge = ImplantDefinition(9) + /* + Projectiles + */ + val bullet_105mm_projectile = ProjectileDefinition(Projectiles.bullet_105mm_projectile) + + val bullet_12mm_projectile = ProjectileDefinition(Projectiles.bullet_12mm_projectile) + + val bullet_12mm_projectileb = ProjectileDefinition(Projectiles.bullet_12mm_projectileb) + + val bullet_150mm_projectile = ProjectileDefinition(Projectiles.bullet_150mm_projectile) + + val bullet_15mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_15mm_apc_projectile) + + val bullet_15mm_projectile = ProjectileDefinition(Projectiles.bullet_15mm_projectile) + + val bullet_20mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_20mm_apc_projectile) + + val bullet_20mm_projectile = ProjectileDefinition(Projectiles.bullet_20mm_projectile) + + val bullet_25mm_projectile = ProjectileDefinition(Projectiles.bullet_25mm_projectile) + + val bullet_35mm_projectile = ProjectileDefinition(Projectiles.bullet_35mm_projectile) + + val bullet_75mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_75mm_apc_projectile) + + val bullet_75mm_projectile = ProjectileDefinition(Projectiles.bullet_75mm_projectile) + + val bullet_9mm_AP_projectile = ProjectileDefinition(Projectiles.bullet_9mm_AP_projectile) + + val bullet_9mm_projectile = ProjectileDefinition(Projectiles.bullet_9mm_projectile) + + val anniversary_projectilea = ProjectileDefinition(Projectiles.anniversary_projectilea) + + val anniversary_projectileb = ProjectileDefinition(Projectiles.anniversary_projectileb) + + val aphelion_immolation_cannon_projectile = ProjectileDefinition(Projectiles.aphelion_immolation_cannon_projectile) + + val aphelion_laser_projectile = ProjectileDefinition(Projectiles.aphelion_laser_projectile) + + val aphelion_plasma_rocket_projectile = ProjectileDefinition(Projectiles.aphelion_plasma_rocket_projectile) + + val aphelion_ppa_projectile = ProjectileDefinition(Projectiles.aphelion_ppa_projectile) + + val aphelion_starfire_projectile = ProjectileDefinition(Projectiles.aphelion_starfire_projectile) + + val bolt_projectile = ProjectileDefinition(Projectiles.bolt_projectile) + + val burster_projectile = ProjectileDefinition(Projectiles.burster_projectile) + + val chainblade_projectile = ProjectileDefinition(Projectiles.chainblade_projectile) + + val colossus_100mm_projectile = ProjectileDefinition(Projectiles.colossus_100mm_projectile) + + val colossus_burster_projectile = ProjectileDefinition(Projectiles.colossus_burster_projectile) + + val colossus_chaingun_projectile = ProjectileDefinition(Projectiles.colossus_chaingun_projectile) + + val colossus_cluster_bomb_projectile = ProjectileDefinition(Projectiles.colossus_cluster_bomb_projectile) + + val colossus_tank_cannon_projectile = ProjectileDefinition(Projectiles.colossus_tank_cannon_projectile) + + val comet_projectile = ProjectileDefinition(Projectiles.comet_projectile) + + val dualcycler_projectile = ProjectileDefinition(Projectiles.dualcycler_projectile) + + val dynomite_projectile = ProjectileDefinition(Projectiles.dynomite_projectile) + + val energy_cell_projectile = ProjectileDefinition(Projectiles.energy_cell_projectile) + + val energy_gun_nc_projectile = ProjectileDefinition(Projectiles.energy_gun_nc_projectile) + + val energy_gun_tr_projectile = ProjectileDefinition(Projectiles.energy_gun_tr_projectile) + + val energy_gun_vs_projectile = ProjectileDefinition(Projectiles.energy_gun_vs_projectile) + + val enhanced_energy_cell_projectile = ProjectileDefinition(Projectiles.enhanced_energy_cell_projectile) + + val enhanced_quasar_projectile = ProjectileDefinition(Projectiles.enhanced_quasar_projectile) + + val falcon_projectile = ProjectileDefinition(Projectiles.falcon_projectile) + + val firebird_missile_projectile = ProjectileDefinition(Projectiles.firebird_missile_projectile) + + val flail_projectile = ProjectileDefinition(Projectiles.flail_projectile) + + val flamethrower_fireball = ProjectileDefinition(Projectiles.flamethrower_fireball) + + val flamethrower_projectile = ProjectileDefinition(Projectiles.flamethrower_projectile) + + val flux_cannon_apc_projectile = ProjectileDefinition(Projectiles.flux_cannon_apc_projectile) + + val flux_cannon_thresher_projectile = ProjectileDefinition(Projectiles.flux_cannon_thresher_projectile) + + val fluxpod_projectile = ProjectileDefinition(Projectiles.fluxpod_projectile) + + val forceblade_projectile = ProjectileDefinition(Projectiles.forceblade_projectile) + + val frag_cartridge_projectile = ProjectileDefinition(Projectiles.frag_cartridge_projectile) + + val frag_cartridge_projectile_b = ProjectileDefinition(Projectiles.frag_cartridge_projectile_b) + + val frag_grenade_projectile = ProjectileDefinition(Projectiles.frag_grenade_projectile) + + val frag_grenade_projectile_enh = ProjectileDefinition(Projectiles.frag_grenade_projectile_enh) + + val galaxy_gunship_gun_projectile = ProjectileDefinition(Projectiles.galaxy_gunship_gun_projectile) + + val gauss_cannon_projectile = ProjectileDefinition(Projectiles.gauss_cannon_projectile) + + val grenade_projectile = ProjectileDefinition(Projectiles.grenade_projectile) + + val heavy_grenade_projectile = ProjectileDefinition(Projectiles.heavy_grenade_projectile) + + val heavy_rail_beam_projectile = ProjectileDefinition(Projectiles.heavy_rail_beam_projectile) + + val heavy_sniper_projectile = ProjectileDefinition(Projectiles.heavy_sniper_projectile) + + val hellfire_projectile = ProjectileDefinition(Projectiles.hellfire_projectile) + + val hunter_seeker_missile_dumbfire = ProjectileDefinition(Projectiles.hunter_seeker_missile_dumbfire) + + val hunter_seeker_missile_projectile = ProjectileDefinition(Projectiles.hunter_seeker_missile_projectile) + + val jammer_cartridge_projectile = ProjectileDefinition(Projectiles.jammer_cartridge_projectile) + + val jammer_cartridge_projectile_b = ProjectileDefinition(Projectiles.jammer_cartridge_projectile_b) + + val jammer_grenade_projectile = ProjectileDefinition(Projectiles.jammer_grenade_projectile) + + val jammer_grenade_projectile_enh = ProjectileDefinition(Projectiles.jammer_grenade_projectile_enh) + + val katana_projectile = ProjectileDefinition(Projectiles.katana_projectile) + + val katana_projectileb = ProjectileDefinition(Projectiles.katana_projectileb) + + val lancer_projectile = ProjectileDefinition(Projectiles.lancer_projectile) + + val lasher_projectile = ProjectileDefinition(Projectiles.lasher_projectile) + + val lasher_projectile_ap = ProjectileDefinition(Projectiles.lasher_projectile_ap) + + val liberator_bomb_cluster_bomblet_projectile = ProjectileDefinition(Projectiles.liberator_bomb_cluster_bomblet_projectile) + + val liberator_bomb_cluster_projectile = ProjectileDefinition(Projectiles.liberator_bomb_cluster_projectile) + + val liberator_bomb_projectile = ProjectileDefinition(Projectiles.liberator_bomb_projectile) + + val maelstrom_grenade_projectile = ProjectileDefinition(Projectiles.maelstrom_grenade_projectile) + + val maelstrom_grenade_projectile_contact = ProjectileDefinition(Projectiles.maelstrom_grenade_projectile_contact) + + val maelstrom_stream_projectile = ProjectileDefinition(Projectiles.maelstrom_stream_projectile) + + val magcutter_projectile = ProjectileDefinition(Projectiles.magcutter_projectile) + + val melee_ammo_projectile = ProjectileDefinition(Projectiles.melee_ammo_projectile) + + val meteor_common = ProjectileDefinition(Projectiles.meteor_common) + + val meteor_projectile_b_large = ProjectileDefinition(Projectiles.meteor_projectile_b_large) + + val meteor_projectile_b_medium = ProjectileDefinition(Projectiles.meteor_projectile_b_medium) + + val meteor_projectile_b_small = ProjectileDefinition(Projectiles.meteor_projectile_b_small) + + val meteor_projectile_large = ProjectileDefinition(Projectiles.meteor_projectile_large) + + val meteor_projectile_medium = ProjectileDefinition(Projectiles.meteor_projectile_medium) + + val meteor_projectile_small = ProjectileDefinition(Projectiles.meteor_projectile_small) + + val mine_projectile = ProjectileDefinition(Projectiles.mine_projectile) + + val mine_sweeper_projectile = ProjectileDefinition(Projectiles.mine_sweeper_projectile) + + val mine_sweeper_projectile_enh = ProjectileDefinition(Projectiles.mine_sweeper_projectile_enh) + + val oicw_projectile = ProjectileDefinition(Projectiles.oicw_projectile) + + val pellet_gun_projectile = ProjectileDefinition(Projectiles.pellet_gun_projectile) + + val peregrine_dual_machine_gun_projectile = ProjectileDefinition(Projectiles.peregrine_dual_machine_gun_projectile) + + val peregrine_mechhammer_projectile = ProjectileDefinition(Projectiles.peregrine_mechhammer_projectile) + + val peregrine_particle_cannon_projectile = ProjectileDefinition(Projectiles.peregrine_particle_cannon_projectile) + + val peregrine_rocket_pod_projectile = ProjectileDefinition(Projectiles.peregrine_rocket_pod_projectile) + + val peregrine_sparrow_projectile = ProjectileDefinition(Projectiles.peregrine_sparrow_projectile) + + val phalanx_av_projectile = ProjectileDefinition(Projectiles.phalanx_av_projectile) + + val phalanx_flak_projectile = ProjectileDefinition(Projectiles.phalanx_flak_projectile) + + val phalanx_projectile = ProjectileDefinition(Projectiles.phalanx_projectile) + + val phoenix_missile_guided_projectile = ProjectileDefinition(Projectiles.phoenix_missile_guided_projectile) + + val phoenix_missile_projectile = ProjectileDefinition(Projectiles.phoenix_missile_projectile) + + val plasma_cartridge_projectile = ProjectileDefinition(Projectiles.plasma_cartridge_projectile) + + val plasma_cartridge_projectile_b = ProjectileDefinition(Projectiles.plasma_cartridge_projectile_b) + + val plasma_grenade_projectile = ProjectileDefinition(Projectiles.plasma_grenade_projectile) + + val plasma_grenade_projectile_B = ProjectileDefinition(Projectiles.plasma_grenade_projectile_B) + + val pounder_projectile = ProjectileDefinition(Projectiles.pounder_projectile) + + val pounder_projectile_enh = ProjectileDefinition(Projectiles.pounder_projectile_enh) + + val ppa_projectile = ProjectileDefinition(Projectiles.ppa_projectile) + + val pulsar_ap_projectile = ProjectileDefinition(Projectiles.pulsar_ap_projectile) + + val pulsar_projectile = ProjectileDefinition(Projectiles.pulsar_projectile) + + val quasar_projectile = ProjectileDefinition(Projectiles.quasar_projectile) + + val radiator_grenade_projectile = ProjectileDefinition(Projectiles.radiator_grenade_projectile) + + val radiator_sticky_projectile = ProjectileDefinition(Projectiles.radiator_sticky_projectile) + + val reaver_rocket_projectile = ProjectileDefinition(Projectiles.reaver_rocket_projectile) + + val rocket_projectile = ProjectileDefinition(Projectiles.rocket_projectile) + + val rocklet_flak_projectile = ProjectileDefinition(Projectiles.rocklet_flak_projectile) + + val rocklet_jammer_projectile = ProjectileDefinition(Projectiles.rocklet_jammer_projectile) + + val scattercannon_projectile = ProjectileDefinition(Projectiles.scattercannon_projectile) + + val scythe_projectile = ProjectileDefinition(Projectiles.scythe_projectile) + + val scythe_projectile_slave = ProjectileDefinition(Projectiles.scythe_projectile_slave) + + val shotgun_shell_AP_projectile = ProjectileDefinition(Projectiles.shotgun_shell_AP_projectile) + + val shotgun_shell_projectile = ProjectileDefinition(Projectiles.shotgun_shell_projectile) + + val six_shooter_projectile = ProjectileDefinition(Projectiles.six_shooter_projectile) + + val skyguard_flak_cannon_projectile = ProjectileDefinition(Projectiles.skyguard_flak_cannon_projectile) + + val sparrow_projectile = ProjectileDefinition(Projectiles.sparrow_projectile) + + val sparrow_secondary_projectile = ProjectileDefinition(Projectiles.sparrow_secondary_projectile) + + val spiker_projectile = ProjectileDefinition(Projectiles.spiker_projectile) + + val spitfire_aa_ammo_projectile = ProjectileDefinition(Projectiles.spitfire_aa_ammo_projectile) + + val spitfire_ammo_projectile = ProjectileDefinition(Projectiles.spitfire_ammo_projectile) + + val starfire_projectile = ProjectileDefinition(Projectiles.starfire_projectile) + + val striker_missile_projectile = ProjectileDefinition(Projectiles.striker_missile_projectile) + + val striker_missile_targeting_projectile = ProjectileDefinition(Projectiles.striker_missile_targeting_projectile) + + val trek_projectile = ProjectileDefinition(Projectiles.trek_projectile) + + val vanu_sentry_turret_projectile = ProjectileDefinition(Projectiles.vanu_sentry_turret_projectile) + + val vulture_bomb_projectile = ProjectileDefinition(Projectiles.vulture_bomb_projectile) + + val vulture_nose_bullet_projectile = ProjectileDefinition(Projectiles.vulture_nose_bullet_projectile) + + val vulture_tail_bullet_projectile = ProjectileDefinition(Projectiles.vulture_tail_bullet_projectile) + + val wasp_gun_projectile = ProjectileDefinition(Projectiles.wasp_gun_projectile) + + val wasp_rocket_projectile = ProjectileDefinition(Projectiles.wasp_rocket_projectile) + + val winchester_projectile = ProjectileDefinition(Projectiles.winchester_projectile) + init_projectile() + /* Equipment (locker_container, kits, ammunition, weapons) */ @@ -1229,6 +1510,1505 @@ object GlobalDefinitions { bullet_150mm.Tile = InventoryTile.Tile44 } + /** + * Initialize `ProjectileDefinition` globals. + */ + private def init_projectile() : Unit = { + bullet_105mm_projectile.Name = "105mmbullet_projectile" + bullet_105mm_projectile.Damage0 = 150 + bullet_105mm_projectile.Damage1 = 300 + bullet_105mm_projectile.Damage2 = 300 + bullet_105mm_projectile.Damage3 = 300 + bullet_105mm_projectile.Damage4 = 180 + bullet_105mm_projectile.DamageAtEdge = 0.1f + bullet_105mm_projectile.DamageRadius = 7f + bullet_105mm_projectile.ProjectileDamageType = DamageType.Splash + bullet_105mm_projectile.InitialVelocity = 100 + bullet_105mm_projectile.Lifespan = 4f + + bullet_12mm_projectile.Name= "12mmbullet_projectile" + bullet_12mm_projectile.Damage0 = 25 + bullet_12mm_projectile.Damage1 = 10 + bullet_12mm_projectile.Damage2 = 25 + bullet_12mm_projectile.Damage3 = 10 + bullet_12mm_projectile.Damage4 = 7 + bullet_12mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_12mm_projectile.DegradeDelay = .015f + bullet_12mm_projectile.DegradeMultiplier = 0.5f + bullet_12mm_projectile.InitialVelocity = 500 + bullet_12mm_projectile.Lifespan = 0.5f + + bullet_12mm_projectileb.Name = "12mmbullet_projectileb" + // TODO for later, maybe : set_resource_parent 12mmbullet_projectileb game_objects 12mmbullet_projectile + bullet_12mm_projectileb.Damage0 = 25 + bullet_12mm_projectileb.Damage1 = 10 + bullet_12mm_projectileb.Damage2 = 25 + bullet_12mm_projectileb.Damage3 = 10 + bullet_12mm_projectileb.Damage4 = 7 + bullet_12mm_projectileb.ProjectileDamageType = DamageType.Direct + bullet_12mm_projectileb.DegradeDelay = .015f + bullet_12mm_projectileb.DegradeMultiplier = 0.5f + bullet_12mm_projectileb.InitialVelocity = 500 + bullet_12mm_projectileb.Lifespan = 0.5f + + bullet_150mm_projectile.Name = "150mmbullet_projectile" + bullet_150mm_projectile.Damage0 = 150 + bullet_150mm_projectile.Damage1 = 450 + bullet_150mm_projectile.Damage2 = 450 + bullet_150mm_projectile.Damage3 = 450 + bullet_150mm_projectile.Damage4 = 400 + bullet_150mm_projectile.DamageAtEdge = 0.10f + bullet_150mm_projectile.DamageRadius = 8f + bullet_150mm_projectile.ProjectileDamageType = DamageType.Splash + bullet_150mm_projectile.InitialVelocity = 100 + bullet_150mm_projectile.Lifespan = 4f + + bullet_15mm_apc_projectile.Name = "15mmbullet_apc_projectile" + // TODO for later, maybe : set_resource_parent 15mmbullet_apc_projectile game_objects 15mmbullet_projectile + bullet_15mm_apc_projectile.Damage0 = 12 + bullet_15mm_apc_projectile.Damage1 = 20 + bullet_15mm_apc_projectile.Damage2 = 30 + bullet_15mm_apc_projectile.Damage3 = 20 + bullet_15mm_apc_projectile.Damage4 = 16 + bullet_15mm_apc_projectile.ProjectileDamageType = DamageType.Direct + bullet_15mm_apc_projectile.DegradeDelay = .015f + bullet_15mm_apc_projectile.DegradeMultiplier = 0.5f + bullet_15mm_apc_projectile.InitialVelocity = 500 + bullet_15mm_apc_projectile.Lifespan = 0.5f + + bullet_15mm_projectile.Name = "15mmbullet_projectile" + bullet_15mm_projectile.Damage0 = 21 + bullet_15mm_projectile.Damage1 = 18 + bullet_15mm_projectile.Damage2 = 25 + bullet_15mm_projectile.Damage3 = 18 + bullet_15mm_projectile.Damage4 = 11 + bullet_15mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_15mm_projectile.DegradeDelay = .015f + bullet_15mm_projectile.DegradeMultiplier = 0.5f + bullet_15mm_projectile.InitialVelocity = 500 + bullet_15mm_projectile.Lifespan = 0.5f + + bullet_20mm_apc_projectile.Name = "20mmbullet_apc_projectile" + // TODO for later, maybe : set_resource_parent 20mmbullet_apc_projectile game_objects 20mmbullet_projectile + bullet_20mm_apc_projectile.Damage0 = 24 + bullet_20mm_apc_projectile.Damage1 = 40 + bullet_20mm_apc_projectile.Damage2 = 60 + bullet_20mm_apc_projectile.Damage3 = 40 + bullet_20mm_apc_projectile.Damage4 = 32 + bullet_20mm_apc_projectile.ProjectileDamageType = DamageType.Direct + bullet_20mm_apc_projectile.DegradeDelay = .015f + bullet_20mm_apc_projectile.DegradeMultiplier = 0.5f + bullet_20mm_apc_projectile.InitialVelocity = 500 + bullet_20mm_apc_projectile.Lifespan = 0.5f + + bullet_20mm_projectile.Name = "20mmbullet_projectile" + bullet_20mm_projectile.Damage0 = 20 + bullet_20mm_projectile.Damage1 = 20 + bullet_20mm_projectile.Damage2 = 40 + bullet_20mm_projectile.Damage3 = 20 + bullet_20mm_projectile.Damage4 = 16 + bullet_20mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_20mm_projectile.DegradeDelay = .015f + bullet_20mm_projectile.DegradeMultiplier = 0.5f + bullet_20mm_projectile.InitialVelocity = 500 + bullet_20mm_projectile.Lifespan = 0.5f + + bullet_25mm_projectile.Name = "25mmbullet_projectile" + bullet_25mm_projectile.Damage0 = 25 + bullet_25mm_projectile.Damage1 = 35 + bullet_25mm_projectile.Damage2 = 50 + bullet_25mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_25mm_projectile.DegradeDelay = .02f + bullet_25mm_projectile.DegradeMultiplier = 0.5f + bullet_25mm_projectile.InitialVelocity = 500 + bullet_25mm_projectile.Lifespan = 0.6f + + bullet_35mm_projectile.Name = "35mmbullet_projectile" + bullet_35mm_projectile.Damage0 = 40 + bullet_35mm_projectile.Damage1 = 50 + bullet_35mm_projectile.Damage2 = 60 + bullet_35mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_35mm_projectile.DegradeDelay = .015f + bullet_35mm_projectile.DegradeMultiplier = 0.5f + bullet_35mm_projectile.InitialVelocity = 200 + bullet_35mm_projectile.Lifespan = 1.5f + + bullet_75mm_apc_projectile.Name = "75mmbullet_apc_projectile" + // TODO for later, maybe : set_resource_parent 75mmbullet_apc_projectile game_objects 75mmbullet_projectile + bullet_75mm_apc_projectile.Damage0 = 85 + bullet_75mm_apc_projectile.Damage1 = 155 + bullet_75mm_apc_projectile.DamageAtEdge = 0.1f + bullet_75mm_apc_projectile.DamageRadius = 5f + bullet_75mm_apc_projectile.ProjectileDamageType = DamageType.Splash + bullet_75mm_apc_projectile.InitialVelocity = 100 + bullet_75mm_apc_projectile.Lifespan = 4f + + bullet_75mm_projectile.Name = "75mmbullet_projectile" + bullet_75mm_projectile.Damage0 = 75 + bullet_75mm_projectile.Damage1 = 125 + bullet_75mm_projectile.DamageAtEdge = 0.1f + bullet_75mm_projectile.DamageRadius = 5f + bullet_75mm_projectile.ProjectileDamageType = DamageType.Splash + bullet_75mm_projectile.InitialVelocity = 100 + bullet_75mm_projectile.Lifespan = 4f + + bullet_9mm_AP_projectile.Name = "9mmbullet_AP_projectile" + // TODO for later, maybe : set_resource_parent 9mmbullet_AP_projectile game_objects 9mmbullet_projectile + bullet_9mm_AP_projectile.Damage0 = 10 + bullet_9mm_AP_projectile.Damage1 = 15 + bullet_9mm_AP_projectile.ProjectileDamageType = DamageType.Direct + bullet_9mm_AP_projectile.DegradeDelay = 0.15f + bullet_9mm_AP_projectile.DegradeMultiplier = 0.25f + bullet_9mm_AP_projectile.InitialVelocity = 500 + bullet_9mm_AP_projectile.Lifespan = 0.4f + bullet_9mm_AP_projectile.UseDamage1Subtract = true + + bullet_9mm_projectile.Name = "9mmbullet_projectile" + bullet_9mm_projectile.Damage0 = 18 + bullet_9mm_projectile.Damage1 = 10 + bullet_9mm_projectile.ProjectileDamageType = DamageType.Direct + bullet_9mm_projectile.DegradeDelay = 0.15f + bullet_9mm_projectile.DegradeMultiplier = 0.25f + bullet_9mm_projectile.InitialVelocity = 500 + bullet_9mm_projectile.Lifespan = 0.4f + bullet_9mm_projectile.UseDamage1Subtract = true + + anniversary_projectilea.Name = "anniversary_projectilea" + anniversary_projectilea.Damage0 = 30 + anniversary_projectilea.Damage1 = 15 + anniversary_projectilea.Damage2 = 15 + anniversary_projectilea.Damage3 = 45 + anniversary_projectilea.Damage4 = 15 + anniversary_projectilea.ProjectileDamageType = DamageType.Direct + anniversary_projectilea.DegradeDelay = 0.04f + anniversary_projectilea.DegradeMultiplier = 0.2f + anniversary_projectilea.InitialVelocity = 500 + anniversary_projectilea.Lifespan = 0.5f + + anniversary_projectileb.Name = "anniversary_projectileb" + // TODO for later, maybe : set_resource_parent anniversary_projectileb game_objects anniversary_projectilea + anniversary_projectileb.Damage0 = 30 + anniversary_projectileb.Damage1 = 15 + anniversary_projectileb.Damage2 = 15 + anniversary_projectileb.Damage3 = 45 + anniversary_projectileb.Damage4 = 15 + anniversary_projectileb.ProjectileDamageType = DamageType.Direct + anniversary_projectileb.DegradeDelay = 0.04f + anniversary_projectileb.DegradeMultiplier = 0.2f + anniversary_projectileb.InitialVelocity = 500 + anniversary_projectileb.Lifespan = 0.5f + + aphelion_immolation_cannon_projectile.Name = "aphelion_immolation_cannon_projectile" + aphelion_immolation_cannon_projectile.Damage0 = 55 + aphelion_immolation_cannon_projectile.Damage1 = 225 + aphelion_immolation_cannon_projectile.Damage2 = 210 + aphelion_immolation_cannon_projectile.Damage3 = 135 + aphelion_immolation_cannon_projectile.Damage4 = 140 + aphelion_immolation_cannon_projectile.DamageAtEdge = 0.1f + aphelion_immolation_cannon_projectile.DamageRadius = 2.0f + aphelion_immolation_cannon_projectile.ProjectileDamageType = DamageType.Splash + aphelion_immolation_cannon_projectile.InitialVelocity = 250 + aphelion_immolation_cannon_projectile.Lifespan = 1.4f + + aphelion_laser_projectile.Name = "aphelion_laser_projectile" + aphelion_laser_projectile.Damage0 = 3 + aphelion_laser_projectile.Damage1 = 5 + aphelion_laser_projectile.Damage2 = 5 + aphelion_laser_projectile.Damage3 = 4 + aphelion_laser_projectile.Damage4 = 5 + aphelion_laser_projectile.ProjectileDamageType = DamageType.Direct + aphelion_laser_projectile.DegradeDelay = .05f + aphelion_laser_projectile.DegradeMultiplier = 0.5f + aphelion_laser_projectile.InitialVelocity = 500 + aphelion_laser_projectile.Lifespan = 0.35f + + aphelion_plasma_rocket_projectile.Name = "aphelion_plasma_rocket_projectile" + aphelion_plasma_rocket_projectile.Damage0 = 38 + aphelion_plasma_rocket_projectile.Damage1 = 70 + aphelion_plasma_rocket_projectile.Damage2 = 95 + aphelion_plasma_rocket_projectile.Damage3 = 55 + aphelion_plasma_rocket_projectile.Damage4 = 60 + aphelion_plasma_rocket_projectile.Acceleration = 20 + aphelion_plasma_rocket_projectile.AccelerationUntil = 2f + aphelion_plasma_rocket_projectile.DamageAtEdge = .1f + aphelion_plasma_rocket_projectile.DamageRadius = 3f + aphelion_plasma_rocket_projectile.ProjectileDamageType = DamageType.Splash + aphelion_plasma_rocket_projectile.InitialVelocity = 75 + aphelion_plasma_rocket_projectile.Lifespan = 5f + + aphelion_ppa_projectile.Name = "aphelion_ppa_projectile" + // TODO for later, maybe : set_resource_parent aphelion_ppa_projectile game_objects ppa_projectile + aphelion_ppa_projectile.Damage0 = 31 + aphelion_ppa_projectile.Damage1 = 84 + aphelion_ppa_projectile.Damage2 = 58 + aphelion_ppa_projectile.Damage3 = 57 + aphelion_ppa_projectile.Damage4 = 60 + aphelion_ppa_projectile.DamageAtEdge = 0.10f + aphelion_ppa_projectile.DamageRadius = 1f + aphelion_ppa_projectile.ProjectileDamageType = DamageType.Splash + aphelion_ppa_projectile.DegradeDelay = .5f + aphelion_ppa_projectile.DegradeMultiplier = 0.55f + aphelion_ppa_projectile.InitialVelocity = 350 + aphelion_ppa_projectile.Lifespan = .7f + + aphelion_starfire_projectile.Name = "aphelion_starfire_projectile" + // TODO for later, maybe : set_resource_parent aphelion_starfire_projectile game_objects starfire_projectile + aphelion_starfire_projectile.Damage0 = 12 + aphelion_starfire_projectile.Damage1 = 20 + aphelion_starfire_projectile.Damage2 = 15 + aphelion_starfire_projectile.Damage3 = 19 + aphelion_starfire_projectile.Damage4 = 17 + aphelion_starfire_projectile.Acceleration = 11 + aphelion_starfire_projectile.AccelerationUntil = 5f + aphelion_starfire_projectile.InitialVelocity = 45 + aphelion_starfire_projectile.Lifespan = 7f + aphelion_starfire_projectile.ProjectileDamageType = DamageType.Aggravated + + bolt_projectile.Name = "bolt_projectile" + bolt_projectile.Damage0 = 100 + bolt_projectile.Damage1 = 50 + bolt_projectile.Damage2 = 50 + bolt_projectile.Damage3 = 50 + bolt_projectile.Damage4 = 75 + bolt_projectile.ProjectileDamageType = DamageType.Splash + bolt_projectile.InitialVelocity = 500 + bolt_projectile.Lifespan = 1.0f + + burster_projectile.Name = "burster_projectile" + burster_projectile.Damage0 = 18 + burster_projectile.Damage1 = 25 + burster_projectile.Damage2 = 50 + burster_projectile.DamageAtEdge = 0.25f + burster_projectile.DamageRadius = 10f + burster_projectile.ProjectileDamageType = DamageType.Direct + burster_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + burster_projectile.InitialVelocity = 125 + burster_projectile.Lifespan = 4f + + chainblade_projectile.Name = "chainblade_projectile" + // TODO for later, maybe : set_resource_parent chainblade_projectile game_objects melee_ammo_projectile + chainblade_projectile.Damage0 = 50 + chainblade_projectile.Damage1 = 0 + chainblade_projectile.ProjectileDamageType = DamageType.Direct + chainblade_projectile.InitialVelocity = 100 + chainblade_projectile.Lifespan = .02f + + colossus_100mm_projectile.Name = "colossus_100mm_projectile" + colossus_100mm_projectile.Damage0 = 58 + colossus_100mm_projectile.Damage1 = 330 + colossus_100mm_projectile.Damage2 = 300 + colossus_100mm_projectile.Damage3 = 165 + colossus_100mm_projectile.Damage4 = 190 + colossus_100mm_projectile.DamageAtEdge = 0.1f + colossus_100mm_projectile.DamageRadius = 5f + colossus_100mm_projectile.ProjectileDamageType = DamageType.Splash + colossus_100mm_projectile.InitialVelocity = 100 + colossus_100mm_projectile.Lifespan = 4f + + colossus_burster_projectile.Name = "colossus_burster_projectile" + // TODO for later, maybe : set_resource_parent colossus_burster_projectile game_objects burster_projectile + colossus_burster_projectile.Damage0 = 18 + colossus_burster_projectile.Damage1 = 26 + colossus_burster_projectile.Damage2 = 18 + colossus_burster_projectile.Damage3 = 22 + colossus_burster_projectile.Damage4 = 20 + colossus_burster_projectile.DamageAtEdge = 0.1f + colossus_burster_projectile.DamageRadius = 7f + colossus_burster_projectile.ProjectileDamageType = DamageType.Direct + colossus_burster_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + colossus_burster_projectile.InitialVelocity = 175 + colossus_burster_projectile.Lifespan = 2.5f + + colossus_chaingun_projectile.Name = "colossus_chaingun_projectile" + // TODO for later, maybe : set_resource_parent colossus_chaingun_projectile game_objects 35mmbullet_projectile + colossus_chaingun_projectile.Damage0 = 15 + colossus_chaingun_projectile.Damage1 = 14 + colossus_chaingun_projectile.Damage2 = 15 + colossus_chaingun_projectile.Damage3 = 13 + colossus_chaingun_projectile.Damage4 = 11 + colossus_chaingun_projectile.ProjectileDamageType = DamageType.Direct + colossus_chaingun_projectile.DegradeDelay = .100f + colossus_chaingun_projectile.DegradeMultiplier = 0.44f + colossus_chaingun_projectile.InitialVelocity = 500 + colossus_chaingun_projectile.Lifespan = .50f + + colossus_cluster_bomb_projectile.Name = "colossus_cluster_bomb_projectile" + colossus_cluster_bomb_projectile.Damage0 = 40 + colossus_cluster_bomb_projectile.Damage1 = 88 + colossus_cluster_bomb_projectile.Damage2 = 100 + colossus_cluster_bomb_projectile.Damage3 = 83 + colossus_cluster_bomb_projectile.Damage4 = 88 + colossus_cluster_bomb_projectile.DamageAtEdge = 0.1f + colossus_cluster_bomb_projectile.DamageRadius = 8f + colossus_cluster_bomb_projectile.ProjectileDamageType = DamageType.Splash + colossus_cluster_bomb_projectile.InitialVelocity = 75 + colossus_cluster_bomb_projectile.Lifespan = 5f + + colossus_tank_cannon_projectile.Name = "colossus_tank_cannon_projectile" + // TODO for later, maybe : set_resource_parent colossus_tank_cannon_projectile game_objects 75mmbullet_projectile + colossus_tank_cannon_projectile.Damage0 = 33 + colossus_tank_cannon_projectile.Damage1 = 90 + colossus_tank_cannon_projectile.Damage2 = 95 + colossus_tank_cannon_projectile.Damage3 = 71 + colossus_tank_cannon_projectile.Damage4 = 66 + colossus_tank_cannon_projectile.DamageAtEdge = 0.1f + colossus_tank_cannon_projectile.DamageRadius = 2f + colossus_tank_cannon_projectile.ProjectileDamageType = DamageType.Splash + colossus_tank_cannon_projectile.InitialVelocity = 165 + colossus_tank_cannon_projectile.Lifespan = 2f + + comet_projectile.Name = "comet_projectile" + comet_projectile.Damage0 = 15 + comet_projectile.Damage1 = 60 + comet_projectile.Damage2 = 60 + comet_projectile.Damage3 = 38 + comet_projectile.Damage4 = 64 + comet_projectile.Acceleration = 10 + comet_projectile.AccelerationUntil = 2f + comet_projectile.DamageAtEdge = 0.45f + comet_projectile.DamageRadius = 1.0f + comet_projectile.ProjectileDamageType = DamageType.Aggravated + comet_projectile.InitialVelocity = 80 + comet_projectile.Lifespan = 3.1f + + dualcycler_projectile.Name = "dualcycler_projectile" + dualcycler_projectile.Damage0 = 18 + dualcycler_projectile.Damage1 = 10 + dualcycler_projectile.ProjectileDamageType = DamageType.Direct + dualcycler_projectile.DegradeDelay = .025f + dualcycler_projectile.DegradeMultiplier = .5f + dualcycler_projectile.InitialVelocity = 500 + dualcycler_projectile.Lifespan = 0.5f + + dynomite_projectile.Name = "dynomite_projectile" + // TODO for later, maybe : set_resource_parent dynomite_projectile game_objects frag_grenade_projectile_enh + dynomite_projectile.Damage0 = 75 + dynomite_projectile.Damage1 = 175 + dynomite_projectile.DamageAtEdge = 0.1f + dynomite_projectile.DamageRadius = 10f + dynomite_projectile.ProjectileDamageType = DamageType.Splash + dynomite_projectile.InitialVelocity = 30 + dynomite_projectile.Lifespan = 3f + + energy_cell_projectile.Name = "energy_cell_projectile" + energy_cell_projectile.Damage0 = 18 + energy_cell_projectile.Damage1 = 10 + energy_cell_projectile.ProjectileDamageType = DamageType.Direct + energy_cell_projectile.DegradeDelay = 0.05f + energy_cell_projectile.DegradeMultiplier = 0.4f + energy_cell_projectile.InitialVelocity = 500 + energy_cell_projectile.Lifespan = .4f + energy_cell_projectile.UseDamage1Subtract = true + + energy_gun_nc_projectile.Name = "energy_gun_nc_projectile" + energy_gun_nc_projectile.Damage0 = 10 + energy_gun_nc_projectile.Damage1 = 13 + energy_gun_nc_projectile.ProjectileDamageType = DamageType.Direct + energy_gun_nc_projectile.InitialVelocity = 500 + energy_gun_nc_projectile.Lifespan = 0.5f + + energy_gun_tr_projectile.Name = "energy_gun_tr_projectile" + energy_gun_tr_projectile.Damage0 = 14 + energy_gun_tr_projectile.Damage1 = 18 + energy_gun_tr_projectile.ProjectileDamageType = DamageType.Direct + energy_gun_tr_projectile.DegradeDelay = .025f + energy_gun_tr_projectile.DegradeMultiplier = .5f + energy_gun_tr_projectile.InitialVelocity = 500 + energy_gun_tr_projectile.Lifespan = 0.5f + + energy_gun_vs_projectile.Name = "energy_gun_vs_projectile" + energy_gun_vs_projectile.Damage0 = 25 + energy_gun_vs_projectile.Damage1 = 35 + energy_gun_vs_projectile.ProjectileDamageType = DamageType.Direct + energy_gun_vs_projectile.DegradeDelay = 0.045f + energy_gun_vs_projectile.DegradeMultiplier = 0.5f + energy_gun_vs_projectile.InitialVelocity = 500 + energy_gun_vs_projectile.Lifespan = .5f + + enhanced_energy_cell_projectile.Name = "enhanced_energy_cell_projectile" + // TODO for later, maybe : set_resource_parent enhanced_energy_cell_projectile game_objects energy_cell_projectile + enhanced_energy_cell_projectile.Damage0 = 7 + enhanced_energy_cell_projectile.Damage1 = 15 + enhanced_energy_cell_projectile.ProjectileDamageType = DamageType.Direct + enhanced_energy_cell_projectile.DegradeDelay = 0.05f + enhanced_energy_cell_projectile.DegradeMultiplier = 0.4f + enhanced_energy_cell_projectile.InitialVelocity = 500 + enhanced_energy_cell_projectile.Lifespan = .4f + enhanced_energy_cell_projectile.UseDamage1Subtract = true + + enhanced_quasar_projectile.Name = "enhanced_quasar_projectile" + // TODO for later, maybe : set_resource_parent enhanced_quasar_projectile game_objects quasar_projectile + enhanced_quasar_projectile.Damage1 = 12 + enhanced_quasar_projectile.Damage0 = 10 + enhanced_quasar_projectile.ProjectileDamageType = DamageType.Direct + enhanced_quasar_projectile.DegradeDelay = 0.045f + enhanced_quasar_projectile.DegradeMultiplier = 0.5f + enhanced_quasar_projectile.InitialVelocity = 500 + enhanced_quasar_projectile.Lifespan = .4f + + falcon_projectile.Name = "falcon_projectile" + falcon_projectile.Damage0 = 35 + falcon_projectile.Damage1 = 132 + falcon_projectile.Damage2 = 132 + falcon_projectile.Damage3 = 83 + falcon_projectile.Damage4 = 144 + falcon_projectile.Acceleration = 10 + falcon_projectile.AccelerationUntil = 2f + falcon_projectile.DamageAtEdge = 0.2f + falcon_projectile.DamageRadius = 1f + falcon_projectile.ProjectileDamageType = DamageType.Splash + falcon_projectile.InitialVelocity = 120 + falcon_projectile.Lifespan = 2.1f + + firebird_missile_projectile.Name = "firebird_missile_projectile" + firebird_missile_projectile.Damage0 = 125 + firebird_missile_projectile.Damage1 = 220 + firebird_missile_projectile.Damage2 = 220 + firebird_missile_projectile.Damage3 = 200 + firebird_missile_projectile.Damage4 = 181 + firebird_missile_projectile.Acceleration = 20 + firebird_missile_projectile.AccelerationUntil = 2f + firebird_missile_projectile.DamageAtEdge = .1f + firebird_missile_projectile.DamageRadius = 5f + firebird_missile_projectile.ProjectileDamageType = DamageType.Splash + firebird_missile_projectile.InitialVelocity = 75 + firebird_missile_projectile.Lifespan = 5f + + flail_projectile.Name = "flail_projectile" + flail_projectile.Damage0 = 75 + flail_projectile.Damage1 = 200 + flail_projectile.Damage2 = 200 + flail_projectile.Damage3 = 200 + flail_projectile.Damage4 = 300 + flail_projectile.DamageAtEdge = 0.1f + flail_projectile.DamageRadius = 15f + flail_projectile.ProjectileDamageType = DamageType.Splash + flail_projectile.DegradeDelay = 1.5f + flail_projectile.DegradeMultiplier = 5f + flail_projectile.InitialVelocity = 75 + flail_projectile.Lifespan = 40f + + flamethrower_fireball.Name = "flamethrower_fireball" + flamethrower_fireball.Damage0 = 30 + flamethrower_fireball.Damage1 = 0 + flamethrower_fireball.Damage2 = 0 + flamethrower_fireball.Damage3 = 20 + flamethrower_fireball.Damage4 = 0 + flamethrower_fireball.DamageAtEdge = 0.15f + flamethrower_fireball.DamageRadius = 5f + flamethrower_fireball.ProjectileDamageType = DamageType.Aggravated + flamethrower_fireball.InitialVelocity = 15 + flamethrower_fireball.Lifespan = 1.2f + + flamethrower_projectile.Name = "flamethrower_projectile" + flamethrower_projectile.Damage0 = 10 + flamethrower_projectile.Damage1 = 0 + flamethrower_projectile.Damage2 = 0 + flamethrower_projectile.Damage3 = 4 + flamethrower_projectile.Damage4 = 0 + flamethrower_projectile.Acceleration = -5 + flamethrower_projectile.AccelerationUntil = 2f + flamethrower_projectile.ProjectileDamageType = DamageType.Aggravated + flamethrower_projectile.DegradeDelay = 1.0f + flamethrower_projectile.DegradeMultiplier = 0.5f + flamethrower_projectile.InitialVelocity = 10 + flamethrower_projectile.Lifespan = 2.0f + + flux_cannon_apc_projectile.Name = "flux_cannon_apc_projectile" + // TODO for later, maybe : set_resource_parent flux_cannon_apc_projectile game_objects flux_cannon_thresher_projectile + flux_cannon_apc_projectile.Damage0 = 14 + flux_cannon_apc_projectile.Damage1 = 23 + flux_cannon_apc_projectile.Damage2 = 35 + flux_cannon_apc_projectile.Damage3 = 23 + flux_cannon_apc_projectile.Damage4 = 18 + flux_cannon_apc_projectile.DamageAtEdge = .5f + flux_cannon_apc_projectile.DamageRadius = 4f + flux_cannon_apc_projectile.ProjectileDamageType = DamageType.Direct + flux_cannon_apc_projectile.InitialVelocity = 300 + flux_cannon_apc_projectile.Lifespan = 1f + + flux_cannon_thresher_projectile.Name = "flux_cannon_thresher_projectile" + flux_cannon_thresher_projectile.Damage0 = 30 + flux_cannon_thresher_projectile.Damage1 = 44 + flux_cannon_thresher_projectile.Damage2 = 44 + flux_cannon_thresher_projectile.Damage3 = 40 + flux_cannon_thresher_projectile.Damage4 = 37 + flux_cannon_thresher_projectile.DamageAtEdge = .5f + flux_cannon_thresher_projectile.DamageRadius = 4f + flux_cannon_thresher_projectile.ProjectileDamageType = DamageType.Splash + flux_cannon_thresher_projectile.InitialVelocity = 75 + flux_cannon_thresher_projectile.Lifespan = 3f + + fluxpod_projectile.Name = "fluxpod_projectile" + fluxpod_projectile.Damage0 = 110 + fluxpod_projectile.Damage1 = 80 + fluxpod_projectile.Damage2 = 125 + fluxpod_projectile.Damage3 = 80 + fluxpod_projectile.Damage4 = 52 + fluxpod_projectile.DamageAtEdge = .3f + fluxpod_projectile.DamageRadius = 3f + fluxpod_projectile.ProjectileDamageType = DamageType.Splash + fluxpod_projectile.InitialVelocity = 80 + fluxpod_projectile.Lifespan = 4f + + forceblade_projectile.Name = "forceblade_projectile" + // TODO for later, maybe : set_resource_parent forceblade_projectile game_objects melee_ammo_projectile + forceblade_projectile.Damage0 = 50 + forceblade_projectile.Damage1 = 0 + forceblade_projectile.ProjectileDamageType = DamageType.Direct + forceblade_projectile.InitialVelocity = 100 + forceblade_projectile.Lifespan = .02f + + frag_cartridge_projectile.Name = "frag_cartridge_projectile" + // TODO for later, maybe : set_resource_parent frag_cartridge_projectile game_objects frag_grenade_projectile + frag_cartridge_projectile.Damage0 = 75 + frag_cartridge_projectile.Damage1 = 100 + frag_cartridge_projectile.DamageAtEdge = 0.1f + frag_cartridge_projectile.DamageRadius = 7f + frag_cartridge_projectile.ProjectileDamageType = DamageType.Splash + frag_cartridge_projectile.InitialVelocity = 30 + frag_cartridge_projectile.Lifespan = 15f + + frag_cartridge_projectile_b.Name = "frag_cartridge_projectile_b" + // TODO for later, maybe : set_resource_parent frag_cartridge_projectile_b game_objects frag_grenade_projectile_enh + frag_cartridge_projectile_b.Damage0 = 75 + frag_cartridge_projectile_b.Damage1 = 100 + frag_cartridge_projectile_b.DamageAtEdge = 0.1f + frag_cartridge_projectile_b.DamageRadius = 5f + frag_cartridge_projectile_b.ProjectileDamageType = DamageType.Splash + frag_cartridge_projectile_b.InitialVelocity = 30 + frag_cartridge_projectile_b.Lifespan = 2f + + frag_grenade_projectile.Name = "frag_grenade_projectile" + frag_grenade_projectile.Damage0 = 75 + frag_grenade_projectile.Damage1 = 100 + frag_grenade_projectile.DamageAtEdge = 0.1f + frag_grenade_projectile.DamageRadius = 7f + frag_grenade_projectile.ProjectileDamageType = DamageType.Splash + frag_grenade_projectile.InitialVelocity = 30 + frag_grenade_projectile.Lifespan = 15f + + frag_grenade_projectile_enh.Name = "frag_grenade_projectile_enh" + // TODO for later, maybe : set_resource_parent frag_grenade_projectile_enh game_objects frag_grenade_projectile + frag_grenade_projectile_enh.Damage0 = 75 + frag_grenade_projectile_enh.Damage1 = 100 + frag_grenade_projectile_enh.DamageAtEdge = 0.1f + frag_grenade_projectile_enh.DamageRadius = 7f + frag_grenade_projectile_enh.ProjectileDamageType = DamageType.Splash + frag_grenade_projectile_enh.InitialVelocity = 30 + frag_grenade_projectile_enh.Lifespan = 2f + + galaxy_gunship_gun_projectile.Name = "galaxy_gunship_gun_projectile" + // TODO for later, maybe : set_resource_parent galaxy_gunship_gun_projectile game_objects 35mmbullet_projectile + galaxy_gunship_gun_projectile.Damage0 = 40 + galaxy_gunship_gun_projectile.Damage1 = 50 + galaxy_gunship_gun_projectile.Damage2 = 80 + galaxy_gunship_gun_projectile.ProjectileDamageType = DamageType.Direct + galaxy_gunship_gun_projectile.DegradeDelay = 0.4f + galaxy_gunship_gun_projectile.DegradeMultiplier = 0.6f + galaxy_gunship_gun_projectile.InitialVelocity = 400 + galaxy_gunship_gun_projectile.Lifespan = 0.8f + + gauss_cannon_projectile.Name = "gauss_cannon_projectile" + gauss_cannon_projectile.Damage0 = 190 + gauss_cannon_projectile.Damage1 = 370 + gauss_cannon_projectile.Damage2 = 370 + gauss_cannon_projectile.Damage3 = 370 + gauss_cannon_projectile.Damage4 = 240 + gauss_cannon_projectile.DamageAtEdge = 0.3f + gauss_cannon_projectile.DamageRadius = 1.5f + gauss_cannon_projectile.ProjectileDamageType = DamageType.Splash + gauss_cannon_projectile.InitialVelocity = 150 + gauss_cannon_projectile.Lifespan = 2.67f + + grenade_projectile.Name = "grenade_projectile" + grenade_projectile.Damage0 = 50 + grenade_projectile.DamageAtEdge = 0.2f + grenade_projectile.DamageRadius = 100f + grenade_projectile.ProjectileDamageType = DamageType.Splash + grenade_projectile.InitialVelocity = 15 + grenade_projectile.Lifespan = 15f + + heavy_grenade_projectile.Name = "heavy_grenade_projectile" + heavy_grenade_projectile.Damage0 = 50 + heavy_grenade_projectile.Damage1 = 82 + heavy_grenade_projectile.Damage2 = 82 + heavy_grenade_projectile.Damage3 = 75 + heavy_grenade_projectile.Damage4 = 66 + heavy_grenade_projectile.DamageAtEdge = 0.1f + heavy_grenade_projectile.DamageRadius = 5f + heavy_grenade_projectile.ProjectileDamageType = DamageType.Splash + heavy_grenade_projectile.InitialVelocity = 75 + heavy_grenade_projectile.Lifespan = 5f + + heavy_rail_beam_projectile.Name = "heavy_rail_beam_projectile" + heavy_rail_beam_projectile.Damage0 = 75 + heavy_rail_beam_projectile.Damage1 = 215 + heavy_rail_beam_projectile.Damage2 = 215 + heavy_rail_beam_projectile.Damage3 = 215 + heavy_rail_beam_projectile.Damage4 = 120 + heavy_rail_beam_projectile.DamageAtEdge = 0.30f + heavy_rail_beam_projectile.DamageRadius = 5f + heavy_rail_beam_projectile.ProjectileDamageType = DamageType.Splash + heavy_rail_beam_projectile.InitialVelocity = 600 + heavy_rail_beam_projectile.Lifespan = .5f + + heavy_sniper_projectile.Name = "heavy_sniper_projectile" + heavy_sniper_projectile.Damage0 = 55 + heavy_sniper_projectile.Damage1 = 28 + heavy_sniper_projectile.Damage2 = 28 + heavy_sniper_projectile.Damage3 = 28 + heavy_sniper_projectile.Damage4 = 42 + heavy_sniper_projectile.ProjectileDamageType = DamageType.Splash + heavy_sniper_projectile.InitialVelocity = 500 + heavy_sniper_projectile.Lifespan = 1.0f + + hellfire_projectile.Name = "hellfire_projectile" + hellfire_projectile.Damage0 = 50 + hellfire_projectile.Damage1 = 250 + hellfire_projectile.Damage2 = 250 + hellfire_projectile.Damage3 = 125 + hellfire_projectile.Damage4 = 250 + hellfire_projectile.Acceleration = 10 + hellfire_projectile.AccelerationUntil = 2f + hellfire_projectile.DamageAtEdge = .25f + hellfire_projectile.DamageRadius = 3f + hellfire_projectile.ProjectileDamageType = DamageType.Splash + hellfire_projectile.InitialVelocity = 125 + hellfire_projectile.Lifespan = 1.5f + + hunter_seeker_missile_dumbfire.Name = "hunter_seeker_missile_dumbfire" + hunter_seeker_missile_dumbfire.Damage0 = 50 + hunter_seeker_missile_dumbfire.Damage1 = 350 + hunter_seeker_missile_dumbfire.Damage2 = 250 + hunter_seeker_missile_dumbfire.Damage3 = 250 + hunter_seeker_missile_dumbfire.Damage4 = 525 + hunter_seeker_missile_dumbfire.DamageAtEdge = 0.1f + hunter_seeker_missile_dumbfire.DamageRadius = 1.5f + hunter_seeker_missile_dumbfire.ProjectileDamageType = DamageType.Splash + hunter_seeker_missile_dumbfire.InitialVelocity = 40 + hunter_seeker_missile_dumbfire.Lifespan = 6.3f + + hunter_seeker_missile_projectile.Name = "hunter_seeker_missile_projectile" + hunter_seeker_missile_projectile.Damage0 = 50 + hunter_seeker_missile_projectile.Damage1 = 350 + hunter_seeker_missile_projectile.Damage2 = 250 + hunter_seeker_missile_projectile.Damage3 = 250 + hunter_seeker_missile_projectile.Damage4 = 525 + hunter_seeker_missile_projectile.DamageAtEdge = 0.1f + hunter_seeker_missile_projectile.DamageRadius = 1.5f + hunter_seeker_missile_projectile.ProjectileDamageType = DamageType.Splash + hunter_seeker_missile_projectile.InitialVelocity = 40 + hunter_seeker_missile_projectile.Lifespan = 6.3f + + jammer_cartridge_projectile.Name = "jammer_cartridge_projectile" + // TODO for later, maybe : set_resource_parent jammer_cartridge_projectile game_objects jammer_grenade_projectile + jammer_cartridge_projectile.Damage0 = 0 + jammer_cartridge_projectile.Damage1 = 0 + jammer_cartridge_projectile.DamageAtEdge = 1.0f + jammer_cartridge_projectile.DamageRadius = 10f + jammer_cartridge_projectile.ProjectileDamageType = DamageType.Splash + jammer_cartridge_projectile.InitialVelocity = 30 + jammer_cartridge_projectile.Lifespan = 15f + + jammer_cartridge_projectile_b.Name = "jammer_cartridge_projectile_b" + // TODO for later, maybe : set_resource_parent jammer_cartridge_projectile_b game_objects jammer_grenade_projectile_enh + jammer_cartridge_projectile_b.Damage0 = 0 + jammer_cartridge_projectile_b.Damage1 = 0 + jammer_cartridge_projectile_b.DamageAtEdge = 1.0f + jammer_cartridge_projectile_b.DamageRadius = 10f + jammer_cartridge_projectile_b.ProjectileDamageType = DamageType.Splash + jammer_cartridge_projectile_b.InitialVelocity = 30 + jammer_cartridge_projectile_b.Lifespan = 2f + + jammer_grenade_projectile.Name = "jammer_grenade_projectile" + jammer_grenade_projectile.Damage0 = 0 + jammer_grenade_projectile.Damage1 = 0 + jammer_grenade_projectile.DamageAtEdge = 1.0f + jammer_grenade_projectile.DamageRadius = 10f + jammer_grenade_projectile.ProjectileDamageType = DamageType.Splash + jammer_grenade_projectile.InitialVelocity = 30 + jammer_grenade_projectile.Lifespan = 15f + + jammer_grenade_projectile_enh.Name = "jammer_grenade_projectile_enh" + // TODO for later, maybe : set_resource_parent jammer_grenade_projectile_enh game_objects jammer_grenade_projectile + jammer_grenade_projectile_enh.Damage0 = 0 + jammer_grenade_projectile_enh.Damage1 = 0 + jammer_grenade_projectile_enh.DamageAtEdge = 1.0f + jammer_grenade_projectile_enh.DamageRadius = 10f + jammer_grenade_projectile_enh.ProjectileDamageType = DamageType.Splash + jammer_grenade_projectile_enh.InitialVelocity = 30 + jammer_grenade_projectile_enh.Lifespan = 3f + + katana_projectile.Name = "katana_projectile" + katana_projectile.Damage0 = 25 + katana_projectile.Damage1 = 0 + katana_projectile.ProjectileDamageType = DamageType.Direct + katana_projectile.InitialVelocity = 100 + katana_projectile.Lifespan = .03f + + katana_projectileb.Name = "katana_projectileb" + // TODO for later, maybe : set_resource_parent katana_projectileb game_objects katana_projectile + katana_projectileb.Damage0 = 25 + katana_projectileb.Damage1 = 0 + katana_projectileb.ProjectileDamageType = DamageType.Direct + katana_projectileb.InitialVelocity = 100 + katana_projectileb.Lifespan = .03f + + lancer_projectile.Name = "lancer_projectile" + lancer_projectile.Damage0 = 25 + lancer_projectile.Damage1 = 175 + lancer_projectile.Damage2 = 125 + lancer_projectile.Damage3 = 125 + lancer_projectile.Damage4 = 263 + lancer_projectile.ProjectileDamageType = DamageType.Direct + lancer_projectile.InitialVelocity = 500 + lancer_projectile.Lifespan = 0.6f + + lasher_projectile.Name = "lasher_projectile" + lasher_projectile.Damage0 = 30 + lasher_projectile.Damage1 = 15 + lasher_projectile.Damage2 = 15 + lasher_projectile.Damage3 = 12 + lasher_projectile.Damage4 = 12 + lasher_projectile.ProjectileDamageType = DamageType.Direct + lasher_projectile.DegradeDelay = 0.012f + lasher_projectile.DegradeMultiplier = 0.3f + lasher_projectile.InitialVelocity = 120 + lasher_projectile.Lifespan = 0.75f + + lasher_projectile_ap.Name = "lasher_projectile_ap" + lasher_projectile_ap.Damage0 = 12 + lasher_projectile_ap.Damage1 = 25 + lasher_projectile_ap.Damage2 = 25 + lasher_projectile_ap.Damage3 = 28 + lasher_projectile_ap.Damage4 = 28 + lasher_projectile_ap.ProjectileDamageType = DamageType.Direct + lasher_projectile_ap.DegradeDelay = 0.012f + lasher_projectile_ap.DegradeMultiplier = 0.3f + lasher_projectile_ap.InitialVelocity = 120 + lasher_projectile_ap.Lifespan = 0.75f + + liberator_bomb_cluster_bomblet_projectile.Name = "liberator_bomb_cluster_bomblet_projectile" + liberator_bomb_cluster_bomblet_projectile.Damage0 = 75 + liberator_bomb_cluster_bomblet_projectile.Damage1 = 100 + liberator_bomb_cluster_bomblet_projectile.DamageAtEdge = 0.25f + liberator_bomb_cluster_bomblet_projectile.DamageRadius = 3f + liberator_bomb_cluster_bomblet_projectile.ProjectileDamageType = DamageType.Splash + liberator_bomb_cluster_bomblet_projectile.InitialVelocity = 0 + liberator_bomb_cluster_bomblet_projectile.Lifespan = 30f + + liberator_bomb_cluster_projectile.Name = "liberator_bomb_cluster_projectile" + liberator_bomb_cluster_projectile.Damage0 = 75 + liberator_bomb_cluster_projectile.Damage1 = 100 + liberator_bomb_cluster_projectile.DamageAtEdge = 0.25f + liberator_bomb_cluster_projectile.DamageRadius = 3f + liberator_bomb_cluster_projectile.ProjectileDamageType = DamageType.Direct + liberator_bomb_cluster_projectile.InitialVelocity = 0 + liberator_bomb_cluster_projectile.Lifespan = 30f + + liberator_bomb_projectile.Name = "liberator_bomb_projectile" + liberator_bomb_projectile.Damage0 = 250 + liberator_bomb_projectile.Damage1 = 1000 + liberator_bomb_projectile.Damage2 = 1000 + liberator_bomb_projectile.Damage3 = 1000 + liberator_bomb_projectile.Damage4 = 600 + liberator_bomb_projectile.DamageAtEdge = 0.1f + liberator_bomb_projectile.DamageRadius = 10f + liberator_bomb_projectile.ProjectileDamageType = DamageType.Splash + liberator_bomb_projectile.InitialVelocity = 0 + liberator_bomb_projectile.Lifespan = 30f + + maelstrom_grenade_projectile.Name = "maelstrom_grenade_projectile" + maelstrom_grenade_projectile.Damage0 = 32 + maelstrom_grenade_projectile.Damage1 = 60 + maelstrom_grenade_projectile.DamageRadius = 20.0f + maelstrom_grenade_projectile.ProjectileDamageType = DamageType.Direct + maelstrom_grenade_projectile.InitialVelocity = 30 + maelstrom_grenade_projectile.Lifespan = 2f + + maelstrom_grenade_projectile_contact.Name = "maelstrom_grenade_projectile_contact" + // TODO for later, maybe : set_resource_parent maelstrom_grenade_projectile_contact game_objects maelstrom_grenade_projectile + maelstrom_grenade_projectile_contact.Damage0 = 32 + maelstrom_grenade_projectile_contact.Damage1 = 60 + maelstrom_grenade_projectile_contact.DamageRadius = 20.0f + maelstrom_grenade_projectile_contact.ProjectileDamageType = DamageType.Direct + maelstrom_grenade_projectile_contact.InitialVelocity = 30 + maelstrom_grenade_projectile_contact.Lifespan = 15f + + maelstrom_stream_projectile.Name = "maelstrom_stream_projectile" + maelstrom_stream_projectile.Damage0 = 15 + maelstrom_stream_projectile.Damage1 = 6 + maelstrom_stream_projectile.ProjectileDamageType = DamageType.Direct + maelstrom_stream_projectile.DegradeDelay = .075f + maelstrom_stream_projectile.DegradeMultiplier = 0.5f + maelstrom_stream_projectile.InitialVelocity = 200 + maelstrom_stream_projectile.Lifespan = 0.2f + + magcutter_projectile.Name = "magcutter_projectile" + // TODO for later, maybe : set_resource_parent magcutter_projectile game_objects melee_ammo_projectile + magcutter_projectile.Damage0 = 50 + magcutter_projectile.Damage1 = 0 + magcutter_projectile.ProjectileDamageType = DamageType.Direct + magcutter_projectile.InitialVelocity = 100 + magcutter_projectile.Lifespan = .02f + + melee_ammo_projectile.Name = "melee_ammo_projectile" + melee_ammo_projectile.Damage0 = 25 + melee_ammo_projectile.Damage1 = 0 + melee_ammo_projectile.ProjectileDamageType = DamageType.Direct + melee_ammo_projectile.InitialVelocity = 100 + melee_ammo_projectile.Lifespan = .02f + + meteor_common.Name = "meteor_common" + meteor_common.DamageAtEdge = .1f + meteor_common.ProjectileDamageType = DamageType.Splash + meteor_common.InitialVelocity = 0 + meteor_common.Lifespan = 40 + + meteor_projectile_b_large.Name = "meteor_projectile_b_large" + // TODO for later, maybe : set_resource_parent meteor_projectile_b_large game_objects meteor_common + meteor_projectile_b_large.Damage0 = 2500 + meteor_projectile_b_large.Damage1 = 5000 + meteor_projectile_b_large.DamageRadius = 15f + meteor_projectile_b_large.DamageAtEdge = .1f + meteor_projectile_b_large.ProjectileDamageType = DamageType.Splash + meteor_projectile_b_large.InitialVelocity = 0 + meteor_projectile_b_large.Lifespan = 40 + + meteor_projectile_b_medium.Name = "meteor_projectile_b_medium" + // TODO for later, maybe : set_resource_parent meteor_projectile_b_medium game_objects meteor_common + meteor_projectile_b_medium.Damage0 = 1250 + meteor_projectile_b_medium.Damage1 = 2500 + meteor_projectile_b_medium.DamageRadius = 10f + meteor_projectile_b_medium.DamageAtEdge = .1f + meteor_projectile_b_medium.ProjectileDamageType = DamageType.Splash + meteor_projectile_b_medium.InitialVelocity = 0 + meteor_projectile_b_medium.Lifespan = 40 + + meteor_projectile_b_small.Name = "meteor_projectile_b_small" + // TODO for later, maybe : set_resource_parent meteor_projectile_b_small game_objects meteor_common + meteor_projectile_b_small.Damage0 = 625 + meteor_projectile_b_small.Damage1 = 1250 + meteor_projectile_b_small.DamageRadius = 5f + meteor_projectile_b_small.DamageAtEdge = .1f + meteor_projectile_b_small.ProjectileDamageType = DamageType.Splash + meteor_projectile_b_small.InitialVelocity = 0 + meteor_projectile_b_small.Lifespan = 40 + + meteor_projectile_large.Name = "meteor_projectile_large" + // TODO for later, maybe : set_resource_parent meteor_projectile_large game_objects meteor_common + meteor_projectile_large.Damage0 = 2500 + meteor_projectile_large.Damage1 = 5000 + meteor_projectile_large.DamageRadius = 15f + meteor_projectile_large.DamageAtEdge = .1f + meteor_projectile_large.ProjectileDamageType = DamageType.Splash + meteor_projectile_large.InitialVelocity = 0 + meteor_projectile_large.Lifespan = 40 + + meteor_projectile_medium.Name = "meteor_projectile_medium" + // TODO for later, maybe : set_resource_parent meteor_projectile_medium game_objects meteor_common + meteor_projectile_medium.Damage0 = 1250 + meteor_projectile_medium.Damage1 = 2500 + meteor_projectile_medium.DamageRadius = 10f + meteor_projectile_medium.DamageAtEdge = .1f + meteor_projectile_medium.ProjectileDamageType = DamageType.Splash + meteor_projectile_medium.InitialVelocity = 0 + meteor_projectile_medium.Lifespan = 40 + + meteor_projectile_small.Name = "meteor_projectile_small" + // TODO for later, maybe : set_resource_parent meteor_projectile_small game_objects meteor_common + meteor_projectile_small.Damage0 = 625 + meteor_projectile_small.Damage1 = 1250 + meteor_projectile_small.DamageRadius = 5f + meteor_projectile_small.DamageAtEdge = .1f + meteor_projectile_small.ProjectileDamageType = DamageType.Splash + meteor_projectile_small.InitialVelocity = 0 + meteor_projectile_small.Lifespan = 40 + + mine_projectile.Name = "mine_projectile" + mine_projectile.Lifespan = 0.01f + mine_projectile.InitialVelocity = 300 + + mine_sweeper_projectile.Name = "mine_sweeper_projectile" + mine_sweeper_projectile.Damage0 = 0 + mine_sweeper_projectile.Damage1 = 0 + mine_sweeper_projectile.DamageAtEdge = .33f + mine_sweeper_projectile.DamageRadius = 25f + mine_sweeper_projectile.ProjectileDamageType = DamageType.Splash + mine_sweeper_projectile.InitialVelocity = 30 + mine_sweeper_projectile.Lifespan = 15f + + mine_sweeper_projectile_enh.Name = "mine_sweeper_projectile_enh" + mine_sweeper_projectile_enh.Damage0 = 0 + mine_sweeper_projectile_enh.Damage1 = 0 + mine_sweeper_projectile_enh.DamageAtEdge = 0.33f + mine_sweeper_projectile_enh.DamageRadius = 25f + mine_sweeper_projectile_enh.InitialVelocity = 30 + mine_sweeper_projectile_enh.Lifespan = 3f + + oicw_projectile.Name = "oicw_projectile" + oicw_projectile.Damage0 = 50 + oicw_projectile.Damage1 = 50 + oicw_projectile.Acceleration = 15 + oicw_projectile.AccelerationUntil = 5f + oicw_projectile.DamageAtEdge = 0.1f + oicw_projectile.DamageRadius = 10f + oicw_projectile.ProjectileDamageType = DamageType.Splash + oicw_projectile.InitialVelocity = 5 + oicw_projectile.Lifespan = 6.1f + + pellet_gun_projectile.Name = "pellet_gun_projectile" + // TODO for later, maybe : set_resource_parent pellet_gun_projectile game_objects shotgun_shell_projectile + pellet_gun_projectile.Damage0 = 12 + pellet_gun_projectile.Damage1 = 8 + pellet_gun_projectile.ProjectileDamageType = DamageType.Direct + pellet_gun_projectile.InitialVelocity = 400 + pellet_gun_projectile.Lifespan = 0.1875f + pellet_gun_projectile.UseDamage1Subtract = false + + peregrine_dual_machine_gun_projectile.Name = "peregrine_dual_machine_gun_projectile" + // TODO for later, maybe : set_resource_parent peregrine_dual_machine_gun_projectile game_objects 35mmbullet_projectile + peregrine_dual_machine_gun_projectile.Damage0 = 16 + peregrine_dual_machine_gun_projectile.Damage1 = 44 + peregrine_dual_machine_gun_projectile.Damage2 = 30 + peregrine_dual_machine_gun_projectile.Damage3 = 27 + peregrine_dual_machine_gun_projectile.Damage4 = 32 + peregrine_dual_machine_gun_projectile.ProjectileDamageType = DamageType.Direct + peregrine_dual_machine_gun_projectile.DegradeDelay = .25f + peregrine_dual_machine_gun_projectile.DegradeMultiplier = 0.65f + peregrine_dual_machine_gun_projectile.InitialVelocity = 250 + peregrine_dual_machine_gun_projectile.Lifespan = 1.1f + + peregrine_mechhammer_projectile.Name = "peregrine_mechhammer_projectile" + peregrine_mechhammer_projectile.Damage0 = 5 + peregrine_mechhammer_projectile.Damage1 = 4 + peregrine_mechhammer_projectile.Damage2 = 4 + peregrine_mechhammer_projectile.Damage3 = 5 + peregrine_mechhammer_projectile.Damage4 = 3 + peregrine_mechhammer_projectile.ProjectileDamageType = DamageType.Direct + peregrine_mechhammer_projectile.InitialVelocity = 500 + peregrine_mechhammer_projectile.Lifespan = 0.4f + + peregrine_particle_cannon_projectile.Name = "peregrine_particle_cannon_projectile" + peregrine_particle_cannon_projectile.Damage0 = 70 + peregrine_particle_cannon_projectile.Damage1 = 525 + peregrine_particle_cannon_projectile.Damage2 = 350 + peregrine_particle_cannon_projectile.Damage3 = 318 + peregrine_particle_cannon_projectile.Damage4 = 310 + peregrine_particle_cannon_projectile.DamageAtEdge = 0.1f + peregrine_particle_cannon_projectile.DamageRadius = 3f + peregrine_particle_cannon_projectile.ProjectileDamageType = DamageType.Splash + peregrine_particle_cannon_projectile.InitialVelocity = 500 + peregrine_particle_cannon_projectile.Lifespan = .6f + + peregrine_rocket_pod_projectile.Name = "peregrine_rocket_pod_projectile" + peregrine_rocket_pod_projectile.Damage0 = 30 + peregrine_rocket_pod_projectile.Damage1 = 50 + peregrine_rocket_pod_projectile.Damage2 = 50 + peregrine_rocket_pod_projectile.Damage3 = 45 + peregrine_rocket_pod_projectile.Damage4 = 40 + peregrine_rocket_pod_projectile.Acceleration = 10 + peregrine_rocket_pod_projectile.AccelerationUntil = 2f + peregrine_rocket_pod_projectile.DamageAtEdge = 0.1f + peregrine_rocket_pod_projectile.DamageRadius = 3f + peregrine_rocket_pod_projectile.ProjectileDamageType = DamageType.Splash + peregrine_rocket_pod_projectile.InitialVelocity = 200 + peregrine_rocket_pod_projectile.Lifespan = 1.85f + + peregrine_sparrow_projectile.Name = "peregrine_sparrow_projectile" + // TODO for later, maybe : set_resource_parent peregrine_sparrow_projectile game_objects sparrow_projectile + peregrine_sparrow_projectile.Damage0 = 20 + peregrine_sparrow_projectile.Damage1 = 40 + peregrine_sparrow_projectile.Damage2 = 30 + peregrine_sparrow_projectile.Damage3 = 30 + peregrine_sparrow_projectile.Damage4 = 31 + peregrine_sparrow_projectile.Acceleration = 12 + peregrine_sparrow_projectile.AccelerationUntil = 5f + peregrine_sparrow_projectile.DamageAtEdge = 0.1f + peregrine_sparrow_projectile.DamageRadius = 2f + peregrine_sparrow_projectile.ProjectileDamageType = DamageType.Splash + peregrine_sparrow_projectile.InitialVelocity = 45 + peregrine_sparrow_projectile.Lifespan = 7.5f + + phalanx_av_projectile.Name = "phalanx_av_projectile" + phalanx_av_projectile.Damage0 = 60 + phalanx_av_projectile.Damage1 = 140 + phalanx_av_projectile.DamageAtEdge = 0.1f + phalanx_av_projectile.DamageRadius = 5f + phalanx_av_projectile.ProjectileDamageType = DamageType.Splash + phalanx_av_projectile.InitialVelocity = 100 + phalanx_av_projectile.Lifespan = 4f + + phalanx_flak_projectile.Name = "phalanx_flak_projectile" + phalanx_flak_projectile.Damage0 = 15 + phalanx_flak_projectile.Damage1 = 25 + phalanx_flak_projectile.Damage2 = 70 + phalanx_flak_projectile.DamageAtEdge = 1f + phalanx_flak_projectile.DamageRadius = 10f + phalanx_flak_projectile.ProjectileDamageType = DamageType.Direct + phalanx_flak_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + phalanx_flak_projectile.InitialVelocity = 100 + phalanx_flak_projectile.Lifespan = 5f + + phalanx_projectile.Name = "phalanx_projectile" + phalanx_projectile.Damage0 = 20 + phalanx_projectile.Damage1 = 30 + phalanx_projectile.Damage2 = 30 + phalanx_projectile.Damage3 = 30 + phalanx_projectile.Damage4 = 18 + phalanx_projectile.ProjectileDamageType = DamageType.Direct + phalanx_projectile.DegradeDelay = 0f + phalanx_projectile.DegradeMultiplier = 0.25f + phalanx_projectile.InitialVelocity = 400 + phalanx_projectile.Lifespan = 1f + + phoenix_missile_guided_projectile.Name = "phoenix_missile_guided_projectile" + // TODO for later, maybe : set_resource_parent phoenix_missile_guided_projectile game_objects phoenix_missile_projectile + phoenix_missile_guided_projectile.Damage0 = 80 + phoenix_missile_guided_projectile.Damage1 = 400 + phoenix_missile_guided_projectile.Damage2 = 400 + phoenix_missile_guided_projectile.Damage3 = 300 + phoenix_missile_guided_projectile.Damage4 = 600 + phoenix_missile_guided_projectile.Acceleration = 60 + phoenix_missile_guided_projectile.AccelerationUntil = 2.5f + phoenix_missile_guided_projectile.DamageAtEdge = 0.3f + phoenix_missile_guided_projectile.DamageRadius = 1.5f + phoenix_missile_guided_projectile.ProjectileDamageType = DamageType.Splash + phoenix_missile_guided_projectile.InitialVelocity = 0 + phoenix_missile_guided_projectile.Lifespan = 3f + + phoenix_missile_projectile.Name = "phoenix_missile_projectile" + phoenix_missile_projectile.Damage0 = 80 + phoenix_missile_projectile.Damage1 = 400 + phoenix_missile_projectile.Damage2 = 400 + phoenix_missile_projectile.Damage3 = 300 + phoenix_missile_projectile.Damage4 = 600 + phoenix_missile_projectile.Acceleration = 60 + phoenix_missile_projectile.AccelerationUntil = 2.5f + phoenix_missile_projectile.DamageAtEdge = 0.3f + phoenix_missile_projectile.DamageRadius = 1.5f + phoenix_missile_projectile.ProjectileDamageType = DamageType.Splash + phoenix_missile_projectile.InitialVelocity = 0 + phoenix_missile_projectile.Lifespan = 3f + + plasma_cartridge_projectile.Name = "plasma_cartridge_projectile" + // TODO for later, maybe : set_resource_parent plasma_cartridge_projectile game_objects plasma_grenade_projectile + plasma_cartridge_projectile.Damage0 = 20 + plasma_cartridge_projectile.Damage1 = 15 + plasma_cartridge_projectile.DamageAtEdge = 0.2f + plasma_cartridge_projectile.DamageRadius = 7f + plasma_cartridge_projectile.ProjectileDamageType = DamageType.Aggravated + plasma_cartridge_projectile.InitialVelocity = 30 + plasma_cartridge_projectile.Lifespan = 15f + + plasma_cartridge_projectile_b.Name = "plasma_cartridge_projectile_b" + // TODO for later, maybe : set_resource_parent plasma_cartridge_projectile_b game_objects plasma_grenade_projectile_B + plasma_cartridge_projectile_b.Damage0 = 20 + plasma_cartridge_projectile_b.Damage1 = 15 + plasma_cartridge_projectile_b.DamageAtEdge = 0.2f + plasma_cartridge_projectile_b.DamageRadius = 7f + plasma_cartridge_projectile_b.ProjectileDamageType = DamageType.Aggravated + plasma_cartridge_projectile_b.InitialVelocity = 30 + plasma_cartridge_projectile_b.Lifespan = 2f + + plasma_grenade_projectile.Name = "plasma_grenade_projectile" + plasma_grenade_projectile.Damage0 = 40 + plasma_grenade_projectile.Damage1 = 30 + plasma_grenade_projectile.DamageAtEdge = 0.1f + plasma_grenade_projectile.DamageRadius = 7f + plasma_grenade_projectile.ProjectileDamageType = DamageType.Aggravated + plasma_grenade_projectile.InitialVelocity = 30 + plasma_grenade_projectile.Lifespan = 15f + + plasma_grenade_projectile_B.Name = "plasma_grenade_projectile_B" + // TODO for later, maybe : set_resource_parent plasma_grenade_projectile_B game_objects plasma_grenade_projectile + plasma_grenade_projectile_B.Damage0 = 40 + plasma_grenade_projectile_B.Damage1 = 30 + plasma_grenade_projectile_B.DamageAtEdge = 0.1f + plasma_grenade_projectile_B.DamageRadius = 7f + plasma_grenade_projectile_B.ProjectileDamageType = DamageType.Aggravated + plasma_grenade_projectile_B.InitialVelocity = 30 + plasma_grenade_projectile_B.Lifespan = 3f + + pounder_projectile.Name = "pounder_projectile" + pounder_projectile.Damage0 = 31 + pounder_projectile.Damage1 = 120 + pounder_projectile.Damage2 = 120 + pounder_projectile.Damage3 = 75 + pounder_projectile.Damage4 = 132 + pounder_projectile.DamageAtEdge = 0.1f + pounder_projectile.DamageRadius = 1f + pounder_projectile.ProjectileDamageType = DamageType.Splash + pounder_projectile.InitialVelocity = 120 + pounder_projectile.Lifespan = 2.5f + + pounder_projectile_enh.Name = "pounder_projectile_enh" + // TODO for later, maybe : set_resource_parent pounder_projectile_enh game_objects pounder_projectile + pounder_projectile_enh.Damage0 = 31 + pounder_projectile_enh.Damage1 = 120 + pounder_projectile_enh.Damage2 = 120 + pounder_projectile_enh.Damage3 = 75 + pounder_projectile_enh.Damage4 = 132 + pounder_projectile_enh.DamageAtEdge = 0.1f + pounder_projectile_enh.DamageRadius = 1f + pounder_projectile_enh.ProjectileDamageType = DamageType.Splash + pounder_projectile_enh.InitialVelocity = 120 + pounder_projectile_enh.Lifespan = 3.2f + + ppa_projectile.Name = "ppa_projectile" + ppa_projectile.Damage0 = 20 + ppa_projectile.Damage1 = 20 + ppa_projectile.Damage2 = 40 + ppa_projectile.Damage3 = 20 + ppa_projectile.Damage4 = 13 + ppa_projectile.ProjectileDamageType = DamageType.Direct + ppa_projectile.InitialVelocity = 400 + ppa_projectile.Lifespan = .5f + + pulsar_ap_projectile.Name = "pulsar_ap_projectile" + // TODO for later, maybe : set_resource_parent pulsar_ap_projectile game_objects pulsar_projectile + pulsar_ap_projectile.Damage0 = 7 + pulsar_ap_projectile.Damage1 = 15 + pulsar_ap_projectile.ProjectileDamageType = DamageType.Direct + pulsar_ap_projectile.DegradeDelay = 0.1f + pulsar_ap_projectile.DegradeMultiplier = 0.5f + pulsar_ap_projectile.InitialVelocity = 500 + pulsar_ap_projectile.Lifespan = .4f + pulsar_ap_projectile.UseDamage1Subtract = true + + pulsar_projectile.Name = "pulsar_projectile" + pulsar_projectile.Damage0 = 20 + pulsar_projectile.Damage1 = 10 + pulsar_projectile.ProjectileDamageType = DamageType.Direct + pulsar_projectile.DegradeDelay = 0.1f + pulsar_projectile.DegradeMultiplier = 0.4f + pulsar_projectile.InitialVelocity = 500 + pulsar_projectile.Lifespan = .4f + pulsar_projectile.UseDamage1Subtract = true + + quasar_projectile.Name = "quasar_projectile" + quasar_projectile.Damage0 = 18 + quasar_projectile.Damage1 = 8 + quasar_projectile.ProjectileDamageType = DamageType.Direct + quasar_projectile.DegradeDelay = 0.045f + quasar_projectile.DegradeMultiplier = 0.5f + quasar_projectile.InitialVelocity = 500 + quasar_projectile.Lifespan = .4f + + radiator_grenade_projectile.Name = "radiator_grenade_projectile" // Todo : Radiator damages ? + radiator_grenade_projectile.ProjectileDamageType = DamageType.Direct + radiator_grenade_projectile.InitialVelocity = 30 + radiator_grenade_projectile.Lifespan = 3f + + radiator_sticky_projectile.Name = "radiator_sticky_projectile" + // TODO for later, maybe : set_resource_parent radiator_sticky_projectile game_objects radiator_grenade_projectile + radiator_sticky_projectile.ProjectileDamageType = DamageType.Direct + radiator_sticky_projectile.InitialVelocity = 30 + radiator_sticky_projectile.Lifespan = 4f + + reaver_rocket_projectile.Name = "reaver_rocket_projectile" + reaver_rocket_projectile.Damage0 = 25 + reaver_rocket_projectile.Damage1 = 88 + reaver_rocket_projectile.Damage2 = 75 + reaver_rocket_projectile.Damage3 = 75 + reaver_rocket_projectile.Damage4 = 88 + reaver_rocket_projectile.Acceleration = 50 + reaver_rocket_projectile.AccelerationUntil = 1f + reaver_rocket_projectile.DamageAtEdge = 0.1f + reaver_rocket_projectile.DamageRadius = 3f + reaver_rocket_projectile.ProjectileDamageType = DamageType.Splash + reaver_rocket_projectile.InitialVelocity = 100 + reaver_rocket_projectile.Lifespan = 2.1f + + rocket_projectile.Name = "rocket_projectile" + rocket_projectile.Damage0 = 50 + rocket_projectile.Damage1 = 105 + rocket_projectile.Damage2 = 75 + rocket_projectile.Damage3 = 75 + rocket_projectile.Damage4 = 75 + rocket_projectile.Acceleration = 10 + rocket_projectile.AccelerationUntil = 2f + rocket_projectile.DamageAtEdge = .5f + rocket_projectile.DamageRadius = 3f + rocket_projectile.ProjectileDamageType = DamageType.Splash + rocket_projectile.InitialVelocity = 50 + rocket_projectile.Lifespan = 8f + + rocklet_flak_projectile.Name = "rocklet_flak_projectile" + rocklet_flak_projectile.Damage0 = 20 + rocklet_flak_projectile.Damage1 = 30 + rocklet_flak_projectile.Damage2 = 57 + rocklet_flak_projectile.Damage3 = 30 + rocklet_flak_projectile.Damage4 = 50 + rocklet_flak_projectile.DamageAtEdge = 0.25f + rocklet_flak_projectile.DamageRadius = 8f + rocklet_flak_projectile.ProjectileDamageType = DamageType.Direct + rocklet_flak_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + rocklet_flak_projectile.InitialVelocity = 60 + rocklet_flak_projectile.Lifespan = 3.2f + + rocklet_jammer_projectile.Name = "rocklet_jammer_projectile" + rocklet_jammer_projectile.Damage0 = 0 + rocklet_jammer_projectile.Acceleration = 10 + rocklet_jammer_projectile.AccelerationUntil = 2f + rocklet_jammer_projectile.DamageAtEdge = 1.0f + rocklet_jammer_projectile.DamageRadius = 10f + rocklet_jammer_projectile.ProjectileDamageType = DamageType.Splash + rocklet_jammer_projectile.InitialVelocity = 50 + rocklet_jammer_projectile.Lifespan = 8f + + scattercannon_projectile.Name = "scattercannon_projectile" + scattercannon_projectile.Damage0 = 11 + scattercannon_projectile.Damage1 = 5 + scattercannon_projectile.ProjectileDamageType = DamageType.Direct + scattercannon_projectile.InitialVelocity = 400 + scattercannon_projectile.Lifespan = 0.25f + + scythe_projectile.Name = "scythe_projectile" + scythe_projectile.Damage0 = 30 + scythe_projectile.Damage1 = 20 + scythe_projectile.ProjectileDamageType = DamageType.Direct + scythe_projectile.DegradeDelay = .015f + scythe_projectile.DegradeMultiplier = 0.35f + scythe_projectile.InitialVelocity = 60 + scythe_projectile.Lifespan = 3f + + scythe_projectile_slave.Name = "scythe_projectile_slave" // Todo how does it work ? + scythe_projectile_slave.InitialVelocity = 30 + scythe_projectile_slave.Lifespan = 3f + + shotgun_shell_AP_projectile.Name = "shotgun_shell_AP_projectile" + // TODO for later, maybe : set_resource_parent shotgun_shell_AP_projectile game_objects shotgun_shell_projectile + shotgun_shell_AP_projectile.Damage0 = 5 + shotgun_shell_AP_projectile.Damage1 = 10 + shotgun_shell_AP_projectile.ProjectileDamageType = DamageType.Direct + shotgun_shell_AP_projectile.InitialVelocity = 400 + shotgun_shell_AP_projectile.Lifespan = 0.25f + shotgun_shell_AP_projectile.UseDamage1Subtract = true + + shotgun_shell_projectile.Name = "shotgun_shell_projectile" + shotgun_shell_projectile.Damage0 = 12 + shotgun_shell_projectile.Damage1 = 5 + shotgun_shell_projectile.ProjectileDamageType = DamageType.Direct + shotgun_shell_projectile.InitialVelocity = 400 + shotgun_shell_projectile.Lifespan = 0.25f + shotgun_shell_projectile.UseDamage1Subtract = true + + six_shooter_projectile.Name = "six_shooter_projectile" + // TODO for later, maybe : set_resource_parent six_shooter_projectile game_objects 9mmbullet_projectile + six_shooter_projectile.Damage0 = 22 + six_shooter_projectile.Damage1 = 20 + six_shooter_projectile.ProjectileDamageType = DamageType.Direct + six_shooter_projectile.DegradeDelay = 0.15f + six_shooter_projectile.DegradeMultiplier = 0.25f + six_shooter_projectile.InitialVelocity = 500 + six_shooter_projectile.Lifespan = 0.4f + six_shooter_projectile.UseDamage1Subtract = false + + skyguard_flak_cannon_projectile.Name = "skyguard_flak_cannon_projectile" + skyguard_flak_cannon_projectile.Damage0 = 15 + skyguard_flak_cannon_projectile.Damage1 = 25 + skyguard_flak_cannon_projectile.Damage2 = 50 + skyguard_flak_cannon_projectile.DamageAtEdge = 1f + skyguard_flak_cannon_projectile.DamageRadius = 10f + skyguard_flak_cannon_projectile.ProjectileDamageType = DamageType.Direct + skyguard_flak_cannon_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + skyguard_flak_cannon_projectile.InitialVelocity = 100 + skyguard_flak_cannon_projectile.Lifespan = 5f + + sparrow_projectile.Name = "sparrow_projectile" + sparrow_projectile.Damage0 = 35 + sparrow_projectile.Damage1 = 50 + sparrow_projectile.Damage2 = 125 + sparrow_projectile.Acceleration = 12 + sparrow_projectile.AccelerationUntil = 5f + sparrow_projectile.DamageAtEdge = 0.1f + sparrow_projectile.DamageRadius = 3f + sparrow_projectile.ProjectileDamageType = DamageType.Splash + sparrow_projectile.InitialVelocity = 60 + sparrow_projectile.Lifespan = 5.85f + + sparrow_secondary_projectile.Name = "sparrow_secondary_projectile" + // TODO for later, maybe : set_resource_parent sparrow_secondary_projectile game_objects sparrow_projectile + sparrow_secondary_projectile.Damage0 = 35 + sparrow_secondary_projectile.Damage1 = 50 + sparrow_secondary_projectile.Damage2 = 125 + sparrow_secondary_projectile.Acceleration = 12 + sparrow_secondary_projectile.AccelerationUntil = 5f + sparrow_secondary_projectile.DamageAtEdge = 0.1f + sparrow_secondary_projectile.DamageRadius = 3f + sparrow_secondary_projectile.ProjectileDamageType = DamageType.Splash + sparrow_secondary_projectile.InitialVelocity = 60 + sparrow_secondary_projectile.Lifespan = 5.85f + + spiker_projectile.Name = "spiker_projectile" + // spiker_projectile.Damage0 = 75 + spiker_projectile.Damage0 = 20 + // spiker_projectile.Damage0_min = 20 + // spiker_projectile.Damage1 = 75 + spiker_projectile.Damage1 = 20 + // spiker_projectile.Damage1_min = 20 + spiker_projectile.DamageAtEdge = 0.1f + spiker_projectile.DamageRadius = 5f + spiker_projectile.DamageRadius = 1f + spiker_projectile.ProjectileDamageType = DamageType.Splash + spiker_projectile.InitialVelocity = 40 + spiker_projectile.Lifespan = 5f + + spitfire_aa_ammo_projectile.Name = "spitfire_aa_ammo_projectile" + spitfire_aa_ammo_projectile.Damage0 = 5 + spitfire_aa_ammo_projectile.Damage1 = 15 + spitfire_aa_ammo_projectile.Damage2 = 12 + spitfire_aa_ammo_projectile.Damage3 = 5 + spitfire_aa_ammo_projectile.Damage4 = 15 + spitfire_aa_ammo_projectile.DamageAtEdge = 1f + spitfire_aa_ammo_projectile.DamageRadius = 10f + spitfire_aa_ammo_projectile.ProjectileDamageType = DamageType.Direct + spitfire_aa_ammo_projectile.ProjectileDamageTypeSecondary = DamageType.Splash + spitfire_aa_ammo_projectile.InitialVelocity = 100 + spitfire_aa_ammo_projectile.Lifespan = 5f + + spitfire_ammo_projectile.Name = "spitfire_ammo_projectile" + spitfire_ammo_projectile.Damage0 = 15 + spitfire_ammo_projectile.Damage1 = 10 + spitfire_ammo_projectile.ProjectileDamageType = DamageType.Direct + spitfire_ammo_projectile.DegradeDelay = .01f + spitfire_ammo_projectile.DegradeMultiplier = 0.5f + spitfire_ammo_projectile.InitialVelocity = 100 + spitfire_ammo_projectile.Lifespan = .5f + + starfire_projectile.Name = "starfire_projectile" + starfire_projectile.Damage0 = 16 + starfire_projectile.Damage1 = 20 + starfire_projectile.Damage2 = 58 + starfire_projectile.Acceleration = 12 + starfire_projectile.AccelerationUntil = 5f + starfire_projectile.ProjectileDamageType = DamageType.Aggravated + starfire_projectile.InitialVelocity = 45 + starfire_projectile.Lifespan = 7.8f + + striker_missile_projectile.Name = "striker_missile_projectile" + striker_missile_projectile.Damage0 = 35 + striker_missile_projectile.Damage1 = 175 + striker_missile_projectile.Damage2 = 125 + striker_missile_projectile.Damage3 = 125 + striker_missile_projectile.Damage4 = 263 + striker_missile_projectile.Acceleration = 20 + striker_missile_projectile.AccelerationUntil = 2f + striker_missile_projectile.DamageAtEdge = 0.1f + striker_missile_projectile.DamageRadius = 1.5f + striker_missile_projectile.ProjectileDamageType = DamageType.Splash + striker_missile_projectile.InitialVelocity = 30 + striker_missile_projectile.Lifespan = 4.2f + + striker_missile_targeting_projectile.Name = "striker_missile_targeting_projectile" + // TODO for later, maybe : set_resource_parent striker_missile_targeting_projectile game_objects striker_missile_projectile + striker_missile_targeting_projectile.Damage0 = 35 + striker_missile_targeting_projectile.Damage1 = 175 + striker_missile_targeting_projectile.Damage2 = 125 + striker_missile_targeting_projectile.Damage3 = 125 + striker_missile_targeting_projectile.Damage4 = 263 + striker_missile_targeting_projectile.Acceleration = 20 + striker_missile_targeting_projectile.AccelerationUntil = 2f + striker_missile_targeting_projectile.DamageAtEdge = 0.1f + striker_missile_targeting_projectile.DamageRadius = 1.5f + striker_missile_targeting_projectile.ProjectileDamageType = DamageType.Splash + striker_missile_targeting_projectile.InitialVelocity = 30 + striker_missile_targeting_projectile.Lifespan = 4.2f + + trek_projectile.Name = "trek_projectile" + trek_projectile.Damage0 = 0 + trek_projectile.Damage1 = 0 + trek_projectile.Damage2 = 0 + trek_projectile.Damage3 = 0 + trek_projectile.Damage4 = 0 + trek_projectile.Acceleration = -20 + trek_projectile.AccelerationUntil = 1f + trek_projectile.ProjectileDamageType = DamageType.Direct + trek_projectile.InitialVelocity = 40 + trek_projectile.Lifespan = 7f + + vanu_sentry_turret_projectile.Name = "vanu_sentry_turret_projectile" + vanu_sentry_turret_projectile.Damage0 = 25 + vanu_sentry_turret_projectile.Damage1 = 35 + vanu_sentry_turret_projectile.Damage2 = 100 + vanu_sentry_turret_projectile.DamageAtEdge = 0.1f + vanu_sentry_turret_projectile.DamageRadius = 3f + vanu_sentry_turret_projectile.ProjectileDamageType = DamageType.Splash + vanu_sentry_turret_projectile.InitialVelocity = 240 + vanu_sentry_turret_projectile.Lifespan = 1.3f + + vulture_bomb_projectile.Name = "vulture_bomb_projectile" + vulture_bomb_projectile.Damage0 = 175 + vulture_bomb_projectile.Damage1 = 1750 + vulture_bomb_projectile.Damage2 = 1000 + vulture_bomb_projectile.Damage3 = 400 + vulture_bomb_projectile.Damage4 = 1500 + vulture_bomb_projectile.DamageAtEdge = 0.1f + vulture_bomb_projectile.DamageRadius = 10f + vulture_bomb_projectile.ProjectileDamageType = DamageType.Splash + vulture_bomb_projectile.InitialVelocity = 0 + vulture_bomb_projectile.Lifespan = 30f + + vulture_nose_bullet_projectile.Name = "vulture_nose_bullet_projectile" + vulture_nose_bullet_projectile.Damage0 = 12 + vulture_nose_bullet_projectile.Damage1 = 15 + vulture_nose_bullet_projectile.Damage2 = 10 + vulture_nose_bullet_projectile.Damage3 = 10 + vulture_nose_bullet_projectile.Damage4 = 15 + vulture_nose_bullet_projectile.ProjectileDamageType = DamageType.Direct + vulture_nose_bullet_projectile.DegradeDelay = .4f + vulture_nose_bullet_projectile.DegradeMultiplier = 0.7f + vulture_nose_bullet_projectile.InitialVelocity = 500 + vulture_nose_bullet_projectile.Lifespan = 0.46f + + vulture_tail_bullet_projectile.Name = "vulture_tail_bullet_projectile" + vulture_tail_bullet_projectile.Damage0 = 25 + vulture_tail_bullet_projectile.Damage1 = 35 + vulture_tail_bullet_projectile.Damage2 = 50 + vulture_tail_bullet_projectile.ProjectileDamageType = DamageType.Direct + vulture_tail_bullet_projectile.DegradeDelay = .02f + vulture_tail_bullet_projectile.DegradeMultiplier = 0.5f + vulture_tail_bullet_projectile.InitialVelocity = 500 + vulture_tail_bullet_projectile.Lifespan = 0.6f + + wasp_gun_projectile.Name = "wasp_gun_projectile" + wasp_gun_projectile.Damage0 = 10 + wasp_gun_projectile.Damage1 = 15 + wasp_gun_projectile.Damage2 = 25 + wasp_gun_projectile.Damage3 = 17 + wasp_gun_projectile.Damage4 = 7 + wasp_gun_projectile.ProjectileDamageType = DamageType.Direct + wasp_gun_projectile.DegradeDelay = .015f + wasp_gun_projectile.DegradeMultiplier = 0.5f + wasp_gun_projectile.InitialVelocity = 500 + wasp_gun_projectile.Lifespan = 0.5f + + wasp_rocket_projectile.Name = "wasp_rocket_projectile" + wasp_rocket_projectile.Damage0 = 35 + wasp_rocket_projectile.Damage1 = 50 + wasp_rocket_projectile.Damage2 = 300 + wasp_rocket_projectile.Acceleration = 10 + wasp_rocket_projectile.AccelerationUntil = 5f + wasp_rocket_projectile.DamageAtEdge = 0.1f + wasp_rocket_projectile.DamageRadius = 3f + wasp_rocket_projectile.ProjectileDamageType = DamageType.Splash + wasp_rocket_projectile.InitialVelocity = 60 + wasp_rocket_projectile.Lifespan = 6.5f + + winchester_projectile.Name = "winchester_projectile" + // TODO for later, maybe : set_resource_parent winchester_projectile game_objects bolt_projectile + winchester_projectile.Damage0 = 80 + winchester_projectile.Damage1 = 40 + winchester_projectile.Damage2 = 50 + winchester_projectile.Damage3 = 50 + winchester_projectile.Damage4 = 75 + winchester_projectile.ProjectileDamageType = DamageType.Direct + winchester_projectile.InitialVelocity = 500 + winchester_projectile.Lifespan = 0.6f + } + /** * Initialize `ToolDefinition` globals. */ @@ -1236,54 +3016,67 @@ object GlobalDefinitions { chainblade.Name = "chainblade" chainblade.Size = EquipmentSize.Melee chainblade.AmmoTypes += melee_ammo + chainblade.ProjectileTypes += melee_ammo_projectile + chainblade.ProjectileTypes += chainblade_projectile chainblade.FireModes += new InfiniteFireModeDefinition chainblade.FireModes.head.AmmoTypeIndices += 0 chainblade.FireModes.head.AmmoSlotIndex = 0 chainblade.FireModes.head.Magazine = 1 chainblade.FireModes += new InfiniteFireModeDefinition chainblade.FireModes(1).AmmoTypeIndices += 0 + chainblade.FireModes(1).ProjectileTypeIndices += 1 chainblade.FireModes(1).AmmoSlotIndex = 0 chainblade.FireModes(1).Magazine = 1 magcutter.Name = "magcutter" magcutter.Size = EquipmentSize.Melee magcutter.AmmoTypes += melee_ammo + magcutter.ProjectileTypes += melee_ammo_projectile + magcutter.ProjectileTypes += magcutter_projectile magcutter.FireModes += new InfiniteFireModeDefinition magcutter.FireModes.head.AmmoTypeIndices += 0 magcutter.FireModes.head.AmmoSlotIndex = 0 magcutter.FireModes.head.Magazine = 1 magcutter.FireModes += new InfiniteFireModeDefinition magcutter.FireModes(1).AmmoTypeIndices += 0 + magcutter.FireModes(1).ProjectileTypeIndices += 1 magcutter.FireModes(1).AmmoSlotIndex = 0 magcutter.FireModes(1).Magazine = 1 forceblade.Name = "forceblade" forceblade.Size = EquipmentSize.Melee forceblade.AmmoTypes += melee_ammo + forceblade.ProjectileTypes += melee_ammo_projectile + forceblade.ProjectileTypes += forceblade_projectile forceblade.FireModes += new InfiniteFireModeDefinition forceblade.FireModes.head.AmmoTypeIndices += 0 forceblade.FireModes.head.AmmoSlotIndex = 0 forceblade.FireModes.head.Magazine = 1 forceblade.FireModes += new InfiniteFireModeDefinition forceblade.FireModes(1).AmmoTypeIndices += 0 + forceblade.FireModes(1).ProjectileTypeIndices += 1 forceblade.FireModes(1).AmmoSlotIndex = 0 forceblade.FireModes(1).Magazine = 1 katana.Name = "katana" katana.Size = EquipmentSize.Melee katana.AmmoTypes += melee_ammo + katana.ProjectileTypes += katana_projectile + katana.ProjectileTypes += katana_projectileb katana.FireModes += new InfiniteFireModeDefinition katana.FireModes.head.AmmoTypeIndices += 0 katana.FireModes.head.AmmoSlotIndex = 0 katana.FireModes.head.Magazine = 1 katana.FireModes += new InfiniteFireModeDefinition katana.FireModes(1).AmmoTypeIndices += 0 + katana.FireModes(1).ProjectileTypeIndices += 1 katana.FireModes(1).AmmoSlotIndex = 0 katana.FireModes(1).Magazine = 1 frag_grenade.Name = "frag_grenade" frag_grenade.Size = EquipmentSize.Pistol frag_grenade.AmmoTypes += frag_grenade_ammo + frag_grenade.ProjectileTypes += frag_grenade_projectile frag_grenade.FireModes += new FireModeDefinition frag_grenade.FireModes.head.AmmoTypeIndices += 0 frag_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -1297,6 +3090,7 @@ object GlobalDefinitions { plasma_grenade.Name = "plasma_grenade" plasma_grenade.Size = EquipmentSize.Pistol plasma_grenade.AmmoTypes += plasma_grenade_ammo + plasma_grenade.ProjectileTypes += plasma_grenade_projectile plasma_grenade.FireModes += new FireModeDefinition plasma_grenade.FireModes.head.AmmoTypeIndices += 0 plasma_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -1310,6 +3104,7 @@ object GlobalDefinitions { jammer_grenade.Name = "jammer_grenade" jammer_grenade.Size = EquipmentSize.Pistol jammer_grenade.AmmoTypes += jammer_grenade_ammo + jammer_grenade.ProjectileTypes += jammer_grenade_projectile jammer_grenade.FireModes += new FireModeDefinition jammer_grenade.FireModes.head.AmmoTypeIndices += 0 jammer_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -1324,58 +3119,91 @@ object GlobalDefinitions { repeater.Size = EquipmentSize.Pistol repeater.AmmoTypes += bullet_9mm repeater.AmmoTypes += bullet_9mm_AP + repeater.ProjectileTypes += bullet_9mm_projectile + repeater.ProjectileTypes += bullet_9mm_AP_projectile repeater.FireModes += new FireModeDefinition repeater.FireModes.head.AmmoTypeIndices += 0 repeater.FireModes.head.AmmoTypeIndices += 1 repeater.FireModes.head.AmmoSlotIndex = 0 repeater.FireModes.head.Magazine = 20 + repeater.FireModes.head.Modifiers.Damage0 = 2 + repeater.FireModes.head.Modifiers.Damage1 = -3 + repeater.FireModes.head.Modifiers.Damage2 = -3 + repeater.FireModes.head.Modifiers.Damage3 = -3 + repeater.FireModes.head.Modifiers.Damage4 = -3 repeater.Tile = InventoryTile.Tile33 isp.Name = "isp" isp.Size = EquipmentSize.Pistol isp.AmmoTypes += shotgun_shell isp.AmmoTypes += shotgun_shell_AP + isp.ProjectileTypes += shotgun_shell_projectile + isp.ProjectileTypes += shotgun_shell_AP_projectile isp.FireModes += new PelletFireModeDefinition isp.FireModes.head.AmmoTypeIndices += 0 isp.FireModes.head.AmmoTypeIndices += 1 isp.FireModes.head.AmmoSlotIndex = 0 isp.FireModes.head.Magazine = 8 isp.FireModes.head.Chamber = 6 //8 shells x 6 pellets = 48 + isp.FireModes.head.Modifiers.Damage0 = 1 + isp.FireModes.head.Modifiers.Damage2 = 1 + isp.FireModes.head.Modifiers.Damage3 = 1 isp.Tile = InventoryTile.Tile33 beamer.Name = "beamer" beamer.Size = EquipmentSize.Pistol beamer.AmmoTypes += energy_cell + beamer.ProjectileTypes += energy_cell_projectile + beamer.ProjectileTypes += enhanced_energy_cell_projectile beamer.FireModes += new FireModeDefinition beamer.FireModes.head.AmmoTypeIndices += 0 beamer.FireModes.head.AmmoSlotIndex = 0 beamer.FireModes.head.Magazine = 16 + beamer.FireModes.head.Modifiers.Damage0 = 4 + beamer.FireModes.head.Modifiers.Damage1 = -1 + beamer.FireModes.head.Modifiers.Damage2 = -1 + beamer.FireModes.head.Modifiers.Damage3 = -1 + beamer.FireModes.head.Modifiers.Damage4 = -1 beamer.FireModes += new FireModeDefinition beamer.FireModes(1).AmmoTypeIndices += 0 + beamer.FireModes(1).ProjectileTypeIndices += 1 beamer.FireModes(1).AmmoSlotIndex = 0 beamer.FireModes(1).Magazine = 16 + beamer.FireModes(1).Modifiers.Damage0 = -3 + beamer.FireModes(1).Modifiers.Damage1 = -3 + beamer.FireModes(1).Modifiers.Damage2 = -3 + beamer.FireModes(1).Modifiers.Damage3 = -3 + beamer.FireModes(1).Modifiers.Damage4 = -3 beamer.Tile = InventoryTile.Tile33 ilc9.Name = "ilc9" ilc9.Size = EquipmentSize.Pistol ilc9.AmmoTypes += bullet_9mm ilc9.AmmoTypes += bullet_9mm_AP + ilc9.ProjectileTypes += bullet_9mm_projectile + ilc9.ProjectileTypes += bullet_9mm_AP_projectile ilc9.FireModes += new FireModeDefinition ilc9.FireModes.head.AmmoTypeIndices += 0 ilc9.FireModes.head.AmmoTypeIndices += 1 ilc9.FireModes.head.AmmoSlotIndex = 0 ilc9.FireModes.head.Magazine = 30 + ilc9.FireModes.head.Modifiers.Damage1 = -3 + ilc9.FireModes.head.Modifiers.Damage4 = -3 ilc9.Tile = InventoryTile.Tile33 suppressor.Name = "suppressor" suppressor.Size = EquipmentSize.Rifle suppressor.AmmoTypes += bullet_9mm suppressor.AmmoTypes += bullet_9mm_AP + suppressor.ProjectileTypes += bullet_9mm_projectile + suppressor.ProjectileTypes += bullet_9mm_AP_projectile suppressor.FireModes += new FireModeDefinition suppressor.FireModes.head.AmmoTypeIndices += 0 suppressor.FireModes.head.AmmoTypeIndices += 1 suppressor.FireModes.head.AmmoSlotIndex = 0 suppressor.FireModes.head.Magazine = 25 + suppressor.FireModes.head.Modifiers.Damage0 = -1 + suppressor.FireModes.head.Modifiers.Damage1 = -1 suppressor.Tile = InventoryTile.Tile63 punisher.Name = "punisher" @@ -1386,11 +3214,19 @@ object GlobalDefinitions { punisher.AmmoTypes += frag_cartridge punisher.AmmoTypes += jammer_cartridge punisher.AmmoTypes += plasma_cartridge + punisher.ProjectileTypes += bullet_9mm_projectile + punisher.ProjectileTypes += bullet_9mm_AP_projectile + punisher.ProjectileTypes += rocket_projectile + punisher.ProjectileTypes += frag_cartridge_projectile + punisher.ProjectileTypes += jammer_cartridge_projectile + punisher.ProjectileTypes += plasma_cartridge_projectile punisher.FireModes += new FireModeDefinition punisher.FireModes.head.AmmoTypeIndices += 0 punisher.FireModes.head.AmmoTypeIndices += 1 punisher.FireModes.head.AmmoSlotIndex = 0 punisher.FireModes.head.Magazine = 30 + punisher.FireModes.head.Modifiers.Damage0 = 1 + punisher.FireModes.head.Modifiers.Damage3 = 1 punisher.FireModes += new FireModeDefinition punisher.FireModes(1).AmmoTypeIndices += 2 punisher.FireModes(1).AmmoTypeIndices += 3 @@ -1404,6 +3240,8 @@ object GlobalDefinitions { flechette.Size = EquipmentSize.Rifle flechette.AmmoTypes += shotgun_shell flechette.AmmoTypes += shotgun_shell_AP + flechette.ProjectileTypes += shotgun_shell_projectile + flechette.ProjectileTypes += shotgun_shell_AP_projectile flechette.FireModes += new PelletFireModeDefinition flechette.FireModes.head.AmmoTypeIndices += 0 flechette.FireModes.head.AmmoTypeIndices += 1 @@ -1416,6 +3254,8 @@ object GlobalDefinitions { cycler.Size = EquipmentSize.Rifle cycler.AmmoTypes += bullet_9mm cycler.AmmoTypes += bullet_9mm_AP + cycler.ProjectileTypes += bullet_9mm_projectile + cycler.ProjectileTypes += bullet_9mm_AP_projectile cycler.FireModes += new FireModeDefinition cycler.FireModes.head.AmmoTypeIndices += 0 cycler.FireModes.head.AmmoTypeIndices += 1 @@ -1427,22 +3267,29 @@ object GlobalDefinitions { gauss.Size = EquipmentSize.Rifle gauss.AmmoTypes += bullet_9mm gauss.AmmoTypes += bullet_9mm_AP + gauss.ProjectileTypes += bullet_9mm_projectile + gauss.ProjectileTypes += bullet_9mm_AP_projectile gauss.FireModes += new FireModeDefinition gauss.FireModes.head.AmmoTypeIndices += 0 gauss.FireModes.head.AmmoTypeIndices += 1 gauss.FireModes.head.AmmoSlotIndex = 0 gauss.FireModes.head.Magazine = 30 + gauss.FireModes.head.Modifiers.Damage0 = 2 + gauss.FireModes.head.Modifiers.Damage3 = 2 gauss.Tile = InventoryTile.Tile63 pulsar.Name = "pulsar" pulsar.Size = EquipmentSize.Rifle pulsar.AmmoTypes += energy_cell + pulsar.ProjectileTypes += pulsar_projectile + pulsar.ProjectileTypes += pulsar_ap_projectile pulsar.FireModes += new FireModeDefinition pulsar.FireModes.head.AmmoTypeIndices += 0 pulsar.FireModes.head.AmmoSlotIndex = 0 pulsar.FireModes.head.Magazine = 40 pulsar.FireModes += new FireModeDefinition pulsar.FireModes(1).AmmoTypeIndices += 0 + pulsar.FireModes(1).ProjectileTypeIndices += 1 pulsar.FireModes(1).AmmoSlotIndex = 0 pulsar.FireModes(1).Magazine = 40 pulsar.Tile = InventoryTile.Tile63 @@ -1450,12 +3297,15 @@ object GlobalDefinitions { anniversary_guna.Name = "anniversary_guna" anniversary_guna.Size = EquipmentSize.Pistol anniversary_guna.AmmoTypes += anniversary_ammo + anniversary_guna.ProjectileTypes += anniversary_projectilea + anniversary_guna.ProjectileTypes += anniversary_projectileb anniversary_guna.FireModes += new FireModeDefinition anniversary_guna.FireModes.head.AmmoTypeIndices += 0 anniversary_guna.FireModes.head.AmmoSlotIndex = 0 anniversary_guna.FireModes.head.Magazine = 6 anniversary_guna.FireModes += new FireModeDefinition anniversary_guna.FireModes(1).AmmoTypeIndices += 0 + anniversary_guna.FireModes(1).ProjectileTypeIndices += 1 anniversary_guna.FireModes(1).AmmoSlotIndex = 0 anniversary_guna.FireModes(1).Magazine = 6 anniversary_guna.Tile = InventoryTile.Tile33 @@ -1463,12 +3313,15 @@ object GlobalDefinitions { anniversary_gun.Name = "anniversary_gun" anniversary_gun.Size = EquipmentSize.Pistol anniversary_gun.AmmoTypes += anniversary_ammo + anniversary_gun.ProjectileTypes += anniversary_projectilea + anniversary_gun.ProjectileTypes += anniversary_projectileb anniversary_gun.FireModes += new FireModeDefinition anniversary_gun.FireModes.head.AmmoTypeIndices += 0 anniversary_gun.FireModes.head.AmmoSlotIndex = 0 anniversary_gun.FireModes.head.Magazine = 6 anniversary_gun.FireModes += new FireModeDefinition anniversary_gun.FireModes(1).AmmoTypeIndices += 0 + anniversary_gun.FireModes(1).ProjectileTypeIndices += 1 anniversary_gun.FireModes(1).AmmoSlotIndex = 0 anniversary_gun.FireModes(1).Magazine = 6 anniversary_gun.Tile = InventoryTile.Tile33 @@ -1476,12 +3329,15 @@ object GlobalDefinitions { anniversary_gunb.Name = "anniversary_gunb" anniversary_gunb.Size = EquipmentSize.Pistol anniversary_gunb.AmmoTypes += anniversary_ammo + anniversary_gunb.ProjectileTypes += anniversary_projectilea + anniversary_gunb.ProjectileTypes += anniversary_projectileb anniversary_gunb.FireModes += new FireModeDefinition anniversary_gunb.FireModes.head.AmmoTypeIndices += 0 anniversary_gunb.FireModes.head.AmmoSlotIndex = 0 anniversary_gunb.FireModes.head.Magazine = 6 anniversary_gunb.FireModes += new FireModeDefinition anniversary_gunb.FireModes(1).AmmoTypeIndices += 0 + anniversary_gunb.FireModes(1).ProjectileTypeIndices += 1 anniversary_gunb.FireModes(1).AmmoSlotIndex = 0 anniversary_gunb.FireModes(1).Magazine = 6 anniversary_gunb.Tile = InventoryTile.Tile33 @@ -1489,6 +3345,7 @@ object GlobalDefinitions { spiker.Name = "spiker" spiker.Size = EquipmentSize.Pistol spiker.AmmoTypes += ancient_ammo_combo + spiker.ProjectileTypes += spiker_projectile spiker.FireModes += new FireModeDefinition spiker.FireModes.head.AmmoTypeIndices += 0 spiker.FireModes.head.AmmoSlotIndex = 0 @@ -1500,6 +3357,8 @@ object GlobalDefinitions { mini_chaingun.Size = EquipmentSize.Rifle mini_chaingun.AmmoTypes += bullet_9mm mini_chaingun.AmmoTypes += bullet_9mm_AP + mini_chaingun.ProjectileTypes += bullet_9mm_projectile + mini_chaingun.ProjectileTypes += bullet_9mm_AP_projectile mini_chaingun.FireModes += new FireModeDefinition mini_chaingun.FireModes.head.AmmoTypeIndices += 0 mini_chaingun.FireModes.head.AmmoTypeIndices += 1 @@ -1511,29 +3370,36 @@ object GlobalDefinitions { r_shotgun.Size = EquipmentSize.Rifle r_shotgun.AmmoTypes += shotgun_shell r_shotgun.AmmoTypes += shotgun_shell_AP + r_shotgun.ProjectileTypes += shotgun_shell_projectile + r_shotgun.ProjectileTypes += shotgun_shell_AP_projectile r_shotgun.FireModes += new PelletFireModeDefinition r_shotgun.FireModes.head.AmmoTypeIndices += 0 r_shotgun.FireModes.head.AmmoTypeIndices += 1 r_shotgun.FireModes.head.AmmoSlotIndex = 0 r_shotgun.FireModes.head.Magazine = 16 r_shotgun.FireModes.head.Chamber = 8 //16 shells * 8 pellets = 128 + r_shotgun.FireModes.head.Modifiers.Damage0 = 1 r_shotgun.FireModes += new PelletFireModeDefinition r_shotgun.FireModes(1).AmmoTypeIndices += 0 r_shotgun.FireModes(1).AmmoTypeIndices += 1 r_shotgun.FireModes(1).AmmoSlotIndex = 0 r_shotgun.FireModes(1).Magazine = 16 r_shotgun.FireModes(1).Chamber = 8 //16 shells * 8 pellets = 128 + r_shotgun.FireModes(1).Modifiers.Damage0 = -3 r_shotgun.Tile = InventoryTile.Tile93 lasher.Name = "lasher" lasher.Size = EquipmentSize.Rifle lasher.AmmoTypes += energy_cell + lasher.ProjectileTypes += lasher_projectile + lasher.ProjectileTypes += lasher_projectile_ap lasher.FireModes += new FireModeDefinition lasher.FireModes.head.AmmoTypeIndices += 0 lasher.FireModes.head.AmmoSlotIndex = 0 lasher.FireModes.head.Magazine = 35 lasher.FireModes += new FireModeDefinition lasher.FireModes(1).AmmoTypeIndices += 0 + lasher.FireModes(1).ProjectileTypeIndices += 1 lasher.FireModes(1).AmmoSlotIndex = 0 lasher.FireModes(1).Magazine = 35 lasher.Tile = InventoryTile.Tile93 @@ -1541,16 +3407,21 @@ object GlobalDefinitions { maelstrom.Name = "maelstrom" maelstrom.Size = EquipmentSize.Rifle maelstrom.AmmoTypes += maelstrom_ammo + maelstrom.ProjectileTypes += maelstrom_stream_projectile + maelstrom.ProjectileTypes += maelstrom_grenade_projectile_contact + maelstrom.ProjectileTypes += maelstrom_grenade_projectile maelstrom.FireModes += new FireModeDefinition maelstrom.FireModes.head.AmmoTypeIndices += 0 maelstrom.FireModes.head.AmmoSlotIndex = 0 maelstrom.FireModes.head.Magazine = 150 maelstrom.FireModes += new FireModeDefinition maelstrom.FireModes(1).AmmoTypeIndices += 0 + maelstrom.FireModes(1).ProjectileTypeIndices += 1 maelstrom.FireModes(1).AmmoSlotIndex = 0 maelstrom.FireModes(1).Magazine = 150 maelstrom.FireModes += new FireModeDefinition maelstrom.FireModes(2).AmmoTypeIndices += 0 + maelstrom.FireModes(2).ProjectileTypeIndices += 2 maelstrom.FireModes(2).AmmoSlotIndex = 0 maelstrom.FireModes(2).Magazine = 150 maelstrom.Tile = InventoryTile.Tile93 @@ -1559,12 +3430,15 @@ object GlobalDefinitions { phoenix.Name = "phoenix" phoenix.Size = EquipmentSize.Rifle phoenix.AmmoTypes += phoenix_missile + phoenix.ProjectileTypes += phoenix_missile_projectile + phoenix.ProjectileTypes += phoenix_missile_guided_projectile phoenix.FireModes += new FireModeDefinition phoenix.FireModes.head.AmmoTypeIndices += 0 phoenix.FireModes.head.AmmoSlotIndex = 0 phoenix.FireModes.head.Magazine = 3 phoenix.FireModes += new FireModeDefinition phoenix.FireModes(1).AmmoTypeIndices += 0 + phoenix.FireModes(1).ProjectileTypeIndices += 1 phoenix.FireModes(1).AmmoSlotIndex = 0 phoenix.FireModes(1).Magazine = 3 phoenix.Tile = InventoryTile.Tile93 @@ -1572,12 +3446,15 @@ object GlobalDefinitions { striker.Name = "striker" striker.Size = EquipmentSize.Rifle striker.AmmoTypes += striker_missile_ammo + striker.ProjectileTypes += striker_missile_targeting_projectile + striker.ProjectileTypes += striker_missile_projectile striker.FireModes += new FireModeDefinition striker.FireModes.head.AmmoTypeIndices += 0 striker.FireModes.head.AmmoSlotIndex = 0 striker.FireModes.head.Magazine = 5 striker.FireModes += new FireModeDefinition striker.FireModes(1).AmmoTypeIndices += 0 + striker.FireModes(1).ProjectileTypeIndices += 1 striker.FireModes(1).AmmoSlotIndex = 0 striker.FireModes(1).Magazine = 5 striker.Tile = InventoryTile.Tile93 @@ -1585,12 +3462,15 @@ object GlobalDefinitions { hunterseeker.Name = "hunterseeker" hunterseeker.Size = EquipmentSize.Rifle hunterseeker.AmmoTypes += hunter_seeker_missile + hunterseeker.ProjectileTypes += hunter_seeker_missile_projectile + hunterseeker.ProjectileTypes += hunter_seeker_missile_dumbfire hunterseeker.FireModes += new FireModeDefinition hunterseeker.FireModes.head.AmmoTypeIndices += 0 hunterseeker.FireModes.head.AmmoSlotIndex = 0 hunterseeker.FireModes.head.Magazine = 1 hunterseeker.FireModes += new FireModeDefinition hunterseeker.FireModes(1).AmmoTypeIndices += 0 + hunterseeker.FireModes(1).ProjectileTypeIndices += 1 hunterseeker.FireModes(1).AmmoSlotIndex = 0 hunterseeker.FireModes(1).Magazine = 1 hunterseeker.Tile = InventoryTile.Tile93 @@ -1598,6 +3478,7 @@ object GlobalDefinitions { lancer.Name = "lancer" lancer.Size = EquipmentSize.Rifle lancer.AmmoTypes += lancer_cartridge + lancer.ProjectileTypes += lancer_projectile lancer.FireModes += new FireModeDefinition lancer.FireModes.head.AmmoTypeIndices += 0 lancer.FireModes.head.AmmoSlotIndex = 0 @@ -1608,6 +3489,8 @@ object GlobalDefinitions { rocklet.Size = EquipmentSize.Rifle rocklet.AmmoTypes += rocket rocklet.AmmoTypes += frag_cartridge + rocklet.ProjectileTypes += rocket_projectile + rocklet.ProjectileTypes += rocklet_flak_projectile rocklet.FireModes += new FireModeDefinition rocklet.FireModes.head.AmmoTypeIndices += 0 rocklet.FireModes.head.AmmoTypeIndices += 1 @@ -1625,6 +3508,9 @@ object GlobalDefinitions { thumper.AmmoTypes += frag_cartridge thumper.AmmoTypes += plasma_cartridge thumper.AmmoTypes += jammer_cartridge + thumper.ProjectileTypes += frag_cartridge_projectile_b + thumper.ProjectileTypes += plasma_cartridge_projectile_b + thumper.ProjectileTypes += jammer_cartridge_projectile_b thumper.FireModes += new FireModeDefinition thumper.FireModes.head.AmmoTypeIndices += 0 thumper.FireModes.head.AmmoTypeIndices += 1 @@ -1642,12 +3528,15 @@ object GlobalDefinitions { radiator.Name = "radiator" radiator.Size = EquipmentSize.Rifle radiator.AmmoTypes += ancient_ammo_combo + radiator.ProjectileTypes += radiator_grenade_projectile + radiator.ProjectileTypes += radiator_sticky_projectile radiator.FireModes += new FireModeDefinition radiator.FireModes.head.AmmoTypeIndices += 0 radiator.FireModes.head.AmmoSlotIndex = 0 radiator.FireModes.head.Magazine = 25 radiator.FireModes += new FireModeDefinition radiator.FireModes(1).AmmoTypeIndices += 0 + radiator.FireModes(1).ProjectileTypeIndices += 1 radiator.FireModes(1).AmmoSlotIndex = 0 radiator.FireModes(1).Magazine = 25 radiator.Tile = InventoryTile.Tile63 @@ -1655,6 +3544,7 @@ object GlobalDefinitions { heavy_sniper.Name = "heavy_sniper" heavy_sniper.Size = EquipmentSize.Rifle heavy_sniper.AmmoTypes += bolt + heavy_sniper.ProjectileTypes += heavy_sniper_projectile heavy_sniper.FireModes += new FireModeDefinition heavy_sniper.FireModes.head.AmmoTypeIndices += 0 heavy_sniper.FireModes.head.AmmoSlotIndex = 0 @@ -1664,6 +3554,7 @@ object GlobalDefinitions { bolt_driver.Name = "bolt_driver" bolt_driver.Size = EquipmentSize.Rifle bolt_driver.AmmoTypes += bolt + bolt_driver.ProjectileTypes += bolt_projectile bolt_driver.FireModes += new FireModeDefinition bolt_driver.FireModes.head.AmmoTypeIndices += 0 bolt_driver.FireModes.head.AmmoSlotIndex = 0 @@ -1673,6 +3564,7 @@ object GlobalDefinitions { oicw.Name = "oicw" oicw.Size = EquipmentSize.Rifle oicw.AmmoTypes += oicw_ammo + oicw.ProjectileTypes += oicw_projectile oicw.FireModes += new FireModeDefinition oicw.FireModes.head.AmmoTypeIndices += 0 oicw.FireModes.head.AmmoSlotIndex = 0 @@ -1686,12 +3578,15 @@ object GlobalDefinitions { flamethrower.Name = "flamethrower" flamethrower.Size = EquipmentSize.Rifle flamethrower.AmmoTypes += flamethrower_ammo + flamethrower.ProjectileTypes += flamethrower_projectile + flamethrower.ProjectileTypes += flamethrower_fireball flamethrower.FireModes += new FireModeDefinition flamethrower.FireModes.head.AmmoTypeIndices += 0 flamethrower.FireModes.head.AmmoSlotIndex = 0 flamethrower.FireModes.head.Magazine = 100 flamethrower.FireModes += new FireModeDefinition flamethrower.FireModes(1).AmmoTypeIndices += 0 + flamethrower.FireModes(1).ProjectileTypeIndices += 1 flamethrower.FireModes(1).AmmoSlotIndex = 0 flamethrower.FireModes(1).Magazine = 100 flamethrower.FireModes(1).Rounds = 50 @@ -1700,6 +3595,7 @@ object GlobalDefinitions { trhev_dualcycler.Name = "trhev_dualcycler" trhev_dualcycler.Size = EquipmentSize.Max trhev_dualcycler.AmmoTypes += dualcycler_ammo + trhev_dualcycler.ProjectileTypes += dualcycler_projectile trhev_dualcycler.FireModes += new FireModeDefinition trhev_dualcycler.FireModes.head.AmmoTypeIndices += 0 trhev_dualcycler.FireModes.head.AmmoSlotIndex = 0 @@ -1716,6 +3612,8 @@ object GlobalDefinitions { trhev_pounder.Name = "trhev_pounder" trhev_pounder.Size = EquipmentSize.Max trhev_pounder.AmmoTypes += pounder_ammo + trhev_pounder.ProjectileTypes += pounder_projectile + trhev_pounder.ProjectileTypes += pounder_projectile_enh trhev_pounder.FireModes += new FireModeDefinition trhev_pounder.FireModes.head.AmmoTypeIndices += 0 //explode on contact trhev_pounder.FireModes.head.AmmoSlotIndex = 0 @@ -1730,20 +3628,24 @@ object GlobalDefinitions { trhev_pounder.FireModes(2).Magazine = 30 trhev_pounder.FireModes += new FireModeDefinition //3-second fuse trhev_pounder.FireModes(3).AmmoTypeIndices += 0 + trhev_pounder.FireModes(3).ProjectileTypeIndices += 1 trhev_pounder.FireModes(3).AmmoSlotIndex = 0 trhev_pounder.FireModes(3).Magazine = 30 trhev_pounder.FireModes += new FireModeDefinition //3-second fuse, anchored trhev_pounder.FireModes(4).AmmoTypeIndices += 0 + trhev_pounder.FireModes(4).ProjectileTypeIndices += 1 trhev_pounder.FireModes(4).AmmoSlotIndex = 0 trhev_pounder.FireModes(4).Magazine = 30 trhev_pounder.FireModes += new FireModeDefinition //3-second fuse, overdrive? trhev_pounder.FireModes(5).AmmoTypeIndices += 0 + trhev_pounder.FireModes(5).ProjectileTypeIndices += 1 trhev_pounder.FireModes(5).AmmoSlotIndex = 0 trhev_pounder.FireModes(5).Magazine = 30 trhev_burster.Name = "trhev_burster" trhev_burster.Size = EquipmentSize.Max trhev_burster.AmmoTypes += burster_ammo + trhev_burster.ProjectileTypes += burster_projectile trhev_burster.FireModes += new FireModeDefinition trhev_burster.FireModes.head.AmmoTypeIndices += 0 trhev_burster.FireModes.head.AmmoSlotIndex = 0 @@ -1752,6 +3654,7 @@ object GlobalDefinitions { nchev_scattercannon.Name = "nchev_scattercannon" nchev_scattercannon.Size = EquipmentSize.Max nchev_scattercannon.AmmoTypes += scattercannon_ammo + nchev_scattercannon.ProjectileTypes += scattercannon_projectile nchev_scattercannon.FireModes += new PelletFireModeDefinition nchev_scattercannon.FireModes.head.AmmoTypeIndices += 0 nchev_scattercannon.FireModes.head.AmmoSlotIndex = 0 @@ -1779,6 +3682,7 @@ object GlobalDefinitions { nchev_sparrow.Name = "nchev_sparrow" nchev_sparrow.Size = EquipmentSize.Max nchev_sparrow.AmmoTypes += sparrow_ammo + nchev_sparrow.ProjectileTypes += sparrow_projectile nchev_sparrow.FireModes += new FireModeDefinition nchev_sparrow.FireModes.head.AmmoTypeIndices += 0 nchev_sparrow.FireModes.head.AmmoSlotIndex = 0 @@ -1787,18 +3691,22 @@ object GlobalDefinitions { vshev_quasar.Name = "vshev_quasar" vshev_quasar.Size = EquipmentSize.Max vshev_quasar.AmmoTypes += quasar_ammo + vshev_quasar.ProjectileTypes += quasar_projectile + vshev_quasar.ProjectileTypes += enhanced_quasar_projectile vshev_quasar.FireModes += new FireModeDefinition vshev_quasar.FireModes.head.AmmoTypeIndices += 0 vshev_quasar.FireModes.head.AmmoSlotIndex = 0 vshev_quasar.FireModes.head.Magazine = 120 vshev_quasar.FireModes += new FireModeDefinition vshev_quasar.FireModes(1).AmmoTypeIndices += 0 + vshev_quasar.FireModes(1).ProjectileTypeIndices += 1 vshev_quasar.FireModes(1).AmmoSlotIndex = 0 vshev_quasar.FireModes(1).Magazine = 120 vshev_comet.Name = "vshev_comet" vshev_comet.Size = EquipmentSize.Max vshev_comet.AmmoTypes += comet_ammo + vshev_comet.ProjectileTypes += comet_projectile vshev_comet.FireModes += new FireModeDefinition vshev_comet.FireModes.head.AmmoTypeIndices += 0 vshev_comet.FireModes.head.AmmoSlotIndex = 0 @@ -1807,6 +3715,7 @@ object GlobalDefinitions { vshev_starfire.Name = "vshev_starfire" vshev_starfire.Size = EquipmentSize.Max vshev_starfire.AmmoTypes += starfire_ammo + vshev_starfire.ProjectileTypes += starfire_projectile vshev_starfire.FireModes += new FireModeDefinition vshev_starfire.FireModes.head.AmmoTypeIndices += 0 vshev_starfire.FireModes.head.AmmoSlotIndex = 0 @@ -1834,6 +3743,8 @@ object GlobalDefinitions { nano_dispenser.FireModes.head.AmmoTypeIndices += 1 nano_dispenser.FireModes.head.AmmoSlotIndex = 0 nano_dispenser.FireModes.head.Magazine = 100 + nano_dispenser.FireModes.head.Modifiers.Damage1 = 20 + nano_dispenser.FireModes.head.Modifiers.Damage4 = 20 nano_dispenser.Tile = InventoryTile.Tile63 bank.Name = "bank" @@ -1856,6 +3767,7 @@ object GlobalDefinitions { trek.Name = "trek" trek.Size = EquipmentSize.Pistol trek.AmmoTypes += trek_ammo + trek.ProjectileTypes += trek_projectile trek.FireModes += new FireModeDefinition trek.FireModes.head.AmmoTypeIndices += 0 trek.FireModes.head.AmmoSlotIndex = 0 @@ -1894,6 +3806,7 @@ object GlobalDefinitions { fury_weapon_systema.Name = "fury_weapon_systema" fury_weapon_systema.Size = EquipmentSize.VehicleWeapon fury_weapon_systema.AmmoTypes += hellfire_ammo + fury_weapon_systema.ProjectileTypes += hellfire_projectile fury_weapon_systema.FireModes += new FireModeDefinition fury_weapon_systema.FireModes.head.AmmoTypeIndices += 0 fury_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -1902,6 +3815,7 @@ object GlobalDefinitions { quadassault_weapon_system.Name = "quadassault_weapon_system" quadassault_weapon_system.Size = EquipmentSize.VehicleWeapon quadassault_weapon_system.AmmoTypes += bullet_12mm + quadassault_weapon_system.ProjectileTypes += bullet_12mm_projectile quadassault_weapon_system.FireModes += new FireModeDefinition quadassault_weapon_system.FireModes.head.AmmoTypeIndices += 0 quadassault_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -1911,18 +3825,21 @@ object GlobalDefinitions { scythe.Size = EquipmentSize.VehicleWeapon scythe.AmmoTypes += ancient_ammo_vehicle scythe.AmmoTypes += ancient_ammo_vehicle + scythe.ProjectileTypes += scythe_projectile scythe.FireModes += new FireModeDefinition scythe.FireModes.head.AmmoTypeIndices += 0 scythe.FireModes.head.AmmoSlotIndex = 0 scythe.FireModes.head.Magazine = 250 scythe.FireModes += new FireModeDefinition scythe.FireModes(1).AmmoTypeIndices += 0 + scythe.FireModes(1).ProjectileTypeIndices += 0 scythe.FireModes(1).AmmoSlotIndex = 1 //note: the scythe has two magazines using a single pool; however, it can not ammo-switch or mode-switch scythe.FireModes(1).Magazine = 250 chaingun_p.Name = "chaingun_p" chaingun_p.Size = EquipmentSize.VehicleWeapon chaingun_p.AmmoTypes += bullet_12mm + chaingun_p.ProjectileTypes += bullet_12mm_projectile chaingun_p.FireModes += new FireModeDefinition chaingun_p.FireModes.head.AmmoTypeIndices += 0 chaingun_p.FireModes.head.AmmoSlotIndex = 0 @@ -1932,6 +3849,8 @@ object GlobalDefinitions { skyguard_weapon_system.Size = EquipmentSize.VehicleWeapon skyguard_weapon_system.AmmoTypes += skyguard_flak_cannon_ammo skyguard_weapon_system.AmmoTypes += bullet_12mm + skyguard_weapon_system.ProjectileTypes += skyguard_flak_cannon_projectile + skyguard_weapon_system.ProjectileTypes += bullet_12mm_projectile skyguard_weapon_system.FireModes += new FireModeDefinition skyguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 skyguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -1944,6 +3863,7 @@ object GlobalDefinitions { grenade_launcher_marauder.Name = "grenade_launcher_marauder" grenade_launcher_marauder.Size = EquipmentSize.VehicleWeapon grenade_launcher_marauder.AmmoTypes += heavy_grenade_mortar + grenade_launcher_marauder.ProjectileTypes += heavy_grenade_projectile grenade_launcher_marauder.FireModes += new FireModeDefinition grenade_launcher_marauder.FireModes.head.AmmoTypeIndices += 0 grenade_launcher_marauder.FireModes.head.AmmoSlotIndex = 0 @@ -1952,6 +3872,7 @@ object GlobalDefinitions { advanced_missile_launcher_t.Name = "advanced_missile_launcher_t" advanced_missile_launcher_t.Size = EquipmentSize.VehicleWeapon advanced_missile_launcher_t.AmmoTypes += firebird_missile + advanced_missile_launcher_t.ProjectileTypes += firebird_missile_projectile advanced_missile_launcher_t.FireModes += new FireModeDefinition advanced_missile_launcher_t.FireModes.head.AmmoTypeIndices += 0 advanced_missile_launcher_t.FireModes.head.AmmoSlotIndex = 0 @@ -1960,6 +3881,7 @@ object GlobalDefinitions { flux_cannon_thresher.Name = "flux_cannon_thresher" flux_cannon_thresher.Size = EquipmentSize.VehicleWeapon flux_cannon_thresher.AmmoTypes += flux_cannon_thresher_battery + flux_cannon_thresher.ProjectileTypes += flux_cannon_thresher_projectile flux_cannon_thresher.FireModes += new FireModeDefinition flux_cannon_thresher.FireModes.head.AmmoTypeIndices += 0 flux_cannon_thresher.FireModes.head.AmmoSlotIndex = 0 @@ -1968,6 +3890,7 @@ object GlobalDefinitions { mediumtransport_weapon_systemA.Name = "mediumtransport_weapon_systemA" mediumtransport_weapon_systemA.Size = EquipmentSize.VehicleWeapon mediumtransport_weapon_systemA.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemA.ProjectileTypes += bullet_20mm_projectile mediumtransport_weapon_systemA.FireModes += new FireModeDefinition mediumtransport_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 mediumtransport_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 @@ -1976,6 +3899,7 @@ object GlobalDefinitions { mediumtransport_weapon_systemB.Name = "mediumtransport_weapon_systemB" mediumtransport_weapon_systemB.Size = EquipmentSize.VehicleWeapon mediumtransport_weapon_systemB.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemB.ProjectileTypes += bullet_20mm_projectile mediumtransport_weapon_systemB.FireModes += new FireModeDefinition mediumtransport_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 mediumtransport_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 @@ -1984,6 +3908,7 @@ object GlobalDefinitions { battlewagon_weapon_systema.Name = "battlewagon_weapon_systema" battlewagon_weapon_systema.Size = EquipmentSize.VehicleWeapon battlewagon_weapon_systema.AmmoTypes += bullet_15mm + battlewagon_weapon_systema.ProjectileTypes += bullet_15mm_projectile battlewagon_weapon_systema.FireModes += new FireModeDefinition battlewagon_weapon_systema.FireModes.head.AmmoTypeIndices += 0 battlewagon_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -1992,6 +3917,7 @@ object GlobalDefinitions { battlewagon_weapon_systemb.Name = "battlewagon_weapon_systemb" battlewagon_weapon_systemb.Size = EquipmentSize.VehicleWeapon battlewagon_weapon_systemb.AmmoTypes += bullet_15mm + battlewagon_weapon_systemb.ProjectileTypes += bullet_15mm_projectile battlewagon_weapon_systemb.FireModes += new FireModeDefinition battlewagon_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 battlewagon_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 @@ -2000,6 +3926,7 @@ object GlobalDefinitions { battlewagon_weapon_systemc.Name = "battlewagon_weapon_systemc" battlewagon_weapon_systemc.Size = EquipmentSize.VehicleWeapon battlewagon_weapon_systemc.AmmoTypes += bullet_15mm + battlewagon_weapon_systemc.ProjectileTypes += bullet_15mm_projectile battlewagon_weapon_systemc.FireModes += new FireModeDefinition battlewagon_weapon_systemc.FireModes.head.AmmoTypeIndices += 0 battlewagon_weapon_systemc.FireModes.head.AmmoSlotIndex = 0 @@ -2008,6 +3935,7 @@ object GlobalDefinitions { battlewagon_weapon_systemd.Name = "battlewagon_weapon_systemd" battlewagon_weapon_systemd.Size = EquipmentSize.VehicleWeapon battlewagon_weapon_systemd.AmmoTypes += bullet_15mm + battlewagon_weapon_systemd.ProjectileTypes += bullet_15mm_projectile battlewagon_weapon_systemd.FireModes += new FireModeDefinition battlewagon_weapon_systemd.FireModes.head.AmmoTypeIndices += 0 battlewagon_weapon_systemd.FireModes.head.AmmoSlotIndex = 0 @@ -2016,6 +3944,7 @@ object GlobalDefinitions { thunderer_weapon_systema.Name = "thunderer_weapon_systema" thunderer_weapon_systema.Size = EquipmentSize.VehicleWeapon thunderer_weapon_systema.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systema.ProjectileTypes += gauss_cannon_projectile thunderer_weapon_systema.FireModes += new FireModeDefinition thunderer_weapon_systema.FireModes.head.AmmoTypeIndices += 0 thunderer_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -2024,6 +3953,7 @@ object GlobalDefinitions { thunderer_weapon_systemb.Name = "thunderer_weapon_systemb" thunderer_weapon_systemb.Size = EquipmentSize.VehicleWeapon thunderer_weapon_systemb.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systemb.ProjectileTypes += gauss_cannon_projectile thunderer_weapon_systemb.FireModes += new FireModeDefinition thunderer_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 thunderer_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 @@ -2032,6 +3962,7 @@ object GlobalDefinitions { aurora_weapon_systema.Name = "aurora_weapon_systema" aurora_weapon_systema.Size = EquipmentSize.VehicleWeapon aurora_weapon_systema.AmmoTypes += fluxpod_ammo + aurora_weapon_systema.ProjectileTypes += fluxpod_projectile aurora_weapon_systema.FireModes += new FireModeDefinition aurora_weapon_systema.FireModes.head.AmmoTypeIndices += 0 aurora_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -2044,6 +3975,7 @@ object GlobalDefinitions { aurora_weapon_systemb.Name = "aurora_weapon_systemb" aurora_weapon_systemb.Size = EquipmentSize.VehicleWeapon aurora_weapon_systemb.AmmoTypes += fluxpod_ammo + aurora_weapon_systemb.ProjectileTypes += fluxpod_projectile aurora_weapon_systemb.FireModes += new FireModeDefinition aurora_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 aurora_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 @@ -2056,6 +3988,7 @@ object GlobalDefinitions { apc_weapon_systema.Name = "apc_weapon_systema" apc_weapon_systema.Size = EquipmentSize.VehicleWeapon apc_weapon_systema.AmmoTypes += bullet_75mm + apc_weapon_systema.ProjectileTypes += bullet_75mm_apc_projectile apc_weapon_systema.FireModes += new FireModeDefinition apc_weapon_systema.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -2064,6 +3997,7 @@ object GlobalDefinitions { apc_weapon_systemb.Name = "apc_weapon_systemb" apc_weapon_systemb.Size = EquipmentSize.VehicleWeapon apc_weapon_systemb.AmmoTypes += bullet_75mm + apc_weapon_systemb.ProjectileTypes += bullet_75mm_apc_projectile apc_weapon_systemb.FireModes += new FireModeDefinition apc_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 @@ -2072,6 +4006,7 @@ object GlobalDefinitions { apc_ballgun_r.Name = "apc_ballgun_r" apc_ballgun_r.Size = EquipmentSize.VehicleWeapon apc_ballgun_r.AmmoTypes += bullet_12mm + apc_ballgun_r.ProjectileTypes += bullet_12mm_projectile apc_ballgun_r.FireModes += new FireModeDefinition apc_ballgun_r.FireModes.head.AmmoTypeIndices += 0 apc_ballgun_r.FireModes.head.AmmoSlotIndex = 0 @@ -2080,6 +4015,7 @@ object GlobalDefinitions { apc_ballgun_l.Name = "apc_ballgun_l" apc_ballgun_l.Size = EquipmentSize.VehicleWeapon apc_ballgun_l.AmmoTypes += bullet_12mm + apc_ballgun_l.ProjectileTypes += bullet_12mm_projectile apc_ballgun_l.FireModes += new FireModeDefinition apc_ballgun_l.FireModes.head.AmmoTypeIndices += 0 apc_ballgun_l.FireModes.head.AmmoSlotIndex = 0 @@ -2088,6 +4024,7 @@ object GlobalDefinitions { apc_weapon_systemc_tr.Name = "apc_weapon_systemc_tr" apc_weapon_systemc_tr.Size = EquipmentSize.VehicleWeapon apc_weapon_systemc_tr.AmmoTypes += bullet_15mm + apc_weapon_systemc_tr.ProjectileTypes += bullet_15mm_apc_projectile apc_weapon_systemc_tr.FireModes += new FireModeDefinition apc_weapon_systemc_tr.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemc_tr.FireModes.head.AmmoSlotIndex = 0 @@ -2096,6 +4033,7 @@ object GlobalDefinitions { apc_weapon_systemd_tr.Name = "apc_weapon_systemd_tr" apc_weapon_systemd_tr.Size = EquipmentSize.VehicleWeapon apc_weapon_systemd_tr.AmmoTypes += bullet_15mm + apc_weapon_systemd_tr.ProjectileTypes += bullet_15mm_apc_projectile apc_weapon_systemd_tr.FireModes += new FireModeDefinition apc_weapon_systemd_tr.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemd_tr.FireModes.head.AmmoSlotIndex = 0 @@ -2104,6 +4042,7 @@ object GlobalDefinitions { apc_weapon_systemc_nc.Name = "apc_weapon_systemc_nc" apc_weapon_systemc_nc.Size = EquipmentSize.VehicleWeapon apc_weapon_systemc_nc.AmmoTypes += bullet_20mm + apc_weapon_systemc_nc.ProjectileTypes += bullet_20mm_apc_projectile apc_weapon_systemc_nc.FireModes += new FireModeDefinition apc_weapon_systemc_nc.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemc_nc.FireModes.head.AmmoSlotIndex = 0 @@ -2112,6 +4051,7 @@ object GlobalDefinitions { apc_weapon_systemd_nc.Name = "apc_weapon_systemd_nc" apc_weapon_systemd_nc.Size = EquipmentSize.VehicleWeapon apc_weapon_systemd_nc.AmmoTypes += bullet_20mm + apc_weapon_systemd_nc.ProjectileTypes += bullet_20mm_apc_projectile apc_weapon_systemd_nc.FireModes += new FireModeDefinition apc_weapon_systemd_nc.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemd_nc.FireModes.head.AmmoSlotIndex = 0 @@ -2120,6 +4060,7 @@ object GlobalDefinitions { apc_weapon_systemc_vs.Name = "apc_weapon_systemc_vs" apc_weapon_systemc_vs.Size = EquipmentSize.VehicleWeapon apc_weapon_systemc_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemc_vs.ProjectileTypes += flux_cannon_apc_projectile apc_weapon_systemc_vs.FireModes += new FireModeDefinition apc_weapon_systemc_vs.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemc_vs.FireModes.head.AmmoSlotIndex = 0 @@ -2128,6 +4069,7 @@ object GlobalDefinitions { apc_weapon_systemd_vs.Name = "apc_weapon_systemd_vs" apc_weapon_systemd_vs.Size = EquipmentSize.VehicleWeapon apc_weapon_systemd_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemd_vs.ProjectileTypes += flux_cannon_apc_projectile apc_weapon_systemd_vs.FireModes += new FireModeDefinition apc_weapon_systemd_vs.FireModes.head.AmmoTypeIndices += 0 apc_weapon_systemd_vs.FireModes.head.AmmoSlotIndex = 0 @@ -2137,6 +4079,8 @@ object GlobalDefinitions { lightning_weapon_system.Size = EquipmentSize.VehicleWeapon lightning_weapon_system.AmmoTypes += bullet_75mm lightning_weapon_system.AmmoTypes += bullet_12mm + lightning_weapon_system.ProjectileTypes += bullet_75mm_projectile + lightning_weapon_system.ProjectileTypes += bullet_12mm_projectile lightning_weapon_system.FireModes += new FireModeDefinition lightning_weapon_system.FireModes.head.AmmoTypeIndices += 0 lightning_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2149,6 +4093,7 @@ object GlobalDefinitions { prowler_weapon_systemA.Name = "prowler_weapon_systemA" prowler_weapon_systemA.Size = EquipmentSize.VehicleWeapon prowler_weapon_systemA.AmmoTypes += bullet_105mm + prowler_weapon_systemA.ProjectileTypes += bullet_105mm_projectile prowler_weapon_systemA.FireModes += new FireModeDefinition prowler_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 prowler_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 @@ -2157,6 +4102,7 @@ object GlobalDefinitions { prowler_weapon_systemB.Name = "prowler_weapon_systemB" prowler_weapon_systemB.Size = EquipmentSize.VehicleWeapon prowler_weapon_systemB.AmmoTypes += bullet_15mm + prowler_weapon_systemB.ProjectileTypes += bullet_15mm_projectile prowler_weapon_systemB.FireModes += new FireModeDefinition prowler_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 prowler_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 @@ -2166,6 +4112,8 @@ object GlobalDefinitions { vanguard_weapon_system.Size = EquipmentSize.VehicleWeapon vanguard_weapon_system.AmmoTypes += bullet_150mm vanguard_weapon_system.AmmoTypes += bullet_20mm + vanguard_weapon_system.ProjectileTypes += bullet_105mm_projectile + vanguard_weapon_system.ProjectileTypes += bullet_20mm_projectile vanguard_weapon_system.FireModes += new FireModeDefinition vanguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 vanguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2178,6 +4126,7 @@ object GlobalDefinitions { particle_beam_magrider.Name = "particle_beam_magrider" particle_beam_magrider.Size = EquipmentSize.VehicleWeapon particle_beam_magrider.AmmoTypes += pulse_battery + particle_beam_magrider.ProjectileTypes += ppa_projectile particle_beam_magrider.FireModes += new FireModeDefinition particle_beam_magrider.FireModes.head.AmmoTypeIndices += 0 particle_beam_magrider.FireModes.head.AmmoSlotIndex = 0 @@ -2186,6 +4135,7 @@ object GlobalDefinitions { heavy_rail_beam_magrider.Name = "heavy_rail_beam_magrider" heavy_rail_beam_magrider.Size = EquipmentSize.VehicleWeapon heavy_rail_beam_magrider.AmmoTypes += heavy_rail_beam_battery + heavy_rail_beam_magrider.ProjectileTypes += heavy_rail_beam_projectile heavy_rail_beam_magrider.FireModes += new FireModeDefinition heavy_rail_beam_magrider.FireModes.head.AmmoTypeIndices += 0 heavy_rail_beam_magrider.FireModes.head.AmmoSlotIndex = 0 @@ -2194,6 +4144,7 @@ object GlobalDefinitions { flail_weapon.Name = "flail_weapon" flail_weapon.Size = EquipmentSize.VehicleWeapon flail_weapon.AmmoTypes += ancient_ammo_vehicle + flail_weapon.ProjectileTypes += flail_projectile flail_weapon.FireModes += new FireModeDefinition flail_weapon.FireModes.head.AmmoTypeIndices += 0 flail_weapon.FireModes.head.AmmoSlotIndex = 0 @@ -2202,6 +4153,7 @@ object GlobalDefinitions { rotarychaingun_mosquito.Name = "rotarychaingun_mosquito" rotarychaingun_mosquito.Size = EquipmentSize.VehicleWeapon rotarychaingun_mosquito.AmmoTypes += bullet_12mm + rotarychaingun_mosquito.ProjectileTypes += bullet_12mm_projectile rotarychaingun_mosquito.FireModes += new FireModeDefinition rotarychaingun_mosquito.FireModes.head.AmmoTypeIndices += 0 rotarychaingun_mosquito.FireModes.head.AmmoSlotIndex = 0 @@ -2211,6 +4163,8 @@ object GlobalDefinitions { lightgunship_weapon_system.Size = EquipmentSize.VehicleWeapon lightgunship_weapon_system.AmmoTypes += bullet_20mm lightgunship_weapon_system.AmmoTypes += reaver_rocket + lightgunship_weapon_system.ProjectileTypes += bullet_20mm_projectile + lightgunship_weapon_system.ProjectileTypes += reaver_rocket_projectile lightgunship_weapon_system.FireModes += new FireModeDefinition lightgunship_weapon_system.FireModes.head.AmmoTypeIndices += 0 lightgunship_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2224,6 +4178,8 @@ object GlobalDefinitions { wasp_weapon_system.Size = EquipmentSize.VehicleWeapon wasp_weapon_system.AmmoTypes += wasp_gun_ammo wasp_weapon_system.AmmoTypes += wasp_rocket_ammo + wasp_weapon_system.ProjectileTypes += wasp_gun_projectile + wasp_weapon_system.ProjectileTypes += wasp_rocket_projectile wasp_weapon_system.FireModes += new FireModeDefinition wasp_weapon_system.FireModes.head.AmmoTypeIndices += 0 wasp_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2236,6 +4192,7 @@ object GlobalDefinitions { liberator_weapon_system.Name = "liberator_weapon_system" liberator_weapon_system.Size = EquipmentSize.VehicleWeapon liberator_weapon_system.AmmoTypes += bullet_35mm + liberator_weapon_system.ProjectileTypes += bullet_35mm_projectile liberator_weapon_system.FireModes += new FireModeDefinition liberator_weapon_system.FireModes.head.AmmoTypeIndices += 0 liberator_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2244,18 +4201,22 @@ object GlobalDefinitions { liberator_bomb_bay.Name = "liberator_bomb_bay" liberator_bomb_bay.Size = EquipmentSize.VehicleWeapon liberator_bomb_bay.AmmoTypes += liberator_bomb + liberator_bomb_bay.ProjectileTypes += liberator_bomb_projectile + liberator_bomb_bay.ProjectileTypes += liberator_bomb_cluster_projectile liberator_bomb_bay.FireModes += new FireModeDefinition liberator_bomb_bay.FireModes.head.AmmoTypeIndices += 0 liberator_bomb_bay.FireModes.head.AmmoSlotIndex = 0 liberator_bomb_bay.FireModes.head.Magazine = 10 liberator_bomb_bay.FireModes += new FireModeDefinition liberator_bomb_bay.FireModes(1).AmmoTypeIndices += 0 + liberator_bomb_bay.FireModes(1).ProjectileTypeIndices += 1 liberator_bomb_bay.FireModes(1).AmmoSlotIndex = 0 liberator_bomb_bay.FireModes(1).Magazine = 10 liberator_25mm_cannon.Name = "liberator_25mm_cannon" liberator_25mm_cannon.Size = EquipmentSize.VehicleWeapon liberator_25mm_cannon.AmmoTypes += bullet_25mm + liberator_25mm_cannon.ProjectileTypes += bullet_25mm_projectile liberator_25mm_cannon.FireModes += new FireModeDefinition liberator_25mm_cannon.FireModes.head.AmmoTypeIndices += 0 liberator_25mm_cannon.FireModes.head.AmmoSlotIndex = 0 @@ -2264,6 +4225,7 @@ object GlobalDefinitions { vulture_nose_weapon_system.Name = "vulture_nose_weapon_system" vulture_nose_weapon_system.Size = EquipmentSize.VehicleWeapon vulture_nose_weapon_system.AmmoTypes += bullet_35mm + vulture_nose_weapon_system.ProjectileTypes += vulture_nose_bullet_projectile vulture_nose_weapon_system.FireModes += new FireModeDefinition vulture_nose_weapon_system.FireModes.head.AmmoTypeIndices += 0 vulture_nose_weapon_system.FireModes.head.AmmoSlotIndex = 0 @@ -2272,6 +4234,7 @@ object GlobalDefinitions { vulture_bomb_bay.Name = "vulture_bomb_bay" vulture_bomb_bay.Size = EquipmentSize.VehicleWeapon vulture_bomb_bay.AmmoTypes += liberator_bomb + vulture_bomb_bay.ProjectileTypes += vulture_bomb_projectile vulture_bomb_bay.FireModes += new FireModeDefinition vulture_bomb_bay.FireModes.head.AmmoTypeIndices += 0 vulture_bomb_bay.FireModes.head.AmmoSlotIndex = 0 @@ -2280,6 +4243,7 @@ object GlobalDefinitions { vulture_tail_cannon.Name = "vulture_tail_cannon" vulture_tail_cannon.Size = EquipmentSize.VehicleWeapon vulture_tail_cannon.AmmoTypes += bullet_25mm + vulture_tail_cannon.ProjectileTypes += vulture_tail_bullet_projectile vulture_tail_cannon.FireModes += new FireModeDefinition vulture_tail_cannon.FireModes.head.AmmoTypeIndices += 0 vulture_tail_cannon.FireModes.head.AmmoSlotIndex = 0 @@ -2288,6 +4252,7 @@ object GlobalDefinitions { cannon_dropship_20mm.Name = "cannon_dropship_20mm" cannon_dropship_20mm.Size = EquipmentSize.VehicleWeapon cannon_dropship_20mm.AmmoTypes += bullet_20mm + cannon_dropship_20mm.ProjectileTypes += bullet_20mm_projectile cannon_dropship_20mm.FireModes += new FireModeDefinition cannon_dropship_20mm.FireModes.head.AmmoTypeIndices += 0 cannon_dropship_20mm.FireModes.head.AmmoSlotIndex = 0 @@ -2296,6 +4261,7 @@ object GlobalDefinitions { dropship_rear_turret.Name = "dropship_rear_turret" dropship_rear_turret.Size = EquipmentSize.VehicleWeapon dropship_rear_turret.AmmoTypes += bullet_20mm + dropship_rear_turret.ProjectileTypes += bullet_20mm_projectile dropship_rear_turret.FireModes += new FireModeDefinition dropship_rear_turret.FireModes.head.AmmoTypeIndices += 0 dropship_rear_turret.FireModes.head.AmmoSlotIndex = 0 @@ -2304,14 +4270,20 @@ object GlobalDefinitions { galaxy_gunship_cannon.Name = "galaxy_gunship_cannon" galaxy_gunship_cannon.Size = EquipmentSize.VehicleWeapon galaxy_gunship_cannon.AmmoTypes += heavy_grenade_mortar + galaxy_gunship_cannon.ProjectileTypes += heavy_grenade_projectile galaxy_gunship_cannon.FireModes += new FireModeDefinition galaxy_gunship_cannon.FireModes.head.AmmoTypeIndices += 0 galaxy_gunship_cannon.FireModes.head.AmmoSlotIndex = 0 galaxy_gunship_cannon.FireModes.head.Magazine = 50 + galaxy_gunship_cannon.FireModes.head.Modifiers.Damage1 = 50 + galaxy_gunship_cannon.FireModes.head.Modifiers.Damage2 = 50 + galaxy_gunship_cannon.FireModes.head.Modifiers.Damage3 = 10 + galaxy_gunship_cannon.FireModes.head.Modifiers.Damage4 = 50 galaxy_gunship_tailgun.Name = "galaxy_gunship_tailgun" galaxy_gunship_tailgun.Size = EquipmentSize.VehicleWeapon galaxy_gunship_tailgun.AmmoTypes += bullet_35mm + galaxy_gunship_tailgun.ProjectileTypes += galaxy_gunship_gun_projectile galaxy_gunship_tailgun.FireModes += new FireModeDefinition galaxy_gunship_tailgun.FireModes.head.AmmoTypeIndices += 0 galaxy_gunship_tailgun.FireModes.head.AmmoSlotIndex = 0 @@ -2320,6 +4292,7 @@ object GlobalDefinitions { galaxy_gunship_gun.Name = "galaxy_gunship_gun" galaxy_gunship_gun.Size = EquipmentSize.VehicleWeapon galaxy_gunship_gun.AmmoTypes += bullet_35mm + galaxy_gunship_gun.ProjectileTypes += galaxy_gunship_gun_projectile galaxy_gunship_gun.FireModes += new FireModeDefinition galaxy_gunship_gun.FireModes.head.AmmoTypeIndices += 0 galaxy_gunship_gun.FireModes.head.AmmoSlotIndex = 0 diff --git a/common/src/main/scala/net/psforever/objects/LocalProjectile.scala b/common/src/main/scala/net/psforever/objects/LocalProjectile.scala new file mode 100644 index 00000000..2481deb5 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/LocalProjectile.scala @@ -0,0 +1,36 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects + +import akka.actor.ActorContext +import net.psforever.objects.serverobject.PlanetSideServerObject +import net.psforever.types.PlanetSideEmpire + +/** + * A `LocalProjectile` is a server-side object designed to populate a fake shared space. + * It is a placeholder intended to block out the existence of projectiles communicated from clients. + * All clients reserve the same internal range of user-generated GUID's from 40100 to 40124, inclusive. + * All clients recognize this same range independent of each other as "their own featureless projectiles." + * @see `Zone.MakeReservedObjects`
+ * `Projectile.BaseUID`
+ * `Projectile.RangeUID` + */ +class LocalProjectile extends PlanetSideServerObject { + def Faction = PlanetSideEmpire.NEUTRAL + + def Definition = LocalProjectile.local +} + +object LocalProjectile { + import net.psforever.objects.definition.ObjectDefinition + def local = new ObjectDefinition(0) { Name = "projectile" } + + /** + * Instantiate and configure a `LocalProjectile` object. + * @param id the unique id that will be assigned to this entity + * @param context a context to allow the object to properly set up `ActorSystem` functionality + * @return the `LocalProjectile` object + */ + def Constructor(id : Int, context : ActorContext) : LocalProjectile = { + new LocalProjectile() + } +} diff --git a/common/src/main/scala/net/psforever/objects/Tool.scala b/common/src/main/scala/net/psforever/objects/Tool.scala index 355c5a23..3aa92530 100644 --- a/common/src/main/scala/net/psforever/objects/Tool.scala +++ b/common/src/main/scala/net/psforever/objects/Tool.scala @@ -1,8 +1,9 @@ // Copyright (c) 2017 PSForever package net.psforever.objects -import net.psforever.objects.definition.{AmmoBoxDefinition, ToolDefinition} -import net.psforever.objects.equipment.{Ammo, Equipment, FireModeDefinition, FireModeSwitch} +import net.psforever.objects.definition.{AmmoBoxDefinition, ProjectileDefinition, ToolDefinition} +import net.psforever.objects.equipment._ +import net.psforever.objects.ballistics.Projectiles import scala.annotation.tailrec @@ -59,6 +60,20 @@ class Tool(private val toolDef : ToolDefinition) extends Equipment with FireMode AmmoType } + def Projectile : ProjectileDefinition = { + toolDef.ProjectileTypes({ + val projIndices = FireMode.ProjectileTypeIndices + if(projIndices.isEmpty) { + AmmoTypeIndex //e.g., bullet_9mm -> bullet_9mm_projectile, bullet_9mm_AP -> bullet_9mm_AP_projectile + } + else { + projIndices(AmmoSlot.AmmoTypeIndex) //e.g., pulsar: f.mode1 -> pulsar_projectile, f.mode2 = pulsar_ap_projectile + } + }) + } + + def ProjectileType : Projectiles.Value = Projectile.ProjectileType + def Magazine : Int = AmmoSlot.Magazine def Magazine_=(mag : Int) : Int = { diff --git a/common/src/main/scala/net/psforever/objects/Vehicle.scala b/common/src/main/scala/net/psforever/objects/Vehicle.scala index e3aa7849..f2a29027 100644 --- a/common/src/main/scala/net/psforever/objects/Vehicle.scala +++ b/common/src/main/scala/net/psforever/objects/Vehicle.scala @@ -323,13 +323,12 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ Some(AccessPermissionGroup.Passenger) } case None => - None - } - CargoHold(seatNumber) match { - case Some(_) => - Some(AccessPermissionGroup.Passenger) - case None => - None + CargoHold(seatNumber) match { + case Some(_) => + Some(AccessPermissionGroup.Passenger) + case None => + None + } } } } diff --git a/common/src/main/scala/net/psforever/objects/ballistics/DamageProfile.scala b/common/src/main/scala/net/psforever/objects/ballistics/DamageProfile.scala new file mode 100644 index 00000000..1d2e877e --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/ballistics/DamageProfile.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.ballistics + +/** + * The different values for five common types of damage that can be dealt, based on target and application. + * In the same way, the five damage modifiers that are applied to the same kind of damage. + */ +trait DamageProfile { + def Damage0 : Int + + def Damage0_=(damage : Int) : Int + + def Damage1 : Int + + def Damage1_=(damage : Int) : Int + + def Damage2 : Int + + def Damage2_=(damage : Int) : Int + + def Damage3 : Int + + def Damage3_=(damage : Int) : Int + + def Damage4 : Int + + def Damage4_=(damage : Int) : Int +} diff --git a/common/src/main/scala/net/psforever/objects/ballistics/DamageType.scala b/common/src/main/scala/net/psforever/objects/ballistics/DamageType.scala new file mode 100644 index 00000000..8f2722b0 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/ballistics/DamageType.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.ballistics + +/** + * An `Enumeration` of the damage type. + * These types are not necessarily representative of the kind of projectile being used; + * for example, the bolt driver's `bolt` is considered "splash." + */ +object DamageType extends Enumeration(1) { + type Type = Value + + final val Direct, + Splash, + Radiation, + Aggravated, + Plasma, + Comet, + None = Value +} diff --git a/common/src/main/scala/net/psforever/objects/ballistics/Projectile.scala b/common/src/main/scala/net/psforever/objects/ballistics/Projectile.scala new file mode 100644 index 00000000..790a4227 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/ballistics/Projectile.scala @@ -0,0 +1,78 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.ballistics + +import net.psforever.objects.definition.{ProjectileDefinition, ToolDefinition} +import net.psforever.objects.entity.SimpleWorldEntity +import net.psforever.types.Vector3 + +/** + * A summation of weapon (`Tool`) discharge. + * @param profile an explanation of the damage that can be performed by this discharge + * @param tool_def the weapon that caused this discharge + * @param shot_origin where the projectile started + * @param shot_angle in which direction the projectile was aimed when it was discharged + * @param resolution whether this projectile has encountered a target or wall; + * defaults to `Unresolved` + * @param fire_time when the weapon discharged was recorded; + * defaults to `System.nanoTime` + * @param hit_time when the discharge had its resolution status updated + */ +final case class Projectile(profile : ProjectileDefinition, + tool_def : ToolDefinition, + shot_origin : Vector3, + shot_angle : Vector3, + resolution : ProjectileResolution.Value, + fire_time : Long = System.nanoTime, + hit_time : Long = 0) { + /** Information about the current world coordinates and orientation of the projectile */ + val current : SimpleWorldEntity = new SimpleWorldEntity() + + /** + * Give the projectile the suggested resolution status. + * Update the world coordinates and orientation. + * @param pos the current position + * @param ang the current orientation + * @param resolution the resolution status + * @return a new projectile with the suggested resolution status, or the original projectile + */ + def Resolve(pos : Vector3, ang : Vector3, resolution : ProjectileResolution.Value) : Projectile = { + val obj = Resolve(resolution) + obj.current.Position = pos + obj.current.Orientation = ang + obj + } + + /** + * Give the projectile the suggested resolution status. + * @param resolution the resolution status + * @return a new projectile with the suggested resolution status, or the original projectile + */ + def Resolve(resolution : ProjectileResolution.Value) : Projectile = { + resolution match { + case ProjectileResolution.Unresolved => + this + case _ => + Projectile(profile, tool_def, shot_origin, shot_angle, resolution, fire_time, System.nanoTime) + } + } +} + +object Projectile { + /** the first projectile GUID used by all clients internally */ + final val BaseUID : Int = 40100 + /** all clients progress through 40100 to 40124 normally, skipping only for long-lived projectiles + * 40125 to 40149 are being reserved as a guard against undetected overflow */ + final val RangeUID : Int = 40150 + + /** + * Overloaded constructor for an `Unresolved` projectile. + * @param profile an explanation of the damage that can be performed by this discharge + * @param tool_def the weapon that caused this discharge + * @param shot_origin where the projectile started + * @param shot_angle in which direction the projectile was aimed when it was discharged + * @return the `Projectile` object + */ + def apply(profile : ProjectileDefinition, tool_def : ToolDefinition, shot_origin : Vector3, shot_angle : Vector3) : Projectile = { + Projectile(profile, tool_def, shot_origin, shot_angle, ProjectileResolution.Unresolved) + } +} diff --git a/common/src/main/scala/net/psforever/objects/ballistics/ProjectileResolution.scala b/common/src/main/scala/net/psforever/objects/ballistics/ProjectileResolution.scala new file mode 100644 index 00000000..5b9436c9 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/ballistics/ProjectileResolution.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.ballistics + +/** + * An `Enumeration` of outcomes regarding what actually happened to the projectile. + */ +object ProjectileResolution extends Enumeration { + type Type = Value + + val + Unresolved, //original basic non-resolution + MissedShot, //projectile did not encounter any collision object and was despawned + Resolved, //a general "projectile encountered something" status with a more specific resolution + Hit, //direct hit, one target + Splash, //area of effect damage, potentially multiple targets + Lash //lashing damage, potentially multiple targets + = Value +} diff --git a/common/src/main/scala/net/psforever/objects/ballistics/Projectiles.scala b/common/src/main/scala/net/psforever/objects/ballistics/Projectiles.scala new file mode 100644 index 00000000..45ed97d4 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/ballistics/Projectiles.scala @@ -0,0 +1,146 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.ballistics + +/** + * An `Enumeration` of all the projectile types in the game, paired with their object id as the `Value`. + */ +object Projectiles extends Enumeration { + final val bullet_105mm_projectile = Value(1) + final val bullet_12mm_projectile = Value(4) + final val bullet_12mm_projectileb = Value(5) + final val bullet_150mm_projectile = Value(7) + final val bullet_15mm_apc_projectile = Value(10) + final val bullet_15mm_projectile = Value(11) + final val bullet_20mm_apc_projectile = Value(17) + final val bullet_20mm_projectile = Value(18) + final val bullet_25mm_projectile = Value(20) + final val bullet_35mm_projectile = Value(22) + final val bullet_75mm_apc_projectile = Value(26) + final val bullet_75mm_projectile = Value(27) + final val bullet_9mm_AP_projectile = Value(30) + final val bullet_9mm_projectile = Value(31) + final val anniversary_projectilea = Value(58) + final val anniversary_projectileb = Value(59) + final val aphelion_immolation_cannon_projectile = Value(87) + final val aphelion_laser_projectile = Value(91) + final val aphelion_plasma_rocket_projectile = Value(99) + final val aphelion_ppa_projectile = Value(103) + final val aphelion_starfire_projectile = Value(108) + final val bolt_projectile = Value(147) + final val burster_projectile = Value(155) + final val chainblade_projectile = Value(176) + final val colossus_100mm_projectile = Value(181) + final val colossus_burster_projectile = Value(188) + final val colossus_chaingun_projectile = Value(193) + final val colossus_cluster_bomb_projectile = Value(197) + final val colossus_tank_cannon_projectile = Value(207) + final val comet_projectile = Value(210) + final val dualcycler_projectile = Value(266) + final val dynomite_projectile = Value(268) + final val energy_cell_projectile = Value(273) + final val energy_gun_nc_projectile = Value(277) + final val energy_gun_tr_projectile = Value(279) + final val energy_gun_vs_projectile = Value(281) + final val enhanced_energy_cell_projectile = Value(282) + final val enhanced_quasar_projectile = Value(283) + final val falcon_projectile = Value(286) + final val firebird_missile_projectile = Value(288) + final val flail_projectile = Value(296) + final val flamethrower_fireball = Value(302) + final val flamethrower_projectile = Value(303) + final val flux_cannon_apc_projectile = Value(305) + final val flux_cannon_thresher_projectile = Value(308) + final val fluxpod_projectile = Value(311) + final val forceblade_projectile = Value(325) + final val frag_cartridge_projectile = Value(328) + final val frag_cartridge_projectile_b = Value(329) + final val frag_grenade_projectile = Value(332) + final val frag_grenade_projectile_enh = Value(333) + final val galaxy_gunship_gun_projectile = Value(341) + final val gauss_cannon_projectile = Value(348) + final val grenade_projectile = Value(372) + final val heavy_grenade_projectile = Value(392) + final val heavy_rail_beam_projectile = Value(395) + final val heavy_sniper_projectile = Value(397) + final val hellfire_projectile = Value(400) + final val hunter_seeker_missile_dumbfire = Value(404) + final val hunter_seeker_missile_projectile = Value(405) + final val jammer_cartridge_projectile = Value(414) + final val jammer_cartridge_projectile_b = Value(415) + final val jammer_grenade_projectile = Value(418) + final val jammer_grenade_projectile_enh = Value(419) + final val katana_projectile = Value(422) + final val katana_projectileb = Value(423) + final val lancer_projectile = Value(427) + final val lasher_projectile = Value(430) + final val lasher_projectile_ap = Value(431) + final val liberator_bomb_cluster_bomblet_projectile = Value(436) + final val liberator_bomb_cluster_projectile = Value(437) + final val liberator_bomb_projectile = Value(438) + final val maelstrom_grenade_projectile = Value(465) + final val maelstrom_grenade_projectile_contact = Value(466) + final val maelstrom_stream_projectile = Value(467) + final val magcutter_projectile = Value(469) + final val melee_ammo_projectile = Value(541) + final val meteor_common = Value(543) + final val meteor_projectile_b_large = Value(544) + final val meteor_projectile_b_medium = Value(545) + final val meteor_projectile_b_small = Value(546) + final val meteor_projectile_large = Value(547) + final val meteor_projectile_medium = Value(548) + final val meteor_projectile_small = Value(549) + final val mine_projectile = Value(551) + final val mine_sweeper_projectile = Value(554) + final val mine_sweeper_projectile_enh = Value(555) + final val oicw_projectile = Value(602) + final val pellet_gun_projectile = Value(631) + final val peregrine_dual_machine_gun_projectile = Value(639) + final val peregrine_mechhammer_projectile = Value(647) + final val peregrine_particle_cannon_projectile = Value(654) + final val peregrine_rocket_pod_projectile = Value(657) + final val peregrine_sparrow_projectile = Value(661) + final val phalanx_av_projectile = Value(665) + final val phalanx_flak_projectile = Value(667) + final val phalanx_projectile = Value(669) + final val phoenix_missile_guided_projectile = Value(675) + final val phoenix_missile_projectile = Value(676) + final val plasma_cartridge_projectile = Value(678) + final val plasma_cartridge_projectile_b = Value(679) + final val plasma_grenade_projectile = Value(682) + final val plasma_grenade_projectile_B = Value(683) + final val pounder_projectile = Value(694) + final val pounder_projectile_enh = Value(695) + final val ppa_projectile = Value(696) + final val pulsar_ap_projectile = Value(702) + final val pulsar_projectile = Value(703) + final val quasar_projectile = Value(713) + final val radiator_grenade_projectile = Value(718) + final val radiator_sticky_projectile = Value(719) + final val reaver_rocket_projectile = Value(723) + final val rocket_projectile = Value(735) + final val rocklet_flak_projectile = Value(738) + final val rocklet_jammer_projectile = Value(739) + final val scattercannon_projectile = Value(746) + final val scythe_projectile = Value(748) + final val scythe_projectile_slave = Value(749) + final val shotgun_shell_AP_projectile = Value(757) + final val shotgun_shell_projectile = Value(758) + final val six_shooter_projectile = Value(763) + final val skyguard_flak_cannon_projectile = Value(787) + final val sparrow_projectile = Value(792) + final val sparrow_secondary_projectile = Value(793) + final val spiker_projectile = Value(818) + final val spitfire_aa_ammo_projectile = Value(821) + final val spitfire_ammo_projectile = Value(824) + final val starfire_projectile = Value(831) + final val striker_missile_projectile = Value(840) + final val striker_missile_targeting_projectile = Value(841) + final val trek_projectile = Value(878) + final val vanu_sentry_turret_projectile = Value(944) + final val vulture_bomb_projectile = Value(988) + final val vulture_nose_bullet_projectile = Value(989) + final val vulture_tail_bullet_projectile = Value(991) + final val wasp_gun_projectile = Value(999) + final val wasp_rocket_projectile = Value(1001) + final val winchester_projectile = Value(1005) +} diff --git a/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala new file mode 100644 index 00000000..892e0f21 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala @@ -0,0 +1,166 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.definition + +import net.psforever.objects.ballistics.{DamageProfile, DamageType, Projectiles} + +/** + * The definition that outlines the damage-dealing characteristics of any projectile. + * `Tool` objects emit `ProjectileDefinition` objects and that is later wrapped into a `Projectile` object. + * @param objectId the object's identifier number + */ +class ProjectileDefinition(objectId : Int) extends ObjectDefinition(objectId) with DamageProfile { + private val projectileType : Projectiles.Value = Projectiles(objectId) //let throw NoSuchElementException + private var damage0 : Int = 0 + private var damage1 : Option[Int] = None + private var damage2 : Option[Int] = None + private var damage3 : Option[Int] = None + private var damage4 : Option[Int] = None + private var acceleration : Int = 0 + private var accelerationUntil : Float = 0f + private var damageType : DamageType.Value = DamageType.None + private var damageTypeSecondary : DamageType.Value = DamageType.None + private var degradeDelay : Float = 1f + private var degradeMultiplier : Float = 1f + private var initialVelocity : Int = 1 + private var lifespan : Float = 1f + private var damageAtEdge : Float = 1f + private var damageRadius : Float = 1f + private var useDamage1Subtract : Boolean = false + Name = "projectile" + + def ProjectileType : Projectiles.Value = projectileType + + def UseDamage1Subtract : Boolean = useDamage1Subtract + + def UseDamage1Subtract_=(useDamage1Subtract : Boolean) : Boolean = { + this.useDamage1Subtract = useDamage1Subtract + UseDamage1Subtract + } + + def Damage0 : Int = damage0 + + def Damage0_=(damage : Int) : Int = { + damage0 = damage + damage0 + } + + def Damage0_=(damage : Option[Int]) : Int = { + damage0 = damage match { + case Some(value) => value + case None => 0 //can not be set to None + } + Damage0 + } + + def Damage1 : Int = damage1.getOrElse(Damage0) + + def Damage1_=(damage : Int) : Int = Damage1_=(Some(damage)) + + def Damage1_=(damage : Option[Int]) : Int = { + this.damage1 = damage + Damage1 + } + + def Damage2 : Int = damage2.getOrElse(Damage1) + + def Damage2_=(damage : Int) : Int = Damage2_=(Some(damage)) + + def Damage2_=(damage : Option[Int]) : Int = { + this.damage2 = damage + Damage2 + } + + def Damage3 : Int = damage3.getOrElse(Damage2) + + def Damage3_=(damage : Int) : Int = Damage3_=(Some(damage)) + + def Damage3_=(damage : Option[Int]) : Int = { + this.damage3 = damage + Damage3 + } + + def Damage4 : Int = damage4.getOrElse(Damage3) + + def Damage4_=(damage : Int) : Int = Damage4_=(Some(damage)) + + def Damage4_=(damage : Option[Int]) : Int = { + this.damage4 = damage + Damage4 + } + + def Acceleration : Int = acceleration + + def Acceleration_=(accel : Int) : Int = { + acceleration = accel + Acceleration + } + + def AccelerationUntil : Float = accelerationUntil + + def AccelerationUntil_=(accelUntil : Float) : Float = { + accelerationUntil = accelUntil + AccelerationUntil + } + + def ProjectileDamageType : DamageType.Value = damageType + + def ProjectileDamageType_=(damageType1 : DamageType.Value) : DamageType.Value = { + damageType = damageType1 + ProjectileDamageType + } + + def ProjectileDamageTypeSecondary : DamageType.Value = damageTypeSecondary + + def ProjectileDamageTypeSecondary_=(damageTypeSecondary1 : DamageType.Value) : DamageType.Value = { + damageTypeSecondary = damageTypeSecondary1 + ProjectileDamageTypeSecondary + } + + def DegradeDelay : Float = degradeDelay + + def DegradeDelay_=(degradeDelay : Float) : Float = { + this.degradeDelay = degradeDelay + DegradeDelay + } + + def DegradeMultiplier : Float = degradeMultiplier + + def DegradeMultiplier_=(degradeMultiplier : Float) : Float = { + this.degradeMultiplier = degradeMultiplier + DegradeMultiplier + } + + def InitialVelocity : Int = initialVelocity + + def InitialVelocity_=(initialVelocity : Int) : Int = { + this.initialVelocity = initialVelocity + InitialVelocity + } + + def Lifespan : Float = lifespan + + def Lifespan_=(lifespan : Float) : Float = { + this.lifespan = lifespan + Lifespan + } + + def DamageAtEdge : Float = damageAtEdge + + def DamageAtEdge_=(damageAtEdge : Float) : Float = { + this.damageAtEdge = damageAtEdge + DamageAtEdge + } + + def DamageRadius : Float = damageRadius + + def DamageRadius_=(damageRadius : Float) : Float = { + this.damageRadius = damageRadius + DamageRadius + } +} + +object ProjectileDefinition { + def apply(projectileType : Projectiles.Value) : ProjectileDefinition = { + new ProjectileDefinition(projectileType.id) + } +} diff --git a/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala index c6a06676..571f2431 100644 --- a/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala @@ -8,12 +8,15 @@ import scala.collection.mutable class ToolDefinition(objectId : Int) extends EquipmentDefinition(objectId) { private val ammoTypes : mutable.ListBuffer[AmmoBoxDefinition] = new mutable.ListBuffer[AmmoBoxDefinition] + private val projectileTypes : mutable.ListBuffer[ProjectileDefinition] = new mutable.ListBuffer[ProjectileDefinition] private val fireModes : mutable.ListBuffer[FireModeDefinition] = new mutable.ListBuffer[FireModeDefinition] Name = "tool" Packet = ToolDefinition.converter def AmmoTypes : mutable.ListBuffer[AmmoBoxDefinition] = ammoTypes + def ProjectileTypes : mutable.ListBuffer[ProjectileDefinition] = projectileTypes + def FireModes : mutable.ListBuffer[FireModeDefinition] = fireModes def NextFireModeIndex(index : Int) : Int = index + 1 diff --git a/common/src/main/scala/net/psforever/objects/entity/SimpleWorldEntity.scala b/common/src/main/scala/net/psforever/objects/entity/SimpleWorldEntity.scala index 704dab21..de2c96c0 100644 --- a/common/src/main/scala/net/psforever/objects/entity/SimpleWorldEntity.scala +++ b/common/src/main/scala/net/psforever/objects/entity/SimpleWorldEntity.scala @@ -4,8 +4,8 @@ package net.psforever.objects.entity import net.psforever.types.Vector3 class SimpleWorldEntity extends WorldEntity { - private var coords : Vector3 = Vector3(0f, 0f, 0f) - private var orient : Vector3 = Vector3(0f, 0f, 0f) + private var coords : Vector3 = Vector3.Zero + private var orient : Vector3 = Vector3.Zero private var vel : Option[Vector3] = None def Position : Vector3 = coords diff --git a/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala b/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala index 631e5e40..50ae85ba 100644 --- a/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala @@ -2,24 +2,30 @@ package net.psforever.objects.equipment import net.psforever.objects.Tool +import net.psforever.objects.ballistics.DamageProfile import scala.collection.mutable class FireModeDefinition { - /** indices pointing to all ammo types used */ + /** indices pointing to all ammo types used, in (an) order + * the ammo types list will be available from the `ToolDefinition` */ private val ammoTypeIndices : mutable.ListBuffer[Int] = mutable.ListBuffer[Int]() + /** custom indices pointing to the projectile type used for this mode's ammo types + * for most weapon fire modes, this list will be empty and the projectile will align with the `ammoTypeIndex` + * if at least one ammo type has a redirected projectile type, all projectiles must be defined for this mode */ + private val projectileTypeIndices : mutable.ListBuffer[Int] = mutable.ListBuffer[Int]() /** ammunition slot number this fire mode utilizes */ private var ammoSlotIndex : Int = 0 /** how many rounds are replenished each reload cycle */ private var magazine : Int = 1 /** how much is subtracted from the magazine each fire cycle; - * most weapons will only fire 1 round per fire cycle; the flamethrower, fire mode 1, fires 50 */ + * most weapons will only fire 1 round per fire cycle; the flamethrower in fire mode 1 fires 50 */ private var rounds : Int = 1 /** how many sub-rounds are queued per round fired; * the flechette fires 8 pellets per shell and generates 8 fire reports before the ammo count goes down */ private var chamber : Int = 1 - - //damage modifiers will follow here ... ? + /** modifiers for each damage type */ + private val modifiers : DamageModifiers = new DamageModifiers def AmmoSlotIndex : Int = ammoSlotIndex @@ -34,6 +40,12 @@ class FireModeDefinition { ammoTypeIndices += index } + def ProjectileTypeIndices : mutable.ListBuffer[Int] = projectileTypeIndices + + def ProjectileTypeIndices_=(index : Int) : mutable.ListBuffer[Int] = { + projectileTypeIndices += index + } + def Magazine : Int = magazine def Magazine_=(inMagazine : Int) : Int = { @@ -55,6 +67,8 @@ class FireModeDefinition { Chamber } + def Modifiers : DamageModifiers = modifiers + /** * Shoot a weapon, remove an anticipated amount of ammunition. * @param weapon the weapon @@ -105,3 +119,46 @@ class InfiniteFireModeDefinition extends FireModeDefinition { */ override def Discharge(weapon : Tool) : Int = 1 } + +class DamageModifiers extends DamageProfile { + private var damage0 : Int = 0 + private var damage1 : Int = 0 + private var damage2 : Int = 0 + private var damage3 : Int = 0 + private var damage4 : Int = 0 + + def Damage0 : Int = damage0 + + def Damage0_=(damage : Int) : Int = { + damage0 = damage + Damage0 + } + + def Damage1 : Int = damage1 + + def Damage1_=(damage : Int) : Int = { + damage1 = damage + Damage1 + } + + def Damage2 : Int = damage2 + + def Damage2_=(damage : Int) : Int = { + damage2 = damage + Damage2 + } + + def Damage3 : Int = damage3 + + def Damage3_=(damage : Int) : Int = { + damage3 = damage + Damage3 + } + + def Damage4 : Int = damage4 + + def Damage4_=(damage : Int) : Int = { + damage4 = damage + Damage4 + } +} diff --git a/common/src/main/scala/net/psforever/objects/zones/Zone.scala b/common/src/main/scala/net/psforever/objects/zones/Zone.scala index 930ac574..a8b13aec 100644 --- a/common/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/common/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -3,7 +3,8 @@ package net.psforever.objects.zones import akka.actor.{ActorContext, ActorRef, Props} import akka.routing.RandomPool -import net.psforever.objects.{Avatar, PlanetSideGameObject, Player, Vehicle} +import net.psforever.objects.ballistics.Projectile +import net.psforever.objects._ import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.NumberPoolHub import net.psforever.objects.guid.actor.UniqueNumberSystem @@ -45,8 +46,6 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { private var accessor : ActorRef = ActorRef.noSender /** The basic support structure for the globally unique number system used by this `Zone`. */ private var guid : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(65536)) - guid.AddPool("environment", (0 to 3000).toList) //TODO tailer ro suit requirements of zone - guid.AddPool("dynamic", (3001 to 10000).toList).Selector = new RandomSelector //TODO unlump pools later; do not make too big /** A synchronized `List` of items (`Equipment`) dropped by players on the ground and can be collected again. */ private val equipmentOnGround : ListBuffer[Equipment] = ListBuffer[Equipment]() /** */ @@ -88,6 +87,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { def Init(implicit context : ActorContext) : Unit = { if(accessor == ActorRef.noSender) { implicit val guid : NumberPoolHub = this.guid //passed into builderObject.Build implicitly + SetupNumberPools() accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystem.AllocateNumberPoolActors(guid))), s"$Id-uns") ground = context.actorOf(Props(classOf[ZoneGroundActor], this, equipmentOnGround), s"$Id-ground") transport = context.actorOf(Props(classOf[ZoneVehicleActor], this, vehicles), s"$Id-vehicles") @@ -100,6 +100,25 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { } } + def SetupNumberPools() : Unit = { + guid.AddPool("environment", (0 to 3000).toList) //TODO tailor to suit requirements of zone + //TODO unlump pools later; do not make any single pool too big + guid.AddPool("dynamic", (3001 to 10000).toList).Selector = new RandomSelector //TODO all things will be registered here, for now + guid.AddPool("b", (10001 to 15000).toList).Selector = new RandomSelector + guid.AddPool("c", (15001 to 20000).toList).Selector = new RandomSelector + guid.AddPool("d", (20001 to 25000).toList).Selector = new RandomSelector + guid.AddPool("e", (25001 to 30000).toList).Selector = new RandomSelector + guid.AddPool("f", (30001 to 35000).toList).Selector = new RandomSelector + guid.AddPool("g", (35001 until 40100).toList).Selector = new RandomSelector + guid.AddPool("projectiles", (Projectile.BaseUID until Projectile.RangeUID).toList) + //TODO disabled temporarily to lighten load times + //guid.AddPool("h", (40150 to 45000).toList).Selector = new RandomSelector + //guid.AddPool("i", (45001 to 50000).toList).Selector = new RandomSelector + //guid.AddPool("j", (50001 to 55000).toList).Selector = new RandomSelector + //guid.AddPool("k", (55001 to 60000).toList).Selector = new RandomSelector + //guid.AddPool("l", (60001 to 65535).toList).Selector = new RandomSelector + } + /** * A reference to the primary `Actor` that governs this `Zone`. * @return an `ActorRef` @@ -150,10 +169,15 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { /** * Replace the current globally unique identifier system with a new one. * The replacement will not occur if the current system is populated or if its synchronized reference has been created. + * The primary use of this function should be testing. + * A warning will be issued. * @return synchronized reference to the globally unique identifier system */ def GUID(hub : NumberPoolHub) : Boolean = { if(actor == ActorRef.noSender && guid.Pools.map({case ((_, pool)) => pool.Count}).sum == 0) { + import org.fusesource.jansi.Ansi.Color.RED + import org.fusesource.jansi.Ansi.ansi + println(ansi().fgBright(RED).a(s"""Caution: replacement of the number pool system for zone $Id; function is for testing purposes only""").reset()) guid = hub true } @@ -162,6 +186,43 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { } } + /** + * Wraps around the globally unique identifier system to insert a new number pool. + * Throws exceptions for specific reasons if the pool can not be populated before the system has been started. + * @see `NumberPoolHub.AddPool` + * @param name the name of the pool + * @param pool the numbers that will belong to the pool + * @return `true`, if the new pool is created; + * `false`, if the new pool can not be created because the system has already been started + */ + def AddPool(name : String, pool : Seq[Int]) : Boolean = { + if(accessor == ActorRef.noSender) { + guid.AddPool(name, pool.toList) + true + } + else { + false + } + } + + /** + * Wraps around the globally unique identifier system to remove an existing number pool. + * Throws exceptions for specific reasons if the pool can not be removed before the system has been started. + * @see `NumberPoolHub.RemovePool` + * @param name the name of the pool + * @return `true`, if the new pool is un-made; + * `false`, if the new pool can not be removed because the system has already been started + */ + def RemovePool(name : String) : Boolean = { + if(accessor == ActorRef.noSender) { + guid.RemovePool(name) + true + } + else { + false + } + } + /** * Recover an object from the globally unique identifier system by the number that was assigned previously. * @param object_guid the globally unique identifier requested diff --git a/common/src/test/scala/objects/ActorTest.scala b/common/src/test/scala/objects/ActorTest.scala index cdb7ca00..6d37c315 100644 --- a/common/src/test/scala/objects/ActorTest.scala +++ b/common/src/test/scala/objects/ActorTest.scala @@ -3,11 +3,23 @@ package objects import akka.actor.ActorSystem import akka.testkit.{ImplicitSender, TestKit} +import com.typesafe.config.{ConfigFactory, ConfigValueFactory} import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} import org.specs2.specification.Scope -abstract class ActorTest(sys : ActorSystem = ActorSystem("system")) extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll { +abstract class ActorTest(sys : ActorSystem = ActorSystem("system", ConfigFactory.parseMap(ActorTest.LoggingConfig))) + extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll { override def afterAll { TestKit.shutdownActorSystem(system) } } + +object ActorTest { + import scala.collection.JavaConverters._ + private val LoggingConfig = Map( + "akka.loggers" -> List("akka.testkit.TestEventListener").asJava, + "akka.loglevel" -> "OFF", + "akka.stdout-loglevel" -> "OFF", + "akka.log-dead-letters" -> "OFF" + ).asJava +} diff --git a/common/src/test/scala/objects/BuildingTest.scala b/common/src/test/scala/objects/BuildingTest.scala index 72da3fab..e4c326b4 100644 --- a/common/src/test/scala/objects/BuildingTest.scala +++ b/common/src/test/scala/objects/BuildingTest.scala @@ -11,8 +11,10 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.PlanetSideGUID import net.psforever.types.PlanetSideEmpire import org.specs2.mutable.Specification +import services.ServiceManager +import services.galaxy.GalaxyService -import scala.concurrent.duration.Duration +import scala.concurrent.duration._ class AmenityTest extends Specification { class AmenityObject extends Amenity { @@ -122,15 +124,20 @@ class BuildingControl1Test extends ActorTest { } class BuildingControl2Test extends ActorTest { + ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService], "galaxy") + val bldg = Building(10, Zone.Nowhere, StructureType.Building) + bldg.Faction = PlanetSideEmpire.TR + bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test") + "Building Control" should { "convert and assert faction affinity on convert request" in { - val bldg = Building(10, Zone.Nowhere, StructureType.Building) - bldg.Faction = PlanetSideEmpire.TR - bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test") - assert(bldg.Faction == PlanetSideEmpire.TR) + expectNoMsg(250 milliseconds) + bldg.Actor ! "startup" + expectNoMsg(250 milliseconds) + assert(bldg.Faction == PlanetSideEmpire.TR) bldg.Actor ! FactionAffinity.ConvertFactionAffinity(PlanetSideEmpire.VS) - val reply = receiveOne(Duration.create(100, "ms")) + val reply = receiveOne(500 milliseconds) assert(reply.isInstanceOf[FactionAffinity.AssertFactionAffinity]) assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].obj == bldg) assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].faction == PlanetSideEmpire.VS) @@ -140,19 +147,25 @@ class BuildingControl2Test extends ActorTest { } class BuildingControl3Test extends ActorTest { + ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService], "galaxy") + val bldg = Building(10, Zone.Nowhere, StructureType.Building) + bldg.Faction = PlanetSideEmpire.TR + bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test") + val door1 = Door(GlobalDefinitions.door) + door1.GUID = PlanetSideGUID(1) + door1.Actor = system.actorOf(Props(classOf[DoorControl], door1), "door1-test") + val door2 = Door(GlobalDefinitions.door) + door2.GUID = PlanetSideGUID(2) + door2.Actor = system.actorOf(Props(classOf[DoorControl], door2), "door2-test") + bldg.Amenities = door2 + bldg.Amenities = door1 + "Building Control" should { "convert and assert faction affinity on convert request, and for each of its amenities" in { - val bldg = Building(10, Zone.Nowhere, StructureType.Building) - bldg.Faction = PlanetSideEmpire.TR - bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "building-test") - val door1 = Door(GlobalDefinitions.door) - door1.GUID = PlanetSideGUID(1) - door1.Actor = system.actorOf(Props(classOf[DoorControl], door1), "door1-test") - val door2 = Door(GlobalDefinitions.door) - door2.GUID = PlanetSideGUID(2) - door2.Actor = system.actorOf(Props(classOf[DoorControl], door2), "door2-test") - bldg.Amenities = door2 - bldg.Amenities = door1 + expectNoMsg(250 milliseconds) + bldg.Actor ! "startup" + expectNoMsg(250 milliseconds) + assert(bldg.Faction == PlanetSideEmpire.TR) assert(bldg.Amenities.length == 2) assert(bldg.Amenities.head == door2) diff --git a/common/src/test/scala/objects/EquipmentTest.scala b/common/src/test/scala/objects/EquipmentTest.scala index fe260a3e..caf8431b 100644 --- a/common/src/test/scala/objects/EquipmentTest.scala +++ b/common/src/test/scala/objects/EquipmentTest.scala @@ -236,6 +236,50 @@ class EquipmentTest extends Specification { obj.AmmoType mustEqual Ammo.rocket } + "projectile types and ammo types" in { + val suppressor_wep = Tool(suppressor) + suppressor_wep.ProjectileType mustEqual bullet_9mm_projectile.ProjectileType + suppressor_wep.NextAmmoType + suppressor_wep.ProjectileType mustEqual bullet_9mm_AP_projectile.ProjectileType + suppressor_wep.NextAmmoType + suppressor_wep.ProjectileType mustEqual bullet_9mm_projectile.ProjectileType + } + + "projectile types and fire modes" in { + val pulsar_wep = Tool(pulsar) + pulsar_wep.ProjectileType mustEqual pulsar_projectile.ProjectileType + pulsar_wep.NextFireMode + pulsar_wep.ProjectileType mustEqual pulsar_ap_projectile.ProjectileType + pulsar_wep.NextFireMode + pulsar_wep.ProjectileType mustEqual pulsar_projectile.ProjectileType + } + + "projectile types and fire modes / ammo types" in { + val punisher_wep = Tool(punisher) + punisher_wep.ProjectileType mustEqual bullet_9mm_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual bullet_9mm_AP_projectile.ProjectileType + + punisher_wep.NextFireMode + punisher_wep.ProjectileType mustEqual rocket_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual frag_cartridge_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual jammer_cartridge_projectile.ProjectileType + + punisher_wep.NextFireMode + punisher_wep.ProjectileType mustEqual bullet_9mm_AP_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual bullet_9mm_projectile.ProjectileType + + punisher_wep.NextFireMode + punisher_wep.ProjectileType mustEqual jammer_cartridge_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual plasma_cartridge_projectile.ProjectileType + punisher_wep.NextAmmoType + punisher_wep.ProjectileType mustEqual rocket_projectile.ProjectileType + } + "discharge (1)" in { val obj = Tool(GlobalDefinitions.punisher) obj.Magazine mustEqual 30 diff --git a/common/src/test/scala/objects/ProjectileTest.scala b/common/src/test/scala/objects/ProjectileTest.scala new file mode 100644 index 00000000..d28aba91 --- /dev/null +++ b/common/src/test/scala/objects/ProjectileTest.scala @@ -0,0 +1,198 @@ +// Copyright (c) 2017 PSForever +package objects + +import net.psforever.objects.{GlobalDefinitions, LocalProjectile, Tool} +import net.psforever.objects.ballistics.{DamageType, Projectile, ProjectileResolution, Projectiles} +import net.psforever.objects.definition.ProjectileDefinition +import net.psforever.types.Vector3 +import org.specs2.mutable.Specification + +class ProjectileTest extends Specification { + "LocalProjectile" should { + "construct" in { + val obj = new LocalProjectile() //since they're just placeholders, they only need to construct + obj.Definition.ObjectId mustEqual 0 + obj.Definition.Name mustEqual "projectile" + } + } + + "ProjectileDefinition" should { + "define (default)" in { + val obj = new ProjectileDefinition(31) //9mmbullet_projectile + + obj.ProjectileType mustEqual Projectiles.bullet_9mm_projectile + obj.ObjectId mustEqual 31 + obj.Damage0 mustEqual 0 + obj.Damage1 mustEqual 0 + obj.Damage2 mustEqual 0 + obj.Damage3 mustEqual 0 + obj.Damage4 mustEqual 0 + obj.Acceleration mustEqual 0 + obj.AccelerationUntil mustEqual 0f + obj.ProjectileDamageType mustEqual DamageType.None + obj.ProjectileDamageTypeSecondary mustEqual DamageType.None + obj.DegradeDelay mustEqual 1f + obj.DegradeMultiplier mustEqual 1f + obj.InitialVelocity mustEqual 1 + obj.Lifespan mustEqual 1f + obj.DamageAtEdge mustEqual 1f + obj.DamageRadius mustEqual 1f + obj.UseDamage1Subtract mustEqual false + } + + "define (custom)" in { + val obj = new ProjectileDefinition(31) //9mmbullet_projectile + obj.Damage0 = 2 + obj.Damage1 = 4 + obj.Damage2 = 8 + obj.Damage3 = 16 + obj.Damage4 = 32 + obj.Acceleration = 5 + obj.AccelerationUntil = 5.5f + obj.ProjectileDamageType = DamageType.Splash + obj.ProjectileDamageTypeSecondary = DamageType.Radiation + obj.DegradeDelay = 11.1f + obj.DegradeMultiplier = 22.2f + obj.InitialVelocity = 50 + obj.Lifespan = 11.2f + obj.DamageAtEdge = 3f + obj.DamageRadius = 3f + obj.UseDamage1Subtract = true + + obj.Damage0 mustEqual 2 + obj.Damage1 mustEqual 4 + obj.Damage2 mustEqual 8 + obj.Damage3 mustEqual 16 + obj.Damage4 mustEqual 32 + obj.Acceleration mustEqual 5 + obj.AccelerationUntil mustEqual 5.5f + obj.ProjectileDamageType mustEqual DamageType.Splash + obj.ProjectileDamageTypeSecondary mustEqual DamageType.Radiation + obj.DegradeDelay mustEqual 11.1f + obj.DegradeMultiplier mustEqual 22.2f + obj.InitialVelocity mustEqual 50 + obj.Lifespan mustEqual 11.2f + obj.DamageAtEdge mustEqual 3f + obj.DamageRadius mustEqual 3f + obj.UseDamage1Subtract mustEqual true + } + + "define (failure)" in { + Projectiles(31) mustEqual Projectiles.bullet_9mm_projectile + try { + ProjectileDefinition(Projectiles.bullet_9mm_projectile) //passes + } + catch { + case _ : NoSuchElementException => + ko + } + + Projectiles(2) must throwA[NoSuchElementException] + new ProjectileDefinition(2) must throwA[NoSuchElementException] + } + + "cascade damage values" in { + val obj = new ProjectileDefinition(31) //9mmbullet_projectile + obj.Damage4 = 32 + obj.Damage3 = 16 + obj.Damage2 = 8 + obj.Damage1 = 4 + obj.Damage0 = 2 + + //initial + obj.Damage4 mustEqual 32 + obj.Damage3 mustEqual 16 + obj.Damage2 mustEqual 8 + obj.Damage1 mustEqual 4 + obj.Damage0 mustEqual 2 + //negate Damage4 + obj.Damage4 = None + obj.Damage4 mustEqual 16 + obj.Damage3 mustEqual 16 + obj.Damage2 mustEqual 8 + obj.Damage1 mustEqual 4 + obj.Damage0 mustEqual 2 + //negate Damage3 + obj.Damage3 = None + obj.Damage4 mustEqual 8 + obj.Damage3 mustEqual 8 + obj.Damage2 mustEqual 8 + obj.Damage1 mustEqual 4 + obj.Damage0 mustEqual 2 + //negate Damage2 + obj.Damage2 = None + obj.Damage4 mustEqual 4 + obj.Damage3 mustEqual 4 + obj.Damage2 mustEqual 4 + obj.Damage1 mustEqual 4 + obj.Damage0 mustEqual 2 + //negate Damage1 + obj.Damage1 = None + obj.Damage4 mustEqual 2 + obj.Damage3 mustEqual 2 + obj.Damage2 mustEqual 2 + obj.Damage1 mustEqual 2 + obj.Damage0 mustEqual 2 + //negate Damage0 + obj.Damage0 = None + obj.Damage4 mustEqual 0 + obj.Damage3 mustEqual 0 + obj.Damage2 mustEqual 0 + obj.Damage1 mustEqual 0 + obj.Damage0 mustEqual 0 + //set Damage3, set Damage0 + obj.Damage3 = 13 + obj.Damage0 = 7 + obj.Damage4 mustEqual 13 + obj.Damage3 mustEqual 13 + obj.Damage2 mustEqual 7 + obj.Damage1 mustEqual 7 + obj.Damage0 mustEqual 7 + } + } + + "Projectile" should { + "construct" in { + val beamer_wep = Tool(GlobalDefinitions.beamer) + val projectile = beamer_wep.Projectile + val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f)) + + obj.profile mustEqual beamer_wep.Projectile + obj.tool_def mustEqual GlobalDefinitions.beamer + obj.shot_origin mustEqual Vector3(1.2f, 3.4f, 5.6f) + obj.shot_angle mustEqual Vector3(0.2f, 0.4f, 0.6f) + obj.resolution mustEqual ProjectileResolution.Unresolved + obj.fire_time <= System.nanoTime mustEqual true + obj.hit_time mustEqual 0 + } + + "resolve" in { + val beamer_wep = Tool(GlobalDefinitions.beamer) + val projectile = beamer_wep.Projectile + val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f)) + val obj2 = obj.Resolve(ProjectileResolution.MissedShot) + + obj.resolution mustEqual ProjectileResolution.Unresolved + obj.fire_time <= System.nanoTime mustEqual true + obj.hit_time mustEqual 0 + obj2.resolution mustEqual ProjectileResolution.MissedShot + obj2.fire_time == obj.fire_time mustEqual true + obj2.hit_time <= System.nanoTime mustEqual true + obj2.fire_time <= obj2.hit_time mustEqual true + } + + "resolve, with coordinates" in { + val beamer_wep = Tool(GlobalDefinitions.beamer) + val projectile = beamer_wep.Projectile + val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f)) + val obj2 = obj.Resolve(Vector3(7.2f, 8.4f, 9.6f), Vector3(1.2f, 1.4f, 1.6f), ProjectileResolution.Resolved) + + obj.resolution mustEqual ProjectileResolution.Unresolved + obj.current.Position mustEqual Vector3.Zero + obj.current.Orientation mustEqual Vector3.Zero + obj2.resolution mustEqual ProjectileResolution.Resolved + obj2.current.Position mustEqual Vector3(7.2f, 8.4f, 9.6f) + obj2.current.Orientation mustEqual Vector3(1.2f, 1.4f, 1.6f) + } + } +} diff --git a/common/src/test/scala/objects/ServerObjectBuilderTest.scala b/common/src/test/scala/objects/ServerObjectBuilderTest.scala index 49678d5f..dacd1e4e 100644 --- a/common/src/test/scala/objects/ServerObjectBuilderTest.scala +++ b/common/src/test/scala/objects/ServerObjectBuilderTest.scala @@ -170,6 +170,24 @@ class VehicleSpawnPadObjectBuilderTest extends ActorTest { } } +class LocalProjectileBuilderTest extends ActorTest { + import net.psforever.objects.LocalProjectile + "Local ProjectileBuilder" should { + "build" in { + val hub = ServerObjectBuilderTest.NumberPoolHub + val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, + LocalProjectile.Constructor), hub), "locker") + actor ! "!" + + val reply = receiveOne(Duration.create(1000, "ms")) + assert(reply.isInstanceOf[LocalProjectile]) + assert(reply.asInstanceOf[LocalProjectile].HasGUID) + assert(reply.asInstanceOf[LocalProjectile].GUID == PlanetSideGUID(1)) + assert(reply == hub(1).get) + } + } +} + class LockerObjectBuilderTest extends ActorTest { import net.psforever.objects.serverobject.mblocker.Locker "LockerObjectBuilder" should { diff --git a/common/src/test/scala/objects/VehicleSpawnPadTest.scala b/common/src/test/scala/objects/VehicleSpawnPadTest.scala index e2693030..f780a817 100644 --- a/common/src/test/scala/objects/VehicleSpawnPadTest.scala +++ b/common/src/test/scala/objects/VehicleSpawnPadTest.scala @@ -3,6 +3,7 @@ package objects import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe +import net.psforever.objects.ballistics.Projectile import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} import net.psforever.objects.serverobject.structures.StructureType @@ -323,10 +324,10 @@ object VehicleSpawnPadControlTest { import net.psforever.objects.Tool import net.psforever.types.CharacterGender - val zone = new Zone("test-zone", map, 0) + val zone = new Zone("test-zone", map, 0) { override def SetupNumberPools() = { } } val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy) val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool] - val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(3)) + val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5)) guid.AddPool("test-pool", (0 to 2).toList) guid.register(vehicle, "test-pool") guid.register(weapon, "test-pool") diff --git a/common/src/test/scala/objects/VehicleTest.scala b/common/src/test/scala/objects/VehicleTest.scala index 42a581ac..6875d4aa 100644 --- a/common/src/test/scala/objects/VehicleTest.scala +++ b/common/src/test/scala/objects/VehicleTest.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package objects -import akka.actor.{ActorSystem, Props} +import akka.actor.Props import net.psforever.objects._ import net.psforever.objects.definition.{SeatDefinition, VehicleDefinition} import net.psforever.objects.serverobject.mount.Mountable diff --git a/common/src/test/scala/objects/ZoneTest.scala b/common/src/test/scala/objects/ZoneTest.scala index 3804825d..234afa89 100644 --- a/common/src/test/scala/objects/ZoneTest.scala +++ b/common/src/test/scala/objects/ZoneTest.scala @@ -3,7 +3,7 @@ package objects import java.util.concurrent.atomic.AtomicInteger -import akka.actor.{Actor, ActorContext, ActorRef, Props} +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.entity.IdentifiableEntity import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.NumberPoolHub @@ -96,18 +96,15 @@ class ZoneTest extends Specification { "can have its unique identifier system changed if no objects were added to it" in { val zone = new Zone("home3", map13, 13) val guid1 : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100)) - guid1.AddPool("pool1", (0 to 50).toList) - guid1.AddPool("pool2", (51 to 75).toList) zone.GUID(guid1) mustEqual true + zone.AddPool("pool1", (0 to 50).toList) + zone.AddPool("pool2", (51 to 75).toList) val obj = new TestObject() guid1.register(obj, "pool2").isSuccess mustEqual true guid1.WhichPool(obj) mustEqual Some("pool2") - val guid2 : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(150)) - guid2.AddPool("pool3", (0 to 50).toList) - guid2.AddPool("pool4", (51 to 75).toList) - zone.GUID(guid2) mustEqual false + zone.GUID(new NumberPoolHub(new LimitedNumberSource(150))) mustEqual false } } } @@ -115,12 +112,54 @@ class ZoneTest extends Specification { class ZoneActorTest extends ActorTest { "Zone" should { "have an Actor" in { - val zone = new Zone("test", new ZoneMap("map6"), 1) + val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-actor") expectNoMsg(Duration.create(100, "ms")) assert(zone.Actor != ActorRef.noSender) } + "create new number pools before the Actor is started" in { + val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = { } } + zone.GUID(new NumberPoolHub(new LimitedNumberSource(10))) + assert( zone.AddPool("test1", 1 to 2) ) + + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-add-pool-actor") //note: not Init'd yet + assert( zone.AddPool("test2", 3 to 4) ) + } + + "remove existing number pools before the Actor is started" in { + val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = { } } + zone.GUID(new NumberPoolHub(new LimitedNumberSource(10))) + assert( zone.AddPool("test1", 1 to 2) ) + assert( zone.RemovePool("test1") ) + + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-remove-pool-actor") //note: not Init'd yet + assert( zone.AddPool("test2", 3 to 4) ) + assert( zone.RemovePool("test2") ) + } + + "refuse new number pools after the Actor is started" in { + val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = { } } + zone.GUID(new NumberPoolHub(new LimitedNumberSource(40150))) + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-add-pool-actor-init") + zone.Actor ! Zone.Init() + expectNoMsg(Duration.create(500, "ms")) + + assert( !zone.AddPool("test1", 1 to 2) ) + } + + "refuse to remove number pools after the Actor is started" in { + val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = { } } + + zone.GUID(new NumberPoolHub(new LimitedNumberSource(10))) + zone.AddPool("test", 1 to 2) + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-remove-pool-actor-init") + zone.Actor ! Zone.Init() + expectNoMsg(Duration.create(300, "ms")) + + assert( !zone.RemovePool("test") ) + } + "set up spawn groups based on buildings" in { val map6 = new ZoneMap("map6") { LocalBuilding(1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1)))) @@ -143,7 +182,7 @@ class ZoneActorTest extends ActorTest { ObjectToBuilding(5, 3) ObjectToBuilding(6, 3) } - val zone = new Zone("test", map6, 1) + val zone = new Zone("test", map6, 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-init") zone.Actor ! Zone.Init() expectNoMsg(Duration.create(300, "ms")) @@ -181,7 +220,7 @@ class ZoneActorTest extends ActorTest { LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) ObjectToBuilding(5, 3) } - val zone = new Zone("test", map6, 1) + val zone = new Zone("test", map6, 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-spawn") zone.Actor ! Zone.Init() expectNoMsg(Duration.create(300, "ms")) @@ -212,7 +251,7 @@ class ZoneActorTest extends ActorTest { LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) ObjectToBuilding(5, 3) } - val zone = new Zone("test", map6, 1) + val zone = new Zone("test", map6, 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-no-spawn") zone.Actor ! Zone.Init() expectNoMsg(Duration.create(300, "ms")) @@ -228,15 +267,13 @@ class ZoneActorTest extends ActorTest { } class ZonePopulationTest extends ActorTest { - val testNum = new AtomicInteger(1) - def TestName : String = s"test${testNum.getAndIncrement()}" - "ZonePopulationActor" should { "add new user to zones" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) assert(zone.Players.isEmpty) assert(zone.LivePlayers.isEmpty) @@ -248,9 +285,10 @@ class ZonePopulationTest extends ActorTest { } "remove user from zones" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() receiveOne(Duration.create(200, "ms")) //consume zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) @@ -263,11 +301,12 @@ class ZonePopulationTest extends ActorTest { } "associate user with a character" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) val player = Player(avatar) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) @@ -283,11 +322,12 @@ class ZonePopulationTest extends ActorTest { } "disassociate character from a user" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) val player = Player(avatar) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) zone.Population ! Zone.Population.Spawn(avatar, player) @@ -305,11 +345,12 @@ class ZonePopulationTest extends ActorTest { } "user tries to Leave, but still has an associated character" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) val player = Player(avatar) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(500, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) zone.Population ! Zone.Population.Spawn(avatar, player) @@ -329,12 +370,13 @@ class ZonePopulationTest extends ActorTest { } "user tries to Spawn a character, but an associated character already exists" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) val player1 = Player(avatar) val player2 = Player(avatar) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) zone.Population ! Zone.Population.Spawn(avatar, player1) @@ -355,11 +397,12 @@ class ZonePopulationTest extends ActorTest { } "user tries to Spawn a character, but did not Join first" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) val player = Player(avatar) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) assert(zone.Players.isEmpty) assert(zone.LivePlayers.isEmpty) @@ -373,10 +416,11 @@ class ZonePopulationTest extends ActorTest { } "user tries to Release a character, but did not Spawn a character first" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Population.Join(avatar) expectNoMsg(Duration.create(100, "ms")) @@ -394,11 +438,12 @@ class ZonePopulationTest extends ActorTest { } "user adds character to list of retired characters" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) player.Release - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) assert(zone.Corpses.isEmpty) zone.Population ! Zone.Corpse.Add(player) @@ -408,11 +453,12 @@ class ZonePopulationTest extends ActorTest { } "user removes character from the list of retired characters" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) player.Release - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Corpse.Add(player) expectNoMsg(Duration.create(100, "ms")) @@ -424,15 +470,16 @@ class ZonePopulationTest extends ActorTest { } "user removes THE CORRECT character from the list of retired characters" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val player1 = Player(Avatar("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) player1.Release val player2 = Player(Avatar("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) player2.Release val player3 = Player(Avatar("Chord3", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) player3.Release - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), TestName) ! "!" - receiveOne(Duration.create(200, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) zone.Population ! Zone.Corpse.Add(player1) zone.Population ! Zone.Corpse.Add(player2) zone.Population ! Zone.Corpse.Add(player3) @@ -450,11 +497,12 @@ class ZonePopulationTest extends ActorTest { } "user tries to add character to list of retired characters, but is not in correct state" in { - val zone = new Zone("test", new ZoneMap(""), 0) + val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } } val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)) //player.Release !!important - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "testC") ! "!" - receiveOne(Duration.create(500, "ms")) //consume + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) assert(zone.Corpses.isEmpty) zone.Population ! Zone.Corpse.Add(player) @@ -468,9 +516,11 @@ class ZoneGroundDropItemTest extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "DropItem" should { "drop item on ground" in { @@ -492,9 +542,11 @@ class ZoneGroundCanNotDropItem1Test extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) //hub.register(item, 10) //!important - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "DropItem" should { "not drop an item that is not registered" in { @@ -516,9 +568,11 @@ class ZoneGroundCanNotDropItem2Test extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) //!important - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } //zone.GUID(hub) //!important - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "DropItem" should { "not drop an item that is not registered to the zone" in { @@ -540,9 +594,11 @@ class ZoneGroundCanNotDropItem3Test extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) //!important - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) //!important - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "DropItem" should { "not drop an item that has already been dropped" in { @@ -572,9 +628,11 @@ class ZoneGroundPickupItemTest extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "PickupItem" should { "pickup an item from ground" in { @@ -599,9 +657,11 @@ class ZoneGroundCanNotPickupItemTest extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) //still registered to this zone - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "PickupItem" should { "not pickup an item if it can not be found" in { @@ -622,9 +682,11 @@ class ZoneGroundRemoveItemTest extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) val hub = new NumberPoolHub(new LimitedNumberSource(20)) hub.register(item, 10) - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { } } zone.GUID(hub) //still registered to this zone - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-test-zone") ! "!" + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName) + zone.Actor ! Zone.Init() + expectNoMsg(200 milliseconds) "RemoveItem" should { "remove an item from the ground without callback (even if the item is not found)" in { @@ -646,12 +708,6 @@ class ZoneGroundRemoveItemTest extends ActorTest { } object ZoneTest { - class ZoneInitActor(zone : Zone) extends Actor { - def receive : Receive = { - case "!" => - zone.Init(context) - sender ! "!" - case _ => ; - } - } + val testNum = new AtomicInteger(1) + def TestName : String = s"test${testNum.getAndIncrement()}" } diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala index 803a6024..bf9ea192 100644 --- a/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala @@ -1,52 +1,17 @@ // Copyright (c) 2017 PSForever package objects.guidtask -import akka.actor.{Actor, ActorSystem, Props} import net.psforever.objects.guid.{GUIDTask, TaskResolver} -import org.specs2.mutable.Specification +import objects.ActorTest -import scala.concurrent.Await -import akka.pattern.ask -import akka.util.Timeout -import scala.concurrent.duration._ +class GUIDTaskRegister1Test extends ActorTest { + "RegisterObjectTask" in { + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = new GUIDTaskTest.TestObject -class GUIDTaskRegister1Test extends Specification { - "RegisterObjectTask" should { - "register (1)" in { - val system = ActorSystem("sys") - val test = system.actorOf(Props(classOf[GUIDTaskRegister1TestActor], system), "test") - - implicit val timeout = Timeout(5 seconds) - val future = test ? "test" - val result = Await.result(future, timeout.duration).asInstanceOf[String] - result mustEqual "success" - } + assert(!obj.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) } } - -private class GUIDTaskRegister1TestActor(implicit system : ActorSystem) extends Actor { - def receive : Receive = { - case "test" => - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = new GUIDTaskTest.TestObject - - assert(!obj.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - sender ! "success" - case _ => ; - } -} - -//class GUIDTaskRegister1Test extends ActorTest() { -// "RegisterObjectTask" in { -// val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup -// val obj = new GUIDTaskTest.TestObject -// -// assert(!obj.HasGUID) -// taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) -// probe.expectMsg(scala.util.Success) -// assert(obj.HasGUID) -// } -//} diff --git a/common/src/test/scala/objects/number/NumberPoolActorTest.scala b/common/src/test/scala/objects/number/NumberPoolActorTest.scala index e9596a0d..e4b8cf47 100644 --- a/common/src/test/scala/objects/number/NumberPoolActorTest.scala +++ b/common/src/test/scala/objects/number/NumberPoolActorTest.scala @@ -9,7 +9,7 @@ import objects.ActorTest import scala.concurrent.duration.Duration -class NumberPoolActorTest extends ActorTest(ActorSystem("test")) { +class NumberPoolActorTest extends ActorTest() { "NumberPoolActor" should { "GetAnyNumber" in { val pool = new ExclusivePool((25 to 50).toList) @@ -22,7 +22,7 @@ class NumberPoolActorTest extends ActorTest(ActorSystem("test")) { } } -class NumberPoolActorTest1 extends ActorTest(ActorSystem("test")) { +class NumberPoolActorTest1 extends ActorTest() { "NumberPoolActor" should { "GetSpecificNumber" in { val pool = new ExclusivePool((25 to 50).toList) @@ -34,7 +34,7 @@ class NumberPoolActorTest1 extends ActorTest(ActorSystem("test")) { } } -class NumberPoolActorTest2 extends ActorTest(ActorSystem("test")) { +class NumberPoolActorTest2 extends ActorTest() { "NumberPoolActor" should { "NoNumber" in { val pool = new ExclusivePool((25 to 25).toList) //pool only has one number - 25 diff --git a/pslogin/src/main/scala/Maps.scala b/pslogin/src/main/scala/Maps.scala index 911979b8..89d8d324 100644 --- a/pslogin/src/main/scala/Maps.scala +++ b/pslogin/src/main/scala/Maps.scala @@ -1,6 +1,8 @@ // Copyright (c) 2017 PSForever import net.psforever.objects.zones.ZoneMap import net.psforever.objects.GlobalDefinitions._ +import net.psforever.objects.LocalProjectile +import net.psforever.objects.ballistics.Projectile import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech import net.psforever.objects.serverobject.locks.IFFLock @@ -13,15 +15,25 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.types.Vector3 object Maps { - val map1 = new ZoneMap("map01") + val map1 = new ZoneMap("map01") { + Projectiles(this) + } - val map2 = new ZoneMap("map02") + val map2 = new ZoneMap("map02") { + Projectiles(this) + } - val map3 = new ZoneMap("map03") + val map3 = new ZoneMap("map03") { + Projectiles(this) + } - val map4 = new ZoneMap("map04") + val map4 = new ZoneMap("map04") { + Projectiles(this) + } - val map5 = new ZoneMap("map05") + val map5 = new ZoneMap("map05") { + Projectiles(this) + } val map6 = new ZoneMap("map06") { Building2() @@ -29,6 +41,7 @@ object Maps { Building42() Building48() Building49() + Projectiles(this) def Building2() : Unit = { //Anguta @@ -420,17 +433,29 @@ object Maps { } } - val map7 = new ZoneMap("map07") + val map7 = new ZoneMap("map07") { + Projectiles(this) + } - val map8 = new ZoneMap("map08") + val map8 = new ZoneMap("map08") { + Projectiles(this) + } - val map9 = new ZoneMap("map09") + val map9 = new ZoneMap("map09") { + Projectiles(this) + } - val map10 = new ZoneMap("map10") + val map10 = new ZoneMap("map10") { + Projectiles(this) + } - val map11 = new ZoneMap("map11") + val map11 = new ZoneMap("map11") { + Projectiles(this) + } - val map12 = new ZoneMap("map12") + val map12 = new ZoneMap("map12") { + Projectiles(this) + } val map13 = new ZoneMap("map13") { Building1() @@ -443,6 +468,7 @@ object Maps { Building77() Building79() Building81() + Projectiles(this) def Building1() : Unit = { //warpgate? @@ -716,29 +742,59 @@ object Maps { } } - val map14 = new ZoneMap("map14") + val map14 = new ZoneMap("map14") { + Projectiles(this) + } - val map15 = new ZoneMap("map15") + val map15 = new ZoneMap("map15") { + Projectiles(this) + } - val map16 = new ZoneMap("map16") + val map16 = new ZoneMap("map16") { + Projectiles(this) + } - val ugd01 = new ZoneMap("ugd01") + val ugd01 = new ZoneMap("ugd01") { + Projectiles(this) + } - val ugd02 = new ZoneMap("ugd02") + val ugd02 = new ZoneMap("ugd02") { + Projectiles(this) + } - val ugd03 = new ZoneMap("ugd03") + val ugd03 = new ZoneMap("ugd03") { + Projectiles(this) + } - val ugd04 = new ZoneMap("ugd04") + val ugd04 = new ZoneMap("ugd04") { + Projectiles(this) + } - val ugd05 = new ZoneMap("ugd05") + val ugd05 = new ZoneMap("ugd05") { + Projectiles(this) + } - val ugd06 = new ZoneMap("ugd06") + val ugd06 = new ZoneMap("ugd06") { + Projectiles(this) + } - val map96 = new ZoneMap("map96") + val map96 = new ZoneMap("map96") { + Projectiles(this) + } - val map97 = new ZoneMap("map97") + val map97 = new ZoneMap("map97") { + Projectiles(this) + } - val map98 = new ZoneMap("map98") + val map98 = new ZoneMap("map98") { + Projectiles(this) + } - val map99 = new ZoneMap("map99") + val map99 = new ZoneMap("map99") { + Projectiles(this) + } + + private def Projectiles(zmap : ZoneMap) : Unit = { + (Projectile.BaseUID until Projectile.RangeUID) foreach { zmap.LocalObject(_, LocalProjectile.Constructor) } + } } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 3897d94e..fae23dcb 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -53,6 +53,7 @@ import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.Success import akka.pattern.ask +import net.psforever.objects.ballistics.{Projectile, ProjectileResolution} class WorldSessionActor extends Actor with MDCContextAware { import WorldSessionActor._ @@ -84,6 +85,7 @@ class WorldSessionActor extends Actor with MDCContextAware { var traveler : Traveler = null var deadState : DeadState.Value = DeadState.Dead var whenUsedLastKit : Long = 0 + val projectiles : Array[Option[Projectile]] = Array.fill[Option[Projectile]](Projectile.RangeUID - Projectile.BaseUID)(None) var amsSpawnPoint : Option[SpawnTube] = None @@ -2586,7 +2588,6 @@ class WorldSessionActor extends Actor with MDCContextAware { else if((player.DrawnSlot = held_holsters) != before) { avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectHeld(player.GUID, player.LastDrawnSlot)) - // Ignore non-equipment holsters //todo: check current suit holster slots? if(held_holsters >= 0 && held_holsters < 5) { @@ -2598,7 +2599,6 @@ class WorldSessionActor extends Actor with MDCContextAware { } case None => ; } - } // Stop using proximity terminals if player unholsters a weapon (which should re-trigger the proximity effect and re-holster the weapon) @@ -2684,11 +2684,22 @@ class WorldSessionActor extends Actor with MDCContextAware { } } + case Some(_ : LocalProjectile) => + FindProjectileEntry(object_guid) match { + case Some(projectile) => + if(projectile.resolution != ProjectileResolution.Unresolved) { + log.warn(s"RequestDestroy: tried to clean up missed projectile ${object_guid.guid} but it was already resolved") + } + ResolveProjectileEntry(object_guid, ProjectileResolution.MissedShot) + case None => + log.warn(s"RequestDestroy: projectile ${object_guid.guid} has never been fired") + } + case Some(thing) => log.warn(s"RequestDestroy: not allowed to delete object $thing") case None => - log.warn(s"RequestDestroy: object $object_guid not found") + log.warn(s"RequestDestroy: object ${object_guid.guid} not found") } case msg @ ObjectDeleteMessage(object_guid, unk1) => @@ -3137,8 +3148,8 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ WeaponFireMessage(seq_time, weapon_guid, projectile_guid, shot_origin, unk1, unk2, unk3, unk4, unk5, unk6, unk7) => log.info("WeaponFire: " + msg) - FindWeapon match { - case Some(tool : Tool) => + FindContainedWeapon match { + case (Some(obj), Some(tool : Tool)) => if(tool.Magazine <= 0) { //safety: enforce ammunition depletion tool.Magazine = 0 sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, weapon_guid, 0)) @@ -3149,7 +3160,17 @@ class WorldSessionActor extends Actor with MDCContextAware { } else { //shooting tool.Discharge - //TODO other stuff? + val projectileIndex = projectile_guid.guid - Projectile.BaseUID + val ang = obj match { + case _ : Player => + obj.Orientation //TODO upper body facing + case _ : Vehicle => + tool.Orientation //TODO this is too simplistic + case _ => + Vector3.Zero + } + projectiles(projectileIndex) = + Some(Projectile(tool.Projectile, tool.Definition, shot_origin, ang)) } case _ => ; } @@ -3158,10 +3179,16 @@ class WorldSessionActor extends Actor with MDCContextAware { log.info("Lazing position: " + pos2.toString) case msg @ HitMessage(seq_time, projectile_guid, unk1, hit_info, unk2, unk3, unk4) => - log.info("Hit: " + msg) + log.info(s"Hit: $msg") + ResolveProjectileEntry(projectile_guid, ProjectileResolution.Hit) - case msg @ SplashHitMessage(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8) => - log.info("SplashHitMessage: " + msg) + case msg @ SplashHitMessage(seq_time, projectile_guid, explosion_pos, direct_victim_uid, unk3, projectile_vel, unk4, targets) => + log.info(s"Splash: $msg") + ResolveProjectileEntry(projectile_guid, ProjectileResolution.Splash) + + case msg @ LashMessage(seq_time, killer_guid, victim_guid, projectile_guid, pos, unk1) => + log.info(s"Lash: $msg") + ResolveProjectileEntry(projectile_guid, ProjectileResolution.Lash) case msg @ AvatarFirstTimeEventMessage(avatar_guid, object_guid, unk1, event_name) => log.info("AvatarFirstTimeEvent: " + msg) @@ -5229,6 +5256,62 @@ class WorldSessionActor extends Actor with MDCContextAware { } } + /** + * Given a globally unique identifier in the 40100 to 40124 range + * (with an optional 25 as buffer), + * find a projectile. + * @param projectile_guid the projectile's GUID + * @return the discovered projectile + */ + def FindProjectileEntry(projectile_guid : PlanetSideGUID) : Option[Projectile] = { + val index = projectile_guid.guid - Projectile.BaseUID + if(0 <= index && index < projectiles.length) { + projectiles(index) + } + else { + log.warn(s"ResolveProjectile: expected projectile, but ${projectile_guid.guid} not found") + None + } + } + + /** + * Find a projectile with the given globally unique identifier and mark it as a resolved shot. + * A `Resolved` shot has either encountered an obstacle or is being cleaned up for not finding an obstacle. + * @param projectile_guid the projectile GUID + * @param resolution the resolution status to promote the projectile + * @return the projectile + */ + def ResolveProjectileEntry(projectile_guid : PlanetSideGUID, resolution : ProjectileResolution.Value) : Option[Projectile] = { + FindProjectileEntry(projectile_guid) match { + case Some(projectile) => + val index = projectile_guid.guid - Projectile.BaseUID + ResolveProjectileEntry(projectile, index, resolution) + case None => + log.warn(s"ResolveProjectile: expected projectile, but ${projectile_guid.guid} not found") + None + } + } + + /** + * Find a projectile with the given globally unique identifier and mark it as a resolved shot. + * A `Resolved` shot has either encountered an obstacle or is being cleaned up for not finding an obstacle. + * The internal copy of the projectile is retained as merely `Resolved` + * while the observed projectile is promoted to the suggested resolution status. + * @param projectile the projectile object + * @param index where the projectile was found + * @param resolution the resolution status to promote the projectile + * @return a copy of the projectile + */ + def ResolveProjectileEntry(projectile : Projectile, index : Int, resolution : ProjectileResolution.Value) : Option[Projectile] = { + if(projectiles(index).contains(projectile)) { + projectiles(index) = Some(projectile.Resolve(ProjectileResolution.Resolved)) + Some(projectile.Resolve(resolution)) + } + else { + None + } + } + def failWithError(error : String) = { log.error(error) sendResponse(ConnectionClose()) diff --git a/pslogin/src/test/scala/ActorTest.scala b/pslogin/src/test/scala/ActorTest.scala index 116f6b21..c2e03982 100644 --- a/pslogin/src/test/scala/ActorTest.scala +++ b/pslogin/src/test/scala/ActorTest.scala @@ -2,17 +2,27 @@ import akka.actor.{ActorRef, ActorSystem, MDCContextAware} import akka.testkit.{ImplicitSender, TestKit, TestProbe} +import com.typesafe.config.{ConfigFactory, ConfigValueFactory} import net.psforever.packet.{ControlPacket, GamePacket} import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} import org.specs2.specification.Scope -abstract class ActorTest(sys : ActorSystem = ActorSystem("system")) extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll { +abstract class ActorTest(sys : ActorSystem = ActorSystem("system", ConfigFactory.parseMap(ActorTest.LoggingConfig))) + extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll { override def afterAll { TestKit.shutdownActorSystem(system) } } object ActorTest { + import scala.collection.JavaConverters._ + private val LoggingConfig = Map( + "akka.loggers" -> List("akka.testkit.TestEventListener").asJava, + "akka.loglevel" -> "OFF", + "akka.stdout-loglevel" -> "OFF", + "akka.log-dead-letters" -> "OFF" + ).asJava + final case class MDCGamePacket(packet : GamePacket) final case class MDCControlPacket(packet : ControlPacket) diff --git a/pslogin/src/test/scala/AvatarServiceTest.scala b/pslogin/src/test/scala/AvatarServiceTest.scala index 9d521c1b..993b02ba 100644 --- a/pslogin/src/test/scala/AvatarServiceTest.scala +++ b/pslogin/src/test/scala/AvatarServiceTest.scala @@ -384,7 +384,7 @@ Even with all this work, the tests have a high chance of failure just due to bei class AvatarReleaseTest extends ActorTest { ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver") val service = system.actorOf(Props[AvatarService], "release-test-service") - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } } val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver") zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone") zone.Actor ! Zone.Init() @@ -433,7 +433,7 @@ class AvatarReleaseTest extends ActorTest { class AvatarReleaseEarly1Test extends ActorTest { ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver") val service = system.actorOf(Props[AvatarService], "release-test-service") - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } } val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver") zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone") zone.Actor ! Zone.Init() @@ -483,7 +483,7 @@ class AvatarReleaseEarly1Test extends ActorTest { class AvatarReleaseEarly2Test extends ActorTest { ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver") val service = system.actorOf(Props[AvatarService], "release-test-service") - val zone = new Zone("test", new ZoneMap("test-map"), 0) + val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } } val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver") zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone") zone.Actor ! Zone.Init()