1 /*
2     SPDX-FileCopyrightText: 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "kapman.h"
8 
9 #include <KgDifficulty>
10 
11 const qreal Kapman::MAX_SPEED_RATIO = 1.5;
12 
Kapman(qreal p_x,qreal p_y,Maze * p_maze)13 Kapman::Kapman(qreal p_x, qreal p_y, Maze *p_maze) : Character(p_x, p_y, p_maze)
14 {
15     m_type = Element::KAPMAN;
16     m_maxSpeed = m_normalSpeed * MAX_SPEED_RATIO;
17 }
18 
~Kapman()19 Kapman::~Kapman()
20 {
21 
22 }
23 
init()24 void Kapman::init()
25 {
26     goRight();
27     updateDirection();
28     // Stop animation
29     Q_EMIT stopped();
30 }
31 
goUp()32 void Kapman::goUp()
33 {
34     m_askedXSpeed = 0;
35     m_askedYSpeed = -m_speed;
36 }
37 
goDown()38 void Kapman::goDown()
39 {
40     m_askedXSpeed = 0;
41     m_askedYSpeed = m_speed;
42 }
43 
goRight()44 void Kapman::goRight()
45 {
46     m_askedXSpeed = m_speed;
47     m_askedYSpeed = 0;
48 }
49 
goLeft()50 void Kapman::goLeft()
51 {
52     m_askedXSpeed = -m_speed;
53     m_askedYSpeed = 0;
54 }
55 
updateDirection()56 void Kapman::updateDirection()
57 {
58     setXSpeed(m_askedXSpeed);
59     setYSpeed(m_askedYSpeed);
60     m_askedXSpeed = 0;
61     m_askedYSpeed = 0;
62     // Signal to the kapman item that the direction changed
63     Q_EMIT directionChanged();
64 }
65 
updateMove()66 void Kapman::updateMove()
67 {
68     // If the kapman does not move
69     if (m_xSpeed == 0 && m_ySpeed == 0) {
70         // If the user asks for moving
71         if (m_askedXSpeed != 0 || m_askedYSpeed != 0) {
72             // Check the next cell with the asked direction
73             if (getAskedNextCell().getType() == Cell::CORRIDOR) {
74                 // Update the direction
75                 updateDirection();
76                 // Move the kapman
77                 move();
78             }
79         }
80     }
81     // If the kapman is already moving
82     else {
83         // If the kapman wants to go back it does not wait to be on a center
84         if ((m_xSpeed != 0 && m_askedXSpeed == -m_xSpeed) || (m_ySpeed != 0 && m_askedYSpeed == -m_ySpeed)) {
85             // Go back
86             updateDirection();
87             // If the kapman just turned at a corner and instantly makes a half-turn, do not run into a wall
88             if (isOnCenter() && getNextCell().getType() != Cell::CORRIDOR) {
89                 // Stop moving
90                 stopMoving();
91             } else {
92                 // Move the kapman
93                 move();
94             }
95         } else {
96             // If the kapman gets on a cell center
97             if (onCenter()) {
98                 // If there is an asked direction (not a half-turn) and the corresponding next cell is accessible
99                 if ((m_askedXSpeed != 0 || m_askedYSpeed != 0)
100                     && (m_askedXSpeed != m_xSpeed || m_askedYSpeed != m_ySpeed)
101                     && (getAskedNextCell().getType() == Cell::CORRIDOR)) {
102                     // Move the kapman on the cell center
103                     moveOnCenter();
104                     // Update the direction
105                     updateDirection();
106                 } else {
107                     // Check the next cell with the kapman current direction
108                     if (getNextCell().getType() != Cell::CORRIDOR) {
109                         // Move the kapman on the cell center
110                         moveOnCenter();
111                         // Stop moving
112                         stopMoving();
113                     } else {
114                         // Move the kapman
115                         move();
116                     }
117                 }
118             } else {
119                 // Move the kapman
120                 move();
121             }
122         }
123     }
124 }
125 
winPoints(Element * p_element)126 void Kapman::winPoints(Element *p_element)
127 {
128     // Emits a signal to the game
129     Q_EMIT sWinPoints(p_element);
130 }
131 
die()132 void Kapman::die()
133 {
134     Q_EMIT eaten();
135 }
136 
emitGameUpdated()137 void Kapman::emitGameUpdated()
138 {
139     Q_EMIT gameUpdated();
140 }
141 
getAskedXSpeed() const142 qreal Kapman::getAskedXSpeed() const
143 {
144     return m_askedXSpeed;
145 }
146 
getAskedYSpeed() const147 qreal Kapman::getAskedYSpeed() const
148 {
149     return m_askedYSpeed;
150 }
151 
getAskedNextCell()152 Cell Kapman::getAskedNextCell()
153 {
154     // Get the current cell coordinates from the character coordinates
155     int curCellRow = m_maze->getRowFromY(m_y);
156     int curCellCol = m_maze->getColFromX(m_x);
157     Cell nextCell;
158 
159     // Get the next cell function of the character asked direction
160     if (m_askedXSpeed > 0) {
161         nextCell = m_maze->getCell(curCellRow, curCellCol + 1);
162     } else if (m_askedXSpeed < 0) {
163         nextCell = m_maze->getCell(curCellRow, curCellCol - 1);
164     } else if (m_askedYSpeed > 0) {
165         nextCell = m_maze->getCell(curCellRow + 1, curCellCol);
166     } else if (m_askedYSpeed < 0) {
167         nextCell = m_maze->getCell(curCellRow - 1, curCellCol);
168     }
169 
170     return nextCell;
171 }
172 
stopMoving()173 void Kapman::stopMoving()
174 {
175     setXSpeed(0);
176     setYSpeed(0);
177     m_askedXSpeed = 0;
178     m_askedYSpeed = 0;
179     Q_EMIT stopped();
180 }
181 
initSpeedInc()182 void Kapman::initSpeedInc()
183 {
184     // Kapman speed increase when level up
185     switch ((int) Kg::difficultyLevel()) {
186     case KgDifficultyLevel::Easy:
187         m_speedIncrease = Character::LOW_SPEED_INC / 2;
188         break;
189     case KgDifficultyLevel::Medium:
190         m_speedIncrease = Character::MEDIUM_SPEED_INC / 2;
191         break;
192     case KgDifficultyLevel::Hard:
193         m_speedIncrease = Character::HIGH_SPEED_INC / 2;
194         break;
195     }
196 }
197