Я пытался решить эту проблему в течение нескольких недель, но ничего, что я сделал, не устранило ее. Похоже, это проблема с информацией Intellisense, которая не обновляется в файле .cpp.
Проблема в том, что ссылки на классы для определенных классов в заголовочном файле не распознаются, а Intellisense только в файле cpp. В заголовочном файле ссылки читаются отлично.
Вот заголовочный файл, извините за некоторую путаницу, поскольку я нахожусь в процессе реорганизации, слияния функций и переделки класса:
#ifndef DAMAGE_H
#define DAMAGE_H
#include <string>
#include "entity.h"#include "hardPoint.h"#include <vector>
using std::string;
using std::vector;
class Damage
{
public:
Damage();
float findDType(string dType, float damage);
void dmgProcessing(bAttacker& bAttacker, bTarget& bTarget);
float dTPiercing1(float damage);
float dTPiercing2(float damage);
float dTPiercing3(float damage);
float dTNapalm1(float damage);
float dTNapalm2(float damage);
float dTNapalm3(float damage);
float dTDesructor(float damage);
float dTNanite1(float damage);
float dTNanite2(float damage);
float dTNanite3(float damage);
float dTDDay1(float damage);
float dTDDay2(float damage);
float dTStealth(float damage);
float dTFOnly(float damage);
float dTEMP1(float damage, Player& mPlayer, Hostile args[], string target);
float dTEMP2(float damage, Player& mPlayer, Hostile args[], string target);
float dTEMP3(float damage, Player& mPlayer, Hostile args[], string target);
float dTVirus1();
float dTVirus2();
float dTVirus3();
float dTVirus4();
float dTMAccel(float damage);
void bPAttack(bool allout, bool spread, bool wsystem, bool single);
void setupWQueue(bAttacker& bAttacker, string atype);
void cleanWQueue();
float processWQueue(bAttacker& bAttacker, bTarget& bTarget);
float processSDamage(bTarget& bTarget, string wdtype);
float processSecDamage(bTarget& bTarget);
void setupBAT(Entity* entity1, Entity* entity2);
bool getSDNTurns();
bool getSDNANTurns();
private:
vector<hardPoint> weaponQueue;
float vDamage; //Vanilla Damage
float mDamage; //Modified Damage
float fDamage; //Final Damage
float sDamage; //Secondary Damage
float tSDamage; //total secodary damage
int i;
int sDNTurns, sDNANTurns; //Number of turns to apply secondary damage for (N = Napalm, NAN = Nanite)int dLow, dHigh;
string wdtype; //store weapon name
int nSDamage, nADamage, nHDamage; //Health interface variables for nanite secondary damage
};
//#endif/*Damage Types:
piercing1: Armor Piercing, does not affect hull
piercing2: Hull Piercing, does not affect armor
piercing3: Armor and Hull piercing
napalm1: low level napalm damage, lasts two turns
napalm2: medium level napalm damage, lasts four turns
napalm3: high level napalm damage, lasts six turns
destructor: higher damage to defenses
nanite1: low level nanite damage, does 5% of HP damage for two turns
nanite2: medium level nanite damage, does 8% of HP damage for four turns
nanite3: high level nanite damage, does 15% of HP damage for eight turns
doomsday1: large scale damage, kills off 25% of population instantly along with 15% of all infrastructure and 10% of biomass
doomsday2: larger scale damage, kills off 40% of population instantly along with 25% of all infrastructure and 18% of biomass
stealth: invisible to point defenses, point defenses will still have a 2% chance to destroy a missile volley per point defense up to 10%.
frigonly: only damages frigate class ships, no damage to higher classes
null: no special damage
emp1: low level shield damage, if shields down will cripple non-emp protected target for one turn
emp2: medium level shield damage, if shields down will cripple non-emp protected target for three turns
emp3: high level shield damage, if shields down will cripple non-emp protected target for seven turns
virus1: scrambles targeting systems of enemy ship, target will not attack for two turns and loses shields
virus2: scrambles targeting systems and crashes computer, target will not attack for five turns and loses shields
virus3: scrambles targeting systems, crashes computer, and disables life support and loses shields (RTS/RPG). Crews of ships lower then crusier class can be killed in two turns and ship can be salvaged whole (twice the resources; RTS only)
virus4: crashes all systems and injects core breach code into engines and loses shields. 35% chance that the ship will self destruct over 4 turns, after which systems reboot and core breach stopped. 10% chance per 20 tech crewmen or 5 tech module on board to avert code breach. (RTS only)
massaccel: Mass Accelerator damage bypasses shield and armor and deals direct hull damage.
*/class bTarget
{
public:
bTarget();
void getShip(Entity* entity);
Ship returnShip(Entity* entity);
Ship* Ship;
};
class bAttacker
{
public:
bAttacker();
void getShip(Entity* entity);
Ship returnShip(Entity* entity);
Ship* Ship;
};
#endif
Все ссылки, относящиеся к bTarget и bAttacker, находятся в этом заголовочном файле, но как только я помещаю определения функций в файл .cpp, Intellisense взрывает, утверждая, что определения не соответствуют объявлению заголовка void setupWQueue (error-type &bAttacker, строка atype) просто в качестве примера.
Однако прямой доступ к классам bAttacker и bTarget, например, для определения функции getShip, вполне подходит.
Редактировать:
Ради того, чтобы быть тщательным в случае, если что-то в нем вызывает это, здесь также находится файл cpp; это будет намного сложнее, чем заголовок по той же причине (извините!):
#include <string>
#include "damage.h"#include "planet.h"#include "random.h"#include "datasystem.h"
using namespace std;
#define EMP1DT 1
#define EMP2DT 3
#define EMP3DT 7
#define NP1P 0.15
#define NAN1P 0.05
#define NP2P 0.28
#define NAN2P 0.08
#define NP3P 0.46
#define NAN3P 0.15
#define NP1T 2
#define NAN1T 2
#define NP2T 4
#define NAN2T 4
#define NP3T 6
#define NAN3T 8
dataSystem ds;
int test = NAN1T;Damage::Damage()
{
}
void Damage::dmgProcessing(bAttacker& bAttacker, bTarget& bTarget)
{
setupWQueue(bAttacker, atype);
}float Damage::dTEMP1(float damage, Player& mPlayer, Hostile args[], string target)
{
if (target == mPlayer.getName()) //Consider creating main class or matrix for all fighting entities/teams to make this easier
{
if ((!mPlayer.Ship.isDisabled()) && (mPlayer.Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
mPlayer.Ship.disableShip(EMP1DT);
}
else if ((mPlayer.Ship.getShieldStatus()) && (mPlayer.Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(8,10);
return mDamage;
}
}
else
{
for (i = 0; i <= sizeof(args)-1; i++)
{
if (target == args[i].getName())
{
if ((!args[i].Ship.isDisabled()) && (args[i].Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
args[i].Ship.disableShip(EMP1DT);
}
else if ((args[i].Ship.getShieldStatus()) && (args[i].Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(8,10);
return mDamage;
}
}
}
}
}
float Damage::dTEMP2(float damage, Player& mPlayer, Hostile args[], string target)
{
if (target == mPlayer.getName()) //Consider creating main class or matrix for all fighting entities/teams to make this easier
{
if ((!mPlayer.Ship.isDisabled()) && (mPlayer.Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
mPlayer.Ship.disableShip(EMP2DT);
}
else if ((mPlayer.Ship.getShieldStatus()) && (mPlayer.Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(5,7);
return mDamage;
}
}
else
{
for (i = 0; i <= sizeof(args)-1; i++)
{
if (target == args[i].getName())
{
if ((!args[i].Ship.isDisabled()) && (args[i].Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
args[i].Ship.disableShip(EMP2DT);
}
else if ((args[i].Ship.getShieldStatus()) && (args[i].Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(5,7);
return mDamage;
}
}
}
}
}
float Damage::dTEMP3(float damage, Player& mPlayer, Hostile args[], string target)
{
if (target == mPlayer.getName()) //Consider creating main class or matrix for all fighting entities/teams to make this easier
{
if ((!mPlayer.Ship.isDisabled()) && (mPlayer.Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
mPlayer.Ship.disableShip(EMP3DT);
}
else if ((mPlayer.Ship.getShieldStatus()) && (mPlayer.Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(2,4);
return mDamage;
}
}
else
{
for (i = 0; i <= sizeof(args)-1; i++)
{
if (target == args[i].getName())
{
if ((!args[i].Ship.isDisabled()) && (args[i].Ship.getSShield() == 0)) //If ship is not disabled already and shilds are 0
{
args[i].Ship.disableShip(EMP3DT);
}
else if ((args[i].Ship.getShieldStatus()) && (args[i].Ship.getSShield() != 0)) //If shields are enabled and are greater then 0
{
mDamage = damage / Random(2,4);
return mDamage;
}
}
}
}
}void Damage::bPAttack(bool allout, bool spread, bool wsystem, bool single)
{
vDamage = 0.0f;
mDamage = 0.0f;
fDamage = 0.0f;
if (allout)
{
fDamage = processWQueue(bAttacker);
//Check for secondary damage
if (getSDNTurns())
{
fDamage += processSecDamage(bAttacker);
sDNTurns -= 1;
}
if (getSDNANTurns())
{
fDamage += processSecDamage(bAttacker);
sDNANTurns -= 1;
}
hostile.takeSDamage(fDamage);
}
else if (spread)
{
}
else if (wsystem)
{
}
else if (single)
{
}
}
float Damage::processWQueue(bAttacker& bAttacker,bTarget& bTarget)
{
for (i = 0; i < weaponQueue.size(); i++)
{
if (weaponQueue.at(i).getHPWType() == "laser")
{
wdtype = bAttacker.Ship->getLWDType(weaponQueue.at(i).getHPSlot()); //send slot of current laser weapon to ship for return of item name
dLow = bAttacker.Ship->lBanks.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRLow();
dHigh = bAttacker.Ship->lBanks.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRHigh();
}
else if (weaponQueue.at(i).getHPWType() == "missile")
{
wdtype = bAttacker.Ship->getMWDType(weaponQueue.at(i).getHPSlot()); //send slot of current missile weapon to ship for return of item name
dLow = bAttacker.Ship->mTurrets.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRLow();
dHigh = bAttacker.Ship->mTurrets.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRHigh();
}
else if (weaponQueue.at(i).getHPWType() == "bomb")
{
wdtype = bAttacker.Ship->getBWDType(weaponQueue.at(i).getHPSlot()); //send slot of current bomb weapon to ship for return of item name
dLow = bAttacker.Ship->bHolds.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRLow();
dHigh = bAttacker.Ship->bHolds.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRHigh();
}
else if (weaponQueue.at(i).getHPWType() == "rail")
{
wdtype = bAttacker.Ship->getRWDType(weaponQueue.at(i).getHPSlot()); //send slot of current rail gun weapon to ship for return of item name
dLow = bAttacker.Ship->rMounts.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRLow();
dHigh = bAttacker.Ship->rMounts.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRHigh();
}
else if (weaponQueue.at(i).getHPWType() == "heavy")
{
wdtype = bAttacker.Ship->getHWDType(weaponQueue.at(i).getHPSlot()); //send slot of current heavy weapon to ship for return of item name
dLow = bAttacker.Ship->hWBays.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRLow();
dHigh = bAttacker.Ship->hWBays.at(weaponQueue.at(i).getHPSlot()).hpWeapon.getWDRHigh();
}
if (wdtype != "null")
{
vDamage += Random(dLow, dHigh);
mDamage += processSDamage(bTarget,wdtype);
}
else
{
vDamage += Random(dLow, dHigh);
}
}
return vDamage;
}
float Damage::processSDamage(bTarget& bTarget, string wdtype)
{
if (wdtype == "napalm1")
{
if (sDamage > 0.0f)
{
sDamage += (0.50 * (vDamage * NP1P));
}
else
{
sDamage = vDamage * NP1P;
}
if (sDNTurns < NP1T)
{
sDNTurns = NP1T;
}
}
else if (wdtype == "napalm2")
{
if (sDamage > 0.0f)
{
sDamage += (0.50 * (vDamage * NP2P));
}
else
{
sDamage = vDamage * NP2P;
}
if (sDNTurns < NP2T)
{
sDNTurns = NP2T;
}
}
else if (wdtype == "napalm3")
{
if (sDamage > 0.0f)
{
sDamage += (0.50 * (vDamage * NP3P));
}
else
{
sDamage = vDamage * NP3P;
}
if (sDNTurns < NP3T)
{
sDNTurns = NP3T;
}
}
else if (wdtype == "nanite1")
{
if (nSDamage > 0.0f)
{
nSDamage += (0.75 * (bTarget.Ship->getSShield() * NAN1P));
}
else
{
nSDamage = bTarget.Ship->getSShield() * NAN1P;
}
if (nADamage > 0.0f)
{
nADamage += (0.75 * (bTarget.Ship->getSShield() * NAN1P));
}
else
{
nADamage = bTarget.Ship->getSShield() * NAN1P;
}
if (nHDamage > 0.0f)
{
nHDamage += (0.75 * (bTarget.Ship->getSShield() * NAN1P));
}
else
{
nHDamage = bTarget.Ship->getSShield() * NAN1P;
}
if (sDNANTurns < NAN1T)
{
sDNANTurns = NAN1T;
}
}
else if (wdtype == "nanite2")
{
if (nSDamage > 0.0f)
{
nSDamage += (0.75 * (bTarget.Ship->getSShield() * NAN2P));
}
else
{
nSDamage = bTarget.Ship->getSShield() * NAN2P;
}
if (nADamage > 0.0f)
{
nADamage += (0.75 * (bTarget.Ship->getSShield() * NAN2P));
}
else
{
nADamage = bTarget.Ship->getSShield() * NAN2P;
}
if (nHDamage > 0.0f)
{
nHDamage += (0.75 * (bTarget.Ship->getSShield() * NAN2P));
}
else
{
nHDamage = bTarget.Ship->getSShield() * NAN2P;
}
if (sDNANTurns < NAN2T)
{
sDNANTurns = NAN2T;
}
}
else if (wdtype == "nanite3")
{
if (nSDamage > 0.0f)
{
nSDamage += (0.75 * (bTarget.Ship->getSShield() * NAN3P));
}
else
{
nSDamage = bTarget.Ship->getSShield() * NAN3P;
}
if (nADamage > 0.0f)
{
nADamage += (0.75 * (bTarget.Ship->getSShield() * NAN3P));
}
else
{
nADamage = bTarget.Ship->getSShield() * NAN3P;
}
if (nHDamage > 0.0f)
{
nHDamage += (0.75 * (bTarget.Ship->getSShield() * NAN3P));
}
else
{
nHDamage = bTarget.Ship->getSShield() * NAN3P;
}
if (sDNANTurns < NAN1T)
{
sDNANTurns = NAN3T;
}
}
}
float Damage::processSecDamage(bTarget& bTarget)
{
if (getSDNTurns())
{
tSDamage += sDamage;
}
if (getSDNANTurns())
{
//Direct damage
bTarget.Ship->setSShield(bTarget.Ship->getSShield()-nSDamage);
bTarget.Ship->setSArmor(bTarget.Ship->getSArmor()-nADamage);
bTarget.Ship->setSHull(bTarget.Ship->getSHull()-nHDamage);
}
return tSDamage;
}
bool Damage::getSDNTurns()
{
return sDNTurns > 0;
}
bool Damage::getSDNANTurns()
{
return sDNANTurns > 0;
}void Damage::setupWQueue(bAttacker& bAttacker, string atype)
{
cleanWQueue(); //Clear vector
if (atype == "allout")
{
for (i = 0; i < bAttacker.Ship->getWVSize(); i++)
{
weaponQueue.push_back(bAttacker.Ship->getSHPoint(i));
}
}
else if (atype == "spread")
{
for (i = 0; i < bAttacker.Ship->getSSize(); i++)
{
weaponQueue.push_back(bAttacker.Ship->getSHPoint(i));
}
}
else if (atype == "wsystem")
{
for (i = 0; i < bAttacker.Ship->getWVSize(); i++)
{
weaponQueue.push_back(bAttacker.Ship->getSHPoint(i));
}
}
else if (atype == "single")
{
weaponQueue.push_back(bAttacker.Ship->getWVHPoint(0));
}
}void Damage::cleanWQueue()
{
weaponQueue.clear();
}void Damage::setupBAT(Entity* entity1, Entity* entity2)
{
bAttacker bAttacker;
bTarget bTarget;
bAttacker.getShip(entity1);
bTarget.getShip(entity2);
dmgProcessing(bAttacker, bTarget);
}//bAttacker
void bAttacker::getShip(Entity* entity)
{
Ship = entity->Ship.rShip(); //Create an easy to use interface to get the ship data
}//bTarget
void bTarget::getShip(Entity* entity)
{
Ship = entity->Ship.rShip();
}
Я наконец сдался и просто переместил и объединил bAttacker и bTarget в новый класс с именем bEntity (боевая сущность) и дважды сослался на него, чтобы создать два экземпляра bEntity для идентификаторов Target и Attacker.
Работает нормально таким образом, я полагаю, проблема была в том, что вы не можете определить несколько несвязанных классов и обращаться к ним нормально (вы можете сделать это, но основной класс должен иметь ссылку или указатель на другие классы в заголовке).
Другая причина может заключаться в том, что я забыл конструкторы в файле cpp для bAttacker и bTarget, но мне все равно нравится моя новая настройка, гораздо более компактная.
Других решений пока нет …