Attached Files |
-
weaponChanges.patch (47,800 bytes) 2007-06-24 21:59
Index: Sim/Projectiles/LightingProjectile.cpp
===================================================================
--- Sim/Projectiles/LightingProjectile.cpp (revision 3842)
+++ Sim/Projectiles/LightingProjectile.cpp (working copy)
@@ -58,7 +58,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: Sim/Projectiles/MissileProjectile.cpp
===================================================================
--- Sim/Projectiles/MissileProjectile.cpp (revision 3842)
+++ Sim/Projectiles/MissileProjectile.cpp (working copy)
@@ -120,7 +120,7 @@
float h=ground->GetHeight2(pos.x,pos.z);
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail) SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -128,7 +128,7 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail) SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -206,7 +206,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -233,6 +233,7 @@
float color=0.6f;
unsigned char col[4];
+ if (weaponDef->visuals.smokeTrail)
if(drawTrail){ //draw the trail as a single quad
float3 dif(interPos-camera->pos);
dif.Normalize();
Index: Sim/Projectiles/StarburstProjectile.cpp
===================================================================
--- Sim/Projectiles/StarburstProjectile.cpp (revision 3842)
+++ Sim/Projectiles/StarburstProjectile.cpp (working copy)
@@ -110,7 +110,7 @@
float h=ground->GetHeight2(pos.x,pos.z);
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail) SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -119,7 +119,7 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail) SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -145,8 +145,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0){
float3 dif(targetPos-pos);
@@ -164,7 +163,7 @@
speed=dir*curSpeed;
} else if(ttl>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -197,7 +196,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -226,6 +225,7 @@
unsigned char col[4];
unsigned char col2[4];
+ if (weaponDef->visuals.smokeTrail)
if(drawTrail){ //draw the trail as a single quad
float3 dif(interPos-camera->pos);
Index: Sim/Projectiles/StarburstProjectile.h
===================================================================
--- Sim/Projectiles/StarburstProjectile.h (revision 3842)
+++ Sim/Projectiles/StarburstProjectile.h (working copy)
@@ -27,6 +27,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: Sim/Units/COB/CobFile.cpp
===================================================================
--- Sim/Units/COB/CobFile.cpp (revision 3842)
+++ Sim/Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: Sim/Units/COB/CobFile.h
===================================================================
--- Sim/Units/COB/CobFile.h (revision 3842)
+++ Sim/Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: Sim/Units/COB/CobInstance.cpp
===================================================================
--- Sim/Units/COB/CobInstance.cpp (revision 3842)
+++ Sim/Units/COB/CobInstance.cpp (working copy)
@@ -650,15 +650,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[type-2048]->targetPos;
- float3 weaponPos = unit->weapons[type-2048]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[type-2048]->weaponMuzzlePos;
unit->weapons[type-2048]->targetPos = pos+dir;
- unit->weapons[type-2048]->weaponPos = pos;
+ unit->weapons[type-2048]->weaponMuzzlePos = pos;
unit->weapons[type-2048]->Fire();
unit->weapons[type-2048]->targetPos = targetPos;
- unit->weapons[type-2048]->weaponPos = weaponPos;
+ unit->weapons[type-2048]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
Index: Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- Sim/Units/UnitTypes/Builder.cpp (revision 3842)
+++ Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -583,9 +583,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(float3(0,1,0)))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: Sim/Weapons/BeamLaser.cpp
===================================================================
--- Sim/Weapons/BeamLaser.cpp (revision 3842)
+++ Sim/Weapons/BeamLaser.cpp (working copy)
@@ -42,6 +42,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -84,7 +85,7 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -92,14 +93,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -125,7 +126,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -147,7 +148,7 @@
#endif
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -192,7 +193,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: Sim/Weapons/Cannon.cpp
===================================================================
--- Sim/Weapons/Cannon.cpp (revision 3842)
+++ Sim/Weapons/Cannon.cpp (working copy)
@@ -59,6 +59,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -94,7 +96,7 @@
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -109,7 +111,7 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
@@ -119,7 +121,7 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
flatlength-30, dir.y, gs->gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
@@ -142,7 +144,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -159,7 +161,7 @@
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -168,8 +170,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if(weaponPos.y<30)
- water->AddExplosion(weaponPos,damages[0]*0.1f,sqrt(damages[0])+80);
+ if(weaponMuzzlePos.y<30)
+ water->AddExplosion(weaponMuzzlePos,damages[0]*0.1f,sqrt(damages[0])+80);
}
void CCannon::SlowUpdate(void)
Index: Sim/Weapons/DGunWeapon.cpp
===================================================================
--- Sim/Weapons/DGunWeapon.cpp (revision 3842)
+++ Sim/Weapons/DGunWeapon.cpp (working copy)
@@ -23,7 +23,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -42,13 +43,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: Sim/Weapons/EmgCannon.cpp
===================================================================
--- Sim/Weapons/EmgCannon.cpp (revision 3842)
+++ Sim/Weapons/EmgCannon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -49,21 +50,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -83,15 +84,16 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Sim/Weapons/FlameThrower.cpp
===================================================================
--- Sim/Weapons/FlameThrower.cpp (revision 3842)
+++ Sim/Weapons/FlameThrower.cpp (working copy)
@@ -26,12 +26,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -49,21 +49,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -73,6 +73,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: Sim/Weapons/LaserCannon.cpp
===================================================================
--- Sim/Weapons/LaserCannon.cpp (revision 3842)
+++ Sim/Weapons/LaserCannon.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -51,7 +52,7 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -59,14 +60,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -83,7 +84,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -95,10 +96,11 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Sim/Weapons/LightingCannon.cpp
===================================================================
--- Sim/Weapons/LightingCannon.cpp (revision 3842)
+++ Sim/Weapons/LightingCannon.cpp (working copy)
@@ -29,6 +29,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -50,21 +51,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -76,14 +77,14 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
}
@@ -94,11 +95,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
Index: Sim/Weapons/MeleeWeapon.cpp
===================================================================
--- Sim/Weapons/MeleeWeapon.cpp (revision 3842)
+++ Sim/Weapons/MeleeWeapon.cpp (working copy)
@@ -27,8 +27,16 @@
void CMeleeWeapon::Update()
{
+ if(targetType!=Target_None){
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
+ wantedDir=targetPos-weaponPos;
+ wantedDir.Normalize();
+ }
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
+ }
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
Index: Sim/Weapons/MissileLauncher.cpp
===================================================================
--- Sim/Weapons/MissileLauncher.cpp (revision 3842)
+++ Sim/Weapons/MissileLauncher.cpp (working copy)
@@ -25,7 +25,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -45,12 +46,15 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
+ if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
+ }
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
@@ -60,7 +64,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -79,7 +83,7 @@
if(pos.y<0)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -91,11 +95,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -106,7 +110,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -115,7 +119,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: Sim/Weapons/Rifle.cpp
===================================================================
--- Sim/Weapons/Rifle.cpp (revision 3842)
+++ Sim/Weapons/Rifle.cpp (working copy)
@@ -37,6 +37,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -56,18 +57,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -75,7 +76,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -84,13 +85,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length=helper->TraceRay(weaponPos,dir,range,damages[0],owner,hit);
+ float length=helper->TraceRay(weaponMuzzlePos,dir,range,damages[0],owner,hit);
if(hit){
hit->DoDamage(damages,owner,ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos+dir*length,hit->speed*0.9f,30,1,owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos+dir*length,hit->speed*0.9f,30,1,owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/StarburstLauncher.cpp
===================================================================
--- Sim/Weapons/StarburstLauncher.cpp (revision 3842)
+++ Sim/Weapons/StarburstLauncher.cpp (working copy)
@@ -30,6 +30,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -37,7 +38,11 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
+ float3 speed(0,weaponDef->startvelocity,0);
+ if(weaponDef->fixedLauncher) {
+ speed=weaponDir * weaponDef->startvelocity;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -59,8 +64,12 @@
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
- return false;
+ if(!weaponDef->fixedLauncher)
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,UpVector,100,0,owner->allyteam,owner))
+ return false;
+ else
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,weaponDir,100,0,owner->allyteam,owner))
+ return false;
return true;
}
Index: Sim/Weapons/TorpedoLauncher.cpp
===================================================================
--- Sim/Weapons/TorpedoLauncher.cpp (revision 3842)
+++ Sim/Weapons/TorpedoLauncher.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -46,7 +47,7 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
@@ -57,7 +58,7 @@
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -76,14 +77,14 @@
if(ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: Sim/Weapons/Weapon.cpp
===================================================================
--- Sim/Weapons/Weapon.cpp (revision 3842)
+++ Sim/Weapons/Weapon.cpp (working copy)
@@ -56,9 +56,11 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(damages),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -127,8 +129,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -167,12 +171,11 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
- owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- } else {
- owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
- }
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
}
if(targetType==Target_Unit){
@@ -249,16 +252,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->waterweapon || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -294,35 +299,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -353,9 +375,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -378,8 +400,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -427,18 +451,17 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
- owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- if(useWeaponPosForAim>1)
- useWeaponPosForAim--;
- } else {
- owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
- }
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -542,7 +565,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
float r=GetRange2D(owner->pos.y-pos.y);
if(dif.SqLength2D()>=r*r)
@@ -586,11 +609,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -616,11 +641,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -631,6 +658,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: Sim/Weapons/Weapon.h
===================================================================
--- Sim/Weapons/Weapon.h (revision 3842)
+++ Sim/Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: Sim/Weapons/WeaponDefHandler.cpp
===================================================================
--- Sim/Weapons/WeaponDefHandler.cpp (revision 3842)
+++ Sim/Weapons/WeaponDefHandler.cpp (working copy)
@@ -109,6 +109,7 @@
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -243,6 +244,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
Index: Sim/Weapons/WeaponDefHandler.h
===================================================================
--- Sim/Weapons/WeaponDefHandler.h (revision 3842)
+++ Sim/Weapons/WeaponDefHandler.h (working copy)
@@ -72,11 +72,14 @@
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
bool tracks;
bool dropped;
-
weaponChangesFix1.patch (57,391 bytes) 2007-07-12 18:12
Index: Projectiles/LightingProjectile.cpp
===================================================================
--- Projectiles/LightingProjectile.cpp (revision 3912)
+++ Projectiles/LightingProjectile.cpp (working copy)
@@ -58,7 +58,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: Projectiles/MissileProjectile.cpp
===================================================================
--- Projectiles/MissileProjectile.cpp (revision 3912)
+++ Projectiles/MissileProjectile.cpp (working copy)
@@ -120,7 +120,8 @@
float h=ground->GetHeight2(pos.x,pos.z);
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -128,7 +129,8 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -206,7 +208,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -233,66 +235,67 @@
float color=0.6f;
unsigned char col[4];
- if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- float alpha=min((float)255,max(float(0),a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char) alpha;
-
- unsigned char col2[4];
- float a2=(1-float(age2)/(Smoke_Time))*255;
- if(age<8)
- a2=0;
- a2*=0.7f+fabs(dif2.dot(oldDir));
- alpha=min((float)255,max((float)0,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char) alpha;
-
- float size=(1);
- float size2=(1+(age2*(1/Smoke_Time))*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- float alpha=255;
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ float alpha=min((float)255,max(float(0),a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
- float size=(1+(a*(1/Smoke_Time))*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ col[3]=(unsigned char) alpha;
+
+ unsigned char col2[4];
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ if(age<8)
+ a2=0;
+ a2*=0.7f+fabs(dif2.dot(oldDir));
+ alpha=min((float)255,max((float)0,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char) alpha;
+
+ float size=(1);
+ float size2=(1+(age2*(1/Smoke_Time))*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ float alpha=255;
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
+ float size=(1+(a*(1/Smoke_Time))*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
//rita flaren
col[0]=255;
col[1]=210;
Index: Projectiles/StarburstProjectile.cpp
===================================================================
--- Projectiles/StarburstProjectile.cpp (revision 3912)
+++ Projectiles/StarburstProjectile.cpp (working copy)
@@ -110,7 +110,8 @@
float h=ground->GetHeight2(pos.x,pos.z);
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -119,7 +120,8 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -145,8 +147,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0){
float3 dif(targetPos-pos);
@@ -164,7 +165,7 @@
speed=dir*curSpeed;
} else if(ttl>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -197,7 +198,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -226,65 +227,66 @@
unsigned char col[4];
unsigned char col2[4];
- if(drawTrail){ //draw the trail as a single quad
-
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldSmokeDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- int alpha=min(255,(int)max(0.f,a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;
-
- float a2=(1-float(age2)/(Smoke_Time))*255;
- a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
- if(age<8)
- a2=0;
- alpha=min(255,(int)max(0.f,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char)alpha;
-
- float size=1;
- float size2=(1+age2*(1/Smoke_Time)*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- col[0]=(unsigned char) (color*255);
- col[1]=(unsigned char) (color*255);
- col[2]=(unsigned char) (color*255);
- col[3]=255;//min(255,max(0,a1*255));
- float size=(1+(a)*(1/Smoke_Time)*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldSmokeDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ int alpha=min(255,(int)max(0.f,a1));
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;
+
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
+ if(age<8)
+ a2=0;
+ alpha=min(255,(int)max(0.f,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char)alpha;
+
+ float size=1;
+ float size2=(1+age2*(1/Smoke_Time)*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ col[0]=(unsigned char) (color*255);
+ col[1]=(unsigned char) (color*255);
+ col[2]=(unsigned char) (color*255);
+ col[3]=255;//min(255,max(0,a1*255));
+ float size=(1+(a)*(1/Smoke_Time)*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
DrawCallback();
if(curCallback==0)
DrawCallback();
Index: Projectiles/StarburstProjectile.h
===================================================================
--- Projectiles/StarburstProjectile.h (revision 3912)
+++ Projectiles/StarburstProjectile.h (working copy)
@@ -27,6 +27,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: Units/COB/CobFile.cpp
===================================================================
--- Units/COB/CobFile.cpp (revision 3912)
+++ Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: Units/COB/CobFile.h
===================================================================
--- Units/COB/CobFile.h (revision 3912)
+++ Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: Units/COB/CobInstance.cpp
===================================================================
--- Units/COB/CobInstance.cpp (revision 3912)
+++ Units/COB/CobInstance.cpp (working copy)
@@ -655,15 +655,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[type-2048]->targetPos;
- float3 weaponPos = unit->weapons[type-2048]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[type-2048]->weaponMuzzlePos;
unit->weapons[type-2048]->targetPos = pos+dir;
- unit->weapons[type-2048]->weaponPos = pos;
+ unit->weapons[type-2048]->weaponMuzzlePos = pos;
unit->weapons[type-2048]->Fire();
unit->weapons[type-2048]->targetPos = targetPos;
- unit->weapons[type-2048]->weaponPos = weaponPos;
+ unit->weapons[type-2048]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
Index: Units/UnitTypes/Builder.cpp
===================================================================
--- Units/UnitTypes/Builder.cpp (revision 3912)
+++ Units/UnitTypes/Builder.cpp (working copy)
@@ -581,9 +581,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(updir))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: Weapons/BeamLaser.cpp
===================================================================
--- Weapons/BeamLaser.cpp (revision 3912)
+++ Weapons/BeamLaser.cpp (working copy)
@@ -42,6 +42,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -84,7 +85,7 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
@@ -93,14 +94,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -126,7 +127,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -150,7 +151,7 @@
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -218,7 +219,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: Weapons/Cannon.cpp
===================================================================
--- Weapons/Cannon.cpp (revision 3912)
+++ Weapons/Cannon.cpp (working copy)
@@ -59,6 +59,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -94,7 +96,7 @@
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -109,7 +111,7 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
@@ -119,7 +121,7 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
flatlength-30, dir.y, gs->gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
@@ -142,7 +144,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -159,7 +161,7 @@
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -168,8 +170,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if(weaponPos.y<30)
- water->AddExplosion(weaponPos,damages[0]*0.1f,sqrt(damages[0])+80);
+ if(weaponMuzzlePos.y<30)
+ water->AddExplosion(weaponMuzzlePos,damages[0]*0.1f,sqrt(damages[0])+80);
}
void CCannon::SlowUpdate(void)
Index: Weapons/DGunWeapon.cpp
===================================================================
--- Weapons/DGunWeapon.cpp (revision 3912)
+++ Weapons/DGunWeapon.cpp (working copy)
@@ -23,7 +23,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -42,13 +43,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: Weapons/EmgCannon.cpp
===================================================================
--- Weapons/EmgCannon.cpp (revision 3912)
+++ Weapons/EmgCannon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -49,21 +50,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -83,15 +84,16 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Weapons/FlameThrower.cpp
===================================================================
--- Weapons/FlameThrower.cpp (revision 3912)
+++ Weapons/FlameThrower.cpp (working copy)
@@ -26,12 +26,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -49,21 +49,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -73,6 +73,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: Weapons/LaserCannon.cpp
===================================================================
--- Weapons/LaserCannon.cpp (revision 3912)
+++ Weapons/LaserCannon.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -51,7 +52,7 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -59,14 +60,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -83,7 +84,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -95,10 +96,11 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Weapons/LightingCannon.cpp
===================================================================
--- Weapons/LightingCannon.cpp (revision 3912)
+++ Weapons/LightingCannon.cpp (working copy)
@@ -29,6 +29,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -50,21 +51,21 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -76,14 +77,14 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
}
@@ -94,11 +95,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
Index: Weapons/MeleeWeapon.cpp
===================================================================
--- Weapons/MeleeWeapon.cpp (revision 3912)
+++ Weapons/MeleeWeapon.cpp (working copy)
@@ -27,8 +27,16 @@
void CMeleeWeapon::Update()
{
+ if(targetType!=Target_None){
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
+ wantedDir=targetPos-weaponPos;
+ wantedDir.Normalize();
+ }
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
+ }
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
Index: Weapons/MissileLauncher.cpp
===================================================================
--- Weapons/MissileLauncher.cpp (revision 3912)
+++ Weapons/MissileLauncher.cpp (working copy)
@@ -25,7 +25,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -45,12 +46,15 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
+ if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
+ }
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
@@ -60,7 +64,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -79,7 +83,7 @@
if(pos.y<0)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -91,11 +95,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -106,7 +110,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -115,7 +119,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: Weapons/Rifle.cpp
===================================================================
--- Weapons/Rifle.cpp (revision 3912)
+++ Weapons/Rifle.cpp (working copy)
@@ -37,6 +37,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -56,18 +57,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -75,7 +76,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -84,13 +85,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length=helper->TraceRay(weaponPos,dir,range,damages[0],owner,hit);
+ float length=helper->TraceRay(weaponMuzzlePos,dir,range,damages[0],owner,hit);
if(hit){
hit->DoDamage(damages,owner,ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos+dir*length,hit->speed*0.9f,30,1,owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos+dir*length,hit->speed*0.9f,30,1,owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Weapons/StarburstLauncher.cpp
===================================================================
--- Weapons/StarburstLauncher.cpp (revision 3912)
+++ Weapons/StarburstLauncher.cpp (working copy)
@@ -30,6 +30,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -37,7 +38,11 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
+ float3 speed(0,weaponDef->startvelocity,0);
+ if(weaponDef->fixedLauncher) {
+ speed=weaponDir * weaponDef->startvelocity;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -59,8 +64,12 @@
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
- return false;
+ if(!weaponDef->fixedLauncher)
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,UpVector,100,0,owner->allyteam,owner))
+ return false;
+ else
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,weaponDir,100,0,owner->allyteam,owner))
+ return false;
return true;
}
Index: Weapons/TorpedoLauncher.cpp
===================================================================
--- Weapons/TorpedoLauncher.cpp (revision 3912)
+++ Weapons/TorpedoLauncher.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -46,7 +47,7 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
@@ -57,7 +58,7 @@
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -76,14 +77,14 @@
if(ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: Weapons/Weapon.cpp
===================================================================
--- Weapons/Weapon.cpp (revision 3912)
+++ Weapons/Weapon.cpp (working copy)
@@ -56,9 +56,11 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(damages),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -130,8 +132,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -173,12 +177,11 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
- owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- } else {
- owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
- }
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
}
if(targetType==Target_Unit){
@@ -255,16 +258,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->waterweapon || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -300,35 +305,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -359,9 +381,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -384,8 +406,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -433,18 +457,17 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
- owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- if(useWeaponPosForAim>1)
- useWeaponPosForAim--;
- } else {
- owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
- }
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -548,7 +571,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
if (targetBorder != 0 && unit) {
float3 diff(dif);
@@ -616,11 +639,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -646,11 +671,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -661,6 +688,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: Weapons/Weapon.h
===================================================================
--- Weapons/Weapon.h (revision 3912)
+++ Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: Weapons/WeaponDefHandler.cpp
===================================================================
--- Weapons/WeaponDefHandler.cpp (revision 3912)
+++ Weapons/WeaponDefHandler.cpp (working copy)
@@ -111,6 +111,7 @@
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -256,6 +257,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
Index: Weapons/WeaponDefHandler.h
===================================================================
--- Weapons/WeaponDefHandler.h (revision 3912)
+++ Weapons/WeaponDefHandler.h (working copy)
@@ -72,11 +72,14 @@
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
bool tracks;
bool dropped;
-
evenMoreWeaponChanges.patch (78,478 bytes) 2007-07-20 17:12
Index: Sim/Projectiles/EmgProjectile.cpp
===================================================================
--- Sim/Projectiles/EmgProjectile.cpp (revision 4026)
+++ Sim/Projectiles/EmgProjectile.cpp (working copy)
@@ -4,6 +4,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Sync/SyncTracer.h"
#include "ProjectileHandler.h"
+#include "Map/Ground.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "mmgr.h"
@@ -52,10 +53,14 @@
void CEmgProjectile::Collision(CUnit* unit)
{
// unit->DoDamage(damages,owner);
-
CWeaponProjectile::Collision(unit);
}
+void CEmgProjectile::Collision() {
+ if (!(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z) < pos.y))
+ CWeaponProjectile::Collision();
+}
+
void CEmgProjectile::Draw(void)
{
inArray=true;
Index: Sim/Projectiles/EmgProjectile.h
===================================================================
--- Sim/Projectiles/EmgProjectile.h (revision 4026)
+++ Sim/Projectiles/EmgProjectile.h (working copy)
@@ -14,6 +14,7 @@
void Update(void);
void Draw(void);
void Collision(CUnit* unit);
+ void Collision();
int ShieldRepulse(CPlasmaRepulser* shield,float3 shieldPos, float shieldForce, float shieldMaxSpeed);
int ttl;
Index: Sim/Projectiles/ExplosiveProjectile.cpp
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.cpp (revision 4026)
+++ Sim/Projectiles/ExplosiveProjectile.cpp (working copy)
@@ -18,18 +18,20 @@
CR_REG_METADATA(CExplosiveProjectile, (
CR_MEMBER(ttl),
- CR_MEMBER(areaOfEffect)
+ CR_MEMBER(areaOfEffect),
+ CR_MEMBER(gravity)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect)
+CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect, float gravity)
: CWeaponProjectile(pos,speed,owner, 0,ZeroVector,weaponDef,0, true),
ttl(ttl),
areaOfEffect(areaOfEffect),
- curTime(0)
+ curTime(0),
+ gravity(gravity)
{
useAirLos=true;
@@ -53,7 +55,7 @@
void CExplosiveProjectile::Update()
{
pos+=speed;
- speed.y+=gs->gravity;
+ speed.y+=gravity;
if(!--ttl)
Collision();
@@ -75,6 +77,9 @@
float3 n=ground->GetNormal(pos.x,pos.z);
pos-=speed*max(0.0f,min(1.0f,float((h-pos.y)*n.y/n.dot(speed)+0.1f)));
}
+ else if (weaponDef->waterweapon) {
+ return; //let waterweapons go underwater
+ }
}
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
Index: Sim/Projectiles/ExplosiveProjectile.h
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.h (revision 4026)
+++ Sim/Projectiles/ExplosiveProjectile.h (working copy)
@@ -12,7 +12,7 @@
{
CR_DECLARE(CExplosiveProjectile);
public:
- CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8);
+ CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8,float gravity=0);
virtual ~CExplosiveProjectile();
virtual void Update();
void Draw(void);
@@ -24,6 +24,7 @@
float areaOfEffect;
float invttl;
float curTime;
+ float gravity;
};
#endif // __EXPLOSIVE_PROJECTILE_H__
Index: Sim/Projectiles/FireBallProjectile.cpp
===================================================================
--- Sim/Projectiles/FireBallProjectile.cpp (revision 4026)
+++ Sim/Projectiles/FireBallProjectile.cpp (working copy)
@@ -3,6 +3,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Game/Camera.h"
#include "Sim/Weapons/WeaponDefHandler.h"
+#include "Map/Ground.h"
#include "creg/STL_Deque.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
@@ -125,6 +126,7 @@
void CFireBallProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z)<pos.y) return; //make waterweapons not explode in water
CWeaponProjectile::Collision();
deleteMe = false;
}
Index: Sim/Projectiles/FlameProjectile.cpp
===================================================================
--- Sim/Projectiles/FlameProjectile.cpp (revision 4026)
+++ Sim/Projectiles/FlameProjectile.cpp (working copy)
@@ -44,6 +44,7 @@
void CFlameProjectile::Collision(void)
{
+ if(ground->GetHeight2(pos.x, pos.z) < pos.y && weaponDef->waterweapon) return; //prevent waterweapons from colliding with water
float3 norm=ground->GetNormal(pos.x,pos.z);
float ns=speed.dot(norm);
speed-=norm*ns*1;
Index: Sim/Projectiles/LaserProjectile.cpp
===================================================================
--- Sim/Projectiles/LaserProjectile.cpp (revision 4026)
+++ Sim/Projectiles/LaserProjectile.cpp (working copy)
@@ -7,6 +7,7 @@
#include "ProjectileHandler.h"
#include "SimpleParticleSystem.h"
#include "mmgr.h"
+#include "Map/Ground.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));
@@ -104,6 +105,8 @@
void CLaserProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x,pos.z) < pos.y)
+ return; //prevent impact on water if waterweapon is set
float3 oldPos=pos;
CWeaponProjectile::Collision();
Index: Sim/Projectiles/LightingProjectile.cpp
===================================================================
--- Sim/Projectiles/LightingProjectile.cpp (revision 4026)
+++ Sim/Projectiles/LightingProjectile.cpp (working copy)
@@ -59,7 +59,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: Sim/Projectiles/MissileProjectile.cpp
===================================================================
--- Sim/Projectiles/MissileProjectile.cpp (revision 4026)
+++ Sim/Projectiles/MissileProjectile.cpp (working copy)
@@ -119,9 +119,11 @@
void CMissileProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if (weaponDef->waterweapon && h < pos.y) return; //let waterweapons travel in water
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -129,7 +131,8 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -207,7 +210,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -234,66 +237,67 @@
float color=0.6f;
unsigned char col[4];
- if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- float alpha=min((float)255,max(float(0),a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char) alpha;
-
- unsigned char col2[4];
- float a2=(1-float(age2)/(Smoke_Time))*255;
- if(age<8)
- a2=0;
- a2*=0.7f+fabs(dif2.dot(oldDir));
- alpha=min((float)255,max((float)0,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char) alpha;
-
- float size=(1);
- float size2=(1+(age2*(1/Smoke_Time))*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- float alpha=255;
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ float alpha=min((float)255,max(float(0),a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
- float size=(1+(a*(1/Smoke_Time))*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ col[3]=(unsigned char) alpha;
+
+ unsigned char col2[4];
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ if(age<8)
+ a2=0;
+ a2*=0.7f+fabs(dif2.dot(oldDir));
+ alpha=min((float)255,max((float)0,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char) alpha;
+
+ float size=(1);
+ float size2=(1+(age2*(1/Smoke_Time))*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ float alpha=255;
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
+ float size=(1+(a*(1/Smoke_Time))*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
//rita flaren
col[0]=255;
col[1]=210;
Index: Sim/Projectiles/StarburstProjectile.cpp
===================================================================
--- Sim/Projectiles/StarburstProjectile.cpp (revision 4026)
+++ Sim/Projectiles/StarburstProjectile.cpp (working copy)
@@ -65,7 +65,12 @@
areaOfEffect(areaOfEffect)
{
this->uptime=uptime;
- ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ if (weaponDef->flighttime == 0) {
+ ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ }
+ else {
+ ttl=weaponDef->flighttime;
+ }
maxGoodDif=cos(tracking*0.6f);
curSpeed=speed.Length();
@@ -109,9 +114,11 @@
void CStarburstProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if(weaponDef->waterweapon && h < pos.y) return; //prevent impact on water if waterweapon is set
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -120,7 +127,8 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -146,8 +154,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0){
float3 dif(targetPos-pos);
@@ -159,13 +166,18 @@
dif=dif-dir;
dif-=dir*(dif.dot(dir));
dif.Normalize();
- dir+=dif*0.06f;
+ if (weaponDef->turnrate != 0) {
+ dir+=dif*weaponDef->turnrate;
+ }
+ else {
+ dir+=dif*0.06;
+ }
dir.Normalize();
}
speed=dir*curSpeed;
} else if(ttl>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -198,7 +210,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -227,65 +239,66 @@
unsigned char col[4];
unsigned char col2[4];
- if(drawTrail){ //draw the trail as a single quad
-
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldSmokeDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- int alpha=min(255,(int)max(0.f,a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;
-
- float a2=(1-float(age2)/(Smoke_Time))*255;
- a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
- if(age<8)
- a2=0;
- alpha=min(255,(int)max(0.f,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char)alpha;
-
- float size=1;
- float size2=(1+age2*(1/Smoke_Time)*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- col[0]=(unsigned char) (color*255);
- col[1]=(unsigned char) (color*255);
- col[2]=(unsigned char) (color*255);
- col[3]=255;//min(255,max(0,a1*255));
- float size=(1+(a)*(1/Smoke_Time)*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldSmokeDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ int alpha=min(255,(int)max(0.f,a1));
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;
+
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
+ if(age<8)
+ a2=0;
+ alpha=min(255,(int)max(0.f,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char)alpha;
+
+ float size=1;
+ float size2=(1+age2*(1/Smoke_Time)*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ col[0]=(unsigned char) (color*255);
+ col[1]=(unsigned char) (color*255);
+ col[2]=(unsigned char) (color*255);
+ col[3]=255;//min(255,max(0,a1*255));
+ float size=(1+(a)*(1/Smoke_Time)*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
DrawCallback();
if(curCallback==0)
DrawCallback();
Index: Sim/Projectiles/StarburstProjectile.h
===================================================================
--- Sim/Projectiles/StarburstProjectile.h (revision 4026)
+++ Sim/Projectiles/StarburstProjectile.h (working copy)
@@ -27,6 +27,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: Sim/Projectiles/TorpedoProjectile.cpp
===================================================================
--- Sim/Projectiles/TorpedoProjectile.cpp (revision 4026)
+++ Sim/Projectiles/TorpedoProjectile.cpp (working copy)
@@ -10,6 +10,7 @@
#include "BubbleProjectile.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "Sim/Weapons/WeaponDefHandler.h"
CR_BIND_DERIVED(CTorpedoProjectile, CTorpedoProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,NULL,NULL));
@@ -82,14 +83,14 @@
void CTorpedoProjectile::Update(void)
{
- if(pos.y>-3){ //tracking etc only work when we have gotten underwater
+ if(!(weaponDef->submissile) && pos.y>-3){ //tracking etc only work when we have gotten underwater
speed.y+=gs->gravity;
if(dir.y>0)
dir.y=0;
dir=speed;
dir.Normalize();
} else {
- if(pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
+ if(!(weaponDef->submissile) && pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
dir.y*=0.5f;
dir.Normalize();
}
@@ -103,7 +104,7 @@
targPos=target->midPos;
else
targPos=helper->GetUnitErrorPos(target,owner->allyteam);
- if(targPos.y>0)
+ if(!(weaponDef->submissile) && targPos.y>0)
targPos.y=0;
float dist=targPos.distance(pos);
Index: Sim/Units/COB/CobFile.cpp
===================================================================
--- Sim/Units/COB/CobFile.cpp (revision 4026)
+++ Sim/Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: Sim/Units/COB/CobFile.h
===================================================================
--- Sim/Units/COB/CobFile.h (revision 4026)
+++ Sim/Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: Sim/Units/COB/CobInstance.cpp
===================================================================
--- Sim/Units/COB/CobInstance.cpp (revision 4026)
+++ Sim/Units/COB/CobInstance.cpp (working copy)
@@ -655,15 +655,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[type-2048]->targetPos;
- float3 weaponPos = unit->weapons[type-2048]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[type-2048]->weaponMuzzlePos;
unit->weapons[type-2048]->targetPos = pos+dir;
- unit->weapons[type-2048]->weaponPos = pos;
+ unit->weapons[type-2048]->weaponMuzzlePos = pos;
unit->weapons[type-2048]->Fire();
unit->weapons[type-2048]->targetPos = targetPos;
- unit->weapons[type-2048]->weaponPos = weaponPos;
+ unit->weapons[type-2048]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
Index: Sim/Units/UnitLoader.cpp
===================================================================
--- Sim/Units/UnitLoader.cpp (revision 4026)
+++ Sim/Units/UnitLoader.cpp (working copy)
@@ -351,7 +351,7 @@
} else if(weapondef->type=="MissileLauncher"){
weapon=SAFE_NEW CMissileLauncher(owner);
} else if(weapondef->type=="TorpedoLauncher"){
- if(owner->unitDef->canfly){
+ if(owner->unitDef->canfly && !weapondef->submissile){
weapon=SAFE_NEW CBombDropper(owner,true);
if(weapondef->tracks)
((CBombDropper*)weapon)->tracking=weapondef->turnrate;
Index: Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- Sim/Units/UnitTypes/Builder.cpp (revision 4026)
+++ Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -582,9 +582,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(updir))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: Sim/Weapons/BeamLaser.cpp
===================================================================
--- Sim/Weapons/BeamLaser.cpp (revision 4026)
+++ Sim/Weapons/BeamLaser.cpp (working copy)
@@ -43,6 +43,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -77,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
@@ -94,14 +97,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -127,7 +130,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -151,7 +154,7 @@
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -219,7 +222,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: Sim/Weapons/bombdropper.cpp
===================================================================
--- Sim/Weapons/bombdropper.cpp (revision 4026)
+++ Sim/Weapons/bombdropper.cpp (working copy)
@@ -56,14 +56,14 @@
if(weaponPos.y>targetPos.y){
float d=targetPos.y-weaponPos.y;
float s=-owner->speed.y;
- float sq=(s-2*d)/-gs->gravity;
+ float sq=(s-2*d)/-(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
if(sq>0)
- predict=s/gs->gravity+sqrt(sq);
+ predict=s/(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity))+sqrt(sq);
else
predict=0;
float3 hitpos=owner->pos+owner->speed*predict;
float speedf=owner->speed.Length();
- if(hitpos.distance2D(targetPos)<(salvoSize-1)*speedf*salvoDelay*0.5f+bombMoveRange){
+ if(hitpos.distance2D(targetPos)<max(1,(salvoSize-1))*speedf*salvoDelay*0.5f+bombMoveRange){
subClassReady=true;
}
}
@@ -99,14 +99,16 @@
float3 dif=targetPos-weaponPos; //fudge a bit better lateral aim to compensate for imprecise aircraft steering
dif.y=0;
float3 dir=owner->speed;
- dir.y=0;
dir.Normalize();
+ dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f); //add a random spray
+ dir.y=min(0.0,dir.y);
+ dir.Normalize();
dif-=dir*dif.dot(dir);
dif/=max(0.01f,predict);
float size=dif.Length();
if(size>1.0f)
dif/=size*1.0f;
- SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect,weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
}
//CWeaponProjectile::CreateWeaponProjectile(owner->pos,owner->speed,owner, NULL, float3(0,0,0), damages, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
Index: Sim/Weapons/Cannon.cpp
===================================================================
--- Sim/Weapons/Cannon.cpp (revision 4026)
+++ Sim/Weapons/Cannon.cpp (working copy)
@@ -26,6 +26,7 @@
CR_MEMBER(minPredict),
CR_MEMBER(highTrajectory),
CR_MEMBER(selfExplode),
+ CR_MEMBER(gravity),
CR_RESERVED(16)
));
@@ -41,11 +42,12 @@
void CCannon::Init(void)
{
+ gravity = weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity);
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
CWeapon::Init();
}
@@ -60,6 +62,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -78,24 +82,26 @@
return false;
}
- if(unit)
- {
- if(unit->isUnderWater)
+ if(!weaponDef->waterweapon) {
+ if(unit)
{
- return false;
+ if(unit->isUnderWater)
+ {
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ {
+ return false;
+ }
}
- } else {
- if(pos.y<0)
- {
- return false;
- }
}
if (projectileSpeed == 0)
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -110,8 +116,8 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
- dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
+ dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
}
@@ -120,8 +126,8 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
- flatlength-30, dir.y, gs->gravity /
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
+ flatlength-30, dir.y, gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
3, owner->allyteam, owner))
@@ -143,7 +149,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -153,14 +159,14 @@
#endif
int ttl = 0;
float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
- int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gs->gravity)
+ int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
: sqrt(diff.SqLength2D() / sqSpeed2D));
if(selfExplode) {
ttl=(int)(predict+gs->randFloat()*2.5f-0.5f);
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect,gravity);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -169,8 +175,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if(weaponPos.y<30)
- water->AddExplosion(weaponPos,damages[0]*0.1f,sqrt(damages[0])+80);
+// if(weaponMuzzlePos.y<30)
+// water->AddExplosion(weaponMuzzlePos,damages[0]*0.1f,sqrt(damages[0])+80);
}
void CCannon::SlowUpdate(void)
@@ -178,10 +184,10 @@
if(owner->useHighTrajectory!=highTrajectory){
highTrajectory=owner->useHighTrajectory;
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
}
CWeapon::SlowUpdate();
@@ -201,7 +207,7 @@
{
float Dsq = diff.SqLength();
float DFsq = diff.SqLength2D();
- float g = gs->gravity;
+ float g = gravity;
float v = projectileSpeed;
float dy = diff.y;
float dxz = sqrt(DFsq);
@@ -237,7 +243,7 @@
float CCannon::GetRange2D(float yDiff) const
{
- float root1 = 1 + 2*gs->gravity*yDiff/(projectileSpeed*projectileSpeed);
+ float root1 = 1 + 2*gravity*yDiff/(projectileSpeed*projectileSpeed);
if(root1 < 0){
return 0;
} else {
Index: Sim/Weapons/Cannon.h
===================================================================
--- Sim/Weapons/Cannon.h (revision 4026)
+++ Sim/Weapons/Cannon.h (working copy)
@@ -22,6 +22,7 @@
float maxPredict;
float minPredict;
+ float gravity;
bool highTrajectory;
bool selfExplode;
void SlowUpdate(void);
Index: Sim/Weapons/DGunWeapon.cpp
===================================================================
--- Sim/Weapons/DGunWeapon.cpp (revision 4026)
+++ Sim/Weapons/DGunWeapon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -46,13 +47,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: Sim/Weapons/EmgCannon.cpp
===================================================================
--- Sim/Weapons/EmgCannon.cpp (revision 4026)
+++ Sim/Weapons/EmgCannon.cpp (working copy)
@@ -31,7 +31,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,29 +46,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -87,15 +90,16 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Sim/Weapons/FlameThrower.cpp
===================================================================
--- Sim/Weapons/FlameThrower.cpp (revision 4026)
+++ Sim/Weapons/FlameThrower.cpp (working copy)
@@ -27,12 +27,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -42,29 +42,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -74,6 +76,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: Sim/Weapons/LaserCannon.cpp
===================================================================
--- Sim/Weapons/LaserCannon.cpp (revision 4026)
+++ Sim/Weapons/LaserCannon.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,14 +46,14 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -60,14 +61,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -84,7 +85,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -96,10 +97,11 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
Index: Sim/Weapons/LightingCannon.cpp
===================================================================
--- Sim/Weapons/LightingCannon.cpp (revision 4026)
+++ Sim/Weapons/LightingCannon.cpp (working copy)
@@ -9,6 +9,7 @@
#include "WeaponDefHandler.h"
#include "Sim/Misc/InterceptHandler.h"
#include "mmgr.h"
+#include "PlasmaRepulser.h"
CR_BIND_DERIVED(CLightingCannon, CWeapon, (NULL));
@@ -30,6 +31,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -43,29 +45,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -77,17 +81,22 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
+ dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
+ dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
+ if(shieldHit) {
+ shieldHit->BeamIntercepted(this);
}
+ }
// if(u)
// u->DoDamage(damages,owner,ZeroVector);
@@ -95,11 +104,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -110,7 +119,8 @@
void CLightingCannon::SlowUpdate(void)
{
CWeapon::SlowUpdate();
- if(targetType==Target_Unit){
- predict=(gs->randFloat()-0.5f)*20*range/weaponPos.distance(targetUnit->midPos)*(1.2f-owner->limExperience); //make the weapon somewhat less effecient against aircrafts hopefully
- }
+ //We don't do hardcoded inaccuracies, use targetMoveError if you want inaccuracy!
+// if(targetType==Target_Unit){
+// predict=(gs->randFloat()-0.5f)*20*range/weaponPos.distance(targetUnit->midPos)*(1.2f-owner->limExperience); //make the weapon somewhat less effecient against aircrafts hopefully
+// }
}
Index: Sim/Weapons/MeleeWeapon.cpp
===================================================================
--- Sim/Weapons/MeleeWeapon.cpp (revision 4026)
+++ Sim/Weapons/MeleeWeapon.cpp (working copy)
@@ -31,8 +31,16 @@
void CMeleeWeapon::Update()
{
+ if(targetType!=Target_None){
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
+ wantedDir=targetPos-weaponPos;
+ wantedDir.Normalize();
+ }
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
+ }
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
Index: Sim/Weapons/MissileLauncher.cpp
===================================================================
--- Sim/Weapons/MissileLauncher.cpp (revision 4026)
+++ Sim/Weapons/MissileLauncher.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -49,12 +50,15 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
+ if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
+ }
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
@@ -64,7 +68,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -75,15 +79,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater){
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater){
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ return false;
}
- } else {
- if(pos.y<0)
- return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -95,11 +101,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -110,7 +116,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -119,7 +125,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: Sim/Weapons/PlasmaRepulser.cpp
===================================================================
--- Sim/Weapons/PlasmaRepulser.cpp (revision 4026)
+++ Sim/Weapons/PlasmaRepulser.cpp (working copy)
@@ -70,6 +70,8 @@
if(weaponDef->shieldPower==0)
curPower=99999999999.0f;
+ else
+ curPower=weaponDef->shieldStartingPower;
CWeapon::Init();
}
Index: Sim/Weapons/Rifle.cpp
===================================================================
--- Sim/Weapons/Rifle.cpp (revision 4026)
+++ Sim/Weapons/Rifle.cpp (working copy)
@@ -41,6 +41,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -60,18 +61,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -79,7 +80,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -88,13 +89,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length=helper->TraceRay(weaponPos,dir,range,damages[0],owner,hit);
+ float length=helper->TraceRay(weaponMuzzlePos,dir,range,damages[0],owner,hit);
if(hit){
hit->DoDamage(damages,owner,ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos+dir*length,hit->speed*0.9f,30,1,owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos+dir*length,hit->speed*0.9f,30,1,owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/StarburstLauncher.cpp
===================================================================
--- Sim/Weapons/StarburstLauncher.cpp (revision 4026)
+++ Sim/Weapons/StarburstLauncher.cpp (working copy)
@@ -32,6 +32,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -39,7 +40,11 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
+ float3 speed(0,weaponDef->startvelocity,0);
+ if(weaponDef->fixedLauncher) {
+ speed=weaponDir * weaponDef->startvelocity;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -54,15 +59,19 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
- return false;
+ if(!weaponDef->fixedLauncher)
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,UpVector,100,0,owner->allyteam,owner))
+ return false;
+ else
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,weaponDir,100,0,owner->allyteam,owner))
+ return false;
return true;
}
Index: Sim/Weapons/TorpedoLauncher.cpp
===================================================================
--- Sim/Weapons/TorpedoLauncher.cpp (revision 4026)
+++ Sim/Weapons/TorpedoLauncher.cpp (working copy)
@@ -32,7 +32,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,18 +49,24 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
// }
- float3 startSpeed=dir*weaponDef->startvelocity;
+ float3 startSpeed;
+ if (!weaponDef->fixedLauncher) {
+ startSpeed=dir*weaponDef->startvelocity;
+ }
+ else {
+ startSpeed=weaponDir*weaponDef->startvelocity;
+ }
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -70,22 +77,22 @@
return false;
if(unit){
- if(unit->unitDef->canhover)
+ if(!(weaponDef->submissile) && unit->unitDef->canhover)
return false;
- if(unit->unitDef->canfly && unit->pos.y>0)
+ if(!(weaponDef->submissile) && unit->unitDef->canfly && unit->pos.y>0)
return false;
}
- if(ground->GetHeight2(pos.x,pos.z)>0)
+ if(!(weaponDef->submissile) && ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: Sim/Weapons/Weapon.cpp
===================================================================
--- Sim/Weapons/Weapon.cpp (revision 4026)
+++ Sim/Weapons/Weapon.cpp (working copy)
@@ -56,9 +56,11 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(damages),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -131,8 +133,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -174,11 +178,14 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //if we couldn't get a line of fire from the muzzle try if we can get it from the aim piece
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
}
@@ -256,16 +263,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->fireSubmersed || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -301,35 +310,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -360,9 +386,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -385,8 +411,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -434,18 +462,23 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //If we can't get a line of fire from the muzzle try the aim piece instead since the weapon may just be turned in a wrong way
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
if(useWeaponPosForAim>1)
useWeaponPosForAim--;
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -549,7 +582,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
float heightDiff;
if (targetBorder != 0 && unit) {
@@ -621,11 +654,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -651,11 +686,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -666,6 +703,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: Sim/Weapons/Weapon.h
===================================================================
--- Sim/Weapons/Weapon.h (revision 4026)
+++ Sim/Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: Sim/Weapons/WeaponDefHandler.cpp
===================================================================
--- Sim/Weapons/WeaponDefHandler.cpp (revision 4026)
+++ Sim/Weapons/WeaponDefHandler.cpp (working copy)
@@ -67,6 +67,7 @@
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;
@@ -94,6 +95,7 @@
sunparser->GetDef(weaponDefs[id].minIntensity, "0", weaponname + "\\MinIntensity");
sunparser->GetDef(weaponDefs[id].dropped, "0", weaponname + "\\dropped");
+ sunparser->GetDef(manualBombSettings, "0", weaponname + "\\manualbombsettings");
sunparser->GetDef(lineofsight, "0", weaponname + "\\lineofsight");
sunparser->GetDef(ballistic, "0", weaponname + "\\ballistic");
sunparser->GetDef(weaponDefs[id].twophase, "0", weaponname + "\\twophase");
@@ -110,7 +112,10 @@
sunparser->GetDef(weaponDefs[id].noSelfDamage, "0", weaponname + "\\NoSelfDamage");
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
+ sunparser->GetDef(weaponDefs[id].fireSubmersed, weaponDefs[id].waterweapon ? "1":"0", weaponname + "\\firesubmersed");
+ sunparser->GetDef(weaponDefs[id].submissile, "0", weaponname + "\\submissile");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -256,6 +261,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
@@ -263,6 +269,7 @@
sunparser->GetDef(weaponDefs[id].selfExplode, "0", weaponname + "\\burnblow");
sunparser->GetDef(weaponDefs[id].sweepFire, "0", weaponname + "\\sweepfire");
sunparser->GetDef(weaponDefs[id].canAttackGround, "1", weaponname + "\\canattackground");
+ weaponDefs[id].myGravity = atof(sunparser->SGetValueDef("0", weaponname + "\\myGravity").c_str());
weaponDefs[id].fireStarter=atof(sunparser->SGetValueDef("0", weaponname + "\\firestarter").c_str())*0.01f;
weaponDefs[id].paralyzer=!!atoi(sunparser->SGetValueDef("0", weaponname + "\\paralyzer").c_str());
@@ -292,6 +299,7 @@
sunparser->GetDef(weaponDefs[id].shieldPower, "0", weaponname + "\\shieldpower");
sunparser->GetDef(weaponDefs[id].shieldPowerRegen, "0", weaponname + "\\shieldpowerregen");
sunparser->GetDef(weaponDefs[id].shieldPowerRegenEnergy, "0", weaponname + "\\shieldpowerregenenergy");
+ sunparser->GetDef(weaponDefs[id].shieldStartingPower, "0", weaponname + "\\shieldstartingpower");
sunparser->GetDef(weaponDefs[id].shieldInterceptType, "0", weaponname + "\\shieldintercepttype");
weaponDefs[id].shieldGoodColor=sunparser->GetFloat3(float3(0.5f,0.5f,1),weaponname + "\\shieldgoodcolor");
weaponDefs[id].shieldBadColor=sunparser->GetFloat3(float3(1,0.5f,0.5f),weaponname + "\\shieldbadcolor");
@@ -345,10 +353,11 @@
weaponDefs[id].visuals.color = tempCol;
weaponDefs[id].uptime = atof(sunparser->SGetValueDef("0", weaponname + "\\weapontimer").c_str());
+ weaponDefs[id].flighttime = atof(sunparser->SGetValueDef("0", weaponname + "\\flighttime").c_str()) * 32;
weaponDefs[id].turnrate = atof(sunparser->SGetValueDef("0", weaponname + "\\turnrate").c_str()) * PI / 0x7fff /30.0f;
- if(weaponDefs[id].type=="AircraftBomb"){
+ if(weaponDefs[id].type=="AircraftBomb" && !manualBombSettings){
if(weaponDefs[id].reload<0.5f){
weaponDefs[id].salvodelay=min(0.2f,weaponDefs[id].reload);
weaponDefs[id].salvosize=(int)(1/weaponDefs[id].salvodelay)+1;
Index: Sim/Weapons/WeaponDefHandler.h
===================================================================
--- Sim/Weapons/WeaponDefHandler.h (revision 4026)
+++ Sim/Weapons/WeaponDefHandler.h (working copy)
@@ -67,17 +67,23 @@
float restTime;
float uptime;
+ int flighttime;
float metalcost;
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
+ bool fireSubmersed;
+ bool submissile; //Lets a torpedo travel above water like it does below water
bool tracks;
bool dropped;
bool paralyzer; //weapon will only paralyze not do real damage
@@ -102,6 +108,7 @@
bool selfExplode;
bool gravityAffected;
+ float myGravity;
bool twophase;
bool guided;
bool vlaunch;
@@ -165,6 +172,7 @@
float shieldPower; //how much damage the shield can reflect (0=infinite)
float shieldPowerRegen; //how fast the power regenerates per second
float shieldPowerRegenEnergy; //how much energy is needed to regenerate power per second
+ float shieldStartingPower; //how much power the shield has when first created
float3 shieldGoodColor; //color when shield at full power
float3 shieldBadColor; //color when shield is empty
float shieldAlpha; //shield alpha value
-
kdr11k_weapon_changes_r4220.patch (79,395 bytes) 2007-08-18 14:16
Index: Sim/Projectiles/EmgProjectile.cpp
===================================================================
--- Sim/Projectiles/EmgProjectile.cpp (revision 4220)
+++ Sim/Projectiles/EmgProjectile.cpp (working copy)
@@ -4,6 +4,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Sync/SyncTracer.h"
#include "ProjectileHandler.h"
+#include "Map/Ground.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "mmgr.h"
@@ -52,10 +53,14 @@
void CEmgProjectile::Collision(CUnit* unit)
{
// unit->DoDamage(damages,owner);
-
CWeaponProjectile::Collision(unit);
}
+void CEmgProjectile::Collision() {
+ if (!(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z) < pos.y))
+ CWeaponProjectile::Collision();
+}
+
void CEmgProjectile::Draw(void)
{
inArray=true;
Index: Sim/Projectiles/EmgProjectile.h
===================================================================
--- Sim/Projectiles/EmgProjectile.h (revision 4220)
+++ Sim/Projectiles/EmgProjectile.h (working copy)
@@ -14,6 +14,7 @@
void Update(void);
void Draw(void);
void Collision(CUnit* unit);
+ void Collision();
int ShieldRepulse(CPlasmaRepulser* shield,float3 shieldPos, float shieldForce, float shieldMaxSpeed);
int ttl;
Index: Sim/Projectiles/ExplosiveProjectile.cpp
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.cpp (revision 4220)
+++ Sim/Projectiles/ExplosiveProjectile.cpp (working copy)
@@ -18,18 +18,20 @@
CR_REG_METADATA(CExplosiveProjectile, (
CR_MEMBER(ttl),
- CR_MEMBER(areaOfEffect)
+ CR_MEMBER(areaOfEffect),
+ CR_MEMBER(gravity)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect)
+CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect, float gravity)
: CWeaponProjectile(pos,speed,owner, 0,ZeroVector,weaponDef,0, true),
ttl(ttl),
areaOfEffect(areaOfEffect),
- curTime(0)
+ curTime(0),
+ gravity(gravity)
{
useAirLos=true;
@@ -53,7 +55,7 @@
void CExplosiveProjectile::Update()
{
pos+=speed;
- speed.y+=gs->gravity;
+ speed.y+=gravity;
if(!--ttl)
Collision();
@@ -75,6 +77,9 @@
float3 n=ground->GetNormal(pos.x,pos.z);
pos-=speed*max(0.0f,min(1.0f,float((h-pos.y)*n.y/n.dot(speed)+0.1f)));
}
+ else if (weaponDef->waterweapon) {
+ return; //let waterweapons go underwater
+ }
}
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
Index: Sim/Projectiles/ExplosiveProjectile.h
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.h (revision 4220)
+++ Sim/Projectiles/ExplosiveProjectile.h (working copy)
@@ -12,7 +12,7 @@
{
CR_DECLARE(CExplosiveProjectile);
public:
- CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8);
+ CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8,float gravity=0);
virtual ~CExplosiveProjectile();
virtual void Update();
void Draw(void);
@@ -24,6 +24,7 @@
float areaOfEffect;
float invttl;
float curTime;
+ float gravity;
};
#endif // __EXPLOSIVE_PROJECTILE_H__
Index: Sim/Projectiles/FireBallProjectile.cpp
===================================================================
--- Sim/Projectiles/FireBallProjectile.cpp (revision 4220)
+++ Sim/Projectiles/FireBallProjectile.cpp (working copy)
@@ -3,6 +3,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Game/Camera.h"
#include "Sim/Weapons/WeaponDefHandler.h"
+#include "Map/Ground.h"
#include "creg/STL_Deque.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
@@ -125,8 +126,10 @@
void CFireBallProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z)<pos.y) return; //make waterweapons not explode in water
CWeaponProjectile::Collision();
deleteMe = false;
}
+
Index: Sim/Projectiles/FlameProjectile.cpp
===================================================================
--- Sim/Projectiles/FlameProjectile.cpp (revision 4220)
+++ Sim/Projectiles/FlameProjectile.cpp (working copy)
@@ -44,6 +44,7 @@
void CFlameProjectile::Collision(void)
{
+ if(ground->GetHeight2(pos.x, pos.z) < pos.y && weaponDef->waterweapon) return; //prevent waterweapons from colliding with water
float3 norm=ground->GetNormal(pos.x,pos.z);
float ns=speed.dot(norm);
speed-=norm*ns*1;
Index: Sim/Projectiles/LaserProjectile.cpp
===================================================================
--- Sim/Projectiles/LaserProjectile.cpp (revision 4220)
+++ Sim/Projectiles/LaserProjectile.cpp (working copy)
@@ -7,6 +7,7 @@
#include "ProjectileHandler.h"
#include "SimpleParticleSystem.h"
#include "mmgr.h"
+#include "Map/Ground.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));
@@ -104,6 +105,8 @@
void CLaserProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x,pos.z) < pos.y)
+ return; //prevent impact on water if waterweapon is set
float3 oldPos=pos;
CWeaponProjectile::Collision();
Index: Sim/Projectiles/LightingProjectile.cpp
===================================================================
--- Sim/Projectiles/LightingProjectile.cpp (revision 4220)
+++ Sim/Projectiles/LightingProjectile.cpp (working copy)
@@ -59,7 +59,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: Sim/Projectiles/MissileProjectile.cpp
===================================================================
--- Sim/Projectiles/MissileProjectile.cpp (revision 4220)
+++ Sim/Projectiles/MissileProjectile.cpp (working copy)
@@ -119,9 +119,11 @@
void CMissileProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if (weaponDef->waterweapon && h < pos.y) return; //let waterweapons travel in water
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -129,7 +131,8 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -207,7 +210,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -234,66 +237,67 @@
float color=0.6f;
unsigned char col[4];
- if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- float alpha=min((float)255,max(float(0),a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char) alpha;
-
- unsigned char col2[4];
- float a2=(1-float(age2)/(Smoke_Time))*255;
- if(age<8)
- a2=0;
- a2*=0.7f+fabs(dif2.dot(oldDir));
- alpha=min((float)255,max((float)0,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char) alpha;
-
- float size=(1);
- float size2=(1+(age2*(1/Smoke_Time))*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- float alpha=255;
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ float alpha=min((float)255,max(float(0),a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
- float size=(1+(a*(1/Smoke_Time))*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ col[3]=(unsigned char) alpha;
+
+ unsigned char col2[4];
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ if(age<8)
+ a2=0;
+ a2*=0.7f+fabs(dif2.dot(oldDir));
+ alpha=min((float)255,max((float)0,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char) alpha;
+
+ float size=(1);
+ float size2=(1+(age2*(1/Smoke_Time))*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ float alpha=255;
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
+ float size=(1+(a*(1/Smoke_Time))*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
//rita flaren
col[0]=255;
col[1]=210;
Index: Sim/Projectiles/StarburstProjectile.cpp
===================================================================
--- Sim/Projectiles/StarburstProjectile.cpp (revision 4220)
+++ Sim/Projectiles/StarburstProjectile.cpp (working copy)
@@ -67,7 +67,12 @@
distanceToTravel(maxdistance)
{
this->uptime=uptime;
- ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ if (weaponDef->flighttime == 0) {
+ ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ }
+ else {
+ ttl=weaponDef->flighttime;
+ }
maxGoodDif=cos(tracking*0.6f);
curSpeed=speed.Length();
@@ -111,9 +116,11 @@
void CStarburstProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if(weaponDef->waterweapon && h < pos.y) return; //prevent impact on water if waterweapon is set
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -122,7 +129,8 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -148,8 +156,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0 && distanceToTravel>0) {
float3 dif(targetPos-pos);
@@ -161,14 +168,20 @@
dif=dif-dir;
dif-=dir*(dif.dot(dir));
dif.Normalize();
- dir+=dif*0.06f;
+ if (weaponDef->turnrate != 0) {
+ dir+=dif*weaponDef->turnrate;
+ }
+ else {
+ dir+=dif*0.06;
+ }
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else if(ttl>0 && distanceToTravel>0) {
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -181,7 +194,8 @@
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else {
dir.y+=gs->gravity;
dir.Normalize();
@@ -202,7 +216,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -231,65 +245,66 @@
unsigned char col[4];
unsigned char col2[4];
- if(drawTrail){ //draw the trail as a single quad
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldSmokeDir));
- dir2.Normalize();
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldSmokeDir));
+ dir2.Normalize();
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- int alpha=min(255,(int)max(0.f,a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ int alpha=min(255,(int)max(0.f,a1));
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;
- float a2=(1-float(age2)/(Smoke_Time))*255;
- a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
- if(age<8)
- a2=0;
- alpha=min(255,(int)max(0.f,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char)alpha;
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
+ if(age<8)
+ a2=0;
+ alpha=min(255,(int)max(0.f,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char)alpha;
- float size=1;
- float size2=(1+age2*(1/Smoke_Time)*7);
+ float size=1;
+ float size2=(1+age2*(1/Smoke_Time)*7);
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- col[0]=(unsigned char) (color*255);
- col[1]=(unsigned char) (color*255);
- col[2]=(unsigned char) (color*255);
- col[3]=255;//min(255,max(0,a1*255));
- float size=(1+(a)*(1/Smoke_Time)*7);
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ col[0]=(unsigned char) (color*255);
+ col[1]=(unsigned char) (color*255);
+ col[2]=(unsigned char) (color*255);
+ col[3]=255;//min(255,max(0,a1*255));
+ float size=(1+(a)*(1/Smoke_Time)*7);
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
DrawCallback();
if(curCallback==0)
DrawCallback();
Index: Sim/Projectiles/StarburstProjectile.h
===================================================================
--- Sim/Projectiles/StarburstProjectile.h (revision 4220)
+++ Sim/Projectiles/StarburstProjectile.h (working copy)
@@ -30,6 +30,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: Sim/Projectiles/TorpedoProjectile.cpp
===================================================================
--- Sim/Projectiles/TorpedoProjectile.cpp (revision 4220)
+++ Sim/Projectiles/TorpedoProjectile.cpp (working copy)
@@ -10,6 +10,7 @@
#include "BubbleProjectile.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "Sim/Weapons/WeaponDefHandler.h"
CR_BIND_DERIVED(CTorpedoProjectile, CTorpedoProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,NULL,NULL));
@@ -82,14 +83,14 @@
void CTorpedoProjectile::Update(void)
{
- if(pos.y>-3){ //tracking etc only work when we have gotten underwater
+ if(!(weaponDef->submissile) && pos.y>-3){ //tracking etc only work when we have gotten underwater
speed.y+=gs->gravity;
if(dir.y>0)
dir.y=0;
dir=speed;
dir.Normalize();
} else {
- if(pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
+ if(!(weaponDef->submissile) && pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
dir.y*=0.5f;
dir.Normalize();
}
@@ -103,7 +104,7 @@
targPos=target->midPos;
else
targPos=helper->GetUnitErrorPos(target,owner->allyteam);
- if(targPos.y>0)
+ if(!(weaponDef->submissile) && targPos.y>0)
targPos.y=0;
float dist=targPos.distance(pos);
Index: Sim/Units/COB/CobFile.cpp
===================================================================
--- Sim/Units/COB/CobFile.cpp (revision 4220)
+++ Sim/Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: Sim/Units/COB/CobFile.h
===================================================================
--- Sim/Units/COB/CobFile.h (revision 4220)
+++ Sim/Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: Sim/Units/COB/CobInstance.cpp
===================================================================
--- Sim/Units/COB/CobInstance.cpp (revision 4220)
+++ Sim/Units/COB/CobInstance.cpp (working copy)
@@ -665,15 +665,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[index]->targetPos;
- float3 weaponPos = unit->weapons[index]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[index]->weaponMuzzlePos;
unit->weapons[index]->targetPos = pos+dir;
- unit->weapons[index]->weaponPos = pos;
+ unit->weapons[index]->weaponMuzzlePos = pos;
unit->weapons[index]->Fire();
unit->weapons[index]->targetPos = targetPos;
- unit->weapons[index]->weaponPos = weaponPos;
+ unit->weapons[index]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
unsigned index = type - 4096;
Index: Sim/Units/UnitLoader.cpp
===================================================================
--- Sim/Units/UnitLoader.cpp (revision 4220)
+++ Sim/Units/UnitLoader.cpp (working copy)
@@ -348,7 +348,7 @@
} else if(weapondef->type=="MissileLauncher"){
weapon=SAFE_NEW CMissileLauncher(owner);
} else if(weapondef->type=="TorpedoLauncher"){
- if(owner->unitDef->canfly){
+ if(owner->unitDef->canfly && !weapondef->submissile){
weapon=SAFE_NEW CBombDropper(owner,true);
if(weapondef->tracks)
((CBombDropper*)weapon)->tracking=weapondef->turnrate;
@@ -493,3 +493,4 @@
}
+
Index: Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- Sim/Units/UnitTypes/Builder.cpp (revision 4220)
+++ Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -582,9 +582,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(updir))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: Sim/Weapons/BeamLaser.cpp
===================================================================
--- Sim/Weapons/BeamLaser.cpp (revision 4220)
+++ Sim/Weapons/BeamLaser.cpp (working copy)
@@ -43,6 +43,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -77,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
@@ -94,14 +97,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -127,7 +130,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -151,7 +154,7 @@
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -220,7 +223,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: Sim/Weapons/bombdropper.cpp
===================================================================
--- Sim/Weapons/bombdropper.cpp (revision 4220)
+++ Sim/Weapons/bombdropper.cpp (working copy)
@@ -56,14 +56,14 @@
if(weaponPos.y>targetPos.y){
float d=targetPos.y-weaponPos.y;
float s=-owner->speed.y;
- float sq=(s-2*d)/-gs->gravity;
+ float sq=(s-2*d)/-(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
if(sq>0)
- predict=s/gs->gravity+sqrt(sq);
+ predict=s/(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity))+sqrt(sq);
else
predict=0;
float3 hitpos=owner->pos+owner->speed*predict;
float speedf=owner->speed.Length();
- if(hitpos.distance2D(targetPos)<(salvoSize-1)*speedf*salvoDelay*0.5f+bombMoveRange){
+ if(hitpos.distance2D(targetPos)<max(1,(salvoSize-1))*speedf*salvoDelay*0.5f+bombMoveRange){
subClassReady=true;
}
}
@@ -108,7 +108,7 @@
float size=dif.Length();
if(size>1.0f)
dif/=size*1.0f;
- SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect,weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
}
//CWeaponProjectile::CreateWeaponProjectile(owner->pos,owner->speed,owner, NULL, float3(0,0,0), damages, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
Index: Sim/Weapons/Cannon.cpp
===================================================================
--- Sim/Weapons/Cannon.cpp (revision 4220)
+++ Sim/Weapons/Cannon.cpp (working copy)
@@ -29,6 +29,7 @@
CR_MEMBER(rangeFactor),
CR_MEMBER(lastDiff),
CR_MEMBER(lastDir),
+ CR_MEMBER(gravity),
CR_RESERVED(16)
));
@@ -47,11 +48,12 @@
void CCannon::Init(void)
{
+ gravity = weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity);
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
CWeapon::Init();
@@ -79,6 +81,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -97,24 +101,26 @@
return false;
}
- if(unit)
- {
- if(unit->isUnderWater)
+ if(!weaponDef->waterweapon) {
+ if(unit)
{
- return false;
+ if(unit->isUnderWater)
+ {
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ {
+ return false;
+ }
}
- } else {
- if(pos.y<0)
- {
- return false;
- }
}
if (projectileSpeed == 0)
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -129,8 +135,8 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
- dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
+ dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
}
@@ -139,8 +145,8 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
- flatlength-30, dir.y, gs->gravity /
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
+ flatlength-30, dir.y, gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
3, owner->allyteam, owner))
@@ -162,7 +168,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -172,14 +178,14 @@
#endif
int ttl = 0;
float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
- int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gs->gravity)
+ int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
: sqrt(diff.SqLength2D() / sqSpeed2D));
if(selfExplode) {
ttl=(int)(predict+gs->randFloat()*2.5f-0.5f);
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect,gravity);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -188,8 +194,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if(weaponPos.y<30)
- water->AddExplosion(weaponPos,damages[0]*0.1f,sqrt(damages[0])+80);
+// if(weaponMuzzlePos.y<30)
+// water->AddExplosion(weaponMuzzlePos,damages[0]*0.1f,sqrt(damages[0])+80);
}
void CCannon::SlowUpdate(void)
@@ -197,10 +203,10 @@
if(owner->useHighTrajectory!=highTrajectory){
highTrajectory=owner->useHighTrajectory;
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
}
CWeapon::SlowUpdate();
@@ -229,7 +235,7 @@
float Dsq = diff.SqLength();
float DFsq = diff.SqLength2D();
- float g = gs->gravity;
+ float g = gravity;
float v = projectileSpeed;
float dy = diff.y;
float dxz = sqrt(DFsq);
@@ -279,10 +285,10 @@
// f(0) == 1, f(smoothHeight) == heightBoostFactor
yDiff *= 1.f + (heightBoostFactor-1.f) * (-yDiff)/smoothHeight;
- float root1 = speed2dSq + 2*gs->gravity*yDiff;
+ float root1 = speed2dSq + 2*gravity*yDiff;
if(root1 < 0.f){
return 0.f;
} else {
- return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gs->gravity);
+ return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gravity);
}
}
Index: Sim/Weapons/Cannon.h
===================================================================
--- Sim/Weapons/Cannon.h (revision 4220)
+++ Sim/Weapons/Cannon.h (working copy)
@@ -36,6 +36,8 @@
bool highTrajectory;
/// burnblow tag. defines flakker-like behaviour
bool selfExplode;
+ /// projectile gravity
+ float gravity;
void SlowUpdate(void);
/// tells where to point the gun to hit the point at pos+diff
Index: Sim/Weapons/DGunWeapon.cpp
===================================================================
--- Sim/Weapons/DGunWeapon.cpp (revision 4220)
+++ Sim/Weapons/DGunWeapon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -46,13 +47,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: Sim/Weapons/EmgCannon.cpp
===================================================================
--- Sim/Weapons/EmgCannon.cpp (revision 4220)
+++ Sim/Weapons/EmgCannon.cpp (working copy)
@@ -31,7 +31,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,29 +46,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -87,15 +90,17 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: Sim/Weapons/FlameThrower.cpp
===================================================================
--- Sim/Weapons/FlameThrower.cpp (revision 4220)
+++ Sim/Weapons/FlameThrower.cpp (working copy)
@@ -27,12 +27,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -42,29 +42,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -74,6 +76,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: Sim/Weapons/LaserCannon.cpp
===================================================================
--- Sim/Weapons/LaserCannon.cpp (revision 4220)
+++ Sim/Weapons/LaserCannon.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,14 +46,14 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -60,14 +61,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -84,7 +85,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -96,10 +97,12 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: Sim/Weapons/LightingCannon.cpp
===================================================================
--- Sim/Weapons/LightingCannon.cpp (revision 4220)
+++ Sim/Weapons/LightingCannon.cpp (working copy)
@@ -31,6 +31,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -44,29 +45,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -78,16 +81,16 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
if(shieldHit) {
@@ -101,11 +104,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
Index: Sim/Weapons/MeleeWeapon.cpp
===================================================================
--- Sim/Weapons/MeleeWeapon.cpp (revision 4220)
+++ Sim/Weapons/MeleeWeapon.cpp (working copy)
@@ -33,21 +33,23 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
}
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
{
if(targetType==Target_Unit){
- float3 impulseDir = targetUnit->pos-weaponPos;
+ float3 impulseDir = targetUnit->pos-weaponMuzzlePos;
impulseDir.Normalize();
- targetUnit->DoDamage(damages,owner,impulseDir,weaponDef->id);
+ // the heavier the unit, the more impulse it does
+ targetUnit->DoDamage(damages,owner,impulseDir*owner->mass,weaponDef->id);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/MissileLauncher.cpp
===================================================================
--- Sim/Weapons/MissileLauncher.cpp (revision 4220)
+++ Sim/Weapons/MissileLauncher.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -49,12 +50,15 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
+ if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
+ }
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
@@ -64,7 +68,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -75,15 +79,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater){
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater){
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ return false;
}
- } else {
- if(pos.y<0)
- return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -95,11 +101,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -110,7 +116,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -119,7 +125,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: Sim/Weapons/PlasmaRepulser.cpp
===================================================================
--- Sim/Weapons/PlasmaRepulser.cpp (revision 4220)
+++ Sim/Weapons/PlasmaRepulser.cpp (working copy)
@@ -70,6 +70,8 @@
if(weaponDef->shieldPower==0)
curPower=99999999999.0f;
+ else
+ curPower=weaponDef->shieldStartingPower;
CWeapon::Init();
}
Index: Sim/Weapons/Rifle.cpp
===================================================================
--- Sim/Weapons/Rifle.cpp (revision 4220)
+++ Sim/Weapons/Rifle.cpp (working copy)
@@ -41,6 +41,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -60,18 +61,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -79,7 +80,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -88,13 +89,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length=helper->TraceRay(weaponPos,dir,range,damages[0],owner,hit,collisionFlags);
+ float length=helper->TraceRay(weaponMuzzlePos,dir,range,damages[0],owner,hit,collisionFlags);
if(hit){
hit->DoDamage(damages,owner,ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos+dir*length,hit->speed*0.9f,30,1,owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos+dir*length,hit->speed*0.9f,30,1,owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/StarburstLauncher.cpp
===================================================================
--- Sim/Weapons/StarburstLauncher.cpp (revision 4220)
+++ Sim/Weapons/StarburstLauncher.cpp (working copy)
@@ -32,6 +32,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -39,7 +40,15 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget,range);
+ float3 speed(0,weaponDef->startvelocity,0);
+ float maxrange;
+ if (weaponDef->fixedLauncher) {
+ speed = weaponDir * weaponDef->startvelocity;
+ maxrange = (float)MAX_WORLD_SIZE;
+ } else {
+ maxrange = (float)range;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget, maxrange);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -54,14 +63,15 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,
+ (weaponDef->fixedLauncher ? weaponDir : UpVector), 100, 0, owner->allyteam, owner))
return false;
return true;
Index: Sim/Weapons/TorpedoLauncher.cpp
===================================================================
--- Sim/Weapons/TorpedoLauncher.cpp (revision 4220)
+++ Sim/Weapons/TorpedoLauncher.cpp (working copy)
@@ -32,7 +32,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,18 +49,24 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
// }
- float3 startSpeed=dir*weaponDef->startvelocity;
+ float3 startSpeed;
+ if (!weaponDef->fixedLauncher) {
+ startSpeed=dir*weaponDef->startvelocity;
+ }
+ else {
+ startSpeed=weaponDir*weaponDef->startvelocity;
+ }
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -70,22 +77,22 @@
return false;
if(unit){
- if(unit->unitDef->canhover)
+ if(!(weaponDef->submissile) && unit->unitDef->canhover)
return false;
- if(unit->unitDef->canfly && unit->pos.y>0)
+ if(!(weaponDef->submissile) && unit->unitDef->canfly && unit->pos.y>0)
return false;
}
- if(ground->GetHeight2(pos.x,pos.z)>0)
+ if(!(weaponDef->submissile) && ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: Sim/Weapons/Weapon.cpp
===================================================================
--- Sim/Weapons/Weapon.cpp (revision 4220)
+++ Sim/Weapons/Weapon.cpp (working copy)
@@ -57,9 +57,11 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(damages),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -133,8 +135,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -177,11 +181,14 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //if we couldn't get a line of fire from the muzzle try if we can get it from the aim piece
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
}
@@ -259,16 +266,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->fireSubmersed || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -304,35 +313,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -363,9 +389,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -388,8 +414,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -437,18 +465,23 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //If we can't get a line of fire from the muzzle try the aim piece instead since the weapon may just be turned in a wrong way
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
if(useWeaponPosForAim>1)
useWeaponPosForAim--;
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -552,7 +585,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
float heightDiff; // negative when target below owner
if (targetBorder != 0 && unit) {
@@ -624,11 +657,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -654,11 +689,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -669,6 +706,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: Sim/Weapons/Weapon.h
===================================================================
--- Sim/Weapons/Weapon.h (revision 4220)
+++ Sim/Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: Sim/Weapons/WeaponDefHandler.cpp
===================================================================
--- Sim/Weapons/WeaponDefHandler.cpp (revision 4220)
+++ Sim/Weapons/WeaponDefHandler.cpp (working copy)
@@ -67,6 +67,7 @@
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;
@@ -94,6 +95,7 @@
sunparser->GetDef(weaponDefs[id].minIntensity, "0", weaponname + "\\MinIntensity");
sunparser->GetDef(weaponDefs[id].dropped, "0", weaponname + "\\dropped");
+ sunparser->GetDef(manualBombSettings, "0", weaponname + "\\manualbombsettings");
sunparser->GetDef(lineofsight, "0", weaponname + "\\lineofsight");
sunparser->GetDef(ballistic, "0", weaponname + "\\ballistic");
sunparser->GetDef(weaponDefs[id].twophase, "0", weaponname + "\\twophase");
@@ -110,7 +112,10 @@
sunparser->GetDef(weaponDefs[id].noSelfDamage, "0", weaponname + "\\NoSelfDamage");
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
+ sunparser->GetDef(weaponDefs[id].fireSubmersed, weaponDefs[id].waterweapon ? "1":"0", weaponname + "\\firesubmersed");
+ sunparser->GetDef(weaponDefs[id].submissile, "0", weaponname + "\\submissile");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -256,6 +261,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
@@ -263,6 +269,7 @@
sunparser->GetDef(weaponDefs[id].selfExplode, "0", weaponname + "\\burnblow");
sunparser->GetDef(weaponDefs[id].sweepFire, "0", weaponname + "\\sweepfire");
sunparser->GetDef(weaponDefs[id].canAttackGround, "1", weaponname + "\\canattackground");
+ weaponDefs[id].myGravity = atof(sunparser->SGetValueDef("0", weaponname + "\\myGravity").c_str());
weaponDefs[id].fireStarter=atof(sunparser->SGetValueDef("0", weaponname + "\\firestarter").c_str())*0.01f;
weaponDefs[id].paralyzer=!!atoi(sunparser->SGetValueDef("0", weaponname + "\\paralyzer").c_str());
@@ -292,6 +299,7 @@
sunparser->GetDef(weaponDefs[id].shieldPower, "0", weaponname + "\\shieldpower");
sunparser->GetDef(weaponDefs[id].shieldPowerRegen, "0", weaponname + "\\shieldpowerregen");
sunparser->GetDef(weaponDefs[id].shieldPowerRegenEnergy, "0", weaponname + "\\shieldpowerregenenergy");
+ sunparser->GetDef(weaponDefs[id].shieldStartingPower, "0", weaponname + "\\shieldstartingpower");
sunparser->GetDef(weaponDefs[id].shieldInterceptType, "0", weaponname + "\\shieldintercepttype");
weaponDefs[id].shieldGoodColor=sunparser->GetFloat3(float3(0.5f,0.5f,1),weaponname + "\\shieldgoodcolor");
weaponDefs[id].shieldBadColor=sunparser->GetFloat3(float3(1,0.5f,0.5f),weaponname + "\\shieldbadcolor");
@@ -353,10 +361,11 @@
weaponDefs[id].visuals.color = tempCol;
weaponDefs[id].uptime = atof(sunparser->SGetValueDef("0", weaponname + "\\weapontimer").c_str());
+ weaponDefs[id].flighttime = atof(sunparser->SGetValueDef("0", weaponname + "\\flighttime").c_str()) * 32;
weaponDefs[id].turnrate = atof(sunparser->SGetValueDef("0", weaponname + "\\turnrate").c_str()) * PI / 0x7fff /30.0f;
- if(weaponDefs[id].type=="AircraftBomb"){
+ if(weaponDefs[id].type=="AircraftBomb" && !manualBombSettings){
if(weaponDefs[id].reload<0.5f){
weaponDefs[id].salvodelay=min(0.2f,weaponDefs[id].reload);
weaponDefs[id].salvosize=(int)(1/weaponDefs[id].salvodelay)+1;
Index: Sim/Weapons/WeaponDefHandler.h
===================================================================
--- Sim/Weapons/WeaponDefHandler.h (revision 4220)
+++ Sim/Weapons/WeaponDefHandler.h (working copy)
@@ -67,17 +67,23 @@
float restTime;
float uptime;
+ int flighttime;
float metalcost;
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
+ bool fireSubmersed;
+ bool submissile; //Lets a torpedo travel above water like it does below water
bool tracks;
bool dropped;
bool paralyzer; //weapon will only paralyze not do real damage
@@ -102,6 +108,7 @@
bool selfExplode;
bool gravityAffected;
+ float myGravity;
bool twophase;
bool guided;
bool vlaunch;
@@ -165,6 +172,7 @@
float shieldPower; //how much damage the shield can reflect (0=infinite)
float shieldPowerRegen; //how fast the power regenerates per second
float shieldPowerRegenEnergy; //how much energy is needed to regenerate power per second
+ float shieldStartingPower; //how much power the shield has when first created
float3 shieldGoodColor; //color when shield at full power
float3 shieldBadColor; //color when shield is empty
float shieldAlpha; //shield alpha value
Index: System/GlobalStuff.h
===================================================================
--- System/GlobalStuff.h (revision 4220)
+++ System/GlobalStuff.h (working copy)
@@ -20,7 +20,7 @@
*
* Defines the maximum world size as 1000000
*/
-#define MAX_WORLD_SIZE 1000000;
+#define MAX_WORLD_SIZE 1000000
/**
* @brief square size
@@ -260,42 +260,42 @@
/**
* @brief disable helper AIs
- *
+ *
* Whether helper AIs are allow, including GroupAI and LuaUI control widgets
*/
bool noHelperAIs;
/**
* @brief definition editing enabled
- *
+ *
* Whether definition editing is enabled
*/
bool editDefsEnabled;
/**
* @brief LuaRules control
- *
+ *
* Whether or not LuaRules is enabled
*/
bool useLuaRules;
/**
* @brief LuaGaia control
- *
+ *
* Whether or not LuaGaia is enabled
*/
bool useLuaGaia;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaTeamID;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaAllyTeamID;
-
kdr11k_weapon_changes_r4220_v2.patch (80,018 bytes) 2007-08-18 17:05
Index: Sim/Projectiles/EmgProjectile.cpp
===================================================================
--- Sim/Projectiles/EmgProjectile.cpp (revision 4220)
+++ Sim/Projectiles/EmgProjectile.cpp (working copy)
@@ -4,6 +4,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Sync/SyncTracer.h"
#include "ProjectileHandler.h"
+#include "Map/Ground.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "mmgr.h"
@@ -52,10 +53,14 @@
void CEmgProjectile::Collision(CUnit* unit)
{
// unit->DoDamage(damages,owner);
-
CWeaponProjectile::Collision(unit);
}
+void CEmgProjectile::Collision() {
+ if (!(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z) < pos.y))
+ CWeaponProjectile::Collision();
+}
+
void CEmgProjectile::Draw(void)
{
inArray=true;
Index: Sim/Projectiles/EmgProjectile.h
===================================================================
--- Sim/Projectiles/EmgProjectile.h (revision 4220)
+++ Sim/Projectiles/EmgProjectile.h (working copy)
@@ -14,6 +14,7 @@
void Update(void);
void Draw(void);
void Collision(CUnit* unit);
+ void Collision();
int ShieldRepulse(CPlasmaRepulser* shield,float3 shieldPos, float shieldForce, float shieldMaxSpeed);
int ttl;
Index: Sim/Projectiles/ExplosiveProjectile.cpp
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.cpp (revision 4220)
+++ Sim/Projectiles/ExplosiveProjectile.cpp (working copy)
@@ -18,18 +18,20 @@
CR_REG_METADATA(CExplosiveProjectile, (
CR_MEMBER(ttl),
- CR_MEMBER(areaOfEffect)
+ CR_MEMBER(areaOfEffect),
+ CR_MEMBER(gravity)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect)
+CExplosiveProjectile::CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl,float areaOfEffect, float gravity)
: CWeaponProjectile(pos,speed,owner, 0,ZeroVector,weaponDef,0, true),
ttl(ttl),
areaOfEffect(areaOfEffect),
- curTime(0)
+ curTime(0),
+ gravity(gravity)
{
useAirLos=true;
@@ -53,7 +55,7 @@
void CExplosiveProjectile::Update()
{
pos+=speed;
- speed.y+=gs->gravity;
+ speed.y+=gravity;
if(!--ttl)
Collision();
@@ -75,6 +77,9 @@
float3 n=ground->GetNormal(pos.x,pos.z);
pos-=speed*max(0.0f,min(1.0f,float((h-pos.y)*n.y/n.dot(speed)+0.1f)));
}
+ else if (weaponDef->waterweapon) {
+ return; //let waterweapons go underwater
+ }
}
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
Index: Sim/Projectiles/ExplosiveProjectile.h
===================================================================
--- Sim/Projectiles/ExplosiveProjectile.h (revision 4220)
+++ Sim/Projectiles/ExplosiveProjectile.h (working copy)
@@ -12,7 +12,7 @@
{
CR_DECLARE(CExplosiveProjectile);
public:
- CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8);
+ CExplosiveProjectile(const float3& pos,const float3& speed,CUnit* owner, WeaponDef *weaponDef, int ttl=100000,float areaOfEffect=8,float gravity=0);
virtual ~CExplosiveProjectile();
virtual void Update();
void Draw(void);
@@ -24,6 +24,7 @@
float areaOfEffect;
float invttl;
float curTime;
+ float gravity;
};
#endif // __EXPLOSIVE_PROJECTILE_H__
Index: Sim/Projectiles/FireBallProjectile.cpp
===================================================================
--- Sim/Projectiles/FireBallProjectile.cpp (revision 4220)
+++ Sim/Projectiles/FireBallProjectile.cpp (working copy)
@@ -3,6 +3,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Game/Camera.h"
#include "Sim/Weapons/WeaponDefHandler.h"
+#include "Map/Ground.h"
#include "creg/STL_Deque.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
@@ -125,8 +126,10 @@
void CFireBallProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z)<pos.y) return; //make waterweapons not explode in water
CWeaponProjectile::Collision();
deleteMe = false;
}
+
Index: Sim/Projectiles/FlameProjectile.cpp
===================================================================
--- Sim/Projectiles/FlameProjectile.cpp (revision 4220)
+++ Sim/Projectiles/FlameProjectile.cpp (working copy)
@@ -44,6 +44,7 @@
void CFlameProjectile::Collision(void)
{
+ if(ground->GetHeight2(pos.x, pos.z) < pos.y && weaponDef->waterweapon) return; //prevent waterweapons from colliding with water
float3 norm=ground->GetNormal(pos.x,pos.z);
float ns=speed.dot(norm);
speed-=norm*ns*1;
Index: Sim/Projectiles/LaserProjectile.cpp
===================================================================
--- Sim/Projectiles/LaserProjectile.cpp (revision 4220)
+++ Sim/Projectiles/LaserProjectile.cpp (working copy)
@@ -7,6 +7,7 @@
#include "ProjectileHandler.h"
#include "SimpleParticleSystem.h"
#include "mmgr.h"
+#include "Map/Ground.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));
@@ -104,6 +105,8 @@
void CLaserProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x,pos.z) < pos.y)
+ return; //prevent impact on water if waterweapon is set
float3 oldPos=pos;
CWeaponProjectile::Collision();
Index: Sim/Projectiles/LightingProjectile.cpp
===================================================================
--- Sim/Projectiles/LightingProjectile.cpp (revision 4220)
+++ Sim/Projectiles/LightingProjectile.cpp (working copy)
@@ -59,7 +59,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: Sim/Projectiles/MissileProjectile.cpp
===================================================================
--- Sim/Projectiles/MissileProjectile.cpp (revision 4220)
+++ Sim/Projectiles/MissileProjectile.cpp (working copy)
@@ -119,9 +119,11 @@
void CMissileProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if (weaponDef->waterweapon && h < pos.y) return; //let waterweapons travel in water
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -129,7 +131,8 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -207,7 +210,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -234,66 +237,67 @@
float color=0.6f;
unsigned char col[4];
- if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- float alpha=min((float)255,max(float(0),a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char) alpha;
-
- unsigned char col2[4];
- float a2=(1-float(age2)/(Smoke_Time))*255;
- if(age<8)
- a2=0;
- a2*=0.7f+fabs(dif2.dot(oldDir));
- alpha=min((float)255,max((float)0,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char) alpha;
-
- float size=(1);
- float size2=(1+(age2*(1/Smoke_Time))*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- float alpha=255;
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ float alpha=min((float)255,max(float(0),a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
- float size=(1+(a*(1/Smoke_Time))*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ col[3]=(unsigned char) alpha;
+
+ unsigned char col2[4];
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ if(age<8)
+ a2=0;
+ a2*=0.7f+fabs(dif2.dot(oldDir));
+ alpha=min((float)255,max((float)0,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char) alpha;
+
+ float size=(1);
+ float size2=(1+(age2*(1/Smoke_Time))*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ float alpha=255;
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
+ float size=(1+(a*(1/Smoke_Time))*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
//rita flaren
col[0]=255;
col[1]=210;
Index: Sim/Projectiles/StarburstProjectile.cpp
===================================================================
--- Sim/Projectiles/StarburstProjectile.cpp (revision 4220)
+++ Sim/Projectiles/StarburstProjectile.cpp (working copy)
@@ -15,6 +15,8 @@
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "LogOutput.h"
+
static const float Smoke_Time=70;
CR_BIND_DERIVED(CStarburstProjectile, CWeaponProjectile, (float3(0,0,0),float3(0,0,0),NULL,float3(0,0,0),0,0,0,0,NULL,NULL,NULL,0));
@@ -67,7 +69,12 @@
distanceToTravel(maxdistance)
{
this->uptime=uptime;
- ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ if (weaponDef->flighttime == 0) {
+ ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ }
+ else {
+ ttl=weaponDef->flighttime;
+ }
maxGoodDif=cos(tracking*0.6f);
curSpeed=speed.Length();
@@ -111,9 +118,11 @@
void CStarburstProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if(weaponDef->waterweapon && h < pos.y) return; //prevent impact on water if waterweapon is set
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -122,7 +131,8 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -148,8 +158,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0 && distanceToTravel>0) {
float3 dif(targetPos-pos);
@@ -161,14 +170,20 @@
dif=dif-dir;
dif-=dir*(dif.dot(dir));
dif.Normalize();
- dir+=dif*0.06f;
+ if (weaponDef->turnrate != 0) {
+ dir+=dif*weaponDef->turnrate;
+ }
+ else {
+ dir+=dif*0.06;
+ }
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else if(ttl>0 && distanceToTravel>0) {
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -181,7 +196,8 @@
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else {
dir.y+=gs->gravity;
dir.Normalize();
@@ -202,7 +218,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -231,65 +247,66 @@
unsigned char col[4];
unsigned char col2[4];
- if(drawTrail){ //draw the trail as a single quad
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldSmokeDir));
- dir2.Normalize();
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldSmokeDir));
+ dir2.Normalize();
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- int alpha=min(255,(int)max(0.f,a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ int alpha=min(255,(int)max(0.f,a1));
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;
- float a2=(1-float(age2)/(Smoke_Time))*255;
- a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
- if(age<8)
- a2=0;
- alpha=min(255,(int)max(0.f,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char)alpha;
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
+ if(age<8)
+ a2=0;
+ alpha=min(255,(int)max(0.f,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char)alpha;
- float size=1;
- float size2=(1+age2*(1/Smoke_Time)*7);
+ float size=1;
+ float size2=(1+age2*(1/Smoke_Time)*7);
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- col[0]=(unsigned char) (color*255);
- col[1]=(unsigned char) (color*255);
- col[2]=(unsigned char) (color*255);
- col[3]=255;//min(255,max(0,a1*255));
- float size=(1+(a)*(1/Smoke_Time)*7);
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ col[0]=(unsigned char) (color*255);
+ col[1]=(unsigned char) (color*255);
+ col[2]=(unsigned char) (color*255);
+ col[3]=255;//min(255,max(0,a1*255));
+ float size=(1+(a)*(1/Smoke_Time)*7);
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
DrawCallback();
if(curCallback==0)
DrawCallback();
Index: Sim/Projectiles/StarburstProjectile.h
===================================================================
--- Sim/Projectiles/StarburstProjectile.h (revision 4220)
+++ Sim/Projectiles/StarburstProjectile.h (working copy)
@@ -30,6 +30,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: Sim/Projectiles/TorpedoProjectile.cpp
===================================================================
--- Sim/Projectiles/TorpedoProjectile.cpp (revision 4220)
+++ Sim/Projectiles/TorpedoProjectile.cpp (working copy)
@@ -10,6 +10,7 @@
#include "BubbleProjectile.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "Sim/Weapons/WeaponDefHandler.h"
CR_BIND_DERIVED(CTorpedoProjectile, CTorpedoProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,NULL,NULL));
@@ -82,14 +83,14 @@
void CTorpedoProjectile::Update(void)
{
- if(pos.y>-3){ //tracking etc only work when we have gotten underwater
+ if(!(weaponDef->submissile) && pos.y>-3){ //tracking etc only work when we have gotten underwater
speed.y+=gs->gravity;
if(dir.y>0)
dir.y=0;
dir=speed;
dir.Normalize();
} else {
- if(pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
+ if(!(weaponDef->submissile) && pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
dir.y*=0.5f;
dir.Normalize();
}
@@ -103,7 +104,7 @@
targPos=target->midPos;
else
targPos=helper->GetUnitErrorPos(target,owner->allyteam);
- if(targPos.y>0)
+ if(!(weaponDef->submissile) && targPos.y>0)
targPos.y=0;
float dist=targPos.distance(pos);
Index: Sim/Units/COB/CobFile.cpp
===================================================================
--- Sim/Units/COB/CobFile.cpp (revision 4220)
+++ Sim/Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: Sim/Units/COB/CobFile.h
===================================================================
--- Sim/Units/COB/CobFile.h (revision 4220)
+++ Sim/Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: Sim/Units/COB/CobInstance.cpp
===================================================================
--- Sim/Units/COB/CobInstance.cpp (revision 4220)
+++ Sim/Units/COB/CobInstance.cpp (working copy)
@@ -665,15 +665,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[index]->targetPos;
- float3 weaponPos = unit->weapons[index]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[index]->weaponMuzzlePos;
unit->weapons[index]->targetPos = pos+dir;
- unit->weapons[index]->weaponPos = pos;
+ unit->weapons[index]->weaponMuzzlePos = pos;
unit->weapons[index]->Fire();
unit->weapons[index]->targetPos = targetPos;
- unit->weapons[index]->weaponPos = weaponPos;
+ unit->weapons[index]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
unsigned index = type - 4096;
Index: Sim/Units/UnitLoader.cpp
===================================================================
--- Sim/Units/UnitLoader.cpp (revision 4220)
+++ Sim/Units/UnitLoader.cpp (working copy)
@@ -348,7 +348,7 @@
} else if(weapondef->type=="MissileLauncher"){
weapon=SAFE_NEW CMissileLauncher(owner);
} else if(weapondef->type=="TorpedoLauncher"){
- if(owner->unitDef->canfly){
+ if(owner->unitDef->canfly && !weapondef->submissile){
weapon=SAFE_NEW CBombDropper(owner,true);
if(weapondef->tracks)
((CBombDropper*)weapon)->tracking=weapondef->turnrate;
@@ -377,7 +377,7 @@
((CStarburstLauncher*)weapon)->tracking=weapondef->turnrate;
else
((CStarburstLauncher*)weapon)->tracking=0;
- ((CStarburstLauncher*)weapon)->uptime=weapondef->uptime*30;
+ ((CStarburstLauncher*)weapon)->uptime=weapondef->uptime*GAME_SPEED;
}else {
logOutput << "Unknown weapon type " << weapondef->type.c_str() << "\n";
return 0;
@@ -493,3 +493,4 @@
}
+
Index: Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- Sim/Units/UnitTypes/Builder.cpp (revision 4220)
+++ Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -582,9 +582,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(updir))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: Sim/Weapons/BeamLaser.cpp
===================================================================
--- Sim/Weapons/BeamLaser.cpp (revision 4220)
+++ Sim/Weapons/BeamLaser.cpp (working copy)
@@ -43,6 +43,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -77,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
@@ -94,14 +97,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -127,7 +130,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -151,7 +154,7 @@
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -220,7 +223,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: Sim/Weapons/bombdropper.cpp
===================================================================
--- Sim/Weapons/bombdropper.cpp (revision 4220)
+++ Sim/Weapons/bombdropper.cpp (working copy)
@@ -56,14 +56,14 @@
if(weaponPos.y>targetPos.y){
float d=targetPos.y-weaponPos.y;
float s=-owner->speed.y;
- float sq=(s-2*d)/-gs->gravity;
+ float sq=(s-2*d)/-(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
if(sq>0)
- predict=s/gs->gravity+sqrt(sq);
+ predict=s/(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity))+sqrt(sq);
else
predict=0;
float3 hitpos=owner->pos+owner->speed*predict;
float speedf=owner->speed.Length();
- if(hitpos.distance2D(targetPos)<(salvoSize-1)*speedf*salvoDelay*0.5f+bombMoveRange){
+ if(hitpos.distance2D(targetPos)<max(1,(salvoSize-1))*speedf*salvoDelay*0.5f+bombMoveRange){
subClassReady=true;
}
}
@@ -108,7 +108,7 @@
float size=dif.Length();
if(size>1.0f)
dif/=size*1.0f;
- SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect,weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
}
//CWeaponProjectile::CreateWeaponProjectile(owner->pos,owner->speed,owner, NULL, float3(0,0,0), damages, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
Index: Sim/Weapons/Cannon.cpp
===================================================================
--- Sim/Weapons/Cannon.cpp (revision 4220)
+++ Sim/Weapons/Cannon.cpp (working copy)
@@ -29,6 +29,7 @@
CR_MEMBER(rangeFactor),
CR_MEMBER(lastDiff),
CR_MEMBER(lastDir),
+ CR_MEMBER(gravity),
CR_RESERVED(16)
));
@@ -47,11 +48,12 @@
void CCannon::Init(void)
{
+ gravity = weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity);
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
CWeapon::Init();
@@ -79,6 +81,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -97,24 +101,26 @@
return false;
}
- if(unit)
- {
- if(unit->isUnderWater)
+ if(!weaponDef->waterweapon) {
+ if(unit)
{
- return false;
+ if(unit->isUnderWater)
+ {
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ {
+ return false;
+ }
}
- } else {
- if(pos.y<0)
- {
- return false;
- }
}
if (projectileSpeed == 0)
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -129,8 +135,8 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
- dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
+ dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
}
@@ -139,8 +145,8 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
- flatlength-30, dir.y, gs->gravity /
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
+ flatlength-30, dir.y, gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
3, owner->allyteam, owner))
@@ -162,7 +168,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -172,14 +178,14 @@
#endif
int ttl = 0;
float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
- int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gs->gravity)
+ int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
: sqrt(diff.SqLength2D() / sqSpeed2D));
if(selfExplode) {
ttl=(int)(predict+gs->randFloat()*2.5f-0.5f);
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect,gravity);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -188,8 +194,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if(weaponPos.y<30)
- water->AddExplosion(weaponPos,damages[0]*0.1f,sqrt(damages[0])+80);
+// if(weaponMuzzlePos.y<30)
+// water->AddExplosion(weaponMuzzlePos,damages[0]*0.1f,sqrt(damages[0])+80);
}
void CCannon::SlowUpdate(void)
@@ -197,10 +203,10 @@
if(owner->useHighTrajectory!=highTrajectory){
highTrajectory=owner->useHighTrajectory;
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
}
CWeapon::SlowUpdate();
@@ -229,7 +235,7 @@
float Dsq = diff.SqLength();
float DFsq = diff.SqLength2D();
- float g = gs->gravity;
+ float g = gravity;
float v = projectileSpeed;
float dy = diff.y;
float dxz = sqrt(DFsq);
@@ -279,10 +285,10 @@
// f(0) == 1, f(smoothHeight) == heightBoostFactor
yDiff *= 1.f + (heightBoostFactor-1.f) * (-yDiff)/smoothHeight;
- float root1 = speed2dSq + 2*gs->gravity*yDiff;
+ float root1 = speed2dSq + 2*gravity*yDiff;
if(root1 < 0.f){
return 0.f;
} else {
- return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gs->gravity);
+ return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gravity);
}
}
Index: Sim/Weapons/Cannon.h
===================================================================
--- Sim/Weapons/Cannon.h (revision 4220)
+++ Sim/Weapons/Cannon.h (working copy)
@@ -36,6 +36,8 @@
bool highTrajectory;
/// burnblow tag. defines flakker-like behaviour
bool selfExplode;
+ /// projectile gravity
+ float gravity;
void SlowUpdate(void);
/// tells where to point the gun to hit the point at pos+diff
Index: Sim/Weapons/DGunWeapon.cpp
===================================================================
--- Sim/Weapons/DGunWeapon.cpp (revision 4220)
+++ Sim/Weapons/DGunWeapon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -46,13 +47,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: Sim/Weapons/EmgCannon.cpp
===================================================================
--- Sim/Weapons/EmgCannon.cpp (revision 4220)
+++ Sim/Weapons/EmgCannon.cpp (working copy)
@@ -31,7 +31,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,29 +46,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -87,15 +90,17 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: Sim/Weapons/FlameThrower.cpp
===================================================================
--- Sim/Weapons/FlameThrower.cpp (revision 4220)
+++ Sim/Weapons/FlameThrower.cpp (working copy)
@@ -27,12 +27,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -42,29 +42,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -74,6 +76,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: Sim/Weapons/LaserCannon.cpp
===================================================================
--- Sim/Weapons/LaserCannon.cpp (revision 4220)
+++ Sim/Weapons/LaserCannon.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,14 +46,14 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -60,14 +61,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -84,7 +85,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -96,10 +97,12 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: Sim/Weapons/LightingCannon.cpp
===================================================================
--- Sim/Weapons/LightingCannon.cpp (revision 4220)
+++ Sim/Weapons/LightingCannon.cpp (working copy)
@@ -31,6 +31,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -44,29 +45,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -78,16 +81,16 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
if(shieldHit) {
@@ -101,11 +104,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
Index: Sim/Weapons/MeleeWeapon.cpp
===================================================================
--- Sim/Weapons/MeleeWeapon.cpp (revision 4220)
+++ Sim/Weapons/MeleeWeapon.cpp (working copy)
@@ -33,21 +33,23 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
}
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
{
if(targetType==Target_Unit){
- float3 impulseDir = targetUnit->pos-weaponPos;
+ float3 impulseDir = targetUnit->pos-weaponMuzzlePos;
impulseDir.Normalize();
- targetUnit->DoDamage(damages,owner,impulseDir,weaponDef->id);
+ // the heavier the unit, the more impulse it does
+ targetUnit->DoDamage(damages,owner,impulseDir*owner->mass,weaponDef->id);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/MissileLauncher.cpp
===================================================================
--- Sim/Weapons/MissileLauncher.cpp (revision 4220)
+++ Sim/Weapons/MissileLauncher.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,8 +49,10 @@
float3 dir;
if(onlyForward){
dir=owner->frontdir;
+ } else if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
@@ -64,7 +67,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -75,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater){
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater){
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ return false;
}
- } else {
- if(pos.y<0)
- return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -95,11 +100,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -110,7 +115,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -119,7 +124,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: Sim/Weapons/PlasmaRepulser.cpp
===================================================================
--- Sim/Weapons/PlasmaRepulser.cpp (revision 4220)
+++ Sim/Weapons/PlasmaRepulser.cpp (working copy)
@@ -70,6 +70,8 @@
if(weaponDef->shieldPower==0)
curPower=99999999999.0f;
+ else
+ curPower=weaponDef->shieldStartingPower;
CWeapon::Init();
}
Index: Sim/Weapons/Rifle.cpp
===================================================================
--- Sim/Weapons/Rifle.cpp (revision 4220)
+++ Sim/Weapons/Rifle.cpp (working copy)
@@ -41,6 +41,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -60,18 +61,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -79,7 +80,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -88,13 +89,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length=helper->TraceRay(weaponPos,dir,range,damages[0],owner,hit,collisionFlags);
+ float length=helper->TraceRay(weaponMuzzlePos,dir,range,damages[0],owner,hit,collisionFlags);
if(hit){
hit->DoDamage(damages,owner,ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos+dir*length,hit->speed*0.9f,30,1,owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos+dir*length,hit->speed*0.9f,30,1,owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: Sim/Weapons/StarburstLauncher.cpp
===================================================================
--- Sim/Weapons/StarburstLauncher.cpp (revision 4220)
+++ Sim/Weapons/StarburstLauncher.cpp (working copy)
@@ -32,6 +32,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -39,7 +40,17 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget,range);
+ float3 speed(0,weaponDef->startvelocity,0);
+ float maxrange;
+ if (weaponDef->fixedLauncher) {
+ speed = weaponDir * weaponDef->startvelocity;
+ maxrange = (float)MAX_WORLD_SIZE;
+ } else if (weaponDef->flighttime > 0) {
+ maxrange = (float)MAX_WORLD_SIZE;
+ } else {
+ maxrange = (float)range;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget, maxrange);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -54,14 +65,15 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,
+ (weaponDef->fixedLauncher ? weaponDir : UpVector), 100, 0, owner->allyteam, owner))
return false;
return true;
Index: Sim/Weapons/TorpedoLauncher.cpp
===================================================================
--- Sim/Weapons/TorpedoLauncher.cpp (revision 4220)
+++ Sim/Weapons/TorpedoLauncher.cpp (working copy)
@@ -32,7 +32,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,18 +49,24 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
// }
- float3 startSpeed=dir*weaponDef->startvelocity;
+ float3 startSpeed;
+ if (!weaponDef->fixedLauncher) {
+ startSpeed=dir*weaponDef->startvelocity;
+ }
+ else {
+ startSpeed=weaponDir*weaponDef->startvelocity;
+ }
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -70,22 +77,22 @@
return false;
if(unit){
- if(unit->unitDef->canhover)
+ if(!(weaponDef->submissile) && unit->unitDef->canhover)
return false;
- if(unit->unitDef->canfly && unit->pos.y>0)
+ if(!(weaponDef->submissile) && unit->unitDef->canfly && unit->pos.y>0)
return false;
}
- if(ground->GetHeight2(pos.x,pos.z)>0)
+ if(!(weaponDef->submissile) && ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: Sim/Weapons/Weapon.cpp
===================================================================
--- Sim/Weapons/Weapon.cpp (revision 4220)
+++ Sim/Weapons/Weapon.cpp (working copy)
@@ -57,9 +57,11 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(damages),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -133,8 +135,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -177,11 +181,14 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //if we couldn't get a line of fire from the muzzle try if we can get it from the aim piece
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
}
@@ -259,16 +266,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->fireSubmersed || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -304,35 +313,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -363,9 +389,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -388,8 +414,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -437,18 +465,23 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //If we can't get a line of fire from the muzzle try the aim piece instead since the weapon may just be turned in a wrong way
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
if(useWeaponPosForAim>1)
useWeaponPosForAim--;
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -552,7 +585,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
float heightDiff; // negative when target below owner
if (targetBorder != 0 && unit) {
@@ -624,11 +657,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -654,11 +689,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -669,6 +706,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: Sim/Weapons/Weapon.h
===================================================================
--- Sim/Weapons/Weapon.h (revision 4220)
+++ Sim/Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: Sim/Weapons/WeaponDefHandler.cpp
===================================================================
--- Sim/Weapons/WeaponDefHandler.cpp (revision 4220)
+++ Sim/Weapons/WeaponDefHandler.cpp (working copy)
@@ -67,6 +67,7 @@
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;
@@ -94,6 +95,7 @@
sunparser->GetDef(weaponDefs[id].minIntensity, "0", weaponname + "\\MinIntensity");
sunparser->GetDef(weaponDefs[id].dropped, "0", weaponname + "\\dropped");
+ sunparser->GetDef(manualBombSettings, "0", weaponname + "\\manualbombsettings");
sunparser->GetDef(lineofsight, "0", weaponname + "\\lineofsight");
sunparser->GetDef(ballistic, "0", weaponname + "\\ballistic");
sunparser->GetDef(weaponDefs[id].twophase, "0", weaponname + "\\twophase");
@@ -110,7 +112,10 @@
sunparser->GetDef(weaponDefs[id].noSelfDamage, "0", weaponname + "\\NoSelfDamage");
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
+ sunparser->GetDef(weaponDefs[id].fireSubmersed, weaponDefs[id].waterweapon ? "1":"0", weaponname + "\\firesubmersed");
+ sunparser->GetDef(weaponDefs[id].submissile, "0", weaponname + "\\submissile");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -256,6 +261,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
@@ -263,6 +269,7 @@
sunparser->GetDef(weaponDefs[id].selfExplode, "0", weaponname + "\\burnblow");
sunparser->GetDef(weaponDefs[id].sweepFire, "0", weaponname + "\\sweepfire");
sunparser->GetDef(weaponDefs[id].canAttackGround, "1", weaponname + "\\canattackground");
+ weaponDefs[id].myGravity = atof(sunparser->SGetValueDef("0", weaponname + "\\myGravity").c_str());
weaponDefs[id].fireStarter=atof(sunparser->SGetValueDef("0", weaponname + "\\firestarter").c_str())*0.01f;
weaponDefs[id].paralyzer=!!atoi(sunparser->SGetValueDef("0", weaponname + "\\paralyzer").c_str());
@@ -292,6 +299,7 @@
sunparser->GetDef(weaponDefs[id].shieldPower, "0", weaponname + "\\shieldpower");
sunparser->GetDef(weaponDefs[id].shieldPowerRegen, "0", weaponname + "\\shieldpowerregen");
sunparser->GetDef(weaponDefs[id].shieldPowerRegenEnergy, "0", weaponname + "\\shieldpowerregenenergy");
+ sunparser->GetDef(weaponDefs[id].shieldStartingPower, "0", weaponname + "\\shieldstartingpower");
sunparser->GetDef(weaponDefs[id].shieldInterceptType, "0", weaponname + "\\shieldintercepttype");
weaponDefs[id].shieldGoodColor=sunparser->GetFloat3(float3(0.5f,0.5f,1),weaponname + "\\shieldgoodcolor");
weaponDefs[id].shieldBadColor=sunparser->GetFloat3(float3(1,0.5f,0.5f),weaponname + "\\shieldbadcolor");
@@ -353,10 +361,11 @@
weaponDefs[id].visuals.color = tempCol;
weaponDefs[id].uptime = atof(sunparser->SGetValueDef("0", weaponname + "\\weapontimer").c_str());
+ weaponDefs[id].flighttime = atof(sunparser->SGetValueDef("0", weaponname + "\\flighttime").c_str()) * 32;
weaponDefs[id].turnrate = atof(sunparser->SGetValueDef("0", weaponname + "\\turnrate").c_str()) * PI / 0x7fff /30.0f;
- if(weaponDefs[id].type=="AircraftBomb"){
+ if(weaponDefs[id].type=="AircraftBomb" && !manualBombSettings){
if(weaponDefs[id].reload<0.5f){
weaponDefs[id].salvodelay=min(0.2f,weaponDefs[id].reload);
weaponDefs[id].salvosize=(int)(1/weaponDefs[id].salvodelay)+1;
Index: Sim/Weapons/WeaponDefHandler.h
===================================================================
--- Sim/Weapons/WeaponDefHandler.h (revision 4220)
+++ Sim/Weapons/WeaponDefHandler.h (working copy)
@@ -67,17 +67,23 @@
float restTime;
float uptime;
+ int flighttime;
float metalcost;
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
+ bool fireSubmersed;
+ bool submissile; //Lets a torpedo travel above water like it does below water
bool tracks;
bool dropped;
bool paralyzer; //weapon will only paralyze not do real damage
@@ -102,6 +108,7 @@
bool selfExplode;
bool gravityAffected;
+ float myGravity;
bool twophase;
bool guided;
bool vlaunch;
@@ -165,6 +172,7 @@
float shieldPower; //how much damage the shield can reflect (0=infinite)
float shieldPowerRegen; //how fast the power regenerates per second
float shieldPowerRegenEnergy; //how much energy is needed to regenerate power per second
+ float shieldStartingPower; //how much power the shield has when first created
float3 shieldGoodColor; //color when shield at full power
float3 shieldBadColor; //color when shield is empty
float shieldAlpha; //shield alpha value
Index: System/GlobalStuff.h
===================================================================
--- System/GlobalStuff.h (revision 4220)
+++ System/GlobalStuff.h (working copy)
@@ -20,7 +20,7 @@
*
* Defines the maximum world size as 1000000
*/
-#define MAX_WORLD_SIZE 1000000;
+#define MAX_WORLD_SIZE 1000000
/**
* @brief square size
@@ -260,42 +260,42 @@
/**
* @brief disable helper AIs
- *
+ *
* Whether helper AIs are allow, including GroupAI and LuaUI control widgets
*/
bool noHelperAIs;
/**
* @brief definition editing enabled
- *
+ *
* Whether definition editing is enabled
*/
bool editDefsEnabled;
/**
* @brief LuaRules control
- *
+ *
* Whether or not LuaRules is enabled
*/
bool useLuaRules;
/**
* @brief LuaGaia control
- *
+ *
* Whether or not LuaGaia is enabled
*/
bool useLuaGaia;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaTeamID;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaAllyTeamID;
-
kdr11k_weapon_changes_r4223_v3.patch (80,656 bytes) 2007-08-18 22:41
Index: rts/Sim/Projectiles/EmgProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/EmgProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/EmgProjectile.cpp (working copy)
@@ -4,6 +4,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Sync/SyncTracer.h"
#include "ProjectileHandler.h"
+#include "Map/Ground.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "mmgr.h"
@@ -52,10 +53,14 @@
void CEmgProjectile::Collision(CUnit* unit)
{
// unit->DoDamage(damages,owner);
-
CWeaponProjectile::Collision(unit);
}
+void CEmgProjectile::Collision() {
+ if (!(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z) < pos.y))
+ CWeaponProjectile::Collision();
+}
+
void CEmgProjectile::Draw(void)
{
inArray=true;
Index: rts/Sim/Projectiles/EmgProjectile.h
===================================================================
--- rts/Sim/Projectiles/EmgProjectile.h (revision 4223)
+++ rts/Sim/Projectiles/EmgProjectile.h (working copy)
@@ -14,6 +14,7 @@
void Update(void);
void Draw(void);
void Collision(CUnit* unit);
+ void Collision();
int ShieldRepulse(CPlasmaRepulser* shield,float3 shieldPos, float shieldForce, float shieldMaxSpeed);
int ttl;
Index: rts/Sim/Projectiles/ExplosiveProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/ExplosiveProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/ExplosiveProjectile.cpp (working copy)
@@ -18,18 +18,21 @@
CR_REG_METADATA(CExplosiveProjectile, (
CR_MEMBER(ttl),
- CR_MEMBER(areaOfEffect)
+ CR_MEMBER(areaOfEffect),
+ CR_MEMBER(gravity)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CExplosiveProjectile::CExplosiveProjectile(const float3& pos, const float3& speed, CUnit* owner, const WeaponDef* weaponDef, int ttl, float areaOfEffect)
+CExplosiveProjectile::CExplosiveProjectile(const float3& pos, const float3& speed,
+ CUnit* owner, const WeaponDef *weaponDef, int ttl, float areaOfEffect, float gravity)
: CWeaponProjectile(pos, speed, owner, 0, ZeroVector, weaponDef, 0, true),
ttl(ttl),
areaOfEffect(areaOfEffect),
- curTime(0)
+ curTime(0),
+ gravity(gravity)
{
useAirLos=true;
@@ -53,7 +56,7 @@
void CExplosiveProjectile::Update()
{
pos+=speed;
- speed.y+=gs->gravity;
+ speed.y+=gravity;
if(!--ttl)
Collision();
@@ -75,6 +78,9 @@
float3 n=ground->GetNormal(pos.x,pos.z);
pos-=speed*max(0.0f,min(1.0f,float((h-pos.y)*n.y/n.dot(speed)+0.1f)));
}
+ else if (weaponDef->waterweapon) {
+ return; //let waterweapons go underwater
+ }
}
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
Index: rts/Sim/Projectiles/ExplosiveProjectile.h
===================================================================
--- rts/Sim/Projectiles/ExplosiveProjectile.h (revision 4223)
+++ rts/Sim/Projectiles/ExplosiveProjectile.h (working copy)
@@ -12,7 +12,8 @@
{
CR_DECLARE(CExplosiveProjectile);
public:
- CExplosiveProjectile(const float3& pos, const float3& speed, CUnit* owner, const WeaponDef* weaponDef, int ttl=100000, float areaOfEffect=8);
+ CExplosiveProjectile(const float3& pos, const float3& speed, CUnit* owner,
+ const WeaponDef *weaponDef, int ttl=100000, float areaOfEffect=8, float gravity=0);
virtual ~CExplosiveProjectile();
virtual void Update();
void Draw(void);
@@ -24,6 +25,7 @@
float areaOfEffect;
float invttl;
float curTime;
+ float gravity;
};
#endif // __EXPLOSIVE_PROJECTILE_H__
Index: rts/Sim/Projectiles/FireBallProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/FireBallProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/FireBallProjectile.cpp (working copy)
@@ -3,6 +3,7 @@
#include "Rendering/GL/VertexArray.h"
#include "Game/Camera.h"
#include "Sim/Weapons/WeaponDefHandler.h"
+#include "Map/Ground.h"
#include "creg/STL_Deque.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
@@ -125,8 +126,10 @@
void CFireBallProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x, pos.z)<pos.y) return; //make waterweapons not explode in water
CWeaponProjectile::Collision();
deleteMe = false;
}
+
Index: rts/Sim/Projectiles/FlameProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/FlameProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/FlameProjectile.cpp (working copy)
@@ -44,6 +44,7 @@
void CFlameProjectile::Collision(void)
{
+ if(ground->GetHeight2(pos.x, pos.z) < pos.y && weaponDef->waterweapon) return; //prevent waterweapons from colliding with water
float3 norm=ground->GetNormal(pos.x,pos.z);
float ns=speed.dot(norm);
speed-=norm*ns*1;
Index: rts/Sim/Projectiles/LaserProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/LaserProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/LaserProjectile.cpp (working copy)
@@ -7,6 +7,7 @@
#include "ProjectileHandler.h"
#include "SimpleParticleSystem.h"
#include "mmgr.h"
+#include "Map/Ground.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));
@@ -104,6 +105,8 @@
void CLaserProjectile::Collision()
{
+ if(weaponDef->waterweapon && ground->GetHeight2(pos.x,pos.z) < pos.y)
+ return; //prevent impact on water if waterweapon is set
float3 oldPos=pos;
CWeaponProjectile::Collision();
Index: rts/Sim/Projectiles/LightingProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/LightingProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/LightingProjectile.cpp (working copy)
@@ -59,7 +59,7 @@
}
if(weapon){
- pos=weapon->weaponPos;
+ pos=weapon->weaponMuzzlePos;
}
for(int a=1;a<10;++a)
displacements[a]+=(gs->randFloat()-0.5f)*0.3f;
Index: rts/Sim/Projectiles/MissileProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/MissileProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/MissileProjectile.cpp (working copy)
@@ -119,9 +119,11 @@
void CMissileProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if (weaponDef->waterweapon && h < pos.y) return; //let waterweapons travel in water
if(h>pos.y && fabs(speed.y)>0.001f)
pos-=speed*std::min((float)1,float((h-pos.y)/fabs(speed.y)));
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
//helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
oldSmoke=pos;
@@ -129,7 +131,8 @@
void CMissileProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,false,true,7,Smoke_Time,0.6f,drawTrail);
// unit->DoDamage(damages,owner);
//helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -207,7 +210,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
CSmokeTrailProjectile* tp=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldDir,owner,age==8,false,7,Smoke_Time,0.6f,drawTrail);
oldSmoke=pos;
oldDir=dir;
@@ -234,66 +237,67 @@
float color=0.6f;
unsigned char col[4];
- if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldDir));
- dir2.Normalize();
-
-
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- float alpha=min((float)255,max(float(0),a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char) alpha;
-
- unsigned char col2[4];
- float a2=(1-float(age2)/(Smoke_Time))*255;
- if(age<8)
- a2=0;
- a2*=0.7f+fabs(dif2.dot(oldDir));
- alpha=min((float)255,max((float)0,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char) alpha;
-
- float size=(1);
- float size2=(1+(age2*(1/Smoke_Time))*7);
-
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
-
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- float alpha=255;
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldDir));
+ dir2.Normalize();
+
+
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ float alpha=min((float)255,max(float(0),a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
- float size=(1+(a*(1/Smoke_Time))*7);
-
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ col[3]=(unsigned char) alpha;
+
+ unsigned char col2[4];
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ if(age<8)
+ a2=0;
+ a2*=0.7f+fabs(dif2.dot(oldDir));
+ alpha=min((float)255,max((float)0,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char) alpha;
+
+ float size=(1);
+ float size2=(1+(age2*(1/Smoke_Time))*7);
+
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldDir*dist*0.33f;
+
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ float alpha=255;
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;//min(255,max(0,a1*255));
+ float size=(1+(a*(1/Smoke_Time))*7);
+
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
//rita flaren
col[0]=255;
col[1]=210;
Index: rts/Sim/Projectiles/StarburstProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/StarburstProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/StarburstProjectile.cpp (working copy)
@@ -15,6 +15,8 @@
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "LogOutput.h"
+
static const float Smoke_Time=70;
CR_BIND_DERIVED(CStarburstProjectile, CWeaponProjectile, (float3(0,0,0),float3(0,0,0),NULL,float3(0,0,0),0,0,0,0,NULL,NULL,NULL,0));
@@ -67,7 +69,12 @@
distanceToTravel(maxdistance)
{
this->uptime=uptime;
- ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ if (weaponDef->flighttime == 0) {
+ ttl=(int)min(3000.f,uptime+(weaponDef?weaponDef->range:0)/maxSpeed+100);
+ }
+ else {
+ ttl=weaponDef->flighttime;
+ }
maxGoodDif=cos(tracking*0.6f);
curSpeed=speed.Length();
@@ -111,9 +118,11 @@
void CStarburstProjectile::Collision()
{
float h=ground->GetHeight2(pos.x,pos.z);
+ if(weaponDef->waterweapon && h < pos.y) return; //prevent impact on water if waterweapon is set
if(h>pos.y)
pos+=speed*(h-pos.y)/speed.y;
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// helper->Explosion(pos,damages,areaOfEffect,owner);
CWeaponProjectile::Collision();
@@ -122,7 +131,8 @@
void CStarburstProjectile::Collision(CUnit *unit)
{
- SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
+ if (weaponDef->visuals.smokeTrail)
+ SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,false,true,7,Smoke_Time,0.7f,drawTrail);
oldSmokeDir=dir;
// unit->DoDamage(damages,owner);
// helper->Explosion(pos,damages,areaOfEffect,owner);
@@ -148,8 +158,7 @@
}
if(uptime>0){
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
- dir=UpVector;
+ curSpeed+=weaponDef->weaponacceleration;
speed=dir*curSpeed;
} else if(doturn && ttl>0 && distanceToTravel>0) {
float3 dif(targetPos-pos);
@@ -161,14 +170,20 @@
dif=dif-dir;
dif-=dir*(dif.dot(dir));
dif.Normalize();
- dir+=dif*0.06f;
+ if (weaponDef->turnrate != 0) {
+ dir+=dif*weaponDef->turnrate;
+ }
+ else {
+ dir+=dif*0.06;
+ }
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else if(ttl>0 && distanceToTravel>0) {
if(curSpeed<maxSpeed)
- curSpeed+=0.1f;
+ curSpeed+=weaponDef->weaponacceleration;
float3 dif(targetPos-pos);
dif.Normalize();
if(dif.dot(dir)>maxGoodDif){
@@ -181,7 +196,8 @@
dir.Normalize();
}
speed=dir*curSpeed;
- distanceToTravel-=speed.Length2D();
+ if (distanceToTravel != MAX_WORLD_SIZE)
+ distanceToTravel-=speed.Length2D();
} else {
dir.y+=gs->gravity;
dir.Normalize();
@@ -202,7 +218,7 @@
age++;
numParts++;
- if(!(age&7)){
+ if(weaponDef->visuals.smokeTrail && !(age&7)){
if(curCallback)
curCallback->drawCallbacker=0;
curCallback=SAFE_NEW CSmokeTrailProjectile(pos,oldSmoke,dir,oldSmokeDir,owner,age==8,false,7,Smoke_Time,0.7f,drawTrail,this);
@@ -231,65 +247,66 @@
unsigned char col[4];
unsigned char col2[4];
- if(drawTrail){ //draw the trail as a single quad
+ if (weaponDef->visuals.smokeTrail)
+ if(drawTrail){ //draw the trail as a single quad
- float3 dif(interPos-camera->pos);
- dif.Normalize();
- float3 dir1(dif.cross(dir));
- dir1.Normalize();
- float3 dif2(oldSmoke-camera->pos);
- dif2.Normalize();
- float3 dir2(dif2.cross(oldSmokeDir));
- dir2.Normalize();
+ float3 dif(interPos-camera->pos);
+ dif.Normalize();
+ float3 dir1(dif.cross(dir));
+ dir1.Normalize();
+ float3 dif2(oldSmoke-camera->pos);
+ dif2.Normalize();
+ float3 dir2(dif2.cross(oldSmokeDir));
+ dir2.Normalize();
- float a1=(1-float(0)/(Smoke_Time))*255;
- a1*=0.7f+fabs(dif.dot(dir));
- int alpha=min(255,(int)max(0.f,a1));
- col[0]=(unsigned char) (color*alpha);
- col[1]=(unsigned char) (color*alpha);
- col[2]=(unsigned char) (color*alpha);
- col[3]=(unsigned char)alpha;
+ float a1=(1-float(0)/(Smoke_Time))*255;
+ a1*=0.7f+fabs(dif.dot(dir));
+ int alpha=min(255,(int)max(0.f,a1));
+ col[0]=(unsigned char) (color*alpha);
+ col[1]=(unsigned char) (color*alpha);
+ col[2]=(unsigned char) (color*alpha);
+ col[3]=(unsigned char)alpha;
- float a2=(1-float(age2)/(Smoke_Time))*255;
- a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
- if(age<8)
- a2=0;
- alpha=min(255,(int)max(0.f,a2));
- col2[0]=(unsigned char) (color*alpha);
- col2[1]=(unsigned char) (color*alpha);
- col2[2]=(unsigned char) (color*alpha);
- col2[3]=(unsigned char)alpha;
+ float a2=(1-float(age2)/(Smoke_Time))*255;
+ a2*=0.7f+fabs(dif2.dot(oldSmokeDir));
+ if(age<8)
+ a2=0;
+ alpha=min(255,(int)max(0.f,a2));
+ col2[0]=(unsigned char) (color*alpha);
+ col2[1]=(unsigned char) (color*alpha);
+ col2[2]=(unsigned char) (color*alpha);
+ col2[3]=(unsigned char)alpha;
- float size=1;
- float size2=(1+age2*(1/Smoke_Time)*7);
+ float size=1;
+ float size2=(1+age2*(1/Smoke_Time)*7);
- float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
- va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
- va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
- va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
- va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
- } else { //draw the trail as particles
- float dist=pos.distance(oldSmoke);
- float3 dirpos1=pos-dir*dist*0.33f;
- float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
+ float txs=weaponDef->visuals.texture2->xend - (weaponDef->visuals.texture2->xend-weaponDef->visuals.texture2->xstart)*(age2/8.0f);//(1-age2/8.0f);
+ va->AddVertexTC(interPos-dir1*size, txs, weaponDef->visuals.texture2->ystart, col);
+ va->AddVertexTC(interPos+dir1*size, txs, weaponDef->visuals.texture2->yend, col);
+ va->AddVertexTC(oldSmoke+dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->yend, col2);
+ va->AddVertexTC(oldSmoke-dir2*size2, weaponDef->visuals.texture2->xend, weaponDef->visuals.texture2->ystart, col2);
+ } else { //draw the trail as particles
+ float dist=pos.distance(oldSmoke);
+ float3 dirpos1=pos-dir*dist*0.33f;
+ float3 dirpos2=oldSmoke+oldSmokeDir*dist*0.33f;
- for(int a=0;a<numParts;++a){
- //float a1=1-float(a)/Smoke_Time;
- col[0]=(unsigned char) (color*255);
- col[1]=(unsigned char) (color*255);
- col[2]=(unsigned char) (color*255);
- col[3]=255;//min(255,max(0,a1*255));
- float size=(1+(a)*(1/Smoke_Time)*7);
+ for(int a=0;a<numParts;++a){
+ //float a1=1-float(a)/Smoke_Time;
+ col[0]=(unsigned char) (color*255);
+ col[1]=(unsigned char) (color*255);
+ col[2]=(unsigned char) (color*255);
+ col[3]=255;//min(255,max(0,a1*255));
+ float size=(1+(a)*(1/Smoke_Time)*7);
- float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
- va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
- va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ float3 pos1=CalcBeizer(float(a)/(numParts),pos,dirpos1,dirpos2,oldSmoke);
+ va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
+ va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
+ }
+
}
-
- }
DrawCallback();
if(curCallback==0)
DrawCallback();
Index: rts/Sim/Projectiles/StarburstProjectile.h
===================================================================
--- rts/Sim/Projectiles/StarburstProjectile.h (revision 4223)
+++ rts/Sim/Projectiles/StarburstProjectile.h (working copy)
@@ -30,6 +30,7 @@
float3 dir;
float maxSpeed;
float curSpeed;
+ float acceleration;
int ttl;
int uptime;
float areaOfEffect;
Index: rts/Sim/Projectiles/TorpedoProjectile.cpp
===================================================================
--- rts/Sim/Projectiles/TorpedoProjectile.cpp (revision 4223)
+++ rts/Sim/Projectiles/TorpedoProjectile.cpp (working copy)
@@ -10,6 +10,7 @@
#include "BubbleProjectile.h"
#include "ProjectileHandler.h"
#include "mmgr.h"
+#include "Sim/Weapons/WeaponDefHandler.h"
CR_BIND_DERIVED(CTorpedoProjectile, CTorpedoProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,NULL,NULL));
@@ -82,14 +83,14 @@
void CTorpedoProjectile::Update(void)
{
- if(pos.y>-3){ //tracking etc only work when we have gotten underwater
+ if(!(weaponDef->submissile) && pos.y>-3){ //tracking etc only work when we have gotten underwater
speed.y+=gs->gravity;
if(dir.y>0)
dir.y=0;
dir=speed;
dir.Normalize();
} else {
- if(pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
+ if(!(weaponDef->submissile) && pos.y-speed.y>-3){ //level out torpedo a bit when hitting water
dir.y*=0.5f;
dir.Normalize();
}
@@ -103,7 +104,7 @@
targPos=target->midPos;
else
targPos=helper->GetUnitErrorPos(target,owner->allyteam);
- if(targPos.y>0)
+ if(!(weaponDef->submissile) && targPos.y>0)
targPos.y=0;
float dist=targPos.distance(pos);
Index: rts/Sim/Units/COB/CobFile.cpp
===================================================================
--- rts/Sim/Units/COB/CobFile.cpp (revision 4223)
+++ rts/Sim/Units/COB/CobFile.cpp (working copy)
@@ -166,7 +166,7 @@
}
//Map common function names to indicies
- scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5);
+ scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 6);
scriptIndex[COBFN_Create] = getFunctionId("Create");
scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving");
scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving");
@@ -197,6 +197,7 @@
scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon);
scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon);
scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap);
+ scriptIndex[COBFN_Shot + i] = getFunctionId("Shot" + weap);
// If new-naming functions are not found, we need to support the old naming scheme
if (i > 2)
Index: rts/Sim/Units/COB/CobFile.h
===================================================================
--- rts/Sim/Units/COB/CobFile.h (revision 4223)
+++ rts/Sim/Units/COB/CobFile.h (working copy)
@@ -46,6 +46,7 @@
const int COBFN_AimFromPrimary = COBFN_AimPrimary + COB_MaxWeapons;
const int COBFN_FirePrimary = COBFN_AimFromPrimary + COB_MaxWeapons;
const int COBFN_EndBurst = COBFN_FirePrimary + COB_MaxWeapons;
+const int COBFN_Shot = COBFN_EndBurst + COB_MaxWeapons;
class CCobFile
{
Index: rts/Sim/Units/COB/CobInstance.cpp
===================================================================
--- rts/Sim/Units/COB/CobInstance.cpp (revision 4223)
+++ rts/Sim/Units/COB/CobInstance.cpp (working copy)
@@ -665,15 +665,15 @@
dir.Normalize();
float3 targetPos = unit->weapons[index]->targetPos;
- float3 weaponPos = unit->weapons[index]->weaponPos;
+ float3 weaponMuzzlePos = unit->weapons[index]->weaponMuzzlePos;
unit->weapons[index]->targetPos = pos+dir;
- unit->weapons[index]->weaponPos = pos;
+ unit->weapons[index]->weaponMuzzlePos = pos;
unit->weapons[index]->Fire();
unit->weapons[index]->targetPos = targetPos;
- unit->weapons[index]->weaponPos = weaponPos;
+ unit->weapons[index]->weaponMuzzlePos = weaponMuzzlePos;
}
else if (type & 4096) {
unsigned index = type - 4096;
Index: rts/Sim/Units/UnitLoader.cpp
===================================================================
--- rts/Sim/Units/UnitLoader.cpp (revision 4223)
+++ rts/Sim/Units/UnitLoader.cpp (working copy)
@@ -348,7 +348,7 @@
} else if(weapondef->type=="MissileLauncher"){
weapon=SAFE_NEW CMissileLauncher(owner);
} else if(weapondef->type=="TorpedoLauncher"){
- if(owner->unitDef->canfly){
+ if(owner->unitDef->canfly && !weapondef->submissile){
weapon=SAFE_NEW CBombDropper(owner,true);
if(weapondef->tracks)
((CBombDropper*)weapon)->tracking=weapondef->turnrate;
@@ -377,7 +377,7 @@
((CStarburstLauncher*)weapon)->tracking=weapondef->turnrate;
else
((CStarburstLauncher*)weapon)->tracking=0;
- ((CStarburstLauncher*)weapon)->uptime=weapondef->uptime*30;
+ ((CStarburstLauncher*)weapon)->uptime=weapondef->uptime*GAME_SPEED;
}else {
logOutput << "Unknown weapon type " << weapondef->type.c_str() << "\n";
return 0;
@@ -461,3 +461,4 @@
}
+
Index: rts/Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- rts/Sim/Units/UnitTypes/Builder.cpp (revision 4223)
+++ rts/Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -582,9 +582,12 @@
{
float3 wantedDir=(pos-this->pos).Normalize();
short int h=GetHeadingFromVector(wantedDir.x,wantedDir.z);
+ short int p=(short int) (asin(wantedDir.dot(updir))*(32768/PI));
+ short int pitch=(short int) (asin(frontdir.dot(updir))*(32768/PI));
std::vector<int> args;
args.push_back(short(h-heading));
+ args.push_back(short(p-pitch));
cob->Call("StartBuilding", args);
int soundIdx = unitDef->sounds.build.getRandomIdx();
Index: rts/Sim/Weapons/BeamLaser.cpp
===================================================================
--- rts/Sim/Weapons/BeamLaser.cpp (revision 4223)
+++ rts/Sim/Weapons/BeamLaser.cpp (working copy)
@@ -43,6 +43,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -77,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
@@ -94,14 +97,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -127,7 +130,7 @@
if(salvoLeft==salvoSize-1){
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
oldDir=dir;
} else {
@@ -151,7 +154,7 @@
float maxLength=range*rangeMod;
float curLength=0;
- float3 curPos=weaponPos;
+ float3 curPos=weaponMuzzlePos;
float3 hitPos;
bool tryAgain=true;
@@ -220,7 +223,7 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, curPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
helper->Explosion(hitPos, weaponDef->dynDamageExp>0?dynDamages*(intensity*damageMul):weaponDef->damages*(intensity*damageMul), areaOfEffect, weaponDef->edgeEffectiveness, weaponDef->explosionSpeed,owner, true, 1.0f, false, weaponDef->explosionGenerator, hit, dir, weaponDef->id);
}
Index: rts/Sim/Weapons/bombdropper.cpp
===================================================================
--- rts/Sim/Weapons/bombdropper.cpp (revision 4223)
+++ rts/Sim/Weapons/bombdropper.cpp (working copy)
@@ -56,14 +56,14 @@
if(weaponPos.y>targetPos.y){
float d=targetPos.y-weaponPos.y;
float s=-owner->speed.y;
- float sq=(s-2*d)/-gs->gravity;
+ float sq=(s-2*d)/-(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
if(sq>0)
- predict=s/gs->gravity+sqrt(sq);
+ predict=s/(weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity))+sqrt(sq);
else
predict=0;
float3 hitpos=owner->pos+owner->speed*predict;
float speedf=owner->speed.Length();
- if(hitpos.distance2D(targetPos)<(salvoSize-1)*speedf*salvoDelay*0.5f+bombMoveRange){
+ if(hitpos.distance2D(targetPos)<max(1,(salvoSize-1))*speedf*salvoDelay*0.5f+bombMoveRange){
subClassReady=true;
}
}
@@ -108,7 +108,7 @@
float size=dif.Length();
if(size>1.0f)
dif/=size*1.0f;
- SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponPos,owner->speed+dif,owner, weaponDef, 1000,areaOfEffect,weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity));
}
//CWeaponProjectile::CreateWeaponProjectile(owner->pos,owner->speed,owner, NULL, float3(0,0,0), damages, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
Index: rts/Sim/Weapons/Cannon.cpp
===================================================================
--- rts/Sim/Weapons/Cannon.cpp (revision 4223)
+++ rts/Sim/Weapons/Cannon.cpp (working copy)
@@ -29,6 +29,7 @@
CR_MEMBER(rangeFactor),
CR_MEMBER(lastDiff),
CR_MEMBER(lastDir),
+ CR_MEMBER(gravity),
CR_RESERVED(16)
));
@@ -47,11 +48,12 @@
void CCannon::Init(void)
{
+ gravity = weaponDef->myGravity==0 ? gs->gravity : -(weaponDef->myGravity);
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
CWeapon::Init();
@@ -79,6 +81,8 @@
if(targetType!=Target_None){
weaponPos=owner->pos + owner->frontdir*relWeaponPos.z
+ owner->updir*relWeaponPos.y + owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos + owner->frontdir*relWeaponMuzzlePos.z
+ + owner->updir*relWeaponMuzzlePos.y + owner->rightdir*relWeaponMuzzlePos.x;
float3 diff = targetPos-weaponPos;
wantedDir = GetWantedDir(diff);
float speed2D = wantedDir.Length2D() * projectileSpeed;
@@ -97,24 +101,26 @@
return false;
}
- if(unit)
- {
- if(unit->isUnderWater)
+ if(!weaponDef->waterweapon) {
+ if(unit)
{
- return false;
+ if(unit->isUnderWater)
+ {
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ {
+ return false;
+ }
}
- } else {
- if(pos.y<0)
- {
- return false;
- }
}
if (projectileSpeed == 0)
{
return true;
}
- float3 dif(pos-weaponPos);
+ float3 dif(pos-weaponMuzzlePos);
float3 dir(GetWantedDir(dif));
@@ -129,8 +135,8 @@
}
flatdir/=flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos, flatdir, flatlength-10,
- dir.y , gs->gravity / (projectileSpeed * projectileSpeed) * 0.5f);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength-10,
+ dir.y , gravity / (projectileSpeed * projectileSpeed) * 0.5f);
if(gc>0) {
return false;
}
@@ -139,8 +145,8 @@
if(gc>0 && gc<length*0.40f)
return false;
*/
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos, flatdir,
- flatlength-30, dir.y, gs->gravity /
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos, flatdir,
+ flatlength-30, dir.y, gravity /
(projectileSpeed * projectileSpeed) * 0.5f,
(accuracy+sprayangle) * 0.6f * (1-owner->limExperience * 0.9f) * 0.9f,
3, owner->allyteam, owner))
@@ -162,7 +168,7 @@
void CCannon::Fire(void)
{
- float3 diff = targetPos-weaponPos;
+ float3 diff = targetPos-weaponMuzzlePos;
float3 dir=GetWantedDir(diff);
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -172,14 +178,14 @@
#endif
int ttl = 0;
float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed;
- int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gs->gravity)
+ int predict = (int)ceil((sqSpeed2D == 0) ? (-2 * projectileSpeed * dir.y / gravity)
: sqrt(diff.SqLength2D() / sqSpeed2D));
if(selfExplode) {
ttl=(int)(predict+gs->randFloat()*2.5f-0.5f);
} else {
ttl=predict*2;
}
- SAFE_NEW CExplosiveProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect);
+ SAFE_NEW CExplosiveProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef, ttl,areaOfEffect,gravity);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,owner->speed,owner, NULL, float3(0,0,0), weaponDef);
// SAFE_NEW CSmokeProjectile(weaponPos,dir*0.01f,90,0.1f,0.02f,owner,0.6f);
@@ -188,8 +194,8 @@
// p->maxheat=p->heat;
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
- if (weaponPos.y < 30)
- water->AddExplosion(weaponPos, weaponDef->damages[0] * 0.1f, sqrt(weaponDef->damages[0]) + 80);
+// if(weaponMuzzlePos.y < 30)
+// water->AddExplosion(weaponMuzzlePos, weaponDef->damages[0] * 0.1f, sqrt(weaponDef->damages[0]) + 80);
}
void CCannon::SlowUpdate(void)
@@ -197,10 +203,10 @@
if(owner->useHighTrajectory!=highTrajectory){
highTrajectory=owner->useHighTrajectory;
if(highTrajectory){
- maxPredict=projectileSpeed*2/-gs->gravity;
- minPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*2/-gravity;
+ minPredict=projectileSpeed*1.41f/-gravity;
} else {
- maxPredict=projectileSpeed*1.41f/-gs->gravity;
+ maxPredict=projectileSpeed*1.41f/-gravity;
}
}
CWeapon::SlowUpdate();
@@ -229,7 +235,7 @@
float Dsq = diff.SqLength();
float DFsq = diff.SqLength2D();
- float g = gs->gravity;
+ float g = gravity;
float v = projectileSpeed;
float dy = diff.y;
float dxz = sqrt(DFsq);
@@ -279,10 +285,10 @@
// f(0) == 1, f(smoothHeight) == heightBoostFactor
yDiff *= 1.f + (heightBoostFactor-1.f) * (-yDiff)/smoothHeight;
- float root1 = speed2dSq + 2*gs->gravity*yDiff;
+ float root1 = speed2dSq + 2*gravity*yDiff;
if(root1 < 0.f){
return 0.f;
} else {
- return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gs->gravity);
+ return rangeFactor*(speed2dSq + speed2d*sqrt(root1))/(-gravity);
}
}
Index: rts/Sim/Weapons/Cannon.h
===================================================================
--- rts/Sim/Weapons/Cannon.h (revision 4223)
+++ rts/Sim/Weapons/Cannon.h (working copy)
@@ -36,6 +36,8 @@
bool highTrajectory;
/// burnblow tag. defines flakker-like behaviour
bool selfExplode;
+ /// projectile gravity
+ float gravity;
void SlowUpdate(void);
/// tells where to point the gun to hit the point at pos+diff
Index: rts/Sim/Weapons/DGunWeapon.cpp
===================================================================
--- rts/Sim/Weapons/DGunWeapon.cpp (revision 4223)
+++ rts/Sim/Weapons/DGunWeapon.cpp (working copy)
@@ -27,7 +27,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -46,13 +47,13 @@
if(onlyForward){
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CFireBallProjectile(weaponPos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
+ SAFE_NEW CFireBallProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,0,targetPos,weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume*0.2f);
}
Index: rts/Sim/Weapons/EmgCannon.cpp
===================================================================
--- rts/Sim/Weapons/EmgCannon.cpp (revision 4223)
+++ rts/Sim/Weapons/EmgCannon.cpp (working copy)
@@ -31,7 +31,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,29 +46,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.5f),owner->allyteam,owner))
return false;
return true;
}
@@ -87,15 +90,17 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
- SAFE_NEW CEmgProjectile(weaponPos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
+ SAFE_NEW CEmgProjectile(weaponMuzzlePos,dir*projectileSpeed,owner,weaponDef->visuals.color,weaponDef->intensity,(int)(range/projectileSpeed), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: rts/Sim/Weapons/FlameThrower.cpp
===================================================================
--- rts/Sim/Weapons/FlameThrower.cpp (revision 4223)
+++ rts/Sim/Weapons/FlameThrower.cpp (working copy)
@@ -27,12 +27,12 @@
void CFlameThrower::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
float3 spread=(gs->randVector()*sprayangle+salvoError)*0.2f;
spread-=dir*0.001f;
- SAFE_NEW CFlameProjectile(weaponPos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
+ SAFE_NEW CFlameProjectile(weaponMuzzlePos,dir*projectileSpeed,spread,owner,weaponDef,(int)(range/projectileSpeed*weaponDef->duration));
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -42,29 +42,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner)){
return false;
}
return true;
@@ -74,6 +76,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
Index: rts/Sim/Weapons/LaserCannon.cpp
===================================================================
--- rts/Sim/Weapons/LaserCannon.cpp (revision 4223)
+++ rts/Sim/Weapons/LaserCannon.cpp (working copy)
@@ -30,7 +30,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -45,14 +46,14 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
@@ -60,14 +61,14 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
}
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.7f),owner->allyteam,owner))
return false;
return true;
}
@@ -84,7 +85,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)){ //the taairmovetype cant align itself properly, change back when that is fixed
dir=owner->frontdir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
}
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.7f);
@@ -96,10 +97,12 @@
fpsSub=6;
#endif
- SAFE_NEW CLaserProjectile(weaponPos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
+ SAFE_NEW CLaserProjectile(weaponMuzzlePos, dir*projectileSpeed, owner, weaponDef->duration*weaponDef->maxvelocity, weaponDef->visuals.color, weaponDef->visuals.color2, weaponDef->intensity, weaponDef, (int)((weaponDef->range-fpsSub*4)/weaponDef->projectilespeed)-fpsSub);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
+
+
Index: rts/Sim/Weapons/LightingCannon.cpp
===================================================================
--- rts/Sim/Weapons/LightingCannon.cpp (revision 4223)
+++ rts/Sim/Weapons/LightingCannon.cpp (working copy)
@@ -31,6 +31,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
@@ -44,29 +45,31 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater)
- return false;
- } else {
- if(pos.y<0)
- return false;
+ if(!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater)
+ return false;
+ } else {
+ if(pos.y<0)
+ return false;
+ }
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(avoidFeature && helper->LineFeatureCol(weaponPos,dir,length))
+ if(avoidFeature && helper->LineFeatureCol(weaponMuzzlePos,dir,length))
return false;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
return true;
}
@@ -78,16 +81,16 @@
void CLightingCannon::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.5f);
dir.Normalize();
CUnit* u=0;
- float r=helper->TraceRay(weaponPos,dir,range,0,owner,u);
+ float r=helper->TraceRay(weaponMuzzlePos,dir,range,0,owner,u);
float3 newDir;
CPlasmaRepulser* shieldHit;
- float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponPos,dir,range,newDir,shieldHit);
+ float shieldLength=interceptHandler.AddShieldInterceptableBeam(this,weaponMuzzlePos,dir,range,newDir,shieldHit);
if(shieldLength<r){
r=shieldLength;
if(shieldHit) {
@@ -101,11 +104,11 @@
// Dynamic Damage
DamageArray dynDamages;
if (weaponDef->dynDamageExp > 0)
- dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponPos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
+ dynDamages = weaponDefHandler->DynamicDamages(weaponDef->damages, weaponMuzzlePos, targetPos, weaponDef->dynDamageRange>0?weaponDef->dynDamageRange:weaponDef->range, weaponDef->dynDamageExp, weaponDef->dynDamageMin, weaponDef->dynDamageInverted);
- helper->Explosion(weaponPos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
+ helper->Explosion(weaponMuzzlePos+dir*r,weaponDef->dynDamageExp>0?dynDamages:weaponDef->damages,areaOfEffect,weaponDef->edgeEffectiveness,weaponDef->explosionSpeed,owner,false,0.5f,true,weaponDef->explosionGenerator, u,dir, weaponDef->id);
- SAFE_NEW CLightingProjectile(weaponPos,weaponPos+dir*(r+10),owner,color,weaponDef,10,this);
+ SAFE_NEW CLightingProjectile(weaponMuzzlePos,weaponMuzzlePos+dir*(r+10),owner,color,weaponDef,10,this);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
Index: rts/Sim/Weapons/MeleeWeapon.cpp
===================================================================
--- rts/Sim/Weapons/MeleeWeapon.cpp (revision 4223)
+++ rts/Sim/Weapons/MeleeWeapon.cpp (working copy)
@@ -33,21 +33,23 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
if(!onlyForward){
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
+// predict=(targetPos-weaponPos).Length()/projectileSpeed;
}
CWeapon::Update();
-
}
void CMeleeWeapon::Fire(void)
{
if(targetType==Target_Unit){
- float3 impulseDir = targetUnit->pos-weaponPos;
+ float3 impulseDir = targetUnit->pos-weaponMuzzlePos;
impulseDir.Normalize();
- targetUnit->DoDamage(weaponDef->damages,owner,impulseDir,weaponDef->id);
+ // the heavier the unit, the more impulse it does
+ targetUnit->DoDamage(weaponDef->damages, owner, impulseDir * owner->mass, weaponDef->id);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: rts/Sim/Weapons/MissileLauncher.cpp
===================================================================
--- rts/Sim/Weapons/MissileLauncher.cpp (revision 4223)
+++ rts/Sim/Weapons/MissileLauncher.cpp (working copy)
@@ -29,7 +29,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,8 +49,10 @@
float3 dir;
if(onlyForward){
dir=owner->frontdir;
+ } else if (weaponDef->fixedLauncher) {
+ dir=weaponDir;
} else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
@@ -64,7 +67,7 @@
if(onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType))
startSpeed+=owner->speed;
- SAFE_NEW CMissileProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,(int)(range/projectileSpeed+25),targetUnit, weaponDef,targetPos);
+ SAFE_NEW CMissileProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef,targetPos);
//CWeaponProjectile::CreateWeaponProjectile(weaponPos,startSpeed,owner,targetUnit, float3(0,0,0), weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
@@ -75,15 +78,17 @@
if(!CWeapon::TryTarget(pos,userTarget,unit))
return false;
- if(unit){
- if(unit->isUnderWater){
- return false;
+ if (!weaponDef->waterweapon) {
+ if(unit){
+ if(unit->isUnderWater){
+ return false;
+ }
+ } else {
+ if(pos.y<0)
+ return false;
}
- } else {
- if(pos.y<0)
- return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir = pos-weaponMuzzlePos;
if(weaponDef->trajectoryHeight>0){ //do a different test depending on if the missile has a high trajectory or not
float3 flatdir(dir.x,0,dir.z);
dir.Normalize();
@@ -95,11 +100,11 @@
float linear=dir.y+weaponDef->trajectoryHeight;
float quadratic=-weaponDef->trajectoryHeight/flatlength;
- float gc=ground->TrajectoryGroundCol(weaponPos,flatdir,flatlength-30,linear,quadratic);
+ float gc=ground->TrajectoryGroundCol(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic);
if(gc>0)
return false;
- if(avoidFriendly && helper->TestTrajectoryCone(weaponPos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
+ if(avoidFriendly && helper->TestTrajectoryCone(weaponMuzzlePos,flatdir,flatlength-30,linear,quadratic,0,8,owner->allyteam,owner)){
return false;
}
} else {
@@ -110,7 +115,7 @@
dir/=length;
if(!onlyForward){ //skip ground col testing for aircrafts
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
} else {
@@ -119,7 +124,7 @@
if(owner->frontdir.dot(goaldir) < maxAngleDif)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle),owner->allyteam,owner))
return false;
}
return true;
Index: rts/Sim/Weapons/PlasmaRepulser.cpp
===================================================================
--- rts/Sim/Weapons/PlasmaRepulser.cpp (revision 4223)
+++ rts/Sim/Weapons/PlasmaRepulser.cpp (working copy)
@@ -70,6 +70,8 @@
if(weaponDef->shieldPower==0)
curPower=99999999999.0f;
+ else
+ curPower=weaponDef->shieldStartingPower;
CWeapon::Init();
}
Index: rts/Sim/Weapons/Rifle.cpp
===================================================================
--- rts/Sim/Weapons/Rifle.cpp (revision 4223)
+++ rts/Sim/Weapons/Rifle.cpp (working copy)
@@ -41,6 +41,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=targetPos-weaponPos;
wantedDir.Normalize();
}
@@ -60,18 +61,18 @@
return false;
}
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- float g=ground->LineGroundCol(weaponPos,pos);
+ float g=ground->LineGroundCol(weaponMuzzlePos,pos);
if(g>0 && g<length*0.9f)
return false;
- if(helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
+ if(helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)*(1-owner->limExperience*0.9f),owner->allyteam,owner)){
return false;
}
return true;
@@ -79,7 +80,7 @@
void CRifle::Fire(void)
{
- float3 dir=targetPos-weaponPos;
+ float3 dir=targetPos-weaponMuzzlePos;
dir.Normalize();
dir+=(gs->randVector()*sprayangle+salvoError)*(1-owner->limExperience*0.9f);
dir.Normalize();
@@ -88,13 +89,13 @@
tracefile << owner->pos.x << " " << dir.x << " " << targetPos.x << " " << targetPos.y << " " << targetPos.z << "\n";
#endif
CUnit* hit;
- float length = helper->TraceRay(weaponPos, dir, range, weaponDef->damages[0], owner, hit, collisionFlags);
- if (hit) {
+ float length=helper->TraceRay(weaponMuzzlePos, dir, range, weaponDef->damages[0], owner, hit, collisionFlags);
+ if(hit) {
hit->DoDamage(weaponDef->damages, owner, ZeroVector, weaponDef->id);
- SAFE_NEW CHeatCloudProjectile(weaponPos + dir * length, hit->speed * 0.9f, 30, 1, owner);
+ SAFE_NEW CHeatCloudProjectile(weaponMuzzlePos + dir * length, hit->speed*0.9f, 30, 1, owner);
}
- SAFE_NEW CTracerProjectile(weaponPos,dir*projectileSpeed,length,owner);
- SAFE_NEW CSmokeProjectile(weaponPos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
+ SAFE_NEW CTracerProjectile(weaponMuzzlePos,dir*projectileSpeed,length,owner);
+ SAFE_NEW CSmokeProjectile(weaponMuzzlePos,float3(0,0.0f,0),70,0.1f,0.02f,owner,0.6f);
if(fireSoundId)
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
Index: rts/Sim/Weapons/StarburstLauncher.cpp
===================================================================
--- rts/Sim/Weapons/StarburstLauncher.cpp (revision 4223)
+++ rts/Sim/Weapons/StarburstLauncher.cpp (working copy)
@@ -32,6 +32,7 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
wantedDir=(targetPos-weaponPos).Normalize(); //the aiming upward is apperently implicid so aim toward target
}
CWeapon::Update();
@@ -39,7 +40,17 @@
void CStarburstLauncher::Fire(void)
{
- CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponPos+float3(0,2,0),float3(0,0.01f,0),owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget,range);
+ float3 speed(0,weaponDef->startvelocity,0);
+ float maxrange;
+ if (weaponDef->fixedLauncher) {
+ speed = weaponDir * weaponDef->startvelocity;
+ maxrange = (float)MAX_WORLD_SIZE;
+ } else if (weaponDef->flighttime > 0) {
+ maxrange = (float)MAX_WORLD_SIZE;
+ } else {
+ maxrange = (float)range;
+ }
+ CStarburstProjectile* p=SAFE_NEW CStarburstProjectile(weaponMuzzlePos+float3(0,2,0),speed,owner,targetPos,areaOfEffect,projectileSpeed,tracking,(int)uptime,targetUnit, weaponDef,interceptTarget, maxrange);
if(weaponDef->targetable)
interceptHandler.AddInterceptTarget(p,targetPos);
@@ -54,14 +65,15 @@
return false;
if(unit){
- if(unit->isUnderWater)
+ if(unit->isUnderWater && !weaponDef->waterweapon)
return false;
} else {
- if(pos.y<0)
+ if(pos.y<0 && !weaponDef->waterweapon)
return false;
}
- if(avoidFriendly && helper->TestCone(weaponPos,UpVector,100,0,owner->allyteam,owner))
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,
+ (weaponDef->fixedLauncher ? weaponDir : UpVector), 100, 0, owner->allyteam, owner))
return false;
return true;
Index: rts/Sim/Weapons/TorpedoLauncher.cpp
===================================================================
--- rts/Sim/Weapons/TorpedoLauncher.cpp (revision 4223)
+++ rts/Sim/Weapons/TorpedoLauncher.cpp (working copy)
@@ -32,7 +32,8 @@
{
if(targetType!=Target_None){
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// if(!onlyForward){
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+// if(!onlyForward){
wantedDir=targetPos-weaponPos;
float dist=wantedDir.Length();
predict=dist/projectileSpeed;
@@ -48,18 +49,24 @@
// if(onlyForward){
// dir=owner->frontdir;
// } else {
- dir=targetPos-weaponPos;
+ dir=targetPos-weaponMuzzlePos;
dir.Normalize();
if(weaponDef->trajectoryHeight>0){
dir.y+=weaponDef->trajectoryHeight;
dir.Normalize();
}
// }
- float3 startSpeed=dir*weaponDef->startvelocity;
+ float3 startSpeed;
+ if (!weaponDef->fixedLauncher) {
+ startSpeed=dir*weaponDef->startvelocity;
+ }
+ else {
+ startSpeed=weaponDir*weaponDef->startvelocity;
+ }
// if(onlyForward)
// startSpeed+=owner->speed*0.5f;
- SAFE_NEW CTorpedoProjectile(weaponPos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,(int)(range/projectileSpeed+15),targetUnit, weaponDef);
+ SAFE_NEW CTorpedoProjectile(weaponMuzzlePos,startSpeed,owner,areaOfEffect,projectileSpeed,tracking,weaponDef->flighttime==0 ? (int)(range/projectileSpeed+25) : weaponDef->flighttime,targetUnit, weaponDef);
if(fireSoundId && (!weaponDef->soundTrigger || salvoLeft==salvoSize-1))
sound->PlaySample(fireSoundId,owner,fireSoundVolume);
}
@@ -70,22 +77,22 @@
return false;
if(unit){
- if(unit->unitDef->canhover)
+ if(!(weaponDef->submissile) && unit->unitDef->canhover)
return false;
- if(unit->unitDef->canfly && unit->pos.y>0)
+ if(!(weaponDef->submissile) && unit->unitDef->canfly && unit->pos.y>0)
return false;
}
- if(ground->GetHeight2(pos.x,pos.z)>0)
+ if(!(weaponDef->submissile) && ground->GetHeight2(pos.x,pos.z)>0)
return 0;
- float3 dir=pos-weaponPos;
+ float3 dir=pos-weaponMuzzlePos;
float length=dir.Length();
if(length==0)
return true;
dir/=length;
- if(avoidFriendly && helper->TestCone(weaponPos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
+ if(avoidFriendly && helper->TestCone(weaponMuzzlePos,dir,length,(accuracy+sprayangle)+0.05f,owner->allyteam,owner)) //+0.05f since torpedoes has an unfortunate tendency to hit own ships due to movement
return false;
return true;
}
Index: rts/Sim/Weapons/Weapon.cpp
===================================================================
--- rts/Sim/Weapons/Weapon.cpp (revision 4223)
+++ rts/Sim/Weapons/Weapon.cpp (working copy)
@@ -57,8 +57,10 @@
CR_MEMBER(subClassReady),
CR_MEMBER(onlyForward),
CR_MEMBER(weaponPos),
+ CR_MEMBER(weaponMuzzlePos),
CR_MEMBER(lastRequest),
CR_MEMBER(relWeaponPos),
+ CR_MEMBER(relWeaponMuzzlePos),
CR_MEMBER(muzzleFlareSize),
CR_MEMBER(lastTargetRetry),
CR_MEMBER(areaOfEffect),
@@ -132,8 +134,10 @@
subClassReady(true),
onlyForward(false),
weaponPos(0,0,0),
+ weaponMuzzlePos(0,0,0),
lastRequest(0),
relWeaponPos(0,1,0),
+ relWeaponMuzzlePos(0,1,0),
muzzleFlareSize(1),
lastTargetRetry(-100),
areaOfEffect(1),
@@ -176,11 +180,14 @@
if(hasCloseTarget){
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //if we couldn't get a line of fire from the muzzle try if we can get it from the aim piece
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
}
@@ -258,16 +265,18 @@
&& subClassReady
&& reloadStatus<=gs->frameNum
&& (!weaponDef->stockpile || numStockpiled)
- && (weaponDef->waterweapon || weaponPos.y>0)
+ && (weaponDef->fireSubmersed || weaponMuzzlePos.y>0)
&& (owner->unitDef->maxFuel==0 || owner->currentFuel > 0)
){
if ((weaponDef->stockpile || (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost))) {
std::vector<int> args;
args.push_back(0);
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
useWeaponPosForAim=reloadTime/16+8;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
if(TryTarget(targetPos,haveUserTarget,targetUnit)){
if(weaponDef->stockpile){
@@ -303,35 +312,52 @@
}
}
}
- if(salvoLeft && nextSalvo<=gs->frameNum){
+ if(salvoLeft && nextSalvo<=gs->frameNum ){
salvoLeft--;
nextSalvo=gs->frameNum+salvoDelay;
owner->lastFireWeapon=gs->frameNum;
+
+ int projectiles = weaponDef->projectilespershot;
+
+ while(projectiles > 0) {
+ --projectiles;
+
+ // add to the commandShotCount if this is the last salvo,
+ // and it is being directed towards the current target
+ // (helps when deciding if a queued ground attack order has been completed)
+ if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
+ ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
+ ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
+ owner->commandShotCount++;
+ }
+
+ std::vector<int> args;
+ args.push_back(0);
+
+ owner->cob->Call(COBFN_Shot+weaponNum,0);
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
+ relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- // add to the commandShotCount if this is the last salvo,
- // and it is being directed towards the current target
- // (helps when deciding if a queued ground attack order has been completed)
- if ((salvoLeft == 0) && (owner->commandShotCount >= 0) &&
- ((targetType == Target_Pos) && (targetPos == owner->userAttackPos)) ||
- ((targetType == Target_Unit) && (targetUnit == owner->userTarget))) {
- owner->commandShotCount++;
- }
+ owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum*/COBFN_QueryPrimary+weaponNum/**/,args);
+ owner->localmodel->GetEmitDirPos(args[0], relWeaponMuzzlePos, weaponDir);
- std::vector<int> args;
- args.push_back(0);
- owner->cob->Call(/*COBFN_AimFromPrimary+weaponNum/*/COBFN_QueryPrimary+weaponNum/**/,args);
- relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
-// logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
-
- if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
- owner->isCloaked = false;
- owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ weaponDir = owner->frontdir * weaponDir.z + owner->updir * weaponDir.y + owner->rightdir * weaponDir.x;
+ weaponDir.Normalize();
+
+ // logOutput.Print("RelPosFire %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
+
+ if (owner->unitDef->decloakOnFire && (owner->scriptCloak <= 2)) {
+ owner->isCloaked = false;
+ owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
+ }
+
+ Fire();
}
- Fire();
-
//Rock the unit in the direction of the fireing
float3 rockDir = wantedDir;
rockDir.y = 0;
@@ -362,9 +388,9 @@
if(!weaponDef->waterweapon && pos.y<1)
pos.y=1;
- weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
if(!TryTarget(pos,userTarget,0))
return false;
@@ -387,8 +413,10 @@
weaponPos= owner->pos + owner->frontdir * relWeaponPos.z
+ owner->updir * relWeaponPos.y + owner->rightdir * relWeaponPos.x;
- if(weaponPos.y < ground->GetHeight2(weaponPos.x, weaponPos.z))
- weaponPos = owner->pos + UpVector * 10;
+ weaponMuzzlePos= owner->pos + owner->frontdir * relWeaponMuzzlePos.z
+ + owner->updir * relWeaponMuzzlePos.y + owner->rightdir * relWeaponMuzzlePos.x;
+ if(weaponMuzzlePos.y < ground->GetHeight2(weaponMuzzlePos.x, weaponMuzzlePos.z))
+ weaponMuzzlePos = owner->pos + UpVector * 10;
//hope that we are underground because we are a popup weapon and will come above ground later
if(!unit){
@@ -441,18 +469,23 @@
#endif
std::vector<int> args;
args.push_back(0);
- if(useWeaponPosForAim){
+ if(useWeaponPosForAim){ //If we can't get a line of fire from the muzzle try the aim piece instead since the weapon may just be turned in a wrong way
owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
if(useWeaponPosForAim>1)
useWeaponPosForAim--;
} else {
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
}
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
+
+ owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
- if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
- weaponPos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+ if(weaponMuzzlePos.y<ground->GetHeight2(weaponMuzzlePos.x,weaponMuzzlePos.z))
+ weaponMuzzlePos=owner->pos+UpVector*10; //hope that we are underground because we are a popup weapon and will come above ground later
+
predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);
if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
@@ -556,7 +589,7 @@
if(weaponDef->stockpile && !numStockpiled)
return false;
- float3 dif=pos-weaponPos;
+ float3 dif=pos-weaponMuzzlePos;
float heightDiff; // negative when target below owner
if (targetBorder != 0 && unit) {
@@ -628,11 +661,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(tempTargetPos,userTarget,unit);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -658,11 +693,13 @@
owner->frontdir = GetVectorFromHeading(owner->heading);
owner->rightdir = owner->frontdir.cross(owner->updir);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
bool val = TryTarget(pos, userTarget, 0);
owner->frontdir = tempfrontdir;
owner->rightdir = temprightdir;
owner->heading = tempHeadding;
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
return val;
}
@@ -673,6 +710,10 @@
owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
+
+ owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
+ relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
+ weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;
// logOutput.Print("RelPos %f %f %f",relWeaponPos.x,relWeaponPos.y,relWeaponPos.z);
if (range > owner->maxRange) {
Index: rts/Sim/Weapons/Weapon.h
===================================================================
--- rts/Sim/Weapons/Weapon.h (revision 4223)
+++ rts/Sim/Weapons/Weapon.h (working copy)
@@ -60,6 +60,11 @@
float3 relWeaponPos; //weaponpos relative to the unit
float3 weaponPos; //absolute weapon pos
+
+ float3 relWeaponMuzzlePos; //position of the firepoint
+ float3 weaponMuzzlePos;
+ float3 weaponDir;
+
float muzzleFlareSize; //size of muzzle flare if drawn
int useWeaponPosForAim; //sometimes weapon pos is better to use than aimpos
bool hasCloseTarget; //might need to update weapon pos more often when enemy is near
Index: rts/Sim/Weapons/WeaponDefHandler.cpp
===================================================================
--- rts/Sim/Weapons/WeaponDefHandler.cpp (revision 4223)
+++ rts/Sim/Weapons/WeaponDefHandler.cpp (working copy)
@@ -67,6 +67,7 @@
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;
@@ -94,6 +95,7 @@
sunparser->GetDef(weaponDefs[id].minIntensity, "0", weaponname + "\\MinIntensity");
sunparser->GetDef(weaponDefs[id].dropped, "0", weaponname + "\\dropped");
+ sunparser->GetDef(manualBombSettings, "0", weaponname + "\\manualbombsettings");
sunparser->GetDef(lineofsight, "0", weaponname + "\\lineofsight");
sunparser->GetDef(ballistic, "0", weaponname + "\\ballistic");
sunparser->GetDef(weaponDefs[id].twophase, "0", weaponname + "\\twophase");
@@ -110,7 +112,10 @@
sunparser->GetDef(weaponDefs[id].noSelfDamage, "0", weaponname + "\\NoSelfDamage");
sunparser->GetDef(weaponDefs[id].waterweapon, "0", weaponname + "\\waterweapon");
+ sunparser->GetDef(weaponDefs[id].fireSubmersed, weaponDefs[id].waterweapon ? "1":"0", weaponname + "\\firesubmersed");
+ sunparser->GetDef(weaponDefs[id].submissile, "0", weaponname + "\\submissile");
sunparser->GetDef(weaponDefs[id].tracks, "0", weaponname + "\\tracks");
+ sunparser->GetDef(weaponDefs[id].fixedLauncher, "0", weaponname + "\\FixedLauncher");
sunparser->GetDef(weaponDefs[id].noExplode, "0", weaponname + "\\NoExplode");
sunparser->GetDef(weaponDefs[id].maxvelocity, "0", weaponname + "\\weaponvelocity");
sunparser->GetDef(weaponDefs[id].isShield, "0", weaponname + "\\IsShield");
@@ -256,6 +261,7 @@
weaponDefs[id].reload = atof(sunparser->SGetValueDef("1", weaponname + "\\reloadtime").c_str());
weaponDefs[id].salvodelay = atof(sunparser->SGetValueDef("0.1", weaponname + "\\burstrate").c_str());
sunparser->GetDef(weaponDefs[id].salvosize, "1", weaponname + "\\burst");
+ sunparser->GetDef(weaponDefs[id].projectilespershot, "1", weaponname + "\\projectiles");
weaponDefs[id].maxAngle = atof(sunparser->SGetValueDef("3000", weaponname + "\\tolerance").c_str()) * 180.0f / 0x7fff;
weaponDefs[id].restTime = 0.0f;
sunparser->GetDef(weaponDefs[id].metalcost, "0", weaponname + "\\metalpershot");
@@ -263,6 +269,7 @@
sunparser->GetDef(weaponDefs[id].selfExplode, "0", weaponname + "\\burnblow");
sunparser->GetDef(weaponDefs[id].sweepFire, "0", weaponname + "\\sweepfire");
sunparser->GetDef(weaponDefs[id].canAttackGround, "1", weaponname + "\\canattackground");
+ weaponDefs[id].myGravity = atof(sunparser->SGetValueDef("0", weaponname + "\\myGravity").c_str());
weaponDefs[id].fireStarter=atof(sunparser->SGetValueDef("0", weaponname + "\\firestarter").c_str())*0.01f;
weaponDefs[id].paralyzer=!!atoi(sunparser->SGetValueDef("0", weaponname + "\\paralyzer").c_str());
@@ -292,6 +299,7 @@
sunparser->GetDef(weaponDefs[id].shieldPower, "0", weaponname + "\\shieldpower");
sunparser->GetDef(weaponDefs[id].shieldPowerRegen, "0", weaponname + "\\shieldpowerregen");
sunparser->GetDef(weaponDefs[id].shieldPowerRegenEnergy, "0", weaponname + "\\shieldpowerregenenergy");
+ sunparser->GetDef(weaponDefs[id].shieldStartingPower, "0", weaponname + "\\shieldstartingpower");
sunparser->GetDef(weaponDefs[id].shieldInterceptType, "0", weaponname + "\\shieldintercepttype");
weaponDefs[id].shieldGoodColor=sunparser->GetFloat3(float3(0.5f,0.5f,1),weaponname + "\\shieldgoodcolor");
weaponDefs[id].shieldBadColor=sunparser->GetFloat3(float3(1,0.5f,0.5f),weaponname + "\\shieldbadcolor");
@@ -353,10 +361,11 @@
weaponDefs[id].visuals.color = tempCol;
weaponDefs[id].uptime = atof(sunparser->SGetValueDef("0", weaponname + "\\weapontimer").c_str());
+ weaponDefs[id].flighttime = atof(sunparser->SGetValueDef("0", weaponname + "\\flighttime").c_str()) * 32;
weaponDefs[id].turnrate = atof(sunparser->SGetValueDef("0", weaponname + "\\turnrate").c_str()) * PI / 0x7fff /30.0f;
- if(weaponDefs[id].type=="AircraftBomb"){
+ if(weaponDefs[id].type=="AircraftBomb" && !manualBombSettings){
if(weaponDefs[id].reload<0.5f){
weaponDefs[id].salvodelay=min(0.2f,weaponDefs[id].reload);
weaponDefs[id].salvosize=(int)(1/weaponDefs[id].salvodelay)+1;
Index: rts/Sim/Weapons/WeaponDefHandler.h
===================================================================
--- rts/Sim/Weapons/WeaponDefHandler.h (revision 4223)
+++ rts/Sim/Weapons/WeaponDefHandler.h (working copy)
@@ -68,17 +68,23 @@
float restTime;
float uptime;
+ int flighttime;
float metalcost;
float energycost;
float supplycost;
+ int projectilespershot;
+
int id;
int tdfId; //the id= tag in the tdf
bool turret;
bool onlyForward;
+ bool fixedLauncher;
bool waterweapon;
+ bool fireSubmersed;
+ bool submissile; //Lets a torpedo travel above water like it does below water
bool tracks;
bool dropped;
bool paralyzer; //weapon will only paralyze not do real damage
@@ -103,6 +109,7 @@
bool selfExplode;
bool gravityAffected;
+ float myGravity;
bool twophase;
bool guided;
bool vlaunch;
@@ -166,6 +173,7 @@
float shieldPower; //how much damage the shield can reflect (0=infinite)
float shieldPowerRegen; //how fast the power regenerates per second
float shieldPowerRegenEnergy; //how much energy is needed to regenerate power per second
+ float shieldStartingPower; //how much power the shield has when first created
float3 shieldGoodColor; //color when shield at full power
float3 shieldBadColor; //color when shield is empty
float shieldAlpha; //shield alpha value
Index: rts/System/GlobalStuff.h
===================================================================
--- rts/System/GlobalStuff.h (revision 4223)
+++ rts/System/GlobalStuff.h (working copy)
@@ -20,7 +20,7 @@
*
* Defines the maximum world size as 1000000
*/
-#define MAX_WORLD_SIZE 1000000;
+#define MAX_WORLD_SIZE 1000000
/**
* @brief square size
@@ -260,42 +260,42 @@
/**
* @brief disable helper AIs
- *
+ *
* Whether helper AIs are allow, including GroupAI and LuaUI control widgets
*/
bool noHelperAIs;
/**
* @brief definition editing enabled
- *
+ *
* Whether definition editing is enabled
*/
bool editDefsEnabled;
/**
* @brief LuaRules control
- *
+ *
* Whether or not LuaRules is enabled
*/
bool useLuaRules;
/**
* @brief LuaGaia control
- *
+ *
* Whether or not LuaGaia is enabled
*/
bool useLuaGaia;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaTeamID;
/**
* @brief gaia team
- *
+ *
* gaia's team id
*/
int gaiaAllyTeamID;
|
---|