Skip to content

Commit 8eb067b

Browse files
committed
Merge branch 'Bughunting'
2 parents e549417 + f7330e9 commit 8eb067b

23 files changed

Lines changed: 1269 additions & 399 deletions

‎bin/data/Ruleset/Xcom1Ruleset.rul‎

Lines changed: 871 additions & 162 deletions
Large diffs are not rendered by default.

‎src/Battlescape/BattlescapeGenerator.cpp‎

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,7 @@ void BattlescapeGenerator::run()
369369

370370
deployAliens(_game->getRuleset()->getAlienRace(_alienRace), ruleDeploy);
371371

372-
if (_save->getMissionType() == "STR_TERROR_MISSION")
373-
{
374-
deployCivilians(16);
375-
}
376-
372+
deployCivilians(_game->getRuleset()->getDeployment(_save->getMissionType())->getCivilians());
377373

378374
fuelPowerSources();
379375

@@ -514,8 +510,10 @@ void BattlescapeGenerator::deployAliens(AlienRace *race, AlienDeployment *deploy
514510
*/
515511
BattleUnit *BattlescapeGenerator::addAlien(Unit *rules, int alienRank, bool outside)
516512
{
517-
if (alienRank > 6)
518-
alienRank = 6;
513+
int difficulty = _game->getSavedGame()->getDifficulty();
514+
int divider = 1;
515+
if (!difficulty)
516+
divider = 2;
519517
BattleUnit *unit = new BattleUnit(rules, FACTION_HOSTILE, _unitSequence++, _game->getRuleset()->getArmor(rules->getArmor()));
520518
Node *node = 0;
521519

@@ -543,11 +541,28 @@ BattleUnit *BattlescapeGenerator::addAlien(Unit *rules, int alienRank, bool outs
543541
_save->setUnitPosition(unit, node->getPosition());
544542
unit->setAIState(new PatrolBAIState(_game->getSavedGame()->getBattleGame(), unit, node));
545543
unit->setDirection(RNG::generate(0,7));
546-
}
547-
548-
549-
_save->getUnits()->push_back(unit);
550544

545+
UnitStats *stats = unit->getStats();
546+
547+
// adjust the unit's stats according to the difficulty level.
548+
stats->tu += 4 * difficulty * stats->tu / 100;
549+
unit->setTimeUnits(stats->tu);
550+
stats->stamina += 4 * difficulty * stats->stamina / 100;
551+
unit->setEnergy(stats->stamina);
552+
stats->reactions += 6 * difficulty * stats->reactions / 100;
553+
stats->strength += 2 * difficulty * stats->strength / 100;
554+
stats->firing = (stats->firing + 6 * difficulty * stats->firing / 100) / divider;
555+
stats->strength += 2 * difficulty * stats->strength / 100;
556+
stats->melee += 4 * difficulty * stats->melee / 100;
557+
stats->psiSkill += 4 * difficulty * stats->psiSkill / 100;
558+
stats->psiStrength += 4 * difficulty * stats->psiStrength / 100;
559+
if (divider > 1)
560+
unit->halveArmor();
561+
562+
// we only add a unit if it has a node to spawn on.
563+
// (stops them spawning at 0,0,0)
564+
_save->getUnits()->push_back(unit);
565+
}
551566
return unit;
552567
}
553568

@@ -1449,17 +1464,20 @@ void BattlescapeGenerator::explodePowerSources()
14491464
*/
14501465
void BattlescapeGenerator::deployCivilians(int max)
14511466
{
1452-
int number = RNG::generate(1, max);
1453-
1454-
for (int i = 0; i < number; ++i)
1467+
if (max)
14551468
{
1456-
if (RNG::generate(0,100) < 50)
1457-
{
1458-
addCivilian(_game->getRuleset()->getUnit("MALE_CIVILIAN"));
1459-
}
1460-
else
1469+
int number = RNG::generate(1, max);
1470+
1471+
for (int i = 0; i < number; ++i)
14611472
{
1462-
addCivilian(_game->getRuleset()->getUnit("FEMALE_CIVILIAN"));
1473+
if (RNG::generate(0,100) < 50)
1474+
{
1475+
addCivilian(_game->getRuleset()->getUnit("MALE_CIVILIAN"));
1476+
}
1477+
else
1478+
{
1479+
addCivilian(_game->getRuleset()->getUnit("FEMALE_CIVILIAN"));
1480+
}
14631481
}
14641482
}
14651483
}

‎src/Battlescape/ExplosionBState.cpp‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "TileEngine.h"
2424
#include "UnitDieBState.h"
2525
#include "Map.h"
26+
#include "Camera.h"
2627
#include "../Engine/Game.h"
2728
#include "../Savegame/BattleUnit.h"
2829
#include "../Savegame/BattleItem.h"
@@ -118,7 +119,9 @@ void ExplosionBState::init()
118119
// bullet hit sound
119120
_parent->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(_item->getRules()->getHitSound())->play();
120121
}
121-
122+
Tile *t = _parent->getSave()->getTile(Position(_center.x/16, _center.y/16, _center.z/24));
123+
if (t->isDiscovered(0))
124+
_parent->getMap()->getCamera()->centerOnPosition(t->getPosition());
122125
}
123126

124127
/*

‎src/Battlescape/Map.cpp‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ void Map::draw()
155155
if (_projectile)
156156
{
157157
t = _save->getTile(Position(_projectile->getPosition(0).x/16, _projectile->getPosition(0).y/16, _projectile->getPosition(0).z/24));
158-
if (t && t->getVisible())
158+
if (t && t->isDiscovered(0))
159159
{
160160
projectileInFOV = true;
161161
}
@@ -165,7 +165,7 @@ void Map::draw()
165165
{
166166
std::set<Explosion*>::iterator i = _explosions.begin();
167167
t = _save->getTile(Position((*i)->getPosition().x/16, (*i)->getPosition().y/16, (*i)->getPosition().z/24));
168-
if (t && t->getVisible())
168+
if (t && t->isDiscovered(0))
169169
{
170170
explosionInFOV = true;
171171
}
@@ -724,7 +724,9 @@ void Map::animate(bool redraw)
724724
// animate certain units (large flying units have a propultion animation)
725725
for (std::vector<BattleUnit*>::iterator i = _save->getUnits()->begin(); i != _save->getUnits()->end(); ++i)
726726
{
727-
if ((*i)->getArmor()->getSize() > 1 && (*i)->getArmor()->getMovementType() == MT_FLY)
727+
if (((*i)->getArmor()->getSize() > 1 && (*i)->getArmor()->getMovementType() == MT_FLY)
728+
|| (*i)->getArmor()->getDrawingRoutine() == 8
729+
|| (*i)->getArmor()->getDrawingRoutine() == 9)
728730
{
729731
(*i)->setCache(0);
730732
cacheUnit(*i);

‎src/Battlescape/TileEngine.cpp‎

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ bool TileEngine::calculateFOV(BattleUnit *unit)
227227

228228
if (unit->isOut())
229229
return false;
230-
230+
Position pos = unit->getPosition();
231+
if ((unit->getHeight() + -_save->getTile(unit->getPosition())->getTerrainLevel()) > 24)
232+
++pos.z;
231233
for (int x = 0; x <= MAX_VIEW_DISTANCE; ++x)
232234
{
233235
if (unit->getDirection()%2)
@@ -267,7 +269,7 @@ bool TileEngine::calculateFOV(BattleUnit *unit)
267269
if (unit->getFaction() == FACTION_PLAYER)
268270
{
269271
// this sets tiles to discovered if they are in LOS - tile visibility is not calculated in voxelspace but in tilespace
270-
if (calculateLine(unit->getPosition(), test, false, 0, unit, false) <= 0)
272+
if (calculateLine(pos, test, false, 0, unit, false) <= 0)
271273
{
272274
unit->addToVisibleTiles(_save->getTile(test));
273275
_save->getTile(test)->setDiscovered(true, 2);
@@ -355,7 +357,7 @@ bool TileEngine::visible(BattleUnit *currentUnit, Tile *tile)
355357
{
356358
targetVoxel.z = i;
357359
_trajectory.clear();
358-
int test = calculateLine(originVoxel, targetVoxel, false, &_trajectory, currentUnit);
360+
int test = calculateLine(originVoxel, targetVoxel, false, &_trajectory, currentUnit, true, true);
359361
if (test == 4)
360362
{
361363
Position hitPosition = Position(_trajectory.at(0).x/16, _trajectory.at(0).y/16, _trajectory.at(0).z/24);
@@ -914,12 +916,15 @@ int TileEngine::vectorToDirection(const Position &vector)
914916
* 1 ufo door is starting to open, make a whoosh sound, don't walk through.
915917
* 3 ufo door is still opening, don't walk through it yet. (have patience, futuristic technology...)
916918
*/
917-
int TileEngine::unitOpensDoor(BattleUnit *unit)
919+
int TileEngine::unitOpensDoor(BattleUnit *unit, bool rClick)
918920
{
919921
int door = -1;
920-
922+
int TUCost = 0;
921923
int size = unit->getArmor()->getSize();
922924

925+
if (size > 1 && rClick)
926+
return door;
927+
923928
for (int x = 0; x < size; x++)
924929
{
925930
for (int y = 0; y < size; y++)
@@ -929,9 +934,12 @@ int TileEngine::unitOpensDoor(BattleUnit *unit)
929934

930935
if (unit->getDirection() == 0 || unit->getDirection() == 1 || unit->getDirection() == 7) // north, northeast or northwest
931936
{
932-
door = tile->openDoor(MapData::O_NORTHWALL);
937+
door = tile->openDoor(MapData::O_NORTHWALL, unit, _save->getDebugMode());
938+
if (door == 0 && rClick)
939+
TUCost = tile->getTUCost(MapData::O_WESTWALL, unit->getArmor()->getMovementType());
933940
if (door == 1)
934941
{
942+
TUCost = tile->getTUCost(MapData::O_NORTHWALL, unit->getArmor()->getMovementType());
935943
// check for adjacent door(s)
936944
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(1, 0, 0));
937945
if (tile) tile->openDoor(MapData::O_NORTHWALL);
@@ -946,9 +954,12 @@ int TileEngine::unitOpensDoor(BattleUnit *unit)
946954
if ((unit->getDirection() == 2 || unit->getDirection() == 1 || unit->getDirection() == 3) && door == -1) // east, northeast or southeast
947955
{
948956
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(1, 0, 0));
949-
if (tile) door = tile->openDoor(MapData::O_WESTWALL);
957+
if (tile) door = tile->openDoor(MapData::O_WESTWALL, unit, _save->getDebugMode());
958+
if (door == 0 && rClick)
959+
TUCost = tile->getTUCost(MapData::O_NORTHWALL, unit->getArmor()->getMovementType());
950960
if (door == 1)
951961
{
962+
TUCost = tile->getTUCost(MapData::O_WESTWALL, unit->getArmor()->getMovementType());
952963
// check for adjacent door(s)
953964
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(1, 1, 0));
954965
if (tile) tile->openDoor(MapData::O_WESTWALL);
@@ -963,9 +974,12 @@ int TileEngine::unitOpensDoor(BattleUnit *unit)
963974
if ((unit->getDirection() == 4 || unit->getDirection() == 5 || unit->getDirection() == 3) && door == -1) // south, southwest or southeast
964975
{
965976
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(0, 1, 0));
966-
if (tile) door = tile->openDoor(MapData::O_NORTHWALL);
977+
if (tile) door = tile->openDoor(MapData::O_NORTHWALL, unit, _save->getDebugMode());
978+
if (door == 0 && rClick)
979+
TUCost = tile->getTUCost(MapData::O_WESTWALL, unit->getArmor()->getMovementType());
967980
if (door == 1)
968981
{
982+
TUCost = tile->getTUCost(MapData::O_NORTHWALL, unit->getArmor()->getMovementType());
969983
// check for adjacent door(s)
970984
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(1, 1, 0));
971985
if (tile) tile->openDoor(MapData::O_NORTHWALL);
@@ -979,9 +993,12 @@ int TileEngine::unitOpensDoor(BattleUnit *unit)
979993
}
980994
if ((unit->getDirection() == 6 || unit->getDirection() == 5 || unit->getDirection() == 7) && door == -1) // west, southwest or northwest
981995
{
982-
door = tile->openDoor(MapData::O_WESTWALL);
996+
door = tile->openDoor(MapData::O_WESTWALL, unit, _save->getDebugMode());
997+
if (door == 0 && rClick)
998+
TUCost = tile->getTUCost(MapData::O_NORTHWALL, unit->getArmor()->getMovementType());
983999
if (door == 1)
9841000
{
1001+
TUCost = tile->getTUCost(MapData::O_WESTWALL, unit->getArmor()->getMovementType());
9851002
// check for adjacent door(s)
9861003
tile = _save->getTile(unit->getPosition() + Position(x,y,0) + Position(0, 1, 0));
9871004
if (tile) tile->openDoor(MapData::O_WESTWALL);
@@ -999,6 +1016,8 @@ int TileEngine::unitOpensDoor(BattleUnit *unit)
9991016

10001017
if (door == 0 || door == 1)
10011018
{
1019+
1020+
unit->spendTimeUnits(TUCost, _save->getDebugMode());
10021021
calculateFOV(unit->getPosition());
10031022
}
10041023

@@ -1031,7 +1050,7 @@ int TileEngine::closeUfoDoors()
10311050
* @param doVoxelCheck Check against voxel or tile blocking? (first one for units visibility and line of fire, second one for terrain visibility)
10321051
* @return the objectnumber(0-3) or unit(4) or out of map (5) or -1(hit nothing)
10331052
*/
1034-
int TileEngine::calculateLine(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, bool doVoxelCheck)
1053+
int TileEngine::calculateLine(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, bool doVoxelCheck, bool LOSCalc)
10351054
{
10361055
int x, x0, x1, delta_x, step_x;
10371056
int y, y0, y1, delta_y, step_y;
@@ -1099,6 +1118,15 @@ int TileEngine::calculateLine(const Position& origin, const Position& target, bo
10991118
if (doVoxelCheck)
11001119
{
11011120
int result = voxelCheck(Position(cx, cy, cz), excludeUnit);
1121+
if (LOSCalc)
1122+
{
1123+
int result2 = voxelCheck(Position(cx, cy, cz-1), excludeUnit);
1124+
int result3 = voxelCheck(Position(cx, cy, cz+1), excludeUnit);
1125+
if (result2 != -1)
1126+
result = result2;
1127+
if (result3 != -1)
1128+
result = result3;
1129+
}
11021130
if (result != -1)
11031131
{
11041132
if (!storeTrajectory && trajectory != 0)

‎src/Battlescape/TileEngine.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ class TileEngine
7575
/// Check if a destroyed tile starts an explosion.
7676
Tile *checkForTerrainExplosions();
7777
/// Unit opens door?
78-
int unitOpensDoor(BattleUnit *unit);
78+
int unitOpensDoor(BattleUnit *unit, bool rClick = false);
7979
/// Close ufo doors.
8080
int closeUfoDoors();
8181
/// Calculate line.
82-
int calculateLine(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, bool doVoxelCheck = true);
82+
int calculateLine(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, bool doVoxelCheck = true, bool LOSCalc = false);
8383
/// Calculate a parabola trajectory.
8484
int calculateParabola(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, double curvature, double accuracy);
8585
bool visible(BattleUnit *currentUnit, Tile *tile);

‎src/Battlescape/UnitTurnBState.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void UnitTurnBState::init()
6767
if (_unit->getStatus() != STATUS_TURNING)
6868
{
6969
// try to open a door
70-
int door = _parent->getTileEngine()->unitOpensDoor(_unit);
70+
int door = _parent->getTileEngine()->unitOpensDoor(_unit, true);
7171
if (door == 0)
7272
{
7373
_parent->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(3)->play(); // normal door
@@ -76,6 +76,10 @@ void UnitTurnBState::init()
7676
{
7777
_parent->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(RNG::generate(20,21))->play(); // ufo door
7878
}
79+
if (door == 4)
80+
{
81+
_action.result = "STR_NOT_ENOUGH_TIME_UNITS";
82+
}
7983
_parent->popState();
8084
}
8185
}

‎src/Battlescape/UnitWalkBState.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ void UnitWalkBState::think()
100100
_parent->getSave()->getTile(_unit->getPosition() + Position(x,y,0))->setUnit(_unit);
101101
}
102102
}
103-
103+
if (!_parent->getMap()->getCamera()->isOnScreen(_unit->getPosition()) && _unit->getFaction() != FACTION_PLAYER && _unit->getVisible())
104+
_parent->getMap()->getCamera()->centerOnPosition(_unit->getPosition());
104105
// if the unit changed level, camera changes level with
105106
_parent->getMap()->getCamera()->setViewHeight(_unit->getPosition().z);
106107
}

‎src/Geoscape/DogfightState.cpp‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,8 @@ DogfightState::~DogfightState()
547547
delete _projectiles.back();
548548
_projectiles.pop_back();
549549
}
550-
_craft->setInDogfight(false);
550+
if (_craft)
551+
_craft->setInDogfight(false);
551552
}
552553

553554
/**
@@ -558,7 +559,7 @@ void DogfightState::think()
558559
if(!_endDogfight)
559560
{
560561
_moveTimer->think(this, 0);
561-
if(!_minimized)
562+
if(!_endDogfight && !_minimized) // check _endDogfight again, because moveTimer can change it
562563
{
563564
_animTimer->think(this, 0);
564565
_w1Timer->think(this, 0);
@@ -567,7 +568,7 @@ void DogfightState::think()
567568
_ufoEscapeTimer->think(this, 0);
568569
_craftDamageAnimTimer->think(this, 0);
569570
}
570-
else if(_craft->getDestination() != _ufo)
571+
else if(!_endDogfight && _craft->getDestination() != _ufo)
571572
{
572573
endDogfight();
573574
}
@@ -947,6 +948,7 @@ void DogfightState::move()
947948
}
948949
delete *c;
949950
(*b)->getCrafts()->erase(c);
951+
_craft = 0;
950952
break;
951953
}
952954
}
@@ -1740,7 +1742,8 @@ Ufo* DogfightState::getUfo() const
17401742
*/
17411743
void DogfightState::endDogfight()
17421744
{
1743-
_craft->setInDogfight(false);
1745+
if (_craft)
1746+
_craft->setInDogfight(false);
17441747
_endDogfight = true;
17451748
}
17461749

‎src/Geoscape/FundingState.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ FundingState::FundingState(Game *game) : State(game)
9191
ss << L'\x01' << Text::formatFunding((*i)->getFunding().at((*i)->getFunding().size()-1)) << L'\x01';
9292
if((*i)->getFunding().size() > 1)
9393
{
94-
ss2 << ((*i)->getFunding().at((*i)->getFunding().size()-1)- (*i)->getFunding().at((*i)->getFunding().size()-2));
94+
ss2 << Text::formatFunding((*i)->getFunding().at((*i)->getFunding().size()-1)- (*i)->getFunding().at((*i)->getFunding().size()-2));
9595
}
9696
else
9797
{
98-
ss2 << "0";
98+
ss2 << L"$0";
9999
}
100100
_lstCountries->addRow(3, _game->getLanguage()->getString((*i)->getRules()->getType()).c_str(), ss.str().c_str(), ss2.str().c_str());
101101
}

0 commit comments

Comments
 (0)