Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
redv committed Sep 14, 2014
1 parent f7ac5e4 commit 84e62ef
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 49 deletions.
5 changes: 2 additions & 3 deletions bin/data/Ruleset/Xcom1Ruleset.rul
Original file line number Diff line number Diff line change
Expand Up @@ -8704,14 +8704,13 @@ startingTime:
day: 1
month: 1
year: 1999
maxViewDistance: 20
maxViewDistanceAtDark: 9
maxDarknessToSeeUnits: 9
costSoldier: 20000
costEngineer: 25000
costScientist: 30000
timePersonnel: 72
initialFunding: 6000
maxViewDistance: 20
maxDarknessToSeeUnits: 9
alienFuel: STR_ELERIUM_115
ufoTrajectories:
- id: P0
Expand Down
58 changes: 35 additions & 23 deletions src/Battlescape/TileEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ const int TileEngine::heightFromCenter[11] = {0,-2,+2,-4,+4,-6,+6,-8,+8,-12,+12}
* Sets up a TileEngine.
* @param save Pointer to SavedBattleGame object.
* @param voxelData List of voxel data.
* @param maxViewDistance Max view distance in tiles.
* @param maxDarknessToSeeUnits Threshold of darkness for LoS calculation.
*/
TileEngine::TileEngine(SavedBattleGame *save, std::vector<Uint16> *voxelData, int maxViewDistance, int maxDarknessToSeeUnits, int maxViewDistanceAtDark) :
TileEngine::TileEngine(SavedBattleGame *save, std::vector<Uint16> *voxelData, int maxViewDistance, int maxDarknessToSeeUnits) :
_save(save), _voxelData(voxelData), _personalLighting(true),
_maxViewDistance(maxViewDistance), _maxViewDistanceAtDark(maxViewDistanceAtDark),
_maxViewDistance(maxViewDistance), _maxViewDistanceSq(maxViewDistance * maxViewDistance),
_maxVoxelViewDistance(maxViewDistance * 16), _maxDarknessToSeeUnits(maxDarknessToSeeUnits)
{
}
Expand Down Expand Up @@ -276,7 +278,7 @@ bool TileEngine::calculateFOV(BattleUnit *unit)
{
const int distanceSqr = x*x + y*y;
test.z = z;
if (distanceSqr <= getMaxViewDistance() * getMaxViewDistance())
if (distanceSqr <= getMaxViewDistanceSq())
{
test.x = center.x + signX[direction]*(swap?y:x);
test.y = center.y + signY[direction]*(swap?x:y);
Expand Down Expand Up @@ -396,24 +398,26 @@ bool TileEngine::visible(BattleUnit *currentUnit, Tile *tile)
return false;
}

if (currentUnit->getFaction() == tile->getUnit()->getFaction()) return true; // friendlies are always seen
// friendlies are always seen
if (currentUnit->getFaction() == tile->getUnit()->getFaction())
{
return true;
}

// aliens can see in the dark, xcom can see at a distance of 9 (MaxViewDistanceAtDark) or less, further if there's enough light.
if (currentUnit->getFaction() == FACTION_PLAYER &&
distance(currentUnit->getPosition(), tile->getPosition()) > getMaxViewDistanceAtDark() &&
// aliens can see in the dark at least 20 tiles (maxViewDistanceSq == maxViewDistanceAtDarkSq).
// Xcom can see at 9 tiles or less.
// further if there's enough light.
if (getMaxViewDistanceSq() > currentUnit->getMaxViewDistanceAtDarkSq() &&
distanceSq(currentUnit->getPosition(), tile->getPosition(), false) > currentUnit->getMaxViewDistanceAtDarkSq() &&
tile->getShade() > getMaxDarknessToSeeUnits())
{
return false;
}

Position originVoxel = getSightOriginVoxel(currentUnit);

bool unitSeen = false;
// for large units origin voxel is in the middle

Position scanVoxel;
std::vector<Position> _trajectory;
unitSeen = canTargetUnit(&originVoxel, tile, &scanVoxel, currentUnit);
bool unitSeen = canTargetUnit(&originVoxel, tile, &scanVoxel, currentUnit);

if (unitSeen)
{
Expand All @@ -426,27 +430,30 @@ bool TileEngine::visible(BattleUnit *currentUnit, Tile *tile)
calculateLine(originVoxel, scanVoxel, true, &_trajectory, currentUnit);
int visibleDistance = _trajectory.size();
int densityOfSmoke = 0;
Position pos16(16, 16, 24);
Position posTile(_trajectory.at(0) / pos16);
Tile *t = _save->getTile(posTile);
Position voxelToTile(16, 16, 24);
Position trackTile(-1, -1, -1);
Tile *t;

for (int i = 0; i < visibleDistance; i++)
{
if (posTile != _trajectory.at(i) / pos16)
_trajectory.at(i) /= voxelToTile;
if (trackTile != _trajectory.at(i))
{
// 3 - coefficient of calculation (see above).
// 20 - maximum view distance in vanilla Xcom.
// even if maxViewDistance will be increased via ruleset, smoke will keep effect.
if (visibleDistance > getMaxVoxelViewDistance() - densityOfSmoke * getMaxViewDistance()/(3 * 20))
{
return false;
}
posTile = _trajectory.at(i) / pos16;
t = _save->getTile(posTile);
trackTile = _trajectory.at(i);
t = _save->getTile(trackTile);
}
if (t->getFire() == 0)
{
densityOfSmoke += t->getSmoke();
}
}
// even if MaxViewDistance will be increased via ruleset, smoke will keep effect
unitSeen = visibleDistance <= getMaxVoxelViewDistance() - densityOfSmoke * getMaxViewDistance()/(3 * 20);
}
return unitSeen;
Expand Down Expand Up @@ -768,7 +775,7 @@ void TileEngine::calculateFOV(const Position &position)
{
for (std::vector<BattleUnit*>::iterator i = _save->getUnits()->begin(); i != _save->getUnits()->end(); ++i)
{
if (distance(position, (*i)->getPosition()) < getMaxViewDistance())
if (distanceSq(position, (*i)->getPosition(), false) < getMaxViewDistanceSq())
{
calculateFOV(*i);
}
Expand Down Expand Up @@ -844,7 +851,7 @@ std::vector<BattleUnit *> TileEngine::getSpottingUnits(BattleUnit* unit)
// not a friend
(*i)->getFaction() != _save->getSide() &&
// closer than 20 tiles
distance(unit->getPosition(), (*i)->getPosition()) <= getMaxViewDistance())
distanceSq(unit->getPosition(), (*i)->getPosition(), false) <= getMaxViewDistanceSq())
{
Position originVoxel = _save->getTileEngine()->getSightOriginVoxel(*i);
originVoxel.z -= 2;
Expand Down Expand Up @@ -2417,8 +2424,13 @@ int TileEngine::distanceSq(const Position &pos1, const Position &pos2, bool cons
{
int x = pos1.x - pos2.x;
int y = pos1.y - pos2.y;
int z = considerZ ? (pos1.z - pos2.z) : 0;
return x*x + y*y + z*z;
int sq = x*x + y*y;
if (considerZ)
{
int z = pos1.z - pos2.z;
sq += z*z;
}
return sq;
}

/**
Expand Down
22 changes: 13 additions & 9 deletions src/Battlescape/TileEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,27 @@ struct BattleAction;
class TileEngine
{
private:
int _maxViewDistance; // 20
int _maxViewDistanceAtDark; // 9
int _maxVoxelViewDistance; // MAX_VIEW_DISTANCE * 16
int _maxDarknessToSeeUnits; // 9
const int _maxViewDistance; // 20 tiles by default
const int _maxViewDistanceSq; // 20 * 20
const int _maxVoxelViewDistance; // maxViewDistance * 16
const int _maxDarknessToSeeUnits; // 9 by default
SavedBattleGame *_save;
std::vector<Uint16> *_voxelData;
static const int heightFromCenter[11];
void addLight(const Position &center, int power, int layer);
int blockage(Tile *tile, const int part, ItemDamageType type, int direction = -1, bool checkingFromOrigin = false);
bool _personalLighting;
inline int getMaxViewDistance() const {return _maxViewDistance;}
inline int getMaxViewDistanceAtDark() const {return _maxViewDistanceAtDark;}
inline int getMaxVoxelViewDistance() const {return _maxVoxelViewDistance;}
inline int getMaxDarknessToSeeUnits() const {return _maxDarknessToSeeUnits;}
/// Get max view distance.
inline int getMaxViewDistance() const {return _maxViewDistance;}
/// Get square of max view distance.
inline int getMaxViewDistanceSq() const {return _maxViewDistanceSq;}
/// Get max view distance in voxel space.
inline int getMaxVoxelViewDistance() const {return _maxVoxelViewDistance;}
/// Get threshold of darkness for LoS calculation.
inline int getMaxDarknessToSeeUnits() const {return _maxDarknessToSeeUnits;}
public:
/// Creates a new TileEngine class.
TileEngine(SavedBattleGame *save, std::vector<Uint16> *voxelData, int maxViewDistance, int maxViewDistanceAtDark, int maxDarknessToSeeUnits);
TileEngine(SavedBattleGame *save, std::vector<Uint16> *voxelData, int maxViewDistance, int maxDarknessToSeeUnits);
/// Cleans up the TileEngine.
~TileEngine();
/// Calculates sun shading of the whole map.
Expand Down
13 changes: 12 additions & 1 deletion src/Ruleset/Armor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace OpenXcom
* type of armor.
* @param type String defining the type.
*/
Armor::Armor(const std::string &type) : _type(type), _spriteSheet(""), _spriteInv(""), _corpseGeo(""), _storeItem(""), _corpseBattle(), _frontArmor(0), _sideArmor(0), _rearArmor(0), _underArmor(0), _drawingRoutine(0), _movementType(MT_WALK), _size(1), _weight(0), _deathFrames(3), _constantAnimation(false), _canHoldWeapon(false)
Armor::Armor(const std::string &type) : _type(type), _spriteSheet(""), _spriteInv(""), _corpseGeo(""), _storeItem(""), _corpseBattle(), _frontArmor(0), _sideArmor(0), _rearArmor(0), _underArmor(0), _drawingRoutine(0), _movementType(MT_WALK), _size(1), _weight(0), _visibilityAtDark(0), _deathFrames(3), _constantAnimation(false), _canHoldWeapon(false)
{
for (int i=0; i < DAMAGE_TYPES; i++)
_damageModifier[i] = 1.0f;
Expand Down Expand Up @@ -70,6 +70,7 @@ void Armor::load(const YAML::Node &node)
_movementType = (MovementType)node["movementType"].as<int>(_movementType);
_size = node["size"].as<int>(_size);
_weight = node["weight"].as<int>(_weight);
_visibilityAtDark = node["visibilityAtDark"].as<int>(_visibilityAtDark);
_stats.merge(node["stats"].as<UnitStats>(_stats));
if (const YAML::Node &dmg = node["damageModifier"])
{
Expand Down Expand Up @@ -284,4 +285,14 @@ bool Armor::getCanHoldWeapon()
{
return _canHoldWeapon;
}

/**
* Gets max view distance at dark in BattleScape.
* @return The distance to see at dark.
*/
int Armor::getVisibilityAtDark() const
{
return _visibilityAtDark;
}

}
4 changes: 3 additions & 1 deletion src/Ruleset/Armor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Armor
std::vector<std::string> _corpseBattle;
int _frontArmor, _sideArmor, _rearArmor, _underArmor, _drawingRoutine;
MovementType _movementType;
int _size, _weight;
int _size, _weight, _visibilityAtDark;
float _damageModifier[DAMAGE_TYPES];
std::vector<int> _loftempsSet;
UnitStats _stats;
Expand Down Expand Up @@ -96,6 +96,8 @@ class Armor
bool getConstantAnimation();
/// Gets if armor can hold weapon.
bool getCanHoldWeapon();
/// Gets max view distance at dark in BattleScape.
int getVisibilityAtDark() const;
};

}
Expand Down
10 changes: 6 additions & 4 deletions src/Ruleset/Ruleset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ namespace OpenXcom
/**
* Creates a ruleset with blank sets of rules.
*/
Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _alienFuel(""), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0)
Ruleset::Ruleset() :
_costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _maxViewDistance(20), _maxDarknessToSeeUnits(9),
_alienFuel(""), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0),
_researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0)
{
// Check in which data dir the folder is stored
std::string path = CrossPlatform::getDataFolder("SoldierName/");
Expand Down Expand Up @@ -407,14 +410,13 @@ void Ruleset::loadFile(const std::string &filename)
}
}
_startingTime.load(doc["startingTime"]);
_maxViewDistance = doc["maxViewDistance"].as<int>(_maxViewDistance);
_maxViewDistanceAtDark = doc["maxViewDistanceAtDark"].as<int>(_maxViewDistanceAtDark);
_maxDarknessToSeeUnits = doc["maxDarknessToSeeUnits"].as<int>(_maxDarknessToSeeUnits);
_costSoldier = doc["costSoldier"].as<int>(_costSoldier);
_costEngineer = doc["costEngineer"].as<int>(_costEngineer);
_costScientist = doc["costScientist"].as<int>(_costScientist);
_timePersonnel = doc["timePersonnel"].as<int>(_timePersonnel);
_initialFunding = doc["initialFunding"].as<int>(_initialFunding);
_maxViewDistance = doc["maxViewDistance"].as<int>(_maxViewDistance);
_maxDarknessToSeeUnits = doc["maxDarknessToSeeUnits"].as<int>(_maxDarknessToSeeUnits);
_alienFuel = doc["alienFuel"].as<std::string>(_alienFuel);
for (YAML::const_iterator i = doc["ufoTrajectories"].begin(); i != doc["ufoTrajectories"].end(); ++i)
{
Expand Down
6 changes: 2 additions & 4 deletions src/Ruleset/Ruleset.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class Ruleset
std::vector<std::pair<std::string, ExtraSounds *> > _extraSounds;
std::map<std::string, ExtraStrings *> _extraStrings;
std::vector<StatString*> _statStrings;
int _maxViewDistance, _maxViewDistanceAtDark, _maxDarknessToSeeUnits;
int _costSoldier, _costEngineer, _costScientist, _timePersonnel, _initialFunding;
int _maxViewDistance, _maxDarknessToSeeUnits;
std::string _alienFuel;
YAML::Node _startingBase;
GameTime _startingTime;
Expand Down Expand Up @@ -226,9 +226,7 @@ class Ruleset
void sortLists();
/// Gets max view distance in BattleScape.
inline int getMaxViewDistance() const {return _maxViewDistance;}
/// Gets max view distance at dark in BattleScape.
inline int getMaxViewDistanceAtDark() const {return _maxViewDistanceAtDark;}
/// Gets max darkness to see units in BattleScape.
/// Gets threshold of darkness for LoS calculation.
inline int getMaxDarknessToSeeUnits() const {return _maxDarknessToSeeUnits;}
/// Gets the research-requirements for Psi-Lab (it's a cache for psiStrengthEval)
std::vector<std::string> getPsiRequirements() const;
Expand Down
12 changes: 12 additions & 0 deletions src/Savegame/BattleUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ BattleUnit::BattleUnit(Soldier *soldier, UnitFaction faction) : _faction(faction
_specab = SPECAB_NONE;
_armor = soldier->getArmor();
_stats += *_armor->getStats(); // armors may modify effective stats
// max view distance at dark is 9 tiles for humans by default, but can be overridden
_maxViewDistanceAtDarkSq = (_armor->getVisibilityAtDark() > 0) ? _armor->getVisibilityAtDark() : 9;
_maxViewDistanceAtDarkSq *= _maxViewDistanceAtDarkSq;
_loftempsSet = _armor->getLoftempsSet();
_gender = soldier->getGender();
_faceDirection = -1;
Expand Down Expand Up @@ -149,6 +152,9 @@ BattleUnit::BattleUnit(Unit *unit, UnitFaction faction, int id, Armor *armor, in
{
adjustStats(diff);
}
// defaults of max view distance at dark is 9 tiles for humans and 20 tiles for aliens, but can be overridden
_maxViewDistanceAtDarkSq = (_armor->getVisibilityAtDark() > 0) ? _armor->getVisibilityAtDark() : (faction == FACTION_HOSTILE) ? 20 : 9;
_maxViewDistanceAtDarkSq *= _maxViewDistanceAtDarkSq;

_tu = _stats.tu;
_energy = _stats.stamina;
Expand Down Expand Up @@ -227,6 +233,12 @@ void BattleUnit::load(const YAML::Node &node)
_spawnUnit = node["spawnUnit"].as<std::string>(_spawnUnit);
_motionPoints = node["motionPoints"].as<int>(0);

// special case if alien under mind control
if (_faction != _originalFaction && _armor->getVisibilityAtDark() <= 0)
{
_maxViewDistanceAtDarkSq = (_originalFaction == FACTION_HOSTILE) ? 20 : 9;
_maxViewDistanceAtDarkSq *= _maxViewDistanceAtDarkSq;
}
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Savegame/BattleUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class BattleUnit
UnitStats _stats;
int _standHeight, _kneelHeight, _floatHeight;
int _value, _deathSound, _aggroSound, _moveSound;
int _intelligence, _aggression;
int _intelligence, _aggression, _maxViewDistanceAtDarkSq;
SpecialAbility _specab;
Armor *_armor;
SoldierGender _gender;
Expand Down Expand Up @@ -345,6 +345,8 @@ class BattleUnit
int getIntelligence() const;
/// Get the unit's aggression.
int getAggression() const;
/// Get square of maximum view distance at dark.
inline int getMaxViewDistanceAtDarkSq() const {return _maxViewDistanceAtDarkSq;}
/// Get the units's special ability.
int getSpecialAbility() const;
/// Set the units's special ability.
Expand Down
5 changes: 3 additions & 2 deletions src/Savegame/SavedBattleGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,12 @@ void SavedBattleGame::initMap(int mapsize_x, int mapsize_y, int mapsize_z)
/**
* Initializes the map utilities.
* @param res Pointer to resource pack.
* @param rule Pointer to the ruleset.
*/
void SavedBattleGame::initUtilities(ResourcePack *res, Ruleset *rules)
void SavedBattleGame::initUtilities(ResourcePack *res, Ruleset *rule)
{
_pathfinding = new Pathfinding(this);
_tileEngine = new TileEngine(this, res->getVoxelData(), rules->getMaxViewDistance(), rules->getMaxViewDistanceAtDark(), rules->getMaxDarknessToSeeUnits());
_tileEngine = new TileEngine(this, res->getVoxelData(), rule->getMaxViewDistance(), rule->getMaxDarknessToSeeUnits());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Savegame/SavedBattleGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class SavedBattleGame
/// Sets the dimensions of the map and initializes it.
void initMap(int mapsize_x, int mapsize_y, int mapsize_z);
/// Initialises the pathfinding and tileengine.
void initUtilities(ResourcePack *res, Ruleset *rules);
void initUtilities(ResourcePack *res, Ruleset *rule);
/// Gets the game's mapdatafiles.
std::vector<MapDataSet*> *getMapDataSets();
/// Sets the mission type.
Expand Down

0 comments on commit 84e62ef

Please sign in to comment.