weapondefhandler.cpp

来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 737 行 · 第 1/2 页

CPP
737
字号

	wd.noAutoTarget = (wd.manualfire || wd.interceptor || wd.isShield);

	wd.onlyTargetCategory = 0xffffffff;
	if (wdTable.GetBool("toAirWeapon", false)) {
		// fix if we sometime call aircrafts otherwise
		wd.onlyTargetCategory = CCategoryHandler::Instance()->GetCategories("VTOL");
		//logOutput.Print("air only weapon %s %i",weaponname.c_str(),wd.onlyTargetCategory);
	}

	wd.largeBeamLaser = wdTable.GetBool("largeBeamLaser", false);
	wd.visuals.tilelength  = wdTable.GetFloat("tileLength", 200.0f);
	wd.visuals.scrollspeed = wdTable.GetFloat("scrollSpeed",  5.0f);
	wd.visuals.pulseSpeed  = wdTable.GetFloat("pulseSpeed",   1.0f);
	wd.visuals.beamdecay   = wdTable.GetFloat("beamDecay",    1.0f);
	wd.visuals.beamttl     = wdTable.GetInt("beamTTL", 0);

	if (wd.type == "Cannon") {
		wd.heightmod = wdTable.GetFloat("heightMod", 0.8f);
	} else if (wd.type == "BeamLaser") {
		wd.heightmod = wdTable.GetFloat("heightMod", 1.0f);
	} else {
		wd.heightmod = wdTable.GetFloat("heightMod", 0.2f);
	}

	wd.supplycost = 0.0f;

	wd.onlyForward = !wd.turret && (wd.type != "StarburstLauncher");

	const int color2 = wdTable.GetInt("color2", 0);

	const float3 rgbcol = hs2rgb(color / float(255), color2 / float(255));
	wd.visuals.color  = wdTable.GetFloat3("rgbColor",  rgbcol);
	wd.visuals.color2 = wdTable.GetFloat3("rgbColor2", float3(1.0f, 1.0f, 1.0f));

	wd.uptime = wdTable.GetFloat("weaponTimer", 0.0f);
	wd.flighttime = wdTable.GetInt("flightTime", 0) * 32;

	wd.turnrate = wdTable.GetFloat("turnRate", 0.0f) * PI / 0x7fff / 30.0f;

	if ((wd.type == "AircraftBomb") && !manualBombSettings) {
		if (wd.reload < 0.5f) {
			wd.salvodelay = min(0.2f, wd.reload);
			wd.salvosize = (int)(1 / wd.salvodelay) + 1;
			wd.reload = 5;
		} else {
			wd.salvodelay = min(0.4f, wd.reload);
			wd.salvosize = 2;
		}
	}
	//if(!wd.turret && (wd.type != "TorpedoLauncher")) {
	//	wd.maxAngle*=0.4f;
	//}

	//2+min(damages[0]*0.0025f,weaponDef->areaOfEffect*0.1f)
	const float tempsize = 2.0f + min(wd.damages[0] * 0.0025f, wd.areaOfEffect * 0.1f);
	wd.size = wdTable.GetFloat("size", tempsize);
	wd.sizeGrowth = wdTable.GetFloat("sizeGrowth", 0.2f);
	wd.collisionSize = wdTable.GetFloat("collisionSize", 0.05f);

	wd.visuals.colorMap = 0;
	const string colormap = wdTable.GetString("colormap", "");
	if (colormap != "") {
		wd.visuals.colorMap = CColorMap::LoadFromDefString(colormap);
	}

	wd.heightBoostFactor = wdTable.GetFloat("heightBoostFactor", -1.0f);
	wd.proximityPriority = wdTable.GetFloat("proximityPriority", 1.0f);

	// get some weapon specific defaults
	if (wd.type == "Cannon") {
		// CExplosiveProjectile
		wd.visuals.texture1 = &ph->plasmatex;
		wd.visuals.color = wdTable.GetFloat3("rgbColor", float3(1.0f,0.5f,0.0f));
		wd.intensity = wdTable.GetFloat("intensity", 0.2f);
	} else if (wd.type == "Rifle") {
		// ...
	} else if (wd.type == "Melee") {
		// ...
	} else if (wd.type == "AircraftBomb") {
		// CExplosiveProjectile or CTorpedoProjectile
		wd.visuals.texture1 = &ph->plasmatex;
	} else if (wd.type == "Shield") {
		wd.visuals.texture1 = &ph->perlintex;
	} else if (wd.type == "Flame") {
		// CFlameProjectile
		wd.visuals.texture1 = &ph->flametex;
		wd.size          = wdTable.GetFloat("size",      tempsize);
		wd.sizeGrowth    = wdTable.GetFloat("sizeGrowth",    0.5f);
		wd.collisionSize = wdTable.GetFloat("collisionSize", 0.5f);
		wd.duration      = wdTable.GetFloat("flameGfxTime",  1.2f);

		if (wd.visuals.colorMap == 0) {
			wd.visuals.colorMap = CColorMap::Load12f(1.000f, 1.000f, 1.000f, 0.100f,
			                                         0.025f, 0.025f, 0.025f, 0.100f,
			                                         0.000f, 0.000f, 0.000f, 0.000f);
		}

	} else if (wd.type == "MissileLauncher") {
		// CMissileProjectile
		wd.visuals.texture1 = &ph->missileflaretex;
		wd.visuals.texture2 = &ph->missiletrailtex;
	} else if (wd.type == "TorpedoLauncher") {
		// CExplosiveProjectile or CTorpedoProjectile
		wd.visuals.texture1 = &ph->plasmatex;
	} else if (wd.type == "LaserCannon") {
		// CLaserProjectile
		wd.visuals.texture1 = &ph->laserfallofftex;
		wd.visuals.texture2 = &ph->laserendtex;
		wd.visuals.hardStop = wdTable.GetBool("hardstop", false);
		wd.collisionSize = wdTable.GetFloat("collisionSize", 0.5f);
	} else if (wd.type == "BeamLaser") {
		if (wd.largeBeamLaser) {
			wd.visuals.texture1 = ph->textureAtlas->GetTexturePtr("largebeam");
			wd.visuals.texture2 = &ph->laserendtex;
			wd.visuals.texture3 = ph->textureAtlas->GetTexturePtr("muzzleside");
			wd.visuals.texture4 = &ph->beamlaserflaretex;
		} else {
			wd.visuals.texture1 = &ph->laserfallofftex;
			wd.visuals.texture2 = &ph->laserendtex;
			wd.visuals.texture3 = &ph->beamlaserflaretex;
		}
	} else if (wd.type == "LightingCannon") {
		wd.visuals.texture1 = &ph->laserfallofftex;
		wd.thickness = wdTable.GetFloat("thickness", 0.8f);
	} else if (wd.type == "EmgCannon") {
		// CEmgProjectile
		wd.visuals.texture1 = &ph->plasmatex;
		wd.visuals.color = wdTable.GetFloat3("rgbColor", float3(0.9f,0.9f,0.2f)); 
		wd.size = wdTable.GetFloat("size", 3.0f);
	} else if (wd.type == "DGun") {
		// CFireBallProjectile
		wd.collisionSize = wdTable.GetFloat("collisionSize", 10.0f);
	} else if (wd.type == "StarburstLauncher") {
		// CStarburstProjectile
		wd.visuals.texture1 = &ph->sbflaretex;
		wd.visuals.texture2 = &ph->sbtrailtex;
		wd.visuals.texture3 = &ph->explotex;
	} else {
		wd.visuals.texture1 = &ph->plasmatex;
		wd.visuals.texture2 = &ph->plasmatex;
	}

	// FIXME -- remove the 'textureN' format?
	LuaTable texTable = wdTable.SubTable("textures");
	string texName;
	texName = wdTable.GetString("texture1", "");
	texName = texTable.GetString(1, texName);
	if (texName != "") {
		wd.visuals.texture1 = ph->textureAtlas->GetTexturePtr(texName);
	}
	texName = wdTable.GetString("texture2", "");
	texName = texTable.GetString(2, texName);
	if (texName != "") {
		wd.visuals.texture2 = ph->textureAtlas->GetTexturePtr(texName);
	}
	texName = wdTable.GetString("texture3", "");
	texName = texTable.GetString(3, texName);
	if (texName != "") {
		wd.visuals.texture3 = ph->textureAtlas->GetTexturePtr(texName);
	}
	texName = wdTable.GetString("texture4", "");
	texName = texTable.GetString(4, texName);
	if (texName != "") {
		wd.visuals.texture4 = ph->textureAtlas->GetTexturePtr(texName);
	}

	const string expGenTag = wdTable.GetString("explosionGenerator", "");
	if (expGenTag.empty()) {
		wd.explosionGenerator = NULL;
	} else {
		wd.explosionGenerator = explGenHandler->LoadGenerator(expGenTag);
	}
	const string bounceExpGenTag = wdTable.GetString("bounceExplosionGenerator", "");
	if (bounceExpGenTag.empty()) {
		wd.bounceExplosionGenerator = NULL;
	} else {
		wd.bounceExplosionGenerator = explGenHandler->LoadGenerator(bounceExpGenTag);
	}

	const float gd = max(30.0f, wd.damages[0] / 20.0f);
	const float defExpSpeed = (8.0f + (gd * 2.5f)) / (9.0f + (sqrtf(gd) * 0.7f)) * 0.5f;
	wd.explosionSpeed = wdTable.GetFloat("explosionSpeed", defExpSpeed);

	// Dynamic Damage
	wd.dynDamageInverted = wdTable.GetBool("dynDamageInverted", false);
	wd.dynDamageExp      = wdTable.GetFloat("dynDamageExp",   0.0f);
	wd.dynDamageMin      = wdTable.GetFloat("dynDamageMin",   0.0f);
	wd.dynDamageRange    = wdTable.GetFloat("dynDamageRange", 0.0f);

	LoadSound(wdTable, wd.firesound, "firesound");
	LoadSound(wdTable, wd.soundhit,  "soundhit");

	if ((wd.firesound.getVolume(0) == -1.0f) ||
	    (wd.soundhit.getVolume(0)  == -1.0f)) {
		// no volume (-1.0f) read from weapon definition, set it dynamically here
		if (wd.damages[0] <= 50.0f) {
			wd.soundhit.setVolume(0, 5.0f);
			wd.firesound.setVolume(0, 5.0f);
		}
		else {
			float soundVolume = sqrt(wd.damages[0] * 0.5f);

			if (wd.type == "LaserCannon") {
				soundVolume *= 0.5f;
			}

			float hitSoundVolume = soundVolume;

			if ((soundVolume > 100.0f) &&
			    ((wd.type == "MissileLauncher") ||
			     (wd.type == "StarburstLauncher"))) {
				soundVolume = 10.0f * sqrt(soundVolume);
			}

			if (wd.firesound.getVolume(0) == -1.0f) {
				wd.firesound.setVolume(0, soundVolume);
			}

			soundVolume = hitSoundVolume;

			if (wd.areaOfEffect > 8.0f) {
				soundVolume *= 2.0f;
			}
			if (wd.type == "DGun") {
				soundVolume *= 0.15f;
			}
			if (wd.soundhit.getVolume(0) == -1.0f) {
				wd.soundhit.setVolume(0, soundVolume);
			}
		}
	}
}


void CWeaponDefHandler::LoadSound(const LuaTable& wdTable,
                                  GuiSoundSet& gsound, const string& soundCat)
{
	string name = "";
	float volume = -1.0f;

	if (soundCat == "firesound") {
		name   = wdTable.GetString("soundStart", "");
		volume = wdTable.GetFloat("soundStartVolume", -1.0f);
	}
	else if (soundCat == "soundhit") {
		name   = wdTable.GetString("soundHit", "");
		volume = wdTable.GetFloat("soundHitVolume", -1.0f);
	}

	if (name != "") {
		if (name.find(".wav") == -1) {
	 		// .wav extension missing, add it
			name += ".wav";
		}

		const string soundPath = "sounds/" + name;
		CFileHandler sfile(soundPath);

		if (sfile.FileExists()) {
			// only push data if we extracted a valid name
			GuiSoundSet::Data soundData(name, 0, volume);
			gsound.sounds.push_back(soundData);

			PUSH_CODE_MODE;
			ENTER_UNSYNCED;
			int id = sound->GetWaveId(soundPath);
			POP_CODE_MODE;

			gsound.setID(0, id);
		}
	}
}


const WeaponDef *CWeaponDefHandler::GetWeapon(const string weaponname2)
{
	string weaponname(StringToLower(weaponname2));

	map<string,int>::iterator ii=weaponID.find(weaponname);
	if(ii == weaponID.end())
		return NULL;

	return &weaponDefs[ii->second];
}

float3 CWeaponDefHandler::hs2rgb(float h, float s)
{
	if(h>0.5f)
		h+=0.1f;
	if(h>1)
		h-=1;

	s=1;
	float invSat=1-s;
	float3 col(invSat/2,invSat/2,invSat/2);

	if(h<1/6.0f){
		col.x+=s;
		col.y+=s*(h*6);
	} else if(h<1/3.0f){
		col.y+=s;
		col.x+=s*((1/3.0f-h)*6);

	} else if(h<1/2.0f){
		col.y+=s;
		col.z+=s*((h-1/3.0f)*6);

	} else if(h<2/3.0f){
		col.z+=s;
		col.y+=s*((2/3.0f-h)*6);

	} else if(h<5/6.0f){
		col.z+=s;
		col.x+=s*((h-2/3.0f)*6);

	} else {
		col.x+=s;
		col.z+=s*((3/3.0f-h)*6);
	}
	return col;
}

DamageArray CWeaponDefHandler::DynamicDamages(DamageArray damages, float3 startPos, float3 curPos, float range, float exp, float damageMin, bool inverted)
{
	DamageArray dynDamages(damages);

	curPos.y = 0;
	startPos.y = 0;

	float travDist = (curPos-startPos).Length()>range?range:(curPos-startPos).Length();
	float ddmod = 0;

	if (damageMin > 0)
		ddmod = damageMin/damages[0]; // get damage mod from first damage type

	if (inverted == true) {
		for(int i = 0; i < damageArrayHandler->GetNumTypes(); ++i) {
			dynDamages[i] = damages[i] - (1 - pow(1 / range * travDist, exp)) * damages[i];

			if (damageMin > 0)
				dynDamages[i] = max(damages[i] * ddmod, dynDamages[i]);

			// div by 0
			dynDamages[i] = max(0.0001f, dynDamages[i]);
//			logOutput.Print("D%i: %f (%f) - mod %f", i, dynDamages[i], damages[i], ddmod);
//			logOutput.Print("F%i: %f - (1 - (1/%f * %f) ^ %f) * %f", i, damages[i], range, travDist, exp, damages[i]);
		}
	}
	else {
		for(int i = 0; i < damageArrayHandler->GetNumTypes(); ++i) {
			dynDamages[i] = (1 - pow(1 / range * travDist, exp)) * damages[i];

			if (damageMin > 0)
				dynDamages[i] = max(damages[i] * ddmod, dynDamages[i]);

			// div by 0
			dynDamages[i] = max(0.0001f, dynDamages[i]);
//			logOutput.Print("D%i: %f (%f) - mod %f", i, dynDamages[i], damages[i], ddmod);
//			logOutput.Print("F%i: (1 - (1/%f * %f) ^ %f) * %f", i, range, travDist, exp, damages[i]);
		}
	}
	return dynDamages;
}

WeaponDef::~WeaponDef() {
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?