weapondefhandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 737 行 · 第 1/2 页
CPP
737 行
#include "StdAfx.h"
#include <algorithm>
#include <cctype>
#include <iostream>
#include <stdexcept>
#include "WeaponDefHandler.h"
#include "Game/Game.h"
#include "Lua/LuaParser.h"
#include "FileSystem/FileHandler.h"
#include "Rendering/Textures/ColorMap.h"
#include "Rendering/Textures/TAPalette.h"
#include "Rendering/GL/myGL.h"
#include "Sim/Misc/DamageArrayHandler.h"
#include "Sim/Misc/CategoryHandler.h"
#include "Sim/Projectiles/ExplosionGenerator.h"
#include "Sim/Projectiles/ProjectileHandler.h"
#include "Sim/Projectiles/Projectile.h"
#include "System/LogOutput.h"
#include "System/Sound.h"
#include "mmgr.h"
using namespace std;
CR_BIND(WeaponDef, );
CWeaponDefHandler* weaponDefHandler = NULL;
CWeaponDefHandler::CWeaponDefHandler()
{
PrintLoadMsg("Loading weapon definitions");
const LuaTable rootTable = game->defsParser->GetRoot().SubTable("WeaponDefs");
if (!rootTable.IsValid()) {
throw content_error("Error loading WeaponDefs");
}
vector<string> weaponNames;
rootTable.GetKeys(weaponNames);
numWeaponDefs = weaponNames.size(); // FIXME: starting at 0, don't need the +1 ?
weaponDefs = SAFE_NEW WeaponDef[numWeaponDefs + 1];
for (int wid = 0; wid < (int)weaponNames.size(); wid++) {
WeaponDef& wd = weaponDefs[wid];
wd.id = wid;
wd.name = weaponNames[wid];
weaponID[wd.name] = wid;
const LuaTable wdTable = rootTable.SubTable(wd.name);
ParseTAWeapon(wdTable, wd);
}
}
CWeaponDefHandler::~CWeaponDefHandler()
{
delete[] weaponDefs;
}
void CWeaponDefHandler::ParseTAWeapon(const LuaTable& wdTable, WeaponDef& wd)
{
bool lineofsight;
bool ballistic;
//bool twophase;
bool beamweapon;
bool manualBombSettings; //Allow the user to manually specify the burst and burstrate for his AircraftBomb
//bool guided;
//bool vlaunch;
int rendertype;
int color;
int beamlaser;
//bool tracking;
//bool selfprop;
//bool turret;
//bool smokeTrail;
//string modelName;
wd.tdfId = wdTable.GetInt("id", 0);
wd.filename = wdTable.GetString("filename", "unknown");
wd.description = wdTable.GetString("name", "Weapon");
wd.cegTag = wdTable.GetString("cegTag", "");
wd.avoidFriendly = wdTable.GetBool("avoidFriendly", true);
wd.avoidFeature = wdTable.GetBool("avoidFeature", true);
wd.collisionFlags = 0;
const bool collideFriendly = wdTable.GetBool("collideFriendly", true);
const bool collideFeature = wdTable.GetBool("collideFeature", true);
if (!collideFriendly) { wd.collisionFlags += COLLISION_NOFRIENDLY; }
if (!collideFeature) { wd.collisionFlags += COLLISION_NOFEATURE; }
wd.minIntensity = wdTable.GetFloat("minIntensity", 0.0f);
wd.dropped = wdTable.GetBool("dropped", false);
manualBombSettings = wdTable.GetBool("manualBombSettings", false);
lineofsight = wdTable.GetBool("lineOfSight", false);
ballistic = wdTable.GetBool("ballistic", false);
wd.twophase = wdTable.GetBool("twoPhase", false);
beamweapon = wdTable.GetBool("beamWeapon", false);
wd.guided = wdTable.GetBool("guidance", false);
rendertype = wdTable.GetInt("renderType", 0);
color = wdTable.GetInt("color", 0);
beamlaser = wdTable.GetInt("beamlaser", 0);
wd.vlaunch = wdTable.GetBool("vlaunch", false);
wd.selfprop = wdTable.GetBool("selfprop", false);
wd.turret = wdTable.GetBool("turret", false);
wd.noSelfDamage = wdTable.GetBool("noSelfDamage", false);
wd.visuals.modelName = wdTable.GetString("model", "");
wd.visuals.smokeTrail = wdTable.GetBool("smokeTrail", false);
wd.visuals.alwaysVisible = wdTable.GetBool("alwaysVisible", false);
wd.waterweapon = wdTable.GetBool("waterWeapon", false);
wd.fireSubmersed = wdTable.GetBool("fireSubmersed", wd.waterweapon);
wd.submissile = wdTable.GetBool("submissile", false);
wd.tracks = wdTable.GetBool("tracks", false);
wd.fixedLauncher = wdTable.GetBool("fixedLauncher", false);
wd.noExplode = wdTable.GetBool("noExplode", false);
wd.isShield = wdTable.GetBool("isShield", false);
wd.maxvelocity = wdTable.GetFloat("weaponVelocity", 0.0f);
wd.beamtime = wdTable.GetFloat("beamTime", 1.0f);
wd.beamburst = wdTable.GetBool("beamburst", false);
wd.waterBounce = wdTable.GetBool("waterbounce", false);
wd.groundBounce = wdTable.GetBool("groundbounce", false);
wd.bounceSlip = wdTable.GetFloat("bounceslip", 1);
wd.bounceRebound = wdTable.GetFloat("bouncerebound", 1);
wd.numBounce = wdTable.GetInt("numbounce", -1);
wd.thickness = wdTable.GetFloat("thickness", 2.0f);
wd.corethickness = wdTable.GetFloat("coreThickness", 0.25f);
wd.laserflaresize = wdTable.GetFloat("laserFlareSize", 15.0f);
wd.intensity = wdTable.GetFloat("intensity", 0.9f);
wd.duration = wdTable.GetFloat("duration", 0.05f);
wd.falloffRate = wdTable.GetFloat("fallOffRate", 0.5f);
wd.lodDistance = wdTable.GetInt("lodDistance", 1000);
wd.visuals.sizeDecay = wdTable.GetFloat("sizeDecay", 0.0f);
wd.visuals.alphaDecay = wdTable.GetFloat("alphaDecay", 1.0f);
wd.visuals.separation = wdTable.GetFloat("separation", 1.0f);
wd.visuals.noGap = wdTable.GetBool("noGap", true);
wd.visuals.stages = wdTable.GetInt("stages", 5);
if (wd.name.find("disintegrator") != string::npos) { //fulhack
wd.visuals.renderType = WEAPON_RENDERTYPE_FIREBALL;
} else if (wd.visuals.modelName.compare("") != 0) {
wd.visuals.renderType = WEAPON_RENDERTYPE_MODEL;
} else if (beamweapon) {
wd.visuals.renderType = WEAPON_RENDERTYPE_LASER;
} else {
wd.visuals.renderType = WEAPON_RENDERTYPE_PLASMA;
}
wd.gravityAffected = false;
if (wd.dropped || ballistic) {
wd.gravityAffected = true;
}
if (wd.dropped) {
wd.type = "AircraftBomb";
} else if (wd.vlaunch) {
wd.type = "StarburstLauncher";
} else if (beamlaser) {
wd.type = "BeamLaser";
} else if (wd.isShield) {
wd.type = "Shield";
} else if (wd.waterweapon) {
wd.type = "TorpedoLauncher";
} else if (wd.name.find("disintegrator") != string::npos) {
wd.type = "DGun";
} else if (lineofsight) {
if (rendertype==7) {
wd.type = "LightingCannon";
} else if (beamweapon) {
wd.type = "LaserCannon";
} else if (wd.visuals.modelName.find("laser") != string::npos) {
wd.type = "LaserCannon"; //swta fix
} else if (/*selfprop && */wd.visuals.smokeTrail) {
wd.type = "MissileLauncher";
} else if (rendertype == 4 && color == 2) {
wd.type = "EmgCannon";
} else if (rendertype == 5) {
wd.type = "Flame";
// } else if(rendertype == 1) {
// wd.type = "MissileLauncher";
} else {
wd.type = "Cannon";
}
} else {
wd.type = "Cannon";
}
string ttype = wdTable.GetString("weaponType", "");
if (ttype != "") {
wd.type = ttype;
}
// logOutput.Print("%s as %s",weaponname.c_str(),wd.type.c_str());
const bool melee = (wd.type == "Melee");
wd.targetBorder = wdTable.GetFloat("targetBorder", melee ? 1.0f : 0.0f);
if (wd.targetBorder > 1.0f) {
logOutput.Print("warning: targetBorder truncated to 1 (was %f)", wd.targetBorder);
wd.targetBorder = 1.0f;
} else if (wd.targetBorder < -1.0f) {
logOutput.Print("warning: targetBorder truncated to -1 (was %f)", wd.targetBorder);
wd.targetBorder = -1.0f;
}
wd.cylinderTargetting = wdTable.GetFloat("cylinderTargetting", melee ? 1.0f : 0.0f);
wd.range = wdTable.GetFloat("range", 10.0f);
const float accuracy = wdTable.GetFloat("accuracy", 0.0f);
const float sprayangle = wdTable.GetFloat("sprayAngle", 0.0f);
const float movingAccuracy = wdTable.GetFloat("movingAccuracy", accuracy);
// should really be tan but TA seem to cap it somehow
// should also be 7fff or ffff theoretically but neither seems good
wd.accuracy = sin((accuracy) * PI / 0xafff);
wd.sprayangle = sin((sprayangle) * PI / 0xafff);
wd.movingAccuracy = sin((movingAccuracy) * PI / 0xafff);
wd.targetMoveError = wdTable.GetFloat("targetMoveError", 0.0f);
wd.leadLimit = wdTable.GetFloat("leadLimit", -1.0f);
wd.leadBonus = wdTable.GetFloat("leadBonus", 0.0f);
// setup the default damages
const LuaTable dmgTable = wdTable.SubTable("damage");
float defDamage = dmgTable.GetFloat("default", 0.0f);
if (defDamage == 0.0f) {
defDamage = 1.0f; //avoid division by zeroes
}
for (int a = 0; a < damageArrayHandler->GetNumTypes(); ++a) {
wd.damages[a] = defDamage;
}
map<string, float> damages;
dmgTable.GetMap(damages);
map<string, float>::const_iterator di;
for (di = damages.begin(); di != damages.end(); ++di) {
const int type = damageArrayHandler->GetTypeFromName(di->first);
if (type != 0) {
float dmg = di->second;
if (dmg != 0.0f) {
wd.damages[type] = dmg;
} else {
wd.damages[type] = 1.0f;
}
}
}
wd.damages.impulseFactor = wdTable.GetFloat("impulseFactor", 1.0f);
wd.damages.impulseBoost = wdTable.GetFloat("impulseBoost", 0.0f);
wd.damages.craterMult = wdTable.GetFloat("craterMult", wd.damages.impulseFactor);
wd.damages.craterBoost = wdTable.GetFloat("craterBoost", 0.0f);
wd.areaOfEffect = wdTable.GetFloat("areaOfEffect", 8.0f) * 0.5f;
wd.edgeEffectiveness = wdTable.GetFloat("edgeEffectiveness", 0.0f);
// prevent 0/0 division in CGameHelper::Explosion
if (wd.edgeEffectiveness > 0.999f) {
wd.edgeEffectiveness = 0.999f;
}
wd.projectilespeed = wdTable.GetFloat("weaponVelocity", 0.0f) / GAME_SPEED;
wd.startvelocity = max(0.01f, wdTable.GetFloat("startVelocity", 0.0f) / GAME_SPEED);
wd.weaponacceleration = wdTable.GetFloat("weaponAcceleration", 0.0f) / GAME_SPEED / GAME_SPEED;
wd.reload = wdTable.GetFloat("reloadtime", 1.0f);
wd.salvodelay = wdTable.GetFloat("burstrate", 0.1f);
wd.salvosize = wdTable.GetInt("burst", 1);
wd.projectilespershot = wdTable.GetInt("projectiles", 1);
wd.maxAngle = wdTable.GetFloat("tolerance", 3000.0f) * 180.0f / 0x7fff;
wd.restTime = 0.0f;
wd.metalcost = wdTable.GetFloat("metalpershot", 0.0f);
wd.energycost = wdTable.GetFloat("energypershot", 0.0f);
wd.selfExplode = wdTable.GetBool("burnblow", false);
wd.predictBoost = wdTable.GetFloat("predictBoost", wd.selfExplode ? 0.5f : 0.0f);
wd.sweepFire = wdTable.GetBool("sweepfire", false);
wd.canAttackGround = wdTable.GetBool("canattackground", true);
wd.myGravity = wdTable.GetFloat("myGravity", 0.0f);
wd.fireStarter = wdTable.GetFloat("fireStarter", 0.0f) * 0.01f;
wd.paralyzer = wdTable.GetBool("paralyzer", false);
if (wd.paralyzer) {
wd.damages.paralyzeDamageTime = max(0, wdTable.GetInt("paralyzeTime", 10));
} else {
wd.damages.paralyzeDamageTime = 0;
}
const float defShake = wd.paralyzer ? 0.0f : wd.damages.GetDefaultDamage();
wd.cameraShake = wdTable.GetFloat("cameraShake", defShake);
wd.cameraShake = max(0.0f, wd.cameraShake);
wd.soundTrigger = wdTable.GetBool("soundTrigger", false);
//sunparser->GetDef(wd.highTrajectory, "0", weaponname + "minbarrelangle");
wd.stockpile = wdTable.GetBool("stockpile", false);
wd.interceptor = wdTable.GetInt("interceptor", 0);
wd.targetable = wdTable.GetInt("targetable", 0);
wd.manualfire = wdTable.GetBool("commandfire", false);
wd.coverageRange = wdTable.GetFloat("coverage", 0.0f);
// FIXME -- remove the old style ?
LuaTable shTable = wdTable.SubTable("shield");
const float3 shieldBadColor (1.0f, 0.5f, 0.5f);
const float3 shieldGoodColor(0.5f, 0.5f, 1.0f);
if (shTable.IsValid()) {
wd.shieldRepulser = shTable.GetBool("repulser", false);
wd.smartShield = shTable.GetBool("smart", false);
wd.exteriorShield = shTable.GetBool("exterior", false);
wd.visibleShield = shTable.GetBool("visible", false);
wd.visibleShieldRepulse = shTable.GetBool("visibleRepulse", false);
wd.visibleShieldHitFrames = shTable.GetInt("visibleHitFrames", 0);
wd.shieldEnergyUse = shTable.GetFloat("energyUse", 0.0f);
wd.shieldForce = shTable.GetFloat("force", 0.0f);
wd.shieldRadius = shTable.GetFloat("radius", 0.0f);
wd.shieldMaxSpeed = shTable.GetFloat("maxSpeed", 0.0f);
wd.shieldPower = shTable.GetFloat("power", 0.0f);
wd.shieldPowerRegen = shTable.GetFloat("powerRegen", 0.0f);
wd.shieldPowerRegenEnergy = shTable.GetFloat("powerRegenEnergy", 0.0f);
wd.shieldStartingPower = shTable.GetFloat("startingPower", 0.0f);
wd.shieldInterceptType = shTable.GetInt("interceptType", 0);
wd.shieldBadColor = shTable.GetFloat3("badColor", shieldBadColor);
wd.shieldGoodColor = shTable.GetFloat3("goodColor", shieldGoodColor);
wd.shieldAlpha = shTable.GetFloat("alpha", 0.2f);
}
else {
wd.shieldRepulser = wdTable.GetBool("shieldRepulser", false);
wd.smartShield = wdTable.GetBool("smartShield", false);
wd.exteriorShield = wdTable.GetBool("exteriorShield", false);
wd.visibleShield = wdTable.GetBool("visibleShield", false);
wd.visibleShieldRepulse = wdTable.GetBool("visibleShieldRepulse", false);
wd.visibleShieldHitFrames = wdTable.GetInt("visibleShieldHitFrames", 0);
wd.shieldEnergyUse = wdTable.GetFloat("shieldEnergyUse", 0.0f);
wd.shieldForce = wdTable.GetFloat("shieldForce", 0.0f);
wd.shieldRadius = wdTable.GetFloat("shieldRadius", 0.0f);
wd.shieldMaxSpeed = wdTable.GetFloat("shieldMaxSpeed", 0.0f);
wd.shieldPower = wdTable.GetFloat("shieldPower", 0.0f);
wd.shieldPowerRegen = wdTable.GetFloat("shieldPowerRegen", 0.0f);
wd.shieldPowerRegenEnergy = wdTable.GetFloat("shieldPowerRegenEnergy", 0.0f);
wd.shieldStartingPower = wdTable.GetFloat("shieldStartingPower", 0.0f);
wd.shieldInterceptType = wdTable.GetInt("shieldInterceptType", 0);
wd.shieldBadColor = wdTable.GetFloat3("shieldBadColor", shieldBadColor);
wd.shieldGoodColor = wdTable.GetFloat3("shieldGoodColor", shieldGoodColor);
wd.shieldAlpha = wdTable.GetFloat("shieldAlpha", 0.2f);
}
int defInterceptType = 0;
if (wd.type == "Cannon") {
defInterceptType = 1;
} else if ((wd.type == "LaserCannon") || (wd.type == "BeamLaser")) {
defInterceptType = 2;
} else if ((wd.type == "StarburstLauncher") || (wd.type == "MissileLauncher")) {
defInterceptType = 4;
}
wd.interceptedByShieldType = wdTable.GetInt("interceptedByShieldType", defInterceptType);
wd.wobble = wdTable.GetFloat("wobble", 0.0f) * PI / 0x7fff / 30.0f;
wd.dance = wdTable.GetFloat("dance", 0.0f) / GAME_SPEED;
wd.trajectoryHeight = wdTable.GetFloat("trajectoryHeight", 0.0f);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?