1 /***************************************************************************
2  *                     Copyright © 2020 - Arianne                          *
3  ***************************************************************************
4  ***************************************************************************
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 package games.stendhal.server.core.rp.achievement.fighting;
13 
14 import static games.stendhal.server.core.rp.achievement.factory.FightingAchievementFactory.ENEMIES_MERMAIDS;
15 import static games.stendhal.server.core.rp.achievement.factory.FightingAchievementFactory.ID_MERMAIDS;
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertFalse;
18 import static org.junit.Assert.assertNotNull;
19 import static org.junit.Assert.assertNull;
20 import static org.junit.Assert.assertTrue;
21 
22 import org.junit.AfterClass;
23 import org.junit.Before;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 
27 import games.stendhal.server.core.engine.SingletonRepository;
28 import games.stendhal.server.core.rp.achievement.AchievementNotifier;
29 import games.stendhal.server.entity.player.Player;
30 import games.stendhal.server.maps.MockStendlRPWorld;
31 import marauroa.server.game.db.DatabaseFactory;
32 import utilities.AchievementTestHelper;
33 import utilities.PlayerTestHelper;
34 
35 public class SerenadeTheSirenAchievementTest {
36 
37 	private static final AchievementNotifier notifier = SingletonRepository.getAchievementNotifier();
38 	private Player player;
39 	private final int reqCount = 10000;
40 
41 
42 	@BeforeClass
setUpBeforeClass()43 	public static void setUpBeforeClass() throws Exception {
44 		new DatabaseFactory().initializeDatabase();
45 		// initialize world
46 		MockStendlRPWorld.get();
47 		notifier.initialize();
48 	}
49 
50 	@Before
setUp()51 	public void setUp() {
52 		AchievementTestHelper.setEnemyNames(ENEMIES_MERMAIDS);
53 	}
54 
55 	@AfterClass
tearDownAfterClass()56 	public static void tearDownAfterClass() throws Exception {
57 		PlayerTestHelper.removeAllPlayers();
58 	}
59 
60 	@Test
init()61 	public void init() {
62 		resetPlayer();
63 		testAchievement();
64 	}
65 
testAchievement()66 	private void testAchievement() {
67 		// test with solo kills for each enemy
68 		for (final String enemy: ENEMIES_MERMAIDS) {
69 			for (int kills = 0; kills < reqCount; kills++) {
70 				kill(enemy, true);
71 
72 				if (kills >= reqCount - 1) {
73 					assertTrue(achievementReached());
74 				} else {
75 					assertFalse(achievementReached());
76 				}
77 			}
78 			assertEquals(reqCount, player.getSoloKill(enemy));
79 
80 			resetPlayer();
81 		}
82 
83 		// test with team kills for each enemy
84 		for (final String enemy: ENEMIES_MERMAIDS) {
85 			for (int kills = 0; kills < reqCount; kills++) {
86 				kill(enemy, false);
87 
88 				if (kills >= reqCount - 1) {
89 					assertTrue(achievementReached());
90 				} else {
91 					assertFalse(achievementReached());
92 				}
93 			}
94 			assertEquals(reqCount, player.getSharedKill(enemy));
95 
96 			resetPlayer();
97 		}
98 
99 		// test with mixed kills
100 		final int enemyTypes = ENEMIES_MERMAIDS.length;
101 		final double killsPerType = reqCount / enemyTypes / 2; // solo & team kills
102 
103 		for (int eType = 0; eType < enemyTypes; eType++) {
104 			for (int kill = 0; kill < killsPerType; kill++) {
105 				final String enemy = ENEMIES_MERMAIDS[eType];
106 
107 				kill(enemy, true);
108 				kill(enemy, false);
109 
110 				if (enemy.equals(ENEMIES_MERMAIDS[enemyTypes - 1]) && kill == killsPerType - 1) {
111 					assertTrue(achievementReached());
112 				} else {
113 					assertFalse(achievementReached());
114 				}
115 			}
116 		}
117 	}
118 
119 
120 	/**
121 	 * Resets player achievements & kills.
122 	 */
resetPlayer()123 	private void resetPlayer() {
124 		player = null;
125 		assertNull(player);
126 		player = PlayerTestHelper.createPlayer("player");
127 		assertNotNull(player);
128 
129 		for (final String enemy: ENEMIES_MERMAIDS) {
130 			assertFalse(player.hasKilledSolo(enemy));
131 			assertFalse(player.hasKilledShared(enemy));
132 		}
133 
134 		AchievementTestHelper.init(player);
135 		assertFalse(achievementReached());
136 	}
137 
138 	/**
139 	 * Checks if the player has reached the achievement.
140 	 *
141 	 * @return
142 	 * 		<code>true</player> if the player has the achievement.
143 	 */
achievementReached()144 	private boolean achievementReached() {
145 		return AchievementTestHelper.achievementReached(player, ID_MERMAIDS);
146 	}
147 
148 	/**
149 	 * Increments kill count for enemy.
150 	 *
151 	 * @param enemyName
152 	 * 		Name of enemy to kill.
153 	 * @param solo
154 	 * 		If <code>true</code>, player was not assisted in kill.
155 	 */
kill(final String enemyName, final boolean solo)156 	private void kill(final String enemyName, final boolean solo) {
157 		if (solo) {
158 			player.setSoloKillCount(enemyName, player.getSoloKill(enemyName) + 1);
159 		} else {
160 			player.setSharedKillCount(enemyName, player.getSharedKill(enemyName) + 1);
161 		}
162 
163 		notifier.onKill(player);
164 	}
165 }
166