📄 laserprojectile.cpp
字号:
#include "StdAfx.h"
#include "Game/Camera.h"
#include "LaserProjectile.h"
#include "LogOutput.h"
#include "Map/Ground.h"
#include "Rendering/GL/VertexArray.h"
#include "Sim/Projectiles/ProjectileHandler.h"
#include "Sim/Projectiles/Unsynced/SimpleParticleSystem.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "mmgr.h"
CR_BIND_DERIVED(CLaserProjectile, CWeaponProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,float3(0,0,0),float3(0,0,0),0,NULL,0));
CR_REG_METADATA(CLaserProjectile,(
CR_MEMBER(dir),
CR_MEMBER(intensity),
CR_MEMBER(color),
CR_MEMBER(color2),
CR_MEMBER(length),
CR_MEMBER(curLength),
CR_MEMBER(speedf),
CR_MEMBER(stayTime),
CR_MEMBER(intensityFalloff),
CR_MEMBER(midtexx),
CR_RESERVED(16)
));
CLaserProjectile::CLaserProjectile(const float3& pos, const float3& speed,
CUnit* owner, float length, const float3& color, const float3& color2,
float intensity, const WeaponDef *weaponDef, int ttl)
: CWeaponProjectile(pos,speed,owner,0,ZeroVector,weaponDef,0, true, ttl),
color(color),
color2(color2),
length(length),
curLength(0),
stayTime(0),
intensity(intensity),
intensityFalloff(intensity*weaponDef->falloffRate)
{
dir=speed;
dir.Normalize();
speedf=speed.Length();
if (weaponDef) SetRadius(weaponDef->collisionSize);
drawRadius=length;
if (weaponDef)midtexx = weaponDef->visuals.texture2->xstart + (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*0.5f;
#ifdef TRACE_SYNC
tracefile << "New laser: ";
tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif
if (cegTag.size() > 0) {
ceg.Load(explGenHandler, cegTag);
}
}
CLaserProjectile::~CLaserProjectile(void)
{
}
void CLaserProjectile::Update(void)
{
pos += speed;
if (checkCol) {
// normal
curLength += speedf;
if (curLength > length)
curLength = length;
} else {
// fading out after hit
if (stayTime <= 0)
curLength -= speedf;
else
stayTime--;
if (curLength <= 0) {
deleteMe = true;
curLength = 0;
}
}
ttl--;
if (ttl > 0 && checkCol) {
if (cegTag.size() > 0) {
ceg.Explosion(pos, ttl, intensity, 0x0, 0.0f, 0x0, speed);
}
}
if (weaponDef->visuals.hardStop) {
if (ttl == 0 && checkCol) {
checkCol = false;
speed = ZeroVector;
if (curLength < length) {
// if the laser wasn't fully extended yet,
// remember how long until it would have been
// fully extended
stayTime = int(1 + (length - curLength) / speedf);
}
}
} else {
if (ttl < 5 && checkCol) {
intensity -= intensityFalloff * 0.2f;
if (intensity <= 0) {
deleteMe = true;
intensity = 0;
}
}
}
float3 tempSpeed = speed;
UpdateGroundBounce();
if (tempSpeed != speed) {
dir = speed;
dir.Normalize();
}
}
void CLaserProjectile::Collision(CUnit* unit)
{
float3 oldPos=pos;
CWeaponProjectile::Collision(unit);
deleteMe=false; //we will fade out over some time
if (!weaponDef->noExplode) {
checkCol = false;
speed = ZeroVector;
pos = oldPos;
if (curLength < length) {
// if the laser wasn't fully extended yet
// and was too short for some reason,
// remember how long until it would have
// been fully extended
curLength += speedf;
stayTime = int(1 + (length - curLength) / speedf);
}
}
}
void CLaserProjectile::Collision(CFeature* feature)
{
float3 oldPos=pos;
CWeaponProjectile::Collision(feature);
// we will fade out over some time
deleteMe = false;
if (!weaponDef->noExplode) {
checkCol = false;
speed = ZeroVector;
pos = oldPos;
if (curLength < length) {
// if the laser wasn't fully extended yet,
// remember how long until it would have been
// fully extended
stayTime = int(1 + (length - curLength) / speedf);
}
}
}
void CLaserProjectile::Collision()
{
if (weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z) < pos.y) {
// prevent impact on water if waterweapon is set
return;
}
float3 oldPos = pos;
CWeaponProjectile::Collision();
// we will fade out over some time
deleteMe = false;
if (!weaponDef->noExplode) {
checkCol = false;
speed = ZeroVector;
pos = oldPos;
if (curLength < length) {
// if the laser wasn't fully extended yet,
// remember how long until it would have been
// fully extended
stayTime = int(1 + (length - curLength) / speedf);
}
}
//CSimpleParticleSystem *ps = SAFE_NEW CSimpleParticleSystem();
//ps->particleLife = 30*3;
//ps->particleLifeSpread = 30*3;
//ps->particleSize = 6;
//ps->particleSizeSpread = 2;
//ps->emitVector = float3(0,0,0);
//ps->emitSpread = float3(4,1,4).Normalize();
//ps->pos = pos;
//ps->numParticles = 2000;
//ps->airdrag = 0.85f;
//ps->speed = 30.0f;
//ps->speedSpread = 8.0f;
//ps->Init();
}
void CLaserProjectile::Draw(void)
{
if(s3domodel) //dont draw if a 3d model has been defined for us
return;
inArray=true;
float3 dif(pos-camera->pos);
float camDist=dif.Length();
dif/=camDist;
float3 dir1(dif.cross(dir));
dir1.Normalize();
float3 dir2(dif.cross(dir1));
unsigned char col[4];
col[0]=(unsigned char) (color.x*intensity*255);
col[1]=(unsigned char) (color.y*intensity*255);
col[2]=(unsigned char) (color.z*intensity*255);
col[3]=1;//intensity*255;
unsigned char col2[4];
col2[0]=(unsigned char) (color2.x*intensity*255);
col2[1]=(unsigned char) (color2.y*intensity*255);
col2[2]=(unsigned char) (color2.z*intensity*255);
col2[3]=1;//intensity*255;
float size=weaponDef->thickness;
float coresize=size * weaponDef->corethickness;
if(camDist<weaponDef->lodDistance){
float3 pos1=pos+speed*gu->timeOffset;
float3 pos2=pos1-dir*curLength;
float texStartOffset;
float texEndOffset;
if (checkCol) { //expanding or contracting?
texStartOffset=0;
texEndOffset=(1.0f - curLength/length)*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
}
else {
texStartOffset=(-1.0f + curLength/length + ((float)stayTime * speedf/length))*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
texEndOffset= ((float)stayTime * speedf/length)*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
}
va->AddVertexTC(pos1-dir1*size, midtexx,weaponDef->visuals.texture2->ystart, col);
va->AddVertexTC(pos1+dir1*size, midtexx,weaponDef->visuals.texture2->yend,col);
va->AddVertexTC(pos1+dir1*size-dir2*size, weaponDef->visuals.texture2->xstart,weaponDef->visuals.texture2->yend,col);
va->AddVertexTC(pos1-dir1*size-dir2*size, weaponDef->visuals.texture2->xstart,weaponDef->visuals.texture2->ystart,col);
va->AddVertexTC(pos1-dir1*coresize,midtexx,weaponDef->visuals.texture2->ystart, col2);
va->AddVertexTC(pos1+dir1*coresize,midtexx,weaponDef->visuals.texture2->yend,col2);
va->AddVertexTC(pos1+dir1*coresize-dir2*coresize,weaponDef->visuals.texture2->xstart,weaponDef->visuals.texture2->yend,col2);
va->AddVertexTC(pos1-dir1*coresize-dir2*coresize,weaponDef->visuals.texture2->xstart,weaponDef->visuals.texture2->ystart,col2);
va->AddVertexTC(pos1-dir1*size,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->ystart, col);
va->AddVertexTC(pos1+dir1*size,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->yend, col);
va->AddVertexTC(pos2+dir1*size,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->yend, col);
va->AddVertexTC(pos2-dir1*size,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->ystart, col);
va->AddVertexTC(pos1-dir1*coresize,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->ystart, col2);
va->AddVertexTC(pos1+dir1*coresize,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->yend, col2);
va->AddVertexTC(pos2+dir1*coresize,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->yend, col2);
va->AddVertexTC(pos2-dir1*coresize,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->ystart, col2);
va->AddVertexTC(pos2-dir1*size, midtexx,weaponDef->visuals.texture2->ystart, col);
va->AddVertexTC(pos2+dir1*size, midtexx,weaponDef->visuals.texture2->yend,col);
va->AddVertexTC(pos2+dir1*size+dir2*size, weaponDef->visuals.texture2->xend,weaponDef->visuals.texture2->yend,col);
va->AddVertexTC(pos2-dir1*size+dir2*size, weaponDef->visuals.texture2->xend,weaponDef->visuals.texture2->ystart,col);
va->AddVertexTC(pos2-dir1*coresize,midtexx,weaponDef->visuals.texture2->ystart, col2);
va->AddVertexTC(pos2+dir1*coresize,midtexx,weaponDef->visuals.texture2->yend,col2);
va->AddVertexTC(pos2+dir1*coresize+dir2*coresize,weaponDef->visuals.texture2->xend,weaponDef->visuals.texture2->yend,col2);
va->AddVertexTC(pos2-dir1*coresize+dir2*coresize,weaponDef->visuals.texture2->xend,weaponDef->visuals.texture2->ystart,col2);
} else {
float3 pos1=pos+speed*gu->timeOffset+dir*(size*0.5f);
float3 pos2=pos1-dir*(curLength+size);
float texStartOffset;
float texEndOffset;
if (checkCol) { //expanding or contracting?
texStartOffset=0;
texEndOffset=(1.0f - curLength/length)*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
}
else {
texStartOffset=(-1.0f + curLength/length + ((float)stayTime * speedf/length))*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
texEndOffset= ((float)stayTime * speedf/length)*(weaponDef->visuals.texture1->xstart - weaponDef->visuals.texture1->xend);
}
va->AddVertexTC(pos1-dir1*size,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->ystart, col);
va->AddVertexTC(pos1+dir1*size,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->yend, col);
va->AddVertexTC(pos2+dir1*size,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->yend, col);
va->AddVertexTC(pos2-dir1*size,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->ystart, col);
va->AddVertexTC(pos1-dir1*coresize,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->ystart, col2);
va->AddVertexTC(pos1+dir1*coresize,weaponDef->visuals.texture1->xstart + texStartOffset,weaponDef->visuals.texture1->yend, col2);
va->AddVertexTC(pos2+dir1*coresize,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->yend, col2);
va->AddVertexTC(pos2-dir1*coresize,weaponDef->visuals.texture1->xend + texEndOffset,weaponDef->visuals.texture1->ystart, col2);
}
}
int CLaserProjectile::ShieldRepulse(CPlasmaRepulser* shield,float3 shieldPos, float shieldForce, float shieldMaxSpeed)
{
float3 sdir=pos-shieldPos;
sdir.Normalize();
if(sdir.dot(speed)<0){
speed-=sdir*sdir.dot(speed)*2;
dir=speed;
dir.Normalize();
return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -