Skip to content

Commit

Permalink
Updated minefield/gate damage to apply leftover damage to tokens corr…
Browse files Browse the repository at this point in the history
…ectly

fixed issue where striking a minefield meant no movement
fixes sirgwain#463
  • Loading branch information
sirgwain committed Sep 28, 2024
1 parent a780677 commit b1193db
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 58 deletions.
21 changes: 10 additions & 11 deletions cs/fleet.go
Original file line number Diff line number Diff line change
Expand Up @@ -892,13 +892,8 @@ func (fleet *Fleet) moveFleet(rules *Rules, mapObjectGetter mapObjectGetter, pla
fleet.completeMove(mapObjectGetter, player, wp0, wp1)
} else {
// update what other people see for this fleet's speed and direction
if fleet.struckMineField {
fleet.WarpSpeed = 0
fleet.Heading = Vector{}
} else {
fleet.WarpSpeed = wp1.WarpSpeed
fleet.Heading = (wp1.Position.Subtract(fleet.Position)).Normalized()
}
fleet.WarpSpeed = wp1.WarpSpeed
fleet.Heading = (wp1.Position.Subtract(fleet.Position)).Normalized()

// move this fleet closer to the next waypoint
wp0.TargetType = MapObjectTypeNone
Expand All @@ -911,6 +906,11 @@ func (fleet *Fleet) moveFleet(rules *Rules, mapObjectGetter mapObjectGetter, pla
fleet.Position = fleet.Position.Round()
wp0.Position = fleet.Position

if fleet.struckMineField {
fleet.WarpSpeed = 0
fleet.Heading = Vector{}
}

// don't do any transport in mid space, reset this
if wp0.Task == WaypointTaskTransport {
wp0.Task = WaypointTaskNone
Expand Down Expand Up @@ -1072,10 +1072,9 @@ func (fleet *Fleet) applyOvergatePenalty(player *Player, rules *Rules, distance
token.Quantity--
i--
if token.QuantityDamaged > 0 {
// get rid of the damaged ships first and redistribute the damage
// i.e. if we have 2 damaged ships with 20 total damage
// we get rid of one of them and leave one with 10 damage
token.Damage = math.Max(0, token.Damage/float64(token.QuantityDamaged))
// get rid of the damaged ships first
// if we're out of damaged ships, reset our
// token damage to 0
token.QuantityDamaged--
// can't have damage without damaged ships
// I don't think this should ever come up
Expand Down
45 changes: 30 additions & 15 deletions cs/shiptoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cs

import "math"

// A Fleet contains multiple ShipTokens, each of which have a design and a quantity.
// A Fleet contains multiple ShipTokens, each of which have a design and a quantity.
type ShipToken struct {
DesignNum int `json:"designNum,omitempty"`
Quantity int `json:"quantity,omitempty"`
Expand Down Expand Up @@ -37,14 +37,17 @@ func (st *ShipToken) applyMineDamage(damage int) tokenDamage {
// if we took 100 damage, and we have 40 armor, we lose 2 tokens
// and have 20 leftover damage to spread across tokens
leftoverDamage := st.Damage - float64(tokensDestroyed*armor)
st.Damage = leftoverDamage
st.Damage = leftoverDamage / float64(st.Quantity)
st.QuantityDamaged = st.Quantity
}

return tokenDamage{damage: remainingDamage, shipsDestroyed: tokensDestroyed}
}

// Apply damage (if any) to each token that overgated
// in testing with overgating 12 scouts
// 479.5 ly with a 250ly gate
// 1st run 12@20% (12 with 4 damage each), subsequent runs damaged at 40, 60, 80, then destroyed all ships
func (st *ShipToken) applyOvergateDamage(dist float64, safeRange int, safeSourceMass int, safeDestMass int, maxMassFactor int) tokenDamage {
rangeDamageFactor := st.getStargateRangeDamageFactor(dist, safeRange)
massDamageFactor := st.getStargateMassDamageFactor(safeSourceMass, safeDestMass, maxMassFactor)
Expand All @@ -53,24 +56,36 @@ func (st *ShipToken) applyOvergateDamage(dist float64, safeRange int, safeSource

// apply damage as a percentage of armor to all tokens
armor := st.design.Spec.Armor
newDamage := int(math.Round(totalDamageFactor * float64(armor)))
st.QuantityDamaged = st.Quantity
st.Damage += float64(newDamage)
existingDamage := st.Damage

tokensDestroyed := int(math.Min(float64(st.Quantity), math.Floor(float64(st.Damage)/float64(armor))))
var tokensDestroyed int
damagePerShip := int(math.Round(totalDamageFactor * float64(armor)))

st.Quantity = st.Quantity - tokensDestroyed
if st.Quantity > 0 {
// Figure out how much damage we have leftover after destroying
// tokens. This will be applied to the rest of the tokens
// if we took 100 damage, and we have 40 armor, we lose 2 tokens
// and have 20 leftover damage to spread across tokens
leftoverDamage := st.Damage - float64(tokensDestroyed*armor)
st.Damage = leftoverDamage
// ships are never destroyed by overgating if they aren't already damaged
if existingDamage == 0 && damagePerShip >= armor {
damagePerShip = armor - 1
}

st.Damage += float64(damagePerShip)

if st.Damage >= float64(armor) {
// our damage exceeds our armor, destroy any previous damaged ships
tokensDestroyed = st.QuantityDamaged
st.Quantity -= st.QuantityDamaged
}

// apply overgate damage to any leftover tokens
if damagePerShip > 0 {
st.Damage = float64(damagePerShip)
st.QuantityDamaged = st.Quantity

if st.Quantity == 0 {
// can't damage something that isn't there
st.Damage = 0
}
}

return tokenDamage{newDamage, tokensDestroyed}
return tokenDamage{damagePerShip, tokensDestroyed}
}

func (t *ShipToken) getStargateRangeDamageFactor(dist float64, safeRange int) float64 {
Expand Down
Loading

0 comments on commit b1193db

Please sign in to comment.