Passed
Push — master ( bc69e6...465240 )
by Jakub
12:35
created

CombatBaseTest::testAssignPositions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 29
rs 9.472
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace HeroesofAbenez\Combat;
5
6
use Tester\Assert;
7
8
require __DIR__ . "/../../bootstrap.php";
9
10
/**
11
 * @author Jakub Konečný
12
 * @testCase
13
 */
14
final class CombatBaseTest extends \Tester\TestCase {
15
  protected CombatLogger $logger;
16
  
17
  use \Testbench\TCompiledContainer;
18
  
19
  public function setUp() {
20
    $this->logger = $this->getService(CombatLogger::class); // @phpstan-ignore assign.propertyType
21
  }
22
  
23
  protected function generateCharacter(int $id): Character {
24
    $stats = [
25
      "id" => $id, "name" => "Player $id", "level" => 1, "initiativeFormula" => "1d2+DEX/4", "strength" => 10,
26
      "dexterity" => 10, "constitution" => 10, "intelligence" => 10, "charisma" => 10
27
    ];
28
    $petStats = [
29
      "id" => $id, "deployed" => true, "bonusStat" => "strength", "bonusValue" => 10
30
    ];
31
    $weaponStats = [
32
      "id" => 1, "name" => "Novice sword", "slot" => Equipment::SLOT_WEAPON, "type" => Weapon::TYPE_SWORD,
33
      "strength" => 1, "worn" => true,
34
    ];
35
    $attackSkillStats = [
36
      "id" => 1, "name" => "Charge", "target" => SkillAttack::TARGET_SINGLE, "levels" => 5,
37
      "baseDamage" => "110%", "damageGrowth" => "5%", "strikes" => 1, "hitRate" => null,
38
    ];
39
    $specialSkillStats = [
40
      "id" => 1, "name" => "type", "target" => SkillSpecial::TARGET_SELF, "levels" => 5,
41
      "type" => SkillSpecial::TYPE_BUFF, "stat" => Character::STAT_DEFENSE, "value" => 15, "valueGrowth" => 3,
42
      "duration" => 3,
43
    ];
44
    $skills = [
45
      new CharacterAttackSkill(new SkillAttack($attackSkillStats), 1),
46
      new CharacterSpecialSkill(new SkillSpecial($specialSkillStats), 1),
47
    ];
48
    return new Character($stats, [new Weapon($weaponStats)], [new Pet($petStats)], $skills);
49
  }
50
  
51
  public function testInvalidStates(): void {
52
    $combat = new CombatBase(clone $this->logger);
53
    Assert::exception(function() use($combat) {
54
      $combat->execute();
55
    }, InvalidStateException::class);
56
    $combat->setTeams(new Team(""), new Team(""));
57
    Assert::exception(function() use($combat) {
58
      $combat->setTeams(new Team(""), new Team(""));
59
    }, ImmutableException::class);
60
  }
61
  
62
  public function testVictoryConditions(): void {
63
    $combat = new CombatBase(clone $this->logger);
64
    Assert::same([VictoryConditions::class, "moreDamage"], $combat->victoryCondition);
65
    $combat->victoryCondition = [VictoryConditions::class, "eliminateSecondTeam"];
66
    Assert::same([VictoryConditions::class, "eliminateSecondTeam"], $combat->victoryCondition);
67
  }
68
  
69
  public function testEffectProviders(): void {
70
    $character1 = $this->generateCharacter(1);
71
    $character2 = $this->generateCharacter(2);
72
    $provider = new EffectsProvider();
73
    $character1->effectProviders[] = $provider;
74
    Assert::same(50, $character1->maxHitpointsBase);
75
    Assert::same(50, $character1->maxHitpoints);
76
    Assert::same(50, $character1->hitpoints);
77
    $combat = new CombatBase(clone $this->logger);
78
    $combat->setDuelParticipants($character1, $character2);
79
    $combat->onRoundStart($combat);
80
    Assert::same(50, $character1->maxHitpointsBase);
81
    Assert::same(60, $character1->maxHitpoints);
82
    Assert::same(60, $character1->hitpoints);
83
    $provider->value = 1;
84
    $combat->onRoundStart($combat);
85
    Assert::same(50, $character1->maxHitpointsBase);
86
    Assert::same(51, $character1->maxHitpoints);
87
    Assert::same(51, $character1->hitpoints);
88
    $combat->onCombatEnd($combat);
89
    Assert::same(50, $character1->maxHitpointsBase);
90
    Assert::same(50, $character1->maxHitpoints);
91
    Assert::same(50, $character1->hitpoints);
92
  }
93
  
94
  public function testSuccessCalculator(): void {
95
    $combat = new CombatBase(clone $this->logger);
96
    Assert::type(RandomSuccessCalculator::class, $combat->successCalculator);
97
    $combat->successCalculator = new StaticSuccessCalculator();
98
    Assert::type(StaticSuccessCalculator::class, $combat->successCalculator);
99
  }
100
  
101
  public function testActionSelector(): void {
102
    $combat = new CombatBase(clone $this->logger);
103
    Assert::type(CombatActionSelector::class, $combat->actionSelector);
104
    $combat->actionSelector = new ActionSelector();
105
    Assert::type(ActionSelector::class, $combat->actionSelector);
106
  }
107
  
108
  public function testAssignPositions(): void {
109
    $combat = new CombatBase(clone $this->logger);
110
    $team1 = new Team("");
111
    $team1->maxRowSize = 2;
112
    $team1[] = $this->generateCharacter(1);
113
    $team1[0]->positionRow = $team1[0]->positionColumn = 1;
114
    $team1[] = $this->generateCharacter(2);
115
    $team1[] = $this->generateCharacter(3);
116
    $team1[] = $this->generateCharacter(4);
117
    $team2 = new Team("");
118
    $team2->maxRowSize = 2;
119
    $team2[] = $this->generateCharacter(5);
120
    $team2[] = $this->generateCharacter(6);
121
    $team2[] = $this->generateCharacter(7);
122
    $team2[] = $this->generateCharacter(8);
123
    $combat->setTeams($team1, $team2);
124
    $combat->assignPositions($combat);
125
    Assert::count(2, $team1->getItems(["positionRow" => 1]));
126
    Assert::count(2, $team1->getItems(["positionRow" => 2]));
127
    Assert::count(0, $team1->getItems(["positionRow" => 3]));
128
    Assert::count(2, $team1->getItems(["positionColumn" => 1]));
129
    Assert::count(2, $team1->getItems(["positionColumn" => 2]));
130
    Assert::count(0, $team1->getItems(["positionColumn" => 3]));
131
    Assert::count(2, $team2->getItems(["positionRow" => 1]));
132
    Assert::count(2, $team2->getItems(["positionRow" => 2]));
133
    Assert::count(0, $team2->getItems(["positionRow" => 3]));
134
    Assert::count(2, $team2->getItems(["positionColumn" => 1]));
135
    Assert::count(2, $team2->getItems(["positionColumn" => 2]));
136
    Assert::count(0, $team2->getItems(["positionColumn" => 3]));
137
  }
138
  
139
  public function testDecreaseEffectsDuration(): void {
140
    $combat = new CombatBase(clone $this->logger);
141
    $character1 = $this->generateCharacter(1);
142
    $character2 = $this->generateCharacter(2);
143
    $combat->setDuelParticipants($character1, $character2);
144
    Assert::count(0, $character1->effects);
145
    $effect = new CharacterEffect([
146
      "id" => "skillEffect", "type" => SkillSpecial::TYPE_STUN, "valueAbsolute" => false,
147
      "value" => 0, "duration" => 1, "stat" => "",
148
    ]);
149
    $character1->effects[] = $effect;
150
    Assert::count(1, $character1->effects);
151
    Assert::true($character1->hasStatus(Character::STATUS_STUNNED));
152
    $combat->decreaseEffectsDuration($combat);
153
    Assert::same(0, $effect->duration);
154
    $character1->recalculateStats();
155
    Assert::count(0, $character1->effects);
156
    Assert::false($character1->hasStatus(Character::STATUS_STUNNED));
157
  }
158
  
159
  public function testApplyPoison(): void {
160
    $combat = new CombatBase(clone $this->logger);
161
    $character1 = $this->generateCharacter(1);
162
    $character2 = $this->generateCharacter(2);
163
    $combat->setDuelParticipants($character1, $character2);
164
    $effect = new CharacterEffect([
165
      "id" => "skillEffect", "type" => SkillSpecial::TYPE_POISON, "valueAbsolute" => false,
166
      "value" => 5, "duration" => 1, "stat" => "",
167
    ]);
168
    $character1->effects[] = $effect;
169
    $character1->effects[] = $effect;
170
    Assert::same(50, $character1->hitpoints);
171
    $combat->applyPoison($combat);
172
    Assert::same(40, $character1->hitpoints);
173
  }
174
  
175
  public function testPostCombat(): void {
176
    $combat = new CombatBase(clone $this->logger);
177
    $combat->healers = function(Team $team1, Team $team2): Team {
178
      return Team::fromArray(array_merge($team1->toArray(), $team2->toArray()), "healers");
179
    };
180
    $character1 = $this->generateCharacter(1);
181
    $character2 = $this->generateCharacter(2);
182
    $combat->setDuelParticipants($character1, $character2);
183
    $combat->execute();
184
    Assert::same(31, $combat->round);
185
    Assert::same(5000, $combat->log->round);
186
    Assert::count(1, $combat->team1->getItems(["initiative" => 0]));
187
    Assert::count(1, $combat->team2->getItems(["initiative" => 0]));
188
  }
189
}
190
191
$test = new CombatBaseTest();
192
$test->run();
193
?>