News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
Proximity Mine Help (based Off SoA Prox Launcher Code) 
Basically it's overall working but
the key issues are
it never seems to stick on world (it otherwise behaves properly more or less), and thus the arming and stick sounds never play. Also even if it doesn't stick the arming sound never plays

besides that it properly triggers on enemies, bounces off doors & enemies etc, and works more or less...

I've been working on this for 9+h and can't figure it out!

void() ProximityBomb =
{
local entity head;
local float blowup;

if (vlen(self.spawnmaster.velocity)>0)
{
ProximityGrenadeExplode();
self.think();
return;
}
if (time > self.delay)
{
mine_disarm();
self.think();
return;
}


self.touch = SUB_Null; //new
self.owner = world;
self.takedamage = DAMAGE_YES;
head = findradius(self.origin, PROX_MINE_RADIUS); //sensor radius
blowup = 0;

while (head) //what to look for
{

// Don't detonate on players or other mines
if ((head != self) && (head.health > 0) && (head.flags & (FL_CLIENT|FL_MONSTER)) && (head.classname != self.classname) && (head != self.lastvictim)) //(head.classname != "player"))
{
blowup = 1;
}


traceline(self.origin,head.origin,TRUE,self);
if (trace_fraction != 1.0)
blowup = 0;


if (blowup==1)
{

ProximityGrenadeExplode();
self.nextthink = time + 0.5;
return;
}
head = head.chain;
}
self.nextthink = time + 0.25;
}; 
 
void() ProximityArmed = //new
{
sound(self, CHAN_WEAPON, "weapons/proxarmed.wav", 1, ATTN_NORM);
self.think = ProximityBomb;
self.nextthink = time + 0.25;
};



void() ProximityGrenadeTouch =
{
if (other == self || other == self.owner) //|| other == self.owner
{
sound (self, CHAN_WEAPON, "weapons/proxbounce.wav", 1, ATTN_NORM); // bounce sound
return;
}

if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// Don't collide with other mines
if (other.classname == self.classname)
{
sound (self, CHAN_WEAPON, "weapons/proxbounce.wav", 1, ATTN_NORM); // bounce sound
self.movetype = MOVETYPE_BOUNCE; // Add this line
return;
}


// Check if it's a brush entity (like doors)
if (other.movetype == MOVETYPE_PUSH) //|| other.solid == SOLID_BSP
{
sound(self, CHAN_WEAPON, "weapons/proxbounce.wav", 1, ATTN_NORM); // bounce sound
self.movetype = MOVETYPE_BOUNCE; // Add this line
return;
}

if (other.flags & FL_CLIENT) //user disarm mine
{
//self.solid = SOLID_NOT;
mine_disarm();
//remove(self);
return;
}

if ((other.takedamage == DAMAGE_AIM || other.solid == SOLID_TRIGGER || other.flags & FL_MONSTER )) //don't det on monsters || other.flags & FL_CLIENT
{
sound(self, CHAN_WEAPON, "weapons/proxbounce.wav", 1, ATTN_NORM);
//self.movetype = MOVETYPE_BOUNCE;
T_Damage(other, self, self.owner, 1);
//self.think();
return;
}


self.movetype = MOVETYPE_TOSS;
if (self.state == 1)
return;

if (vlen(other.velocity) > 0)
{
ProximityGrenadeExplode();
self.think();
return;
}

else
{

sound (self, CHAN_WEAPON, "weapons/proxstick.wav", 1, ATTN_NORM); // bounce sound
self.movetype = MOVETYPE_NONE;
setsize (self, '-5 -5 -5', '5 5 5');
self.state = 1;
self.spawnmaster = other;

self.velocity = '0 0 0';

// Start arming sequence
self.think = ProximityArmed;
self.nextthink = time + 2;

self.touch = SUB_Null; //new
self.solid = SOLID_NOT; //new
}
}; 
 
void() ThrowProxMine =
{
float x;

// Check if enough time has passed since last throw
if (self.last_mine_time > time - 1.5)
return;

// Check if player has enough ammo
if (self.ammo_rockets2 < 1)



local entity missile; //, mpuff;

self.currentammo = self.ammo_rockets2 = self.ammo_rockets2 - 1;
self.last_mine_time = time; // Update last throw time

sound (self, CHAN_BODY, "zombie/z_shot1.wav", 0.8, ATTN_STATIC);

self.punchangle_x = -2;

missile = spawn ();
missile.owner = self;
missile.lastvictim = self;
missile.movetype = MOVETYPE_TOSS;// MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "proximity_mine";
missile.takedamage = DAMAGE_YES; //DAMAGE_NO;
missile.health = 2;
missile.state = 0; //not armed

// set missile speed
makevectors (self.v_angle);


if (self.v_angle_x)
missile.velocity = v_forward*400 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, 10000);
missile.velocity = missile.velocity * 400;
missile.velocity_z = 200;
}
missile.avelocity = '100 400 100';


missile.angles = vectoangles(missile.velocity);

missile.touch = ProximityGrenadeTouch;
// set missile duration
missile.nextthink = time + 2; //min time until mine can explode from enemy
missile.think = ProximityBomb; //arm
missile.th_die = ProximityGrenadeExplode;
missile.delay = time + 90; // time until mine auto disarms

setmodel (missile, "progs/proxmine.mdl");
setorigin (missile, (self.origin) + (v_forward * 0) + (v_right * -17) + '0 0 10');

setsize (missile, '-4 -4 -4', '4 4 4');

}; 
Debugging 
The difficult part with your ProximityGrenadeTouch function is there are so many return statements which MIGHT end the function, and the bit of code that makes it stick to the wall is at the very end.

I would recommend you add some dprint statements to the function after each "checkpoint" - each place where the function has avoided a branch that contains a return. Then you can check how far execution gets through the function when you throw one against a wall, and deduce which exit is being taken unexpectedly. Two tips
a) pull down the console as soon as the bomb hits a wall for the first time, as you'll get a huge pile of debug messages if you let it bounce all over the shop first
b) remove the debug statements once you have solved the mystery, or they will be a pain in future 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2025 John Fitzgibbons. All posts are copyright their respective authors.