Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

Death messages

| Inside3d Forums Forum Index -> QuakeC Programming

View previous topic :: View next topic
Author | Message
--- | ---
redrum Joined: 28 Mar 2007 Posts: 367 Location: Long Island, New York |

Posted: Mon Dec 10, 2007 3:08 am Post subject: Death messages |

Guys, got a problem that I need help with. I changed the lightning gun to a lava launcher. You can catch on fire from the lavaball and then die well after the shots have been fired. If I am using a different weapon when the target dies, the death message displays for the current weapon and not the lava launcher
Here is my death message code:

Code:
else if (rnum == IT_LIGHTNING) { deathstring = " gets torched "; deathstring2 = "'s lava launcher!\n"; }

So, I tried to do this instead:

Code:
else if (targ.deathtype == "lava") { bprint (PRINT_MEDIUM, attacker.netname); bprint (PRINT_MEDIUM, " torches "); bprint (PRINT_MEDIUM, targ.netname);
bprint (PRINT_MEDIUM, " with the lava launcher!\n");
return;
}

Problem is that I can't get the compiler to recognize "lava".
How can I associate "lava" so that it works correctly?
Here is the rest of the code:

Code:
void(vector org) Flame_Burn = { flame = spawn (); flame.owner = self; flame.classname = "lava";
flame.movetype = MOVETYPE_FLYMISSILE;
flame.solid = SOLID_NOT;
flame.origin = org;
flame.velocity = '0 0 75';
setmodel (flame, "progs/flame2.mdl");
setsize (flame, '0 0 0', '0 0 0');
flame.nextthink = time + .01;
flame.think = s_explode1;
};
void() Flame_Think =
{
local float r;
if (self.enemy.waterlevel == 3 || self.enemy.health <= 0)
{
BecomeExplosion ();
return;
}
self.origin = self.enemy.origin + '0 0 25';
if (r < 0.5)
T_Damage (self.enemy, self, self.owner, 1);
self.nextthink = time + 0.01;
self.classname = "lava";
};
void(vector org, entity e) Flame_Onfire =
{
flame = spawn ();
flame.owner = self.owner;
flame.enemy = e;
flame.classname = "lava";
flame.movetype = MOVETYPE_NONE;
flame.solid = SOLID_NOT;
flame.origin = org;
flame.velocity = '0 0 0';
setmodel (flame, "progs/flame2.mdl");
setsize (flame, '0 0 -15', '0 0 0');
flame.nextthink = time + 0.01;
flame.think = Flame_Think;
flame.effects = flame.effects | EF_DIMLIGHT;
};
void() Flame_Touch =
{
local float r;
local vector org;
if (other.takedamage)
{
org = other.origin;
org_z = self.origin_z;
Flame_Burn (org);
T_Damage (other, self, self.owner, 8);
remove (self);
r = random ();
if (r < 0.2)
{
if ((other.classname == "player"))
{
centerprint (other,"You are on fire!\n\nFind WATER fast");
stuffcmd (other,"bf\n");
}
Flame_Onfire (org, other);
}
}
};
void() W_FireLightning =
{
if (self.ammo_cells < 1)
{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
if (deathmatch != 4)
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
sound (self, CHAN_WEAPON, "hknight/hit.wav", .8, ATTN_NORM);
makevectors (self.angles);
self.velocity = self.velocity - v_forward * 50;
if (self.health >= 1 && self.health <= 25)
{
makevectors (self.angles);
self.velocity = self.velocity - v_forward * 100;
}
msg_entity = self;
flame = spawn ();
flame.voided=0;
flame.owner = self;
flame.movetype = MOVETYPE_BOUNCE;
flame.solid = SOLID_BBOX;
flame.classname = "lava";
makevectors (self.v_angle);
if (self.v_angle_x)
flame.velocity = v_forward*500 + v_up * 225 + crandom()*v_right*25 + crandom()*v_up*25;
else
{
flame.velocity = aim(self, 10000);
flame.velocity = flame.velocity * 400;
flame.velocity_z = 100;
}
flame.avelocity = '300 300 300';
flame.angles = vectoangles(newmis.velocity);
flame.touch = Flame_Touch;
flame.nextthink = time + 1.0;
flame.think = s_explode1;
setmodel (flame, "progs/lavaball.mdl");
setsize (flame, '0 0 0', '0 0 0');
setorigin (flame, self.origin);
};

_________________
Welcome to the Overlook Hotel 69.113.123.178:27500

Back to top |

Dr. Shadowborg Inside3D Staff Joined: 16 Oct 2004 Posts: 726 |

Posted: Mon Dec 10, 2007 5:05 pm Post subject: |

Open combat.qc, then go into the T_Damage function. Look for where the code looks like this:

Code:
if(targ.health <= 0) { Killed(targ, attacker); return; }

Put inside the same if check just before Killed() is called so that the above looks like this:

Code:
if(targ.health <= 0) { if(inflictor.classname == "lava") targ.deathtype = "lava"; Killed(targ, attacker);
return;
}

That should do the trick.
_________________
"Roboto suggests Plasma Bazooka."

Back to top |

Orion Joined: 12 Jan 2007 Posts: 414 Location: Brazil |

Posted: Mon Dec 10, 2007 11:30 pm Post subject: |

An easier way to do that is: Go to Flame_Touch(), and before T_Damage(), add:

Code:
other.deathtype = "lava";

And in Flame_Think(), before T_Damage() too, add:

Code:
self.enemy.deathtype = "lava";

I did that with the code that contained my bots.
Don't forget to put brackets between (if (r < 0.5)) and the 2 lines of code.
You can use an if() without brackets only if there's only 1 line of code. otherwise you should put brackets between the lines.
BUT, if you use more than 1 if(), you don't need to use brackets. Here's an example:

Code:
if() if() if() { code
code
code
}

This won't have any problems, if you use:

Code:
if() { if() { if()
{
code
code
code
}
}
}

It will work exactly the same, but will have an increased size of code.
But the better of bests ways is using AND (&&) and/or OR (||) inside an if().
Example:

Code:
if(something && something && something) { code code code
}

This might work exactly the same as the 2 codes above.
Now I'll show you a better example. It's a code that searches for damageable entities, and I'll show the if() differences.

Code:
local entity ent; ent = findradius(self.origin, 1000); while (ent) { if (ent != self)
if (ent.health > 0)
if (ent.takedamage == DAMAGE_AIM)
if (visible(ent))
self.enemy = ent;
ent = ent.chain;
}

Notice that if you don't use brackets between a while(), it will cause problems too.
Here's another way:

Code:
local entity ent; ent = findradius(self.origin, 1000); while (ent) { if (ent != self && ent.takedamage == DAMAGE_AIM && ent.health > 0 && visible(ent))
self.enemy = ent;
ent = ent.chain;
}

This is a shorter way, better use and (&&) and/or or (||) instead of creating many ifs.
This gone a bit off-topic, but it's ok.
_________________
There's no signature here. Stop looking for one.

Back to top |

redrum Joined: 28 Mar 2007 Posts: 367 Location: Long Island, New York |

Posted: Tue Dec 11, 2007 12:11 am Post subject: |

Awesome! Thanks guys! _________________ Welcome to the Overlook Hotel 69.113.123.178:27500

Back to top |

Spike Joined: 05 Nov 2004 Posts: 944 Location: UK |

Posted: Tue Dec 11, 2007 2:22 am Post subject: |

if (blah) if (blah) if (blah) blah(); results in more efficient code than
if (blah && blah && blah)
blah();
Its a pain to read, but multiple conditions is more efficient. This is especially important when you're itterating over a lot of entities.
QuakeC does not typically early-out like C does. The entire statement is evallulated (including function calls!) before the result is compared.
Both FrikQCC and FTEQCC can do it, but doing so is not always advised, and can break some code (admittedly such code is arguably poorly written).
in the above example, the line:
if (ent != self && ent.takedamage == DAMAGE_AIM && ent.health > 0 && visible(ent))
is exactly identical to (except that it would break else statements):
temp = (ent != self);
temp2 = ent.takedamage;
temp2 = (temp2 == DAMAGE_AIM);
temp = (temp && temp2);
temp2 = ent.health;
temp2 = temp2 > 0;
temp = temp && temp2;
arg0 = ent;
temp2 = visible(arg0);
temp = temp && temp2;
if (temp)
{
...
}
Yes, the entire thing is executed for every ent within those 1000 units.
Note that earlier qc compilers will use new temps for each line, instead of reusing them.
The multiple-if form goes:
temp = (ent != self);
if (temp)
{
temp = ent.takedamage;
temp = (temp == DAMAGE_AIM);
if (temp)
{
temp = ent.health;
temp = temp > 0;
if (temp)
{
arg0 = ent;
temp = visible(arg0);
if (temp)
{
...
}
}
}
}
In both examples, each line (baring braces) is a single qc instruction.
Due to the comparisons instead of logic operators, the second form will run more efficiently. The function call can be particuarly nasty, depending on the length of the function - ranging from mearly inefficient to downright nasty.
Consider that visible is a qc function containing 18 instructions, one of them a call to a builtin which recurses down the bsp tree, using floating point maths, followed by a quick run through all the entities in the block and a recursion down any bsp trees within the region, and you'll realise how important that seperating your conditions into seperate if statements can be in quakec.
But yes, the logical 'and' (&&) and 'or' (||) operators are more readable.
I suspect I might be overcomplicating the issue, and going slightly off topic.
_________________
What's a signature?

Back to top |

redrum Joined: 28 Mar 2007 Posts: 367 Location: Long Island, New York |

Posted: Tue Dec 11, 2007 12:30 pm Post subject: |

Didn't grasp all of that but I get the jist of it! I have a lot to learn. Where/how did you guys acquire all of this knowledge? _________________ Welcome to the Overlook Hotel 69.113.123.178:27500

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Tue Dec 11, 2007 3:31 pm Post subject: |

No lives? _________________ Look out for Twigboy

Back to top |

Spike Joined: 05 Nov 2004 Posts: 944 Location: UK |

Posted: Tue Dec 11, 2007 5:07 pm Post subject: |

redrum wrote:
Where/how did you guys acquire all of this knowledge?

As Urre said. I need to get out more.
_________________
What's a signature?

Back to top |

Dr. Shadowborg Inside3D Staff Joined: 16 Oct 2004 Posts: 726 |

Posted: Tue Dec 11, 2007 6:49 pm Post subject: |

Off and on, endless amounts of tinkering, abandoning, restarting, recoding mods. (What Urre said.) The more you work with quakec the better you will become over time. _________________ "Roboto suggests Plasma Bazooka."

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> QuakeC Programming | All times are GMT
Page 1 of 1

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group