Completed
Branch v1.x-dev (5c2708)
by Benjamin
04:14
created

RuleConfigBuilder::createStarPlayerInducement()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 27
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 22
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 27
ccs 21
cts 21
cp 1
crap 5
rs 9.2568
1
<?php
2
3
namespace Obblm\Core\Helper\Rule;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Criteria;
7
use Obblm\Core\Contracts\InducementInterface;
8
use Obblm\Core\Contracts\RosterInterface;
9
use Obblm\Core\Contracts\Rule\RuleBuilderInterface;
10
use Obblm\Core\Contracts\SkillInterface;
11
use Obblm\Core\Entity\Team;
12
use Obblm\Core\Exception\NotFoundKeyException;
13
use Obblm\Core\Helper\CoreTranslation;
14
use Obblm\Core\Helper\Rule\Config\ConfigResolver;
15
use Obblm\Core\Helper\Rule\Config\RuleConfigResolver;
16
use Obblm\Core\Helper\Rule\Inducement\Inducement;
17
use Obblm\Core\Helper\Rule\Inducement\InducementType;
18
use Obblm\Core\Helper\Rule\Inducement\MultipleStarPlayer;
19
use Obblm\Core\Helper\Rule\Inducement\StarPlayer;
20
use Obblm\Core\Helper\Rule\Roster\Roster;
21
use Obblm\Core\Helper\Rule\Skill\Skill;
22
23
class RuleConfigBuilder extends RuleConfigResolver implements RuleBuilderInterface
24
{
25
    /** @var ArrayCollection */
26
    private $injuries;
27
    /** @var ArrayCollection|Skill[] */
28
    private $skills;
29
    /** @var ArrayCollection|InducementType[] */
30
    private $inducementTypes;
31
    /** @var ArrayCollection */
32
    private $sppLevels;
33
    /** @var ArrayCollection|InducementInterface[] */
34
    private $inducements;
35
    /** @var ArrayCollection|RosterInterface[] */
36
    private $rosters;
37
38 1
    protected function build(string $ruleKey, array $rule)
39
    {
40 1
        $treeResolver = new ConfigResolver($this);
41 1
        $rule = $treeResolver->resolve($rule);
42 1
        $this->prepareInjuriesTable($ruleKey, $rule);
43 1
        $this->prepareSppTable($ruleKey, $rule);
44 1
        $this->prepareSkillsTable($ruleKey, $rule);
45 1
        $this->prepareInducementTypes($ruleKey);
46 1
        $this->prepareInducementTable($ruleKey, $rule);
47 1
        $this->prepareRosterTable($ruleKey, $rule);
48 1
    }
49
50
    public function getInjuries():ArrayCollection
51
    {
52
        return $this->injuries;
53
    }
54
55
    public function setInjuries(ArrayCollection $injuries):self
56
    {
57
        $this->injuries = $injuries;
58
        return $this;
59
    }
60
61 2
    public function getInducementTypes():ArrayCollection
62
    {
63 2
        return $this->inducementTypes;
64
    }
65
66
    public function setInducementTypes(ArrayCollection $inducementTypes):self
67
    {
68
        $this->inducementTypes = $inducementTypes;
69
        return $this;
70
    }
71
72 2
    public function getInducementType(string $type):InducementType
73
    {
74 2
        return $this->getInducementTypes()->get($type);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getInducementTypes()->get($type) could return the type null which is incompatible with the type-hinted return Obblm\Core\Helper\Rule\Inducement\InducementType. Consider adding an additional type-check to rule them out.
Loading history...
75
    }
76
77
    public function getSppLevels():ArrayCollection
78
    {
79
        return $this->sppLevels;
80
    }
81
82
    public function setSppLevels(ArrayCollection $sppLevels):self
83
    {
84
        $this->sppLevels = $sppLevels;
85
        return $this;
86
    }
87
88 2
    public function getInducementTable():ArrayCollection
89
    {
90 2
        return $this->inducements;
91
    }
92
93
    public function setInducementTable(ArrayCollection $inducements):self
94
    {
95
        $this->inducements = $inducements;
96
        return $this;
97
    }
98
99
    /** @return RosterInterface[]|ArrayCollection */
100 4
    public function getRosters():ArrayCollection
101
    {
102 4
        return $this->rosters;
103
    }
104
105 1
    public function getRoster(Team $team):RosterInterface
106
    {
107 1
        return $this->rosters->get($team->getRoster());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->rosters->get($team->getRoster()) could return the type null which is incompatible with the type-hinted return Obblm\Core\Contracts\RosterInterface. Consider adding an additional type-check to rule them out.
Loading history...
108
    }
109
110
    public function setRosters(ArrayCollection $rosters):self
111
    {
112
        $this->rosters = $rosters;
113
        return $this;
114
    }
115
116 2
    public function getSkills():ArrayCollection
117
    {
118 2
        return $this->skills;
119
    }
120
121
    public function getSkill($key):SkillInterface
122
    {
123
        $criteria = (Criteria::create())
124
            ->where(
125
                Criteria::expr()
126
                ->eq('key', $key)
127
            );
128
        $criteria->setMaxResults(1);
129
        $result = $this->getSkills()->matching($criteria);
130
        if (!$result->first()) {
131
            throw new NotFoundKeyException($key, 'skills', self::class);
132
        }
133
134
        return $result->first();
135
    }
136
137
    public function setSkills(ArrayCollection $skills):self
138
    {
139
        $this->skills = $skills;
140
        return $this;
141
    }
142
143 1
    private function prepareInjuriesTable(string $ruleKey, array $rule)
144
    {
145 1
        $this->injuries = new ArrayCollection();
146 1
        foreach ($rule['injuries'] as $key => $injury) {
147 1
            $label = CoreTranslation::getInjuryKey($ruleKey, $key);
148 1
            $effectLabel = CoreTranslation::getInjuryEffect($ruleKey, $key);
149 1
            if (isset($injury['to'])) {
150 1
                for ($i = $injury['from']; $i <= $injury['to']; $i++) {
151 1
                    $this->injuries->set(
152 1
                        $i,
153 1
                        (object) ['value' => $i, 'label' => $label, 'effect_label' => $effectLabel, 'effects' => $injury['effects']]
154
                    );
155
                }
156
            } else {
157 1
                $this->injuries->set(
158 1
                    $injury['from'],
159 1
                    (object) ['value' => $injury['from'], 'label' => $label, 'effect_label' => $effectLabel, 'effects' => $injury['effects']]
160
                );
161
            }
162
        }
163 1
    }
164
165 1
    private function prepareInducementTypes(string $ruleKey)
166
    {
167 1
        $this->inducementTypes = new ArrayCollection();
168 1
        $this->inducementTypes->set('star_players', new InducementType([
169 1
            'key' => 'star_players',
170 1
            'name' => CoreTranslation::getStarPlayerTitle($ruleKey),
171 1
            'translation_domain' => $ruleKey,
172
        ]));
173 1
        $this->inducementTypes->set('inducements', new InducementType([
174 1
            'key' => 'inducements',
175 1
            'name' => CoreTranslation::getInducementTitle($ruleKey),
176 1
            'translation_domain' => $ruleKey,
177
        ]));
178 1
        $this->inducementTypes->set('mercenary', new InducementType([
179 1
            'key' => 'mercenary',
180 1
            'name' => CoreTranslation::getMercenaryTitle($ruleKey),
181 1
            'translation_domain' => $ruleKey,
182
        ]));
183 1
    }
184
185 1
    private function prepareSppTable(string $ruleKey, array $rule)
186
    {
187 1
        $spps = new ArrayCollection($rule['spp_levels']);
188 1
        foreach ($spps as $from => $level) {
189 1
            $to = $spps->next();
190 1
            if ($to) {
191 1
                for ($i = $from; $i < $spps->indexOf($to); $i++) {
192 1
                    if (!isset($spps[$i])) {
193 1
                        $spps[$i] = $level;
194
                    }
195
                }
196
            }
197
        }
198 1
        $spps = $spps->toArray();
199 1
        ksort($spps);
200 1
        $this->sppLevels = new ArrayCollection($spps);
201 1
    }
202
203 1
    private function prepareSkillsTable(string $ruleKey, array $rule)
204
    {
205 1
        $this->skills = new ArrayCollection();
206 1
        foreach ($rule['skills'] as $type => $skills) {
207 1
            foreach ($skills as $skill) {
208 1
                $key = join(CoreTranslation::TRANSLATION_GLUE, [$type, $skill]);
209 1
                $this->skills->set(
210 1
                    $key,
211 1
                    new Skill([
212 1
                        'key'         => $skill,
213 1
                        'type'        => $type,
214 1
                        'name'        => CoreTranslation::getSkillNameKey($ruleKey, $skill),
215 1
                        'description' => CoreTranslation::getSkillDescription($ruleKey, $skill),
216 1
                        'type_name'   => CoreTranslation::getSkillType($ruleKey, $type),
217 1
                        'translation_domain'      => $ruleKey,
218
                    ])
219
                );
220
            }
221
        }
222 1
    }
223
224 1
    private function prepareInducementTable(string $ruleKey, array $rule)
225
    {
226 1
        $this->inducements = new ArrayCollection();
227
228 1
        foreach ($rule['inducements'] as $key => $value) {
229 1
            if ($key !== 'star_players') {
230 1
                $inducement = new Inducement([
231 1
                    'type' => $this->inducementTypes['inducements'],
232 1
                    'key' => join(CoreTranslation::TRANSLATION_GLUE, [$ruleKey, 'inducements', $key]),
233 1
                    'translation_domain' => $ruleKey,
234 1
                    'name' => CoreTranslation::getInducementName($ruleKey, $key),
235 1
                    'max' => $value['max'] ?? 0,
236 1
                    'rosters' => $value['rosters'] ?? null,
237 1
                    'value' => $value['cost'],
238 1
                    'discount_value' => $value['discount_cost'] ?? null,
239
                ]);
240 1
                if (!$this->inducements->contains($inducement)) {
241 1
                    $this->inducements->set($inducement->getKey(), $inducement);
242
                }
243
            }
244
        }
245 1
        foreach ($rule['star_players'] as $key => $starPlayer) {
246 1
            $inducement = $this->createStarPlayerInducement($ruleKey, $key, $starPlayer);
247 1
            if (!$this->inducements->contains($inducement)) {
248 1
                $this->inducements->set($inducement->getKey(), $inducement);
249
            }
250
        }
251 1
    }
252
253 1
    private function prepareRosterTable(string $ruleKey, array $rule)
254
    {
255 1
        $this->rosters = new ArrayCollection();
256 1
        foreach ($rule['rosters'] as $key => $roster) {
257 1
            $this->rosters->set(
258 1
                $key,
259 1
                new Roster([
260 1
                    'key' => $key,
261 1
                    'name' => CoreTranslation::getRosterKey($ruleKey, $key),
262 1
                    'translation_domain' => $ruleKey,
263 1
                    'player_types' => $roster['players'],
264 1
                    'reroll_cost' => $roster['reroll_cost'] ?? 0,
265 1
                    'can_have_apothecary' => $roster['options']['can_have_apothecary'] ?? true,
266 1
                    'inducement_options' => $roster['options']['inducements'] ?? [],
267
                ])
268
            );
269
        }
270 1
    }
271
272 1
    private function createStarPlayerInducement(string $ruleKey, string $key, array $starPlayer):InducementInterface
273
    {
274
        $options = [
275 1
            'type' => $this->inducementTypes['star_players'],
276 1
            'key' => join(CoreTranslation::TRANSLATION_GLUE, [$ruleKey, 'star_players', $key]),
277 1
            'value' => $starPlayer['cost'],
278 1
            'discount_value' => $starPlayer['discount_cost'] ?? null,
279 1
            'translation_domain' => $ruleKey,
280 1
            'name' => CoreTranslation::getStarPlayerName($ruleKey, $key),
281 1
            'max' => $starPlayer['max'] ?? 1,
282 1
            'characteristics' => $starPlayer['characteristics'] ?? null,
283 1
            'skills' => $starPlayer['skills'] ?? null,
284 1
            'rosters' => $starPlayer['rosters'] ?? null,
285
        ];
286 1
        if (isset($starPlayer['multi_parts']) && $starPlayer['multi_parts']) {
287 1
            $options['parts'] = [];
288 1
            $first = true;
289 1
            foreach ($starPlayer['multi_parts'] as $key => $part) {
290 1
                $part['cost'] = $first ? $starPlayer['cost'] : 0;
291 1
                $options['parts'][] = $this->createStarPlayerInducement($ruleKey, $key, $part);
292 1
                $first = false;
293
            }
294 1
            $inducement = new MultipleStarPlayer($options);
295
        } else {
296 1
            $inducement = new StarPlayer($options);
297
        }
298 1
        return $inducement;
299
    }
300
}
301