• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DaniSomoza / galactic-commander / 15029782185

14 May 2025 07:52PM UTC coverage: 47.664% (-4.4%) from 52.086%
15029782185

Pull #12

github

web-flow
Merge d58e631f3 into a8e301a23
Pull Request #12: [fleets] Explore planets

216 of 930 branches covered (23.23%)

Branch coverage included in aggregate %.

162 of 529 new or added lines in 56 files covered. (30.62%)

10 existing lines in 9 files now uncovered.

1569 of 2815 relevant lines covered (55.74%)

3.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

17.95
/packages/game-engine/src/engine/tasks/processStartFleetTask.ts
1
import FleetModel from '../../models/FleetModel'
4✔
2
import { IPlanetDocument } from '../../models/PlanetModel'
3
import { IPlayerDocument } from '../../models/PlayerModel'
4
import { IPlayerUnitsDocument } from '../../models/PlayerUnitsModel'
5
import getTaskModel, { ITaskTypeDocument } from '../../models/TaskModel'
4✔
6
import fleetRepository from '../../repositories/fleetRepository'
4✔
7
import planetRepository from '../../repositories/planetRepository'
4✔
8
import playerRepository from '../../repositories/playerRepository'
4✔
9
import playerUnitsRepository from '../../repositories/playerUnitsRepository'
4✔
10
import {
4✔
11
  FINISH_FLEET_TASK_TYPE,
12
  FinishFleetTaskType,
13
  ITask,
14
  PENDING_TASK_STATUS,
15
  StartFleetTaskType
16
} from '../../types/ITask'
17
import computedBonus from '../bonus/computedBonus'
4✔
18
import GameEngineError from '../errors/GameEngineError'
4✔
19
import getAmountOfTroops from '../fleets/getAmountOfTroops'
4✔
20
import getFleetDuration from '../fleets/getFleetDuration'
4✔
21
import getFleetResourceCapacity from '../fleets/getFleetResourceCapacity'
4✔
22
import getFleetTroopsCapacity from '../fleets/getFleetTroopsCapacity'
4✔
23

24
async function processStartFleetTask(task: ITaskTypeDocument<StartFleetTaskType>, second: number) {
25
  // get all the required data from DB
NEW
26
  const player = await playerRepository.findPlayerById(task.data.playerId)
×
NEW
27
  const fromPlanet = await planetRepository.findPlanetById(task.data.fromPlanetId)
×
NEW
28
  const toPlanet = await planetRepository.findPlanetById(task.data.toPlanetId)
×
29

NEW
30
  if (!player) {
×
NEW
31
    throw new GameEngineError('invalid player')
×
32
  }
33

NEW
34
  if (!fromPlanet) {
×
NEW
35
    throw new GameEngineError('invalid from planet')
×
36
  }
37

NEW
38
  if (!toPlanet) {
×
NEW
39
    throw new GameEngineError('invalid to planet')
×
40
  }
41

NEW
42
  if (toPlanet._id.equals(fromPlanet._id)) {
×
NEW
43
    throw new GameEngineError('invalid planet')
×
44
  }
45

NEW
46
  const activePlayerFleets = await fleetRepository.findFleetsByPlayerId(player._id.toString())
×
47

NEW
48
  const maxPlayerFleets = computedBonus(player.perks, 'MAX_FLEETS_ALLOWED_BONUS')
×
49

NEW
50
  if (activePlayerFleets && activePlayerFleets.length > maxPlayerFleets) {
×
NEW
51
    throw new GameEngineError('invalid amount of active fleets')
×
52
  }
53

NEW
54
  const playerUnitsInThePlanet = await playerUnitsRepository.findPlayerUnitsInThePlanet(
×
55
    player._id.toString(),
56
    fromPlanet._id.toString()
57
  )
58

NEW
59
  if (!playerUnitsInThePlanet) {
×
NEW
60
    throw new GameEngineError('invalid units in the planet')
×
61
  }
62

63
  // units present in the planet and no defenses present
NEW
64
  const isInvalidFleetUnits = task.data.units.some(({ unit, amount }) => {
×
NEW
65
    const planetUnit = playerUnitsInThePlanet.units.find(
×
NEW
66
      (planetUnit) => planetUnit.unit.name === unit.name
×
67
    )
68

NEW
69
    return !planetUnit || amount > planetUnit.amount || unit.type === 'DEFENSE'
×
70
  })
71

NEW
72
  if (isInvalidFleetUnits) {
×
NEW
73
    throw new GameEngineError('invalid units in the planet')
×
74
  }
75

76
  // check troops capacity
NEW
77
  const troopsCapacity = getFleetTroopsCapacity(task.data.units)
×
NEW
78
  const amountOfTroops = getAmountOfTroops(task.data.units)
×
79

NEW
80
  if (amountOfTroops > troopsCapacity) {
×
NEW
81
    throw new GameEngineError('invalid amount of troops in the fleet')
×
82
  }
83

84
  // check resources
NEW
85
  if (task.data.resources > fromPlanet.resources) {
×
NEW
86
    throw new GameEngineError('invalid resources')
×
87
  }
88

NEW
89
  const fleetResourceCapacity = getFleetResourceCapacity(task.data.units)
×
90

NEW
91
  if (task.data.resources > fleetResourceCapacity) {
×
NEW
92
    throw new GameEngineError('invalid fleet resources capacity')
×
93
  }
94

NEW
95
  if (task.data.fleetType === 'EXPLORE_FLEET_TYPE') {
×
NEW
96
    return processStartExploreFleetTask({
×
97
      player,
98
      fromPlanet,
99
      toPlanet,
100
      taskData: task.data,
101
      second,
102
      playerUnitsInThePlanet
103
    })
104
  }
105

NEW
106
  throw 'fleet type not implemented'
×
107
}
108

109
export default processStartFleetTask
4✔
110

111
type StartExploreFleetType = {
112
  player: IPlayerDocument
113
  fromPlanet: IPlanetDocument
114
  toPlanet: IPlanetDocument
115
  taskData: ITask<'START_FLEET_UNITS_TASK'>['data']
116
  second: number
117
  playerUnitsInThePlanet: IPlayerUnitsDocument
118
}
119

120
async function processStartExploreFleetTask({
121
  player,
122
  fromPlanet,
123
  toPlanet,
124
  taskData,
125
  second,
126
  playerUnitsInThePlanet
127
}: StartExploreFleetType) {
NEW
128
  const fleetDuration = getFleetDuration(fromPlanet, toPlanet, taskData.units, player)
×
NEW
129
  const executeTaskAt = second + fleetDuration
×
130

131
  // update planet units
NEW
132
  taskData.units.forEach((fleetUnit) => {
×
NEW
133
    const planetUnit = playerUnitsInThePlanet.units.find(
×
NEW
134
      ({ unit }) => unit.name === fleetUnit.unit.name
×
135
    )
136

NEW
137
    planetUnit!.amount -= fleetUnit.amount
×
138
  })
139

NEW
140
  const newPlayerFleet = new FleetModel({
×
141
    playerId: player._id.toString(),
142
    units: taskData.units,
143
    isReturning: false,
144
    isFinished: false,
145
    fromPlanet,
146
    toPlanet,
147
    startedAt: second,
148
    arriveAt: executeTaskAt,
149
    duration: fleetDuration,
150
    fleetType: taskData.fleetType,
151
    resources: 0
152
  })
153

154
  // TODO: implement createBaseTask helper function
NEW
155
  const finishFleetTask: ITask<FinishFleetTaskType> = {
×
156
    type: FINISH_FLEET_TASK_TYPE,
157
    universeId: player.universeId,
158
    data: {
159
      playerId: player._id.toString(),
160
      fromPlanetId: fromPlanet._id.toString(),
161
      toPlanetId: toPlanet._id.toString(),
162
      units: taskData.units,
163
      resources: 0,
164
      fleetType: taskData.fleetType,
165
      allUnitsInThePlanet: false,
166
      allResourcesInThePlanet: false,
167
      isReturning: false,
168
      arriveAt: executeTaskAt,
169
      fleetId: newPlayerFleet._id.toString()
170
    },
171
    status: PENDING_TASK_STATUS,
172
    isCancellable: true,
173
    executeTaskAt,
174
    processedAt: null,
175
    processingDuration: null,
176
    history: [
177
      {
178
        taskStatus: PENDING_TASK_STATUS,
179
        updatedAt: new Date().getTime()
180
      }
181
    ],
182
    errorDetails: null
183
  }
NEW
184
  const taskModel = getTaskModel<FinishFleetTaskType>()
×
NEW
185
  const newTask = new taskModel(finishFleetTask)
×
186

NEW
187
  newPlayerFleet.taskId = newTask._id.toString()
×
188

NEW
189
  return Promise.all([
×
190
    newTask.save(),
191
    player.save(),
192
    playerUnitsInThePlanet.save(),
193
    newPlayerFleet.save(),
194
    fromPlanet.save()
195
  ])
196
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc