3626998a33
Eight ship-group operations land on the inspector behind a single inline-form panel: split, send, load, unload, modernize, dismantle, transfer, join fleet. Each action either appends a typed command to the local order draft or surfaces a tooltip explaining the disabled state. Partial-ship operations emit an implicit breakShipGroup command before the targeted action so the engine sees a clean (Break, Action) pair on the wire. `pkg/calc.BlockUpgradeCost` migrates from `game/internal/controller/ship_group_upgrade.go` so the calc bridge can wrap a pure pkg/calc formula; the controller now imports it. The bridge surfaces the function as `core.blockUpgradeCost`, which the inspector calls once per ship block to render the modernize cost preview. `GameReport.otherRaces` is decoded from the report's player block (non-extinct, ≠ self) and feeds the transfer-to-race picker. The planet inspector's stationed-ship rows become clickable for own groups so the actions panel is reachable from the standard click flow (the renderer continues to hide on-planet groups). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
97 lines
3.4 KiB
Go
97 lines
3.4 KiB
Go
package calc
|
|
|
|
import "math"
|
|
|
|
// Эффективность двигателя -
|
|
// равна мощности Двигателей, умноженной на технологический уровень блока Двигателей
|
|
func DriveEffective(drive, driveTech float64) float64 {
|
|
return drive * driveTech
|
|
}
|
|
|
|
// Масса перевозимого груза -
|
|
// общее количество единиц груза, деленное на технологический уровень Грузоперевозок
|
|
func CarryingMass(load, cargoTech float64) float64 {
|
|
if load <= 0 {
|
|
return 0
|
|
}
|
|
return load / cargoTech
|
|
}
|
|
|
|
// Грузоподъёмность одного корабля
|
|
func CargoCapacity(cargo, cargoTech float64) float64 {
|
|
return cargoTech * (cargo + (cargo*cargo)/20)
|
|
}
|
|
|
|
// Корабли перемещаются за один ход на количество световых лет, равное
|
|
// эффективности двигателя, умноженной на 20 и деленной на "Полную массу" корабля
|
|
func Speed(driveEffective, fullMass float64) float64 {
|
|
if fullMass <= 0 {
|
|
return 0
|
|
}
|
|
return driveEffective * 20 / fullMass
|
|
}
|
|
|
|
// Полная масса -
|
|
// массу корабля самого по себе плюс масса перевозимого груза
|
|
func FullMass(emptyMass, carryingMass float64) float64 {
|
|
return emptyMass + carryingMass
|
|
}
|
|
|
|
func EmptyMass(drive, weapons float64, armament uint, shields, cargo float64) (float64, bool) {
|
|
wm, ok := WeaponsBlockMass(weapons, armament)
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
return drive + shields + cargo + wm, true
|
|
}
|
|
|
|
func WeaponsBlockMass(weapons float64, armament uint) (float64, bool) {
|
|
if (armament == 0 && weapons != 0) || (armament != 0 && weapons == 0) {
|
|
return 0, false
|
|
}
|
|
return float64(armament+1) * (weapons / 2), true
|
|
}
|
|
|
|
// Стоимость модернизации одного блока корабля -
|
|
// доля недостающего технологического уровня (1 - currentBlockTech/targetBlockTech),
|
|
// умноженная на массу блока и нормирующий коэффициент 10.
|
|
// Возвращает 0, если масса блока равна нулю или целевой уровень не выше текущего.
|
|
func BlockUpgradeCost(blockMass, currentBlockTech, targetBlockTech float64) float64 {
|
|
if blockMass == 0 || targetBlockTech <= currentBlockTech {
|
|
return 0
|
|
}
|
|
return (1 - currentBlockTech/targetBlockTech) * 10 * blockMass
|
|
}
|
|
|
|
func DestructionProbability(
|
|
attackingWeapons,
|
|
attackingWeaponsTech,
|
|
defendingShields,
|
|
defendingShiledsTech,
|
|
defendingFullMass float64,
|
|
) float64 {
|
|
return DestructionProbabilityEffective(
|
|
EffectiveAttack(attackingWeapons, attackingWeaponsTech),
|
|
EffectiveDefence(defendingShields, defendingShiledsTech, defendingFullMass),
|
|
)
|
|
}
|
|
|
|
func DestructionProbabilityEffective(effectiveAttack, effectiveDefence float64) float64 {
|
|
return (math.Log10(effectiveAttack/effectiveDefence)/math.Log10(4) + 1) / 2
|
|
}
|
|
|
|
func EffectiveAttack(weapons, weaponsTech float64) float64 {
|
|
return weapons * weaponsTech
|
|
}
|
|
|
|
func EffectiveDefence(
|
|
defendingShields,
|
|
defendingShiledsTech,
|
|
defendingFullMass float64,
|
|
) float64 {
|
|
if defendingFullMass <= 0 {
|
|
return 0
|
|
}
|
|
return defendingShields * defendingShiledsTech / math.Pow(defendingFullMass, 1./3.) * math.Pow(30., 1./3.)
|
|
}
|