Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Naval and Smart missiles #6027

Merged
merged 5 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions data/libs/EquipType.lua
Original file line number Diff line number Diff line change
Expand Up @@ -548,13 +548,20 @@ local ThrusterType = utils.inherits(EquipType, "Equipment.ThrusterType")

--==============================================================================

---@class Equipment.MissileType : EquipType
---@field missile_stats table
local MissileType = utils.inherits(EquipType, "Equipment.MissileType")

--==============================================================================

Serializer:RegisterClass("EquipType", EquipType)
Serializer:RegisterClass("Equipment.LaserType", LaserType)
Serializer:RegisterClass("Equipment.HyperdriveType", HyperdriveType)
Serializer:RegisterClass("Equipment.SensorType", SensorType)
Serializer:RegisterClass("Equipment.BodyScannerType", BodyScannerType)
Serializer:RegisterClass("Equipment.CabinType", CabinType)
Serializer:RegisterClass("Equipment.ThrusterType", ThrusterType)
Serializer:RegisterClass("Equipment.MissileType", MissileType)

EquipType:SetupPrototype()
LaserType:SetupPrototype()
Expand All @@ -563,6 +570,7 @@ SensorType:SetupPrototype()
BodyScannerType:SetupPrototype()
CabinType:SetupPrototype()
ThrusterType:SetupPrototype()
MissileType:SetupPrototype()

return {
laser = laser,
Expand All @@ -575,4 +583,5 @@ return {
BodyScannerType = BodyScannerType,
CabinType = CabinType,
ThrusterType = ThrusterType,
MissileType = MissileType,
}
3 changes: 1 addition & 2 deletions data/libs/Ship.lua
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,10 @@ function Ship:FireMissileAt(missile, target)
-- FIXME: handle multiple-count missile mounts
equipSet:Remove(missile)

local missile_object = self:SpawnMissile(missile.missile_type)
local missile_object = self:SpawnMissile(missile.missile_stats, target)

if missile_object then
if target then
missile_object:AIKamikaze(target)
Event.Queue("onShipFiring", self)
end
-- Let's keep a safe distance before activating this device, shall we ?
Expand Down
6 changes: 6 additions & 0 deletions data/meta/CoreObject/Ship.meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,9 @@ function Ship:IsLanded() end
-- Get the starport this ship is docked with, if any
---@return SpaceStation?
function Ship:GetDockedWith() end

-- Spawn a new missile from this ship
---@param stats table Information about the missile to spawn. Must include a shipType: string field
---@param target Body? Optional body to target with the missile
---@return Body? missile The spawned missile if valid
function Ship:SpawnMissile(stats, target) end
32 changes: 20 additions & 12 deletions data/modules/Debug/DebugShip.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,19 @@ local templateOptions = {
}

local missileOptions = {
"Guided Missile",
"Unguided Missile",
"Smart Missile",
"Naval Missile"
"S1 Guided Missile",
"S1 Unguided Missile",
"S2 Guided Missile",
"S3 Smart Missile",
"S4 Naval Missile"
}

local missileTypes = {
"missile_guided",
"missile_unguided",
"missile_smart",
"missile_naval",
"missile.guided_s1",
"missile.unguided_s1",
"missile.guided_s2",
"missile.smart_s3",
"missile.naval_s4",
}

---@type HullConfig[]
Expand Down Expand Up @@ -221,15 +223,21 @@ end

function DebugShipTool:onSpawnMissile()

local missile_type = missileTypes[self.missileIdx]
local missile_type = require 'Equipment'.Get(missileTypes[self.missileIdx]) --[[@as Equipment.MissileType?]]

if missile_type ~= "missile_unguided" and not Game.player:GetCombatTarget() then
if not missile_type then
Notification.add(Notification.Type.Error, "No missile equipment {}" % { missileTypes[self.missileIdx] })
return
end

if missile_type.missile_stats.guided and not Game.player:GetCombatTarget() then
Notification.add(Notification.Type.Error, "Debug: no target for {}" % { missileOptions[self.missileIdx] })
return
end

local missile = Game.player:SpawnMissile(missile_type)
missile:AIKamikaze(Game.player:GetCombatTarget())
local missile = Game.player:SpawnMissile(missile_type.missile_stats, Game.player:GetCombatTarget())

if not missile then return end

Timer:CallAt(Game.time + 1, function()
if missile:exists() then
Expand Down
21 changes: 11 additions & 10 deletions data/modules/Equipment/Weapons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local Slot = require 'HullConfig'.Slot

local EquipType = EquipTypes.EquipType
local LaserType = EquipTypes.LaserType
local MissileType = EquipTypes.MissileType

--===============================================
-- Pulse Cannons
Expand Down Expand Up @@ -199,46 +200,46 @@ Equipment.Register("laser.miningcannon_17mw", LaserType.New {
-- Missiles
--===============================================

Equipment.Register("missile.unguided_s1", EquipType.New {
Equipment.Register("missile.unguided_s1", MissileType.New {
l10n_key="MISSILE_UNGUIDED",
price=30, purchasable=true, tech_level=1,
missile_type="missile_unguided",
missile_stats = { shipType="missile_unguided", guided=false, warheadSize=200.0, fuzeRadius=100.0, effectiveRadius=1000.0, chargeEffectiveness=1.0, ecmResist=5.0 },
volume=0, mass=0.045,
slot = { type="missile", size=1, hardpoint=true },
icon_name="equip_missile_unguided"
})
-- Approximately equivalent in size to an R60M / AA-8 'Aphid'
Equipment.Register("missile.guided_s1", EquipType.New {
Equipment.Register("missile.guided_s1", MissileType.New {
l10n_key="MISSILE_GUIDED",
price=45, purchasable=true, tech_level=5,
missile_type="missile_guided",
missile_stats = { shipType="missile_guided", guided=true, warheadSize=125.0, fuzeRadius=30.0, effectiveRadius=800.0, chargeEffectiveness=3.0, ecmResist=1.0 },
volume=0, mass=0.065,
slot = { type="missile", size=1, hardpoint=true },
icon_name="equip_missile_guided"
})
-- Approximately equivalent in size to an R73 / AA-11 'Archer'
Equipment.Register("missile.guided_s2", EquipType.New {
Equipment.Register("missile.guided_s2", MissileType.New {
l10n_key="MISSILE_GUIDED",
price=60, purchasable=true, tech_level=5,
missile_type="missile_guided",
missile_stats = { shipType="missile_guided", guided=true, warheadSize=200.0, fuzeRadius=40.0, effectiveRadius=1500.0, chargeEffectiveness=3.5, ecmResist=1.0 },
volume=0, mass=0.145,
slot = { type="missile", size=2, hardpoint=true },
icon_name="equip_missile_guided"
})
-- Approximately equivalent in size to an R77 / AA-12 'Adder'
Equipment.Register("missile.smart_s3", EquipType.New {
Equipment.Register("missile.smart_s3", MissileType.New {
l10n_key="MISSILE_SMART",
price=95, purchasable=true, tech_level=9,
missile_type="missile_smart",
missile_stats = { shipType="missile_smart", guided=true, warheadSize=320.0, fuzeRadius=35.0, effectiveRadius=2000.0, chargeEffectiveness=4.0, ecmResist=2.0 },
volume=0, mass=0.5,
slot = { type="missile", size=3, hardpoint=true },
icon_name="equip_missile_smart"
})
-- TBD
Equipment.Register("missile.naval_s4", EquipType.New {
Equipment.Register("missile.naval_s4", MissileType.New {
l10n_key="MISSILE_NAVAL",
price=160, purchasable=true, tech_level="MILITARY",
missile_type="missile_naval",
missile_stats = { shipType="missile_naval", guided=true, warheadSize=580.0, fuzeRadius=40.0, effectiveRadius=2000.0, chargeEffectiveness=4.5, ecmResist=3.0 },
volume=0, mass=1,
slot = { type="missile", size=4, hardpoint=true },
icon_name="equip_missile_naval"
Expand Down
56 changes: 31 additions & 25 deletions data/pigui/modules/equipment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
-- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt

local Engine = require 'Engine'
local Equipment = require 'Equipment'
local Game = require 'Game'
local utils = require 'utils'
local Event = require 'Event'
Expand Down Expand Up @@ -72,16 +73,9 @@ local function displayECM(uiPos)
return uiPos
end

local function getMissileIcon(missile)
if icons[missile.missile_type] then
return icons[missile.missile_type]
else
print("no icon for missile " .. missile.missile_type)
return icons.bullseye
end
end

local function fireMissile(missile)
---@param player Player
---@param missile Equipment.MissileType
local function fireMissile(player, missile)
if not player:GetCombatTarget() then
Game.AddCommsLogLine(lc.SELECT_A_TARGET, "", 1)
else
Expand All @@ -90,28 +84,40 @@ local function fireMissile(missile)
end

local function displayMissiles(uiPos)
player = Game.player
local current_view = Game.CurrentView()
if Game.CurrentView() == "WorldView" then

if current_view == "WorldView" then
local paused = Game.paused
local docked = Game.player:GetDockedWith()

local missiles = Game.player:GetComponent("EquipSet"):GetInstalledOfType("missile") --[[@as Equipment.MissileType[] ]]

local groups = utils.automagic()

local missiles = player:GetComponent("EquipSet"):GetInstalledOfType("missile")
local count = {}
local types = {}
for i, missile in ipairs(missiles) do
local group = groups[missile.id]

for i,missile in ipairs(missiles) do
count[missile.missile_type] = (count[missile.missile_type] or 0) + 1
types[missile.missile_type] = missile
group.count = (group.count or 0) + 1
group.size = missile.slot.size
group.proto = missile:GetPrototype()
group.index = i
end

for t,missile in pairs(types) do
local c = count[t]
local size,clicked = iconEqButton(uiPos, getMissileIcon(missile), true, mainWideIconSize, c, c == 0, mainBackgroundColor, mainForegroundColor, mainHoverColor, mainPressedColor, lec[missile.l10n_key])
local display = utils.build_array(pairs(groups))
table.sort(display, function(a, b) return
a.size < b.size or (a.size == b.size and (not a.guided and b.guided))
end)

for _, group in ipairs(display) do
local count = tostring(group.count)

-- TODO: slot size indicators should have a translated string at some point
local tooltip = "{} (S{})" % { group.proto:GetName(), group.size }
local size, clicked = iconEqButton(uiPos, icons[group.proto.icon_name], false, mainIconSize,
count, false, mainBackgroundColor, mainForegroundColor, mainHoverColor, mainPressedColor, tooltip)
uiPos.y = uiPos.y + size.y + 10

if clicked then
print("firing missile " .. t)
fireMissile(missile)
if clicked and not paused and not docked then
fireMissile(Game.player, missiles[group.index])
end
end

Expand Down
Loading