Adding more random messages.

Discuss programming in the QuakeC language.
Post Reply
glitchhunter96
Posts: 4
Joined: Sat Oct 13, 2012 12:12 am

Adding more random messages.

Post by glitchhunter96 »

How do i add random messages IE when someone dies form a weapon, uses an item or connects, disconnects, and suicides? I am using reaper bot.
void () ClientConnect =
{

local string tmp;
local float num;

bprint (self.netname);
bprint (" has joined the fight\n");
self.id = FindGood();
self.impulse = 204.000;
initscore ();
if ( intermission_running ) {

ExitIntermission ();

}

};

void () ClientDisconnect =
{

local float num;

if ( gameover )
{

return ;

}
bprint (self.teamname);
bprint (self.netname);
bprint (" left the game with ");
MakeGood(self.id);
bprint (ftos (self.frags));
bprint (" kills\n");
sound (self,CHAN_BODY,"player/tornoff2.wav",TRUE,ATTN_NONE);
self.classname = "nobody";
set_suicide_frame ();

};

void (entity targ, entity attacker) ClientObituary =
{

local float rnum;
local string deathstring;
local string deathstring2;
local string deathstring3;
local string deathstring4;
local string deathstring5;
local string deathstring6;

rnum = random ();
if ( ((targ.classname == "player") || (targ.classname == "dmbot")) ) {

if ( (attacker.classname == "teledeath") )
{
bprint (targ.netname);
local float zufall;
zufall = random(); // randomize death messages
if (zufall > 0.75)
bprint (" was telefraged by ");
else if (zufall > 0.5)
bprint (" got in the way of ");
else if (zufall > 0.25)
bprint (" experienced birthing by ");
else
bprint (" had his personal space invaded by ");
bprint (attacker.owner.netname);
bprint ("\n");
if ( (attacker.owner.classname == "dmbot") )
{

TELEFRAGFLAG = TRUE;

}
attacker.owner.frags = (attacker.owner.frags + TRUE);
countkill (attacker.owner,targ);
if (attacker.owner.classname == "dmbot")
{
WriteByte( MSG_ALL, MSG_UPDATEFRAGS );
WriteByte( MSG_ALL, attacker.owner.id );
WriteShort( MSG_ALL, attacker.owner.frags );
}

return ;

}
if ( (attacker.classname == "teledeath2") )
{

bprint ("Satan's power deflects ");
bprint (targ.teamname);
bprint (targ.netname);
bprint ("'s telefrag\n");
countkill (targ,targ);
targ.frags = (targ.frags - TRUE);
if (targ.classname == "dmbot")
{
WriteByte( MSG_ALL, MSG_UPDATEFRAGS );
WriteByte( MSG_ALL, targ.id );
WriteShort( MSG_ALL, targ.frags );
}

return ;

}
if ( ((attacker.classname == "player") || (attacker.classname == "dmbot")) )
{

if ( (targ == attacker) ) {

attacker.frags = (attacker.frags - TRUE);
if (attacker.classname == "dmbot")
{
WriteByte( MSG_ALL, MSG_UPDATEFRAGS );
WriteByte( MSG_ALL, attacker.id );
WriteShort( MSG_ALL, attacker.frags );
}

countkill (attacker,attacker);
bprint (targ.teamname);
bprint (targ.netname);
if ( ((targ.weapon == FL_GODMODE) && (targ.waterlevel > TRUE)) ) {

bprint (" discharges into the water.\n");
return ;

}
if ( (targ.weapon == FL_INWATER) ) {

bprint (" tries to put the pin back in\n");

}
else
{

if ( rnum )
{

bprint (" becomes bored with life\n");

}
else
{

bprint (" checks if his weapon is loaded\n");

}


}
return ;

}
else
{

attacker.frags = (attacker.frags + TRUE);

if (attacker.classname == "dmbot")
{
WriteByte( MSG_ALL, MSG_UPDATEFRAGS );
WriteByte( MSG_ALL, attacker.id );
WriteShort( MSG_ALL, attacker.frags );
}

countkill (attacker,targ);
rnum = attacker.weapon;
if ( (rnum == IT_AXE) )
{
deathstring = " was ax-murdered by ";
deathstring = " was sliced by ";
deathstring = " was diced by ";
deathstring2 = "\n";
}
if ( (rnum == IT_SHOTGUN) )
{
deathstring = " chewed on ";
deathstring2 = "'s lead\n";

deathstring = " sucked on ";
deathstring2 = "'s shottie\n";

}
if ( (rnum == IT_SUPER_SHOTGUN) )
{

deathstring = " ate 2 loads of ";
deathstring2 = "'s shotgun shells\n";

}
if ( (rnum == IT_NAILGUN) )
{

deathstring = " was nailed by ";
deathstring2 = "'s nailgun\n";

}
if (rnum == IT_SUPER_NAILGUN)
{
deathstring = " was nailed to the wall by ";
deathstring2 = "'s supernail gun\n";
}
if ( (rnum == IT_GRENADE_LAUNCHER) )
{

deathstring = " eats ";
deathstring2 = "'s pineapple\n";
if ( (targ.health < -40.000) )
{

deathstring = " was gibbed by ";
deathstring2 = "'s grenade\n";

}

}
if (rnum == IT_ROCKET_LAUNCHER)
{
deathstring = " found ";
deathstring2 = "'s rocket up his ass\n";
if (targ.health < -40)
{
deathstring = " was destroyed by ";
deathstring2 = "'s rocket\n" ;
}
}
if ( (rnum == IT_LIGHTNING) ) {

deathstring = " accepts ";
if ( (attacker.waterlevel > TRUE) )
{

deathstring2 = "'s discharge\n";

}
else
{

deathstring2 = "'s shaft\n";

}

}
bprint (targ.teamname);
bprint (targ.netname);
bprint (deathstring);
bprint (attacker.teamname);
bprint (attacker.netname);
bprint (deathstring2);

}
return ;

} else {

targ.frags = (targ.frags - TRUE);
if (targ.classname == "dmbot")
{
WriteByte( MSG_ALL, MSG_UPDATEFRAGS );
WriteByte( MSG_ALL, targ.id );
WriteShort( MSG_ALL, targ.frags );
}

rnum = targ.watertype;
countkill (targ,targ);
bprint (targ.teamname);
bprint (targ.netname);
if ( (rnum == CONTENT_WATER) ) {

if ( (random () < 0.500) ) {

bprint (" sleeps with the fishes\n");

} else {

bprint (" sucks it down\n");

}
return ;

} else {

if ( (rnum == CONTENT_SLIME) ) {

if ( (random () < 0.500) ) {

bprint (" gulped a load of slime\n");

} else {

bprint (" can't exist on slime alone\n");

}
return ;

} else {

if ( (rnum == CONTENT_LAVA) ) {

if ( (targ.health < -15.000) ) {

bprint (" burst into flames\n");
return ;

}
if ( (random () < 0.500) ) {

bprint (" turned into hot slag\n");

} else {

bprint (" visits the Volcano God\n");

}
return ;

}

}

}
if ( (attacker.flags & FL_MONSTER) ) {

if ( (attacker.classname == "monster_army") ) {

bprint (" was shot by a Grunt\n");

}
if ( (attacker.classname == "monster_demon1") ) {

bprint (" was eviscerated by a Fiend\n");

}
if ( (attacker.classname == "monster_dog") ) {

bprint (" was mauled by a Rottweiler\n");

}
if ( (attacker.classname == "monster_dragon") ) {

bprint (" was fried by a Dragon\n");

}
if ( (attacker.classname == "monster_enforcer") ) {

bprint (" was blasted by an Enforcer\n");

}
if ( (attacker.classname == "monster_fish") ) {

bprint (" was fed to the Rotfish\n");

}
if ( (attacker.classname == "monster_hell_knight") ) {

bprint (" was slain by a Death Knight\n");

}
if ( (attacker.classname == "monster_knight") ) {

bprint (" was slashed by a Knight\n");

}
if ( (attacker.classname == "monster_ogre") ) {

bprint (" was destroyed by an Ogre\n");

}
if ( (attacker.classname == "monster_oldone") ) {

bprint (" became one with Shub-Niggurath\n");

}
if ( (attacker.classname == "monster_shalrath") ) {

bprint (" was exploded by a Vore\n");

}
if ( (attacker.classname == "monster_shambler") ) {

bprint (" was smashed by a Shambler\n");

}
if ( (attacker.classname == "monster_tarbaby") ) {

bprint (" was slimed by a Spawn\n");

}
if ( (attacker.classname == "monster_vomit") ) {

bprint (" was vomited on by a Vomitus\n");

}
if ( (attacker.classname == "monster_wizard") ) {

bprint (" was scragged by a Scrag\n");

}
if ( (attacker.classname == "monster_zombie") ) {

bprint (" joins the Zombies\n");

}
return ;

}
if ( (attacker.classname == "explo_box") ) {

bprint (" blew up\n");
return ;

}
if ( ((attacker.solid == SOLID_BSP) && (attacker != world)) )
{

local float zufall;
zufall = random(); // randomize death messages
if (zufall > 0.75)
bprint (" was squished\n");
else if (zufall > 0.5)
bprint (" did the monster mash\n");
else if (zufall > 0.25)
bprint (" was squashed\n");
else
bprint (" is more compact\n");
return;
}
if ( (targ.deathtype == "falling") ) {

targ.deathtype = "";
bprint (" fell to his death\n");
return ;

}
if ( ((attacker.classname == "trap_shooter") || (attacker.classname == "trap_spikeshooter")) ) {

bprint (" was spiked\n");
return;

}
if ( (attacker.classname == "fireball") ) {

bprint (" ate a lavaball\n");
return ;

}
if ( (attacker.classname == "trigger_changelevel") ) {

bprint (" tried to leave\n");
return ;

}
local float zufall;
zufall = random(); // randomize death messages
if (zufall > 0.75)
bprint (" died\n");
else if (zufall > 0.5)
bprint (" went to the wrong place\n");
else if (zufall > 0.25)
bprint (" went somewhere it wasn't supposed to be in\n");

}

}

};
glitchhunter96
Posts: 4
Joined: Sat Oct 13, 2012 12:12 am

Re: Adding more random messages.

Post by glitchhunter96 »

as you can see, thanks to Seven i've added Zufall to work as random death messages which works for the most part except i cannot print randomly when i either kill someone with a weapon but then everything prints when ever I commit suicide.
I've also added death strings for the weapons but it didn't print the others (that was the problem with weapons.)
bprint (self.netname);
bprint (self.netname);
local float zufall;
zufall = random(); // randomize death messages
if (zufall > 0.75)
bprint (" wins the Darwin Awards\n");
if (zufall > 0.5)
bprint (" Budd Dwyered\n");
if (zufall > 0.25)
bprint (" did the game a favor\n");
if (zufall > 0.35)
bprint (" is suicidal\n");
if (zufall > 0.45)
bprint (" thought life was tough\n");
if (zufall > 0.55)
bprint (" hates himself\n");
if (zufall > 0.65)
bprint (" is emo\n");
set_suicide_frame ();
self.modelindex = modelindex_player;
self.frags = self.frags - 2; // extra penalty
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Adding more random messages.

Post by Spike »

you probably want to learn how to use the 'else' keyword.

if (a)
dosomething();
else if (b)
dosomethingelse();

the two are mutually exclusive. if a is true, it really doesn't care at all about b.

(technically, 'else if' is a combination of two separate constructs. that is, the second if is embedded within the else clause of the first if. thus you can just keep adding 'else if (foo)dosomeanotherthing();' on the end as many times as you want)
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: Adding more random messages.

Post by r00k »

does code execute faster or whatever if its

Code: Select all

if (this) 
{
   that();
}
else
{   
   if (another)
   {
       blahfoo();
   }
   else
   {
       if (yadayada)
       {
           dodaday();
       }
       else
       {
           if (blah)
           {
...
etc.?


or is it just easier to read?
thats just how i've always done it....
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Adding more random messages.

Post by frag.machine »

As a rule of thumb, first write your code to just work, in the cleanest(i.e. more legible) way possible; later, if after *measuring* you decide your code needs a better performance, you may try to rewrite the hot spots to improve performance.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Adding more random messages.

Post by Spike »

if (foo)
fnar();
else
{
if (bar)
foobar();
else
smudge();
}

really doesn't matter whether that {} is there or not. makes absolutely no difference. same with the new line between the else and the if.
write it in whatever way is most readable. different people will naturally have different interpretations of 'most readable', but whatever.
glitchhunter96
Posts: 4
Joined: Sat Oct 13, 2012 12:12 am

Re: Adding more random messages.

Post by glitchhunter96 »

Source file: progs.src
outputfile: ../progs.dat
compiling defs.qc
compiling botit_th.qc
compiling func.qc
compiling floater.qc
compiling subs.qc
compiling fight.qc
compiling ai.qc
in function FindTarget (line 304),
ai.qc:316: warning: 'FindTarget' should return float
compiling combat.qc
compiling items.qc
in function PlaceItem (line 22),
items.qc:33: warning: droptofloor: Too few parameters
defs.qc:375: droptofloor is defined here
compiling rankings.qc
in function msgUpdateNameToPlayer (line 57),
rankings.qc:335: warning: msgUpdateNameToPlayer: contains unreachable code
in function msgUpdateColorsToPlayer (line 60),
rankings.qc:354: warning: msgUpdateColorsToPlayer: contains unreachable code
in function msgUpdateFragsToPlayer (line 63),
rankings.qc:373: warning: msgUpdateFragsToPlayer: contains unreachable code
compiling ccam.qc
compiling weapons.qc
compiling world.qc
compiling client.qc
in function FindIntermission (line 237),
client.qc:274: warning: FindIntermission: not all control paths return a value
in function ClientKill (line 54),
client.qc:517: error: Unknown value "else".
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: error: expected ;, found if
in function ClientObituary (line 6),
client.qc:1864: warning: zufall duplicate definition ignored
client.qc:1505: zufall is defined here
client.qc:1901: warning: zufall duplicate definition ignored
client.qc:1505: zufall is defined here

************ ERROR ************
Errors have occured

Error in client.qc on line 1919
Curious as to the reason why this keeps giving me a compile error.
Am i supposed to place Zufall in new brackets? :?:
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Adding more random messages.

Post by Spike »

if you have more than one statement between the if and the else, you'll need to add braces (aka: curly brackets) around them.
glitchhunter96
Posts: 4
Joined: Sat Oct 13, 2012 12:12 am

Re: Adding more random messages.

Post by glitchhunter96 »

void () ClientKill =
{
bprint (self.netname);
local float zufall;
zufall = random(); // randomize death messages
else if (zufall > 0.75);
bprint (" hates himself\n");
else if (zufall > 0.5);
bprint (" budd dwyered himself\n");
set_suicide_frame ();
self.modelindex = modelindex_player;
self.frags = self.frags - 2; // extra penalty
respawn ();
};
Where an i supposed to put the brackets then.
Seven
Posts: 301
Joined: Sat Oct 06, 2007 8:49 pm
Location: Germany

Re: Adding more random messages.

Post by Seven »

Hello shambler234,

this is what FTEQCC tells you;
in function ClientKill (line 54),
client.qc:517: error: Unknown value "else".
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: warning: Expected punctuation
client.qc:517: error: expected ;, found if
In your post above you showed us how your function ClientKill looks like.
So, please listen what fteqcc tells you, as it is your friend ;)
In your .txt editor you should have a line number. So go to line 517 and you will find:
else if ...
there is no "if" before this, so the compiler doesnt know your "else" in line 517.
That is why it says:
error: Unknown value "else".
No "else" without "if" first ! :)

The next warnings tell you, that you should NOT write a ";" at the end of "if" lines.
When you look through original QC code, you will see, that there is no semicolon at the end of "if" lines (also "else" and "else if")

Also, even when you fixed that, you have a 50% chance to see no deathmessage,
because you only cover >0.7 and >0.5
But what if random creates a value of 0.3 ?
Always be sure to cover the complete range what random can produce: 0....1


I posted the sample code at quakeone and can post it here too (it has all you need):
local float zufall;
zufall = random(); // randomize death messages
if (zufall > 0.75)
bprint (" was squished\n");
else if (zufall > 0.5)
bprint (" did the monster mash\n");
else if (zufall > 0.25)
bprint (" was squashed\n");
else
bprint (" is more compact\n");
Each death message has a chance of 25% to be printed here. And only 1 message will be printed.
If you use this principle on all death messages, it will work as intended.
It doesnt matter if a monster killed the player or a weapon or a teleporter or anything. Just be sure to keep your { } around each block so that they are tight together and are used for that specific death case (if the function handles more than 1 death case).


Next warnings in your function ClientObituary means:
You define "zufall" multiple times.
Only define it once per function. It will only bring up warnings and no errors, but anyhow.


Like Spike said in his earlier post:
Your errors are based on not correct usage of "if" check syntax.
Please first learn how to use "if" checks in QC.
My example above may help you.

Best of luck,
Seven
Post Reply