Beam Damage

  • Thread starter Thread starter Hammurabi
  • Start date Start date
H

Hammurabi

Guest
I'm trying to make a weapon (flamethrower) that delivers damage with a few cBeam entities instead of with bullets, but I can't figure out how to make a cBeam entity deal damage when it touches anything. I know this is probably a very simple thing to do, but nothing I've tried so far has worked.

How can this be done?
 
Have it trace lines every think frame to the end of the beam entities, and inflict damage on stuff touching that. It's a workarround, but it'll work.

-Angry Lawyer
 
That's how it's done in the code for the stalkers and vortigaunts in HL2. I've been trying to do it that way but I haven't been able to get it to work.

Actually even if I get that working I'll need to find some way of dealing area damage across the radius of the beams. That way I can set whole roomfuls of zombies aflame at once.

Beam rifle = easy to make
Wide area flamethrower = much more complicated
 
There's a trace square, or something, somewhere in the code, that works in a similar way to tracelines, although wider.

Alternatively, just use multiple tracelines, using the width of the beam, and make it so when it hits an object, it keeps going.

-Angry Lawyer
 
I think I've found it- AI_TraceHull(...), but I'm having a hard time using it.
 
I've never really used it, but I think it could be the one.

-Angry Lawyer
 
This code works for applying damage via a traced line. Flamethrower spread can be surprisingly well simulated by doing this serveral times in rapid succession at different angles. I'm not sure the way I'm handling vForce is correct, but it's definitely functional.

trace_t tr;
AI_TraceLine( vecSrc, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
CBaseEntity *pEntity = tr.m_pEnt;
if(pEntity){
Vector vForce = pEntity->WorldSpaceCenter() - WorldSpaceCenter();
VectorNormalize( vForce );
vForce *= 96;
CTakeDamageInfo damage(pOwner,pOwner,vForce, pEntity->GetAbsOrigin(), int_damage,DMG_BURN | DMG_BLAST);
pEntity->TakeDamage(damage);
}

The end point of the traced line can be randomly generated within a certain distance of the actual end point fairly easily by finding a perpendicular vector to the traced line at the end of the line and then using it and the cross product of those two vectors as axis'.

Here's the function I use for calculating bullet accuracy in my mod using this technique. It could be very easily converted to calculate flamethrower trace spread.

//Inches = farthest off a bullet can be from its original trajectory at #distance inches from the muzzle
void FloatAim(float inches, float distance){
Vector n = GetAbsVelocity();
Vector p = Vector(-1/n.x, -1/n.y, -1/n.z);
Vector c = CrossProduct(n,p);
VectorNormalize(p);
VectorNormalize(c);
float fields = FastSqrt((n.x)*(n.x) + (n.y)*(n.y) + (n.z)*(n.z) ) / distance;
fields *= inches;

n += (p * fields * random->RandomFloat( -1, 1 ));
n += (c * fields * random->RandomFloat( -1, 1 ));
SetAbsVelocity(n);
}
 
Clever stuff, although I can imagine it causing latency mayhem in a multiplayer game if everyone in the server uses one.

-Angry Lawyer
 
In a single player game it actually seems faster to calculate than using normal bullets because the default bullets use a more complex accuracy algorithm (degrees), have to mark where they've hit, and play impact sounds.

HL2's engine is remarkably efficient. My mod I've developing uses physical bullets with realistic velocities, air resistance, and gravity, and they don't noticeably slow down the game at all unless you spawn and bounce around a couple hundred of them simultaneously. Funny how I can code that in a day but still can't get the stupid beams to point the right way when I give the flamethrower to npcs.

Edit: I figured it out. I was making the silly mistake of trying to use a vector meant to represent a velocity as the end point.
When launching projectiles this works:
Vector vecSrc = pOperator->Weapon_ShootPosition();
Vector vecAiming = npc->GetActualShootTrajectory( vecSrc );//represents velocity

When specifying the end point of a beam this seems to work:
vecSrc = pOperator->Weapon_ShootPosition();
vecAiming = vecSrc + npc->GetActualShootTrajectory( vecSrc ) * TORCH_RANGE;//represents actual end position

I'll need to find a better position to start the beam than at the owner's Weapon_ShootPosition() because that's right in the middle of his face. The muzzle of the gun would obviously be a better choice.
 
Yeah. Use an attachment on the weapon model barrel itself. I forget how to do it, but I'm sure it's done for shotguns and the like.

-Angry Lawyer
 
Back
Top