Skip to content

Commit e190860

Browse files
committed
- fixed walking animation.
- lighting and vision calculation reworked. - right-click aborts walking. - first unit is now selected at start instead of last one. - units are properly shaded and properly cached. git-svn-id: https://openxcom.svn.sourceforge.net/svnroot/openxcom/trunk@265 11c4a5ed-7179-4546-81a6-367b3be9d812
1 parent b0d0b05 commit e190860

17 files changed

Lines changed: 370 additions & 224 deletions

src/Battlescape/BattlescapeGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ void BattlescapeGenerator::run()
194194
if ((*i)->getCraft() == _craft)
195195
addSoldier((*i), _game->getRuleset()->getUnitSprites("XCOM_0"));
196196
}
197+
_save->setSelectedUnit(_save->getUnits()->at(0)); // select first soldier
197198

198199
// add items that are in the craft
199200
for (std::map<std::string, Item*>::iterator i = _craft->getItems()->begin(); i != _craft->getItems()->end(); i++)
@@ -252,7 +253,6 @@ void BattlescapeGenerator::addSoldier(Soldier *soldier, RuleUnitSprite *rules)
252253
}
253254

254255
_save->getUnits()->push_back(unit);
255-
_save->setSelectedUnit(unit);
256256
}
257257

258258
/**

src/Battlescape/BattlescapeState.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,21 @@ void BattlescapeState::think()
240240
*/
241241
void BattlescapeState::mapClick(Action *action)
242242
{
243+
// right-click abort walking
244+
if (action->getDetails()->button.button == SDL_BUTTON_RIGHT)
245+
{
246+
BattleUnit *unit = _battleGame->getSelectedUnit();
247+
if (unit->getStatus() == STATUS_WALKING)
248+
{
249+
_battleGame->getPathfinding()->abortPath();
250+
return;
251+
}
252+
}
253+
243254
// don't handle mouseclicks below 140, because they are in the buttons area (it overlaps with map surface)
244255
if (action->getDetails()->motion.y/action->getYScale() > BUTTONS_AREA) return;
245256

246-
// don't accept clicks if there is no cursor
257+
// don't accept below clicks if there is no cursor
247258
if (_map->isCursorHidden()) return;
248259

249260
Position pos;
@@ -433,31 +444,31 @@ void BattlescapeState::moveUnit()
433444

434445
if (unit->getStatus() == STATUS_WALKING)
435446
{
436-
unit->keepWalking();
437-
438-
// play footstep sound every step = two steps between two tiles
447+
// play footstep sound 1
439448
if (unit->getWalkingPhase() == 3)
440449
{
441450
Tile *tile = _battleGame->getTile(unit->getPosition());
442451
if (tile->getFootstepSound())
443452
_game->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(22 + (tile->getFootstepSound()*2))->play();
444453
}
445-
// at walking phase 4 the unit moved from one tile to the other
446-
if (unit->getWalkingPhase() == 4)
447-
{
448-
_battleGame->getTile(unit->getLastPosition())->setUnit(0);
449-
_battleGame->getTile(unit->getPosition())->setUnit(unit);
450-
}
451-
// play footstep sound every step = two steps between two tiles
454+
// play footstep sound 2
452455
if (unit->getWalkingPhase() == 7)
453456
{
454457
Tile *tile = _battleGame->getTile(unit->getPosition());
455458
if (tile->getFootstepSound())
456459
_game->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(23 + (tile->getFootstepSound()*2))->play();
457-
tile->setUnit(unit); // unit is now on this tile
458460
}
459461

460-
if (unit->getStatus() != STATUS_STANDING)
462+
unit->keepWalking(); // advances the phase
463+
464+
// unit moved from one tile to the other, update the tiles
465+
if (unit->getPosition() != unit->getLastPosition())
466+
{
467+
_battleGame->getTile(unit->getLastPosition())->setUnit(0);
468+
_battleGame->getTile(unit->getPosition())->setUnit(unit);
469+
}
470+
471+
if (unit->getStatus() != STATUS_STANDING) // we handle the standing part below
461472
{
462473
_map->cacheUnits();
463474
_map->draw();
@@ -467,7 +478,7 @@ void BattlescapeState::moveUnit()
467478
if (unit->getStatus() == STATUS_TURNING)
468479
{
469480
unit->turn();
470-
_battleGame->getTerrainModifier()->calculateLineOfSight(unit);
481+
_battleGame->getTerrainModifier()->calculateFOV(unit);
471482
_map->cacheUnits();
472483
_map->draw();
473484
}
@@ -497,24 +508,24 @@ void BattlescapeState::moveUnit()
497508
unit->startWalking(dir, destination);
498509
_map->hideCursor(true); // hide cursor while walking
499510
_game->getCursor()->setVisible(false);
511+
512+
_map->cacheUnits();
513+
_map->draw(); // draws phase 0
500514
}
501515
}
502-
else if (_map->isCursorHidden())
503-
{
504-
_battleGame->getTerrainModifier()->calculateLighting();
505-
_map->hideCursor(false); // show cursor again
506-
_game->getCursor()->setVisible(true);
507-
}
508516

509-
if (moved)
517+
if (moved) // we have moved one tile: the walking cycle is finished
510518
{
511519
moved = false;
512520
_map->setViewHeight(unit->getPosition().z);
513-
_battleGame->getTerrainModifier()->calculateLineOfSight(unit);
521+
_battleGame->getTerrainModifier()->calculateFOV(unit);
514522
// if you want lighting to be calculated every step, uncomment next line
515523
//_battleGame->getTerrainModifier()->calculateLighting();
516-
if (unit->getStatus() == STATUS_STANDING)
524+
if (unit->getStatus() == STATUS_STANDING) // we finished walking
517525
{
526+
_battleGame->getTerrainModifier()->calculateLighting();
527+
_map->hideCursor(false); // show cursor again
528+
_game->getCursor()->setVisible(true);
518529
_map->cacheUnits();
519530
_map->draw();
520531
}

src/Battlescape/Map.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "../Engine/Font.h"
3232
#include "../Engine/Language.h"
3333
#include "../Engine/Palette.h"
34+
#include "../Engine/RNG.h"
3435
#include "../Engine/Game.h"
3536
#include "../Savegame/SavedBattleGame.h"
3637
#include "../Savegame/Tile.h"
@@ -319,7 +320,6 @@ void Map::drawTerrain()
319320
}
320321
}
321322

322-
323323
// Draw cursor front
324324
if (_selectorX == itY && _selectorY == itX && !_hideCursor)
325325
{
@@ -339,7 +339,8 @@ void Map::drawTerrain()
339339
frame->setY(screenPosition.y);
340340
frame->blit(this);
341341
}
342-
342+
343+
tile = _save->getTile(mapPosition);
343344
// Draw smoke/fire
344345
if (tile->getFire() && tile->isDiscovered())
345346
{
@@ -349,6 +350,14 @@ void Map::drawTerrain()
349350
frame->setY(screenPosition.y);
350351
frame->blit(this);
351352
}
353+
if (tile->getSmoke() && tile->isDiscovered())
354+
{
355+
frameNumber = 8 + int(floor((tile->getSmoke() / 5.0) - 0.1)); // see http://www.ufopaedia.org/images/c/cb/Smoke.gif
356+
frame = _res->getSurfaceSet("SMOKE.PCK")->getFrame(frameNumber + (_animFrame / 2));
357+
frame->setX(screenPosition.x);
358+
frame->setY(screenPosition.y);
359+
frame->blit(this);
360+
}
352361

353362
}
354363
}
@@ -393,9 +402,15 @@ void Map::keyboardPress(Action *action, State *state)
393402
// "f" - puts a tile on fire (for testing purposes)
394403
if (action->getDetails()->key.keysym.sym == SDLK_f)
395404
{
396-
_save->getTile(pos)->setFire(1);
405+
_save->getTile(pos)->setFire(RNG::generate(1,5));
397406
_save->getTerrainModifier()->calculateLighting();
398407
}
408+
// "s" - puts a tile on smoke (for testing purposes)
409+
if (action->getDetails()->key.keysym.sym == SDLK_s)
410+
{
411+
_save->getTile(pos)->setSmoke(RNG::generate(1,50));
412+
//_save->getTerrainModifier()->calculateLighting();
413+
}
399414
}
400415

401416
/**
@@ -581,7 +596,8 @@ void Map::scroll()
581596
*/
582597
void Map::animate()
583598
{
584-
_animFrame = _animFrame == 7 ? 0 : _animFrame+1;
599+
_animFrame++;
600+
if (_animFrame == 8) _animFrame = 0;
585601

586602
for (int i = 0; i < _tileCount; i++)
587603
{
@@ -691,29 +707,31 @@ void Map::getSelectorPosition(Position *pos)
691707
*/
692708
void Map::calculateWalkingOffset(BattleUnit *unit, Position *offset)
693709
{
694-
int offsetX[8] = { 1, 2, 1, 0, -1, -2, -1, 0 };
695-
int offsetY[8] = { 1, 0, -1, -2, -1, 0, 1, 2 };
696-
int phase = unit->getWalkingPhase();
710+
int offsetX[8] = { 1, 1, 1, 0, -1, -1, -1, 0 };
711+
int offsetY[8] = { 1, 0, -1, -1, -1, 0, 1, 1 };
712+
int phase = unit->getWalkingPhase() + unit->getDiagonalWalkingPhase();
697713
int dir = unit->getDirection();
714+
int midphase = 4 + 4 * (dir % 2);
715+
int endphase = 8 + 8 * (dir % 2);
698716

699-
if (phase)
717+
if (unit->getStatus() == STATUS_WALKING)
700718
{
701-
if (phase < 4)
719+
if (phase < midphase)
702720
{
703721
offset->x = phase * 2 * offsetX[dir];
704722
offset->y = - phase * offsetY[dir];
705723
}
706724
else
707725
{
708-
offset->x = (phase - 8) * 2 * offsetX[dir];
709-
offset->y = - (phase - 8) * offsetY[dir];
726+
offset->x = (phase - endphase) * 2 * offsetX[dir];
727+
offset->y = - (phase - endphase) * offsetY[dir];
710728
}
711729
}
712730

713731
// If we are walking in between tiles, interpolate it's terrain level.
714-
if (phase)
732+
if (unit->getStatus() == STATUS_WALKING)
715733
{
716-
if (phase < 4)
734+
if (phase < midphase)
717735
{
718736
int fromLevel = _save->getTile(unit->getPosition())->getTerrainLevel();
719737
int toLevel = _save->getTile(unit->getDestination())->getTerrainLevel();
@@ -726,7 +744,7 @@ void Map::calculateWalkingOffset(BattleUnit *unit, Position *offset)
726744
// going up a level, so toLevel 0 becomes -24, -8 becomes -16
727745
toLevel = -24*(unit->getDestination().z - unit->getPosition().z) + abs(toLevel);
728746
}
729-
offset->y += ((fromLevel * (8 - phase)) / 8) + ((toLevel * (phase)) / 8);
747+
offset->y += ((fromLevel * (endphase - phase)) / endphase) + ((toLevel * (phase)) / endphase);
730748
}
731749
else
732750
{
@@ -743,7 +761,7 @@ void Map::calculateWalkingOffset(BattleUnit *unit, Position *offset)
743761
// going up a level, so fromLevel 0 becomes +24, -8 becomes 16
744762
fromLevel = -24*(unit->getDestination().z - unit->getLastPosition().z) + abs(fromLevel);
745763
}
746-
offset->y += ((fromLevel * (8 - phase)) / 8) + ((toLevel * (phase)) / 8);
764+
offset->y += ((fromLevel * (endphase - phase)) / endphase) + ((toLevel * (phase)) / endphase);
747765
}
748766
}
749767
else
@@ -925,16 +943,11 @@ void Map::cacheUnits()
925943
unitSprite->draw();
926944
unitSprite->blit(_unitCache.at((*i)->getId()));
927945

928-
// non player units get shaded according to the tile's shade
929-
if ((*i)->getFaction() != FACTION_PLAYER)
930-
{
931-
_unitCache.at((*i)->getId())->setShade(_save->getTile((*i)->getPosition())->getShade());
932-
}
946+
_unitCache.at((*i)->getId())->setShade(_save->getTile((*i)->getPosition())->getShade());
947+
(*i)->setCached(true);
933948
}
934949
}
935950
delete unitSprite;
936951
}
937952

938-
939-
940953
}

src/Battlescape/Pathfinding.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ int Pathfinding::dequeuePath()
261261
return last_element;
262262
}
263263

264+
/*
265+
* Abort path clears the path vector.
266+
*/
267+
void Pathfinding::abortPath()
268+
{
269+
_path.clear();
270+
}
271+
264272

265273
/*
266274
* Whether a certain part of a tile blocks movement.

src/Battlescape/Pathfinding.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class Pathfinding
6666
int dequeuePath();
6767
/// Get's the TU cost to move from 1 tile to the other.
6868
int getTUCost(const Position &startPosition, const int direction, Position *endPosition, BattleUnit *unit);
69+
/// Abort the current path.
70+
void abortPath();
6971
};
7072

7173
}

0 commit comments

Comments
 (0)