Skip to content

Commit d1d45d5

Browse files
committed
- Renamed ItemAction to BattleAction and made it a more general class.
- Added Projectile class. - Cleaned up the BattlescapeState class. - Draw the handob sprite on the unit. - Added handob and floorob setters/getters to RuleItem. - Minor stuff.
1 parent 16fd1c1 commit d1d45d5

28 files changed

Lines changed: 888 additions & 316 deletions

‎src/Battlescape/BattleAction.cpp‎

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
/*
2+
* Copyright 2010 OpenXcom Developers.
3+
*
4+
* This file is part of OpenXcom.
5+
*
6+
* OpenXcom 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 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* OpenXcom is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
#include "BattleAction.h"
20+
#include "Pathfinding.h"
21+
#include "Terrainmodifier.h"
22+
#include "Projectile.h"
23+
#include "../Savegame/BattleItem.h"
24+
#include "../Savegame/BattleUnit.h"
25+
#include "../Savegame/SavedBattleGame.h"
26+
#include "../Savegame/Tile.h"
27+
#include "../Resource/ResourcePack.h"
28+
#include "../Resource/XcomResourcePack.h"
29+
#include "../Engine/RNG.h"
30+
#include "../Engine/SoundSet.h"
31+
#include "../Engine/Sound.h"
32+
33+
34+
namespace OpenXcom
35+
{
36+
37+
/**
38+
* Sets up an BattleAction.
39+
* @param item pointer to the item object.
40+
*/
41+
BattleAction::BattleAction(SavedBattleGame *save, ResourcePack *res, BattleItem *item, BattleActionType type) : _save(save), _res(res), _item(item), _status(PENDING), _type(type), _result(""), _projectile(0)
42+
{
43+
44+
}
45+
46+
/**
47+
* Deletes the BattleAction.
48+
*/
49+
BattleAction::~BattleAction()
50+
{
51+
}
52+
53+
/**
54+
* Set the target.
55+
* todo: multiple targets are possible with blaster launchers, so we need list of targets here with add/remove
56+
*/
57+
void BattleAction::setTarget(const Position &target)
58+
{
59+
_target = target;
60+
}
61+
62+
/**
63+
* Start the action.
64+
* There has got to be a more elegant way to write this.
65+
*/
66+
void BattleAction::start()
67+
{
68+
if (_type == THROW)
69+
{
70+
71+
}
72+
else if (_type == AUTO_SHOT)
73+
{
74+
75+
}
76+
else if (_type == SNAP_SHOT)
77+
{
78+
79+
}
80+
else if (_type == AIMED_SHOT)
81+
{
82+
83+
}
84+
else if (_type == STUN)
85+
{
86+
87+
}
88+
else if (_type == HIT)
89+
{
90+
91+
}
92+
else if (_type == EXPLODE)
93+
{
94+
95+
}
96+
else if (_type == WALK)
97+
{
98+
Pathfinding *pf = _save->getPathfinding();
99+
pf->calculate(_save->getSelectedUnit(), _target);
100+
}
101+
else if (_type == TURN)
102+
{
103+
BattleUnit *unit = _save->getSelectedUnit();
104+
unit->lookAt(_target);
105+
if (unit->getStatus() != STATUS_TURNING)
106+
{
107+
unitOpensDoor(unit);
108+
_status = FINISHED;
109+
}
110+
}
111+
112+
113+
}
114+
115+
/**
116+
* moveBullet is triggered by a timer. It advances the projectile, until it hits something or flies out of the map.
117+
*/
118+
void BattleAction::moveBullet()
119+
{
120+
if (_projectile)
121+
{
122+
_projectile->move();
123+
}
124+
}
125+
126+
/**
127+
* moveUnit is triggered by a timer to advance unit movement.
128+
*/
129+
void BattleAction::moveUnit()
130+
{
131+
int tu = 0;
132+
BattleUnit *unit = _save->getSelectedUnit();
133+
Pathfinding *pf = _save->getPathfinding();
134+
135+
if (unit->getStatus() == STATUS_TURNING)
136+
{
137+
unit->turn(_type == TURN);
138+
_save->getTerrainModifier()->calculateFOV(unit);
139+
// if we finished turning and the action was to turn, the action is finished
140+
if (unit->getStatus() == STATUS_STANDING && _type == TURN)
141+
{
142+
_status = FINISHED;
143+
}
144+
}
145+
146+
// during a walking cycle we make step sounds
147+
if (unit->getStatus() == STATUS_WALKING)
148+
{
149+
// play footstep sound 1
150+
if (unit->getWalkingPhase() == 3)
151+
{
152+
Tile *tile = _save->getTile(unit->getPosition());
153+
if (tile->getFootstepSound())
154+
{
155+
_res->getSoundSet("BATTLE.CAT")->getSound(22 + (tile->getFootstepSound()*2))->play();
156+
}
157+
}
158+
// play footstep sound 2
159+
if (unit->getWalkingPhase() == 7)
160+
{
161+
Tile *tile = _save->getTile(unit->getPosition());
162+
if (tile->getFootstepSound())
163+
{
164+
_res->getSoundSet("BATTLE.CAT")->getSound(23 + (tile->getFootstepSound()*2))->play();
165+
}
166+
}
167+
168+
unit->keepWalking(); // advances the phase
169+
170+
// unit moved from one tile to the other, update the tiles
171+
if (unit->getPosition() != unit->getLastPosition())
172+
{
173+
_save->getTile(unit->getLastPosition())->setUnit(0);
174+
_save->getTile(unit->getPosition())->setUnit(unit);
175+
}
176+
177+
// is the walking cycle finished?
178+
if (unit->getStatus() == STATUS_STANDING)
179+
{
180+
_save->getTerrainModifier()->calculateFOV(unit);
181+
// if you want lighting to be calculated every step, uncomment next line
182+
//_save->getTerrainModifier()->calculateLighting();
183+
}
184+
}
185+
186+
// we are just standing around, shouldn't we be walking?
187+
if (unit->getStatus() == STATUS_STANDING)
188+
{
189+
int dir = pf->getStartDirection();
190+
if (dir != -1)
191+
{
192+
// we are looking in the wrong way, turn first
193+
if (dir != unit->getDirection())
194+
{
195+
unit->lookAt(dir);
196+
return;
197+
}
198+
199+
// now open doors (if any)
200+
if (unitOpensDoor(unit))
201+
{
202+
return; // don't start walking yet, wait for the ufo door to open
203+
}
204+
205+
// now start moving
206+
dir = pf->dequeuePath();
207+
Position destination;
208+
tu = pf->getTUCost(unit->getPosition(), dir, &destination, unit);
209+
unit->startWalking(dir, destination);
210+
}
211+
else
212+
{
213+
// no more waypoints, this means we succesfully finished this action
214+
_save->getTerrainModifier()->calculateUnitLighting();
215+
_status = FINISHED;
216+
}
217+
}
218+
}
219+
220+
/**
221+
* animate animates explosions and bullet impacts. Triggered by the animation timer.
222+
*/
223+
void BattleAction::animate()
224+
{
225+
226+
}
227+
228+
/**
229+
* Cancel the current action (if it was still pending) or try to abort the walking sequence.
230+
*/
231+
void BattleAction::cancel()
232+
{
233+
if (_status == INPROGRESS && _type == WALK)
234+
{
235+
_save->getPathfinding()->abortPath();
236+
}
237+
else if (_status == PENDING)
238+
{
239+
_status = FINISHED;
240+
}
241+
}
242+
243+
/*
244+
* Get the action result. Returns error messages or an empty string when everything went fine.
245+
* @return returnmessage Empty when everything is fine.
246+
*/
247+
std::string BattleAction::getResult() const
248+
{
249+
return _result;
250+
}
251+
252+
/**
253+
* Returns the action's status.
254+
* @return actionstatus PENDING/INPROGRESS/FINISHED
255+
*/
256+
BattleActionStatus BattleAction::getStatus() const
257+
{
258+
return _status;
259+
}
260+
261+
/**
262+
* Returns the action's type.
263+
* @return actiontype
264+
*/
265+
BattleActionType BattleAction::getType() const
266+
{
267+
return _type;
268+
}
269+
270+
/**
271+
* Soldier opens a door (if any) by rightclick, or by walking through it.
272+
* Normal door changes the tile objects. We need to make a sound 3 here.
273+
* Ufo door updates the ufodooropened flag of the tile. We need to make a sound 20 or 21 and start the animation.
274+
* An ufo door takes a few animation frames: while this animation is running this function returns true.
275+
* @return false if there is no door
276+
*/
277+
bool BattleAction::unitOpensDoor(BattleUnit *unit)
278+
{
279+
int door = -1;
280+
Tile *tile = _save->getTile(unit->getPosition());
281+
switch(unit->getDirection())
282+
{
283+
case 0: // north
284+
door = tile->openDoor(O_NORTHWALL);
285+
break;
286+
case 2: // east
287+
tile = _save->getTile(tile->getPosition() + Position(1, 0, 0));
288+
if (tile) door = tile->openDoor(O_WESTWALL);
289+
break;
290+
case 4: // south
291+
tile = _save->getTile(tile->getPosition() + Position(0, -1, 0));
292+
if (tile) door = tile->openDoor(O_NORTHWALL);
293+
break;
294+
case 6: // west
295+
door = tile->openDoor(O_WESTWALL);
296+
break;
297+
}
298+
299+
if (door == 0) //normal door
300+
{
301+
_res->getSoundSet("BATTLE.CAT")->getSound(3)->play();
302+
_save->getTerrainModifier()->calculateFOV(tile->getPosition());
303+
return true;
304+
}
305+
if (door == 1) // ufo door
306+
{
307+
_res->getSoundSet("BATTLE.CAT")->getSound(RNG::generate(20,21))->play();
308+
_save->getTerrainModifier()->calculateFOV(tile->getPosition());
309+
return true;
310+
}
311+
if (door == 3) // ufo door opening
312+
{
313+
return true;
314+
}
315+
316+
return false;
317+
}
318+
319+
}

0 commit comments

Comments
 (0)