I always love how in Wolf you scream when you fall a big fall, I think in wolf the sound is implemented via a trigger in the map, if I'm not mistaken, so I decided to implement this situation and a couple of others in a little bit more dynamic way.
In doom3 when the player is not touching the floor, he is in "fall mode", as all anims in the game the fall state is controlled by a loop, if I can use this loop to my advantage I can make him scream the voice of angels when the time is right, this is without adding any new loop to the system, only adding a couple of IFs and a couple of STARTSOUNDs
once I'm on this why not add a gory sound like the spine crush when he lands to instant dead ("player cratered" as it stated in the console in Quake 2), then again Quake 1 did several crushes on the player spine, it was the players sound for hard landing. but now I want to be the last sound the player hears along it's own "hard landing" scream.
all of this with scripting. no SDK, now there are problems:
- "fall mode" is also enabled when the player goes "noclip" and I bet that in multi-player when the player is in spectator mode it's invisible player model is also in "fall mode" so this has to be taken into account (not yet solved)
- I think that when the player dies all is handled in the SDK code. to the point where the anims states defined in the script don't seem to be used. (wich means big fail for me and my method)
- in scripts sys.getCVar("noclip"); fails to work?
the first part, the easyget the sounds: you can get the the baritone scream from our beloved RTCW itself, but if you want to distribute it, you might want to get a scream from Open Arena, although the fall screams from OA are a bit lame, they are GPL and free. (or you could record it, ah! common it will be fun!

)
the crush sounds , I couldn't find one free, so I took the one form ET, it's free but I'm sure the content is not GPL. you can do this or record a melon beaten with a pan(yeah, now I'm sure you wanna record it! isn't it?

)
script up some sound shader declarations for those two sound: I gave them the names: "player_fall_scream" and "player_spine_irreversible_damage" within a "player_extra.sndshd" file
the second part, the codeadd those sounds to the player def declaration
I added two new sound slots after all other sound slots in the player_base entity_def:
Code:
"snd_fallscream" "player_fall_scream"
"snd_spine" "player_spine_irreversible_damage"
those are the sound slots used by the code in order to play the sounds.
then the fun part, I added a constant and a couple of variables in the ai_player.script:
Code:
object player : player_base {
#define TIME_TO_SCREAM 1 // <-- this one
weapon_base weapon;
boolean weapon_changed;
boolean start_fire;
boolean fall_scream_done; // <-- this one
float current_scream_time; // <-- this one
void init();
// called by player code
void EnterCinematic();
void ExitCinematic();
void LowerWeapon();
...blah blah blah...
}
all is left to code is within the "legs_fall" state
Code:
void player::Legs_Fall() {
current_scream_time = 0;
fall_scream_done = false;
playCycle( ANIMCHANNEL_LEGS, "fall" );
eachFrame {
if ( AI_JUMP ) {
animState( ANIMCHANNEL_LEGS, "Legs_Jump", 2 );
}
if (( !AI_ONGROUND && (current_scream_time >= TIME_TO_SCREAM) ) && !fall_scream_done)
{
fall_scream_done = true;
//sys.println("fall scream");
startSound( "snd_fallscream", SND_CHANNEL_VOICE, true );
}
if ( AI_ONGROUND ) {
if ( AI_HARDLANDING ) {
if (fall_scream_done)
{
//sys.println("break spine");
startSound( "snd_spine", SND_CHANNEL_ANY, false );
}
animState( ANIMCHANNEL_LEGS, "Legs_Land_Hard", 2 );
}
if ( AI_SOFTLANDING ) {
animState( ANIMCHANNEL_LEGS, "Legs_Land_Soft", 2 );
}
animState( ANIMCHANNEL_LEGS, "Legs_Idle", 4 );
}
//if ( ( ( sys.getCVar("noclip") ) == 0 ) || !fall_scream_done )
//{
current_scream_time = current_scream_time + 0.016;
//}
}
}
the constant it's useful in order to tweak when does the player starts to scream, you could read it as seconds. you can play with it. it's a floating point constant, so you're not limited to integer amounts of time.
so, what does this actually do? it screams once per fall, but the crush sound doesn't work as I wanted. adn the control of time doesn't stop after the sound, wasting unecessary cycles, (that's because of the noclip problem, re-enable the last IF in the code and erase the noclip thing within it for a more efficient code)
right now death is handled with SDK, and only there I could call the crush sound. because I think the death in the script it's overridden there. so now every hard land crushes the spine of the player... which is totally incorrect, yet kinda funny

.
so...
the third part, the questionshow do I check if noclip is set? right now if I enable the noclip part in my code the game refuses to compile it (" Unknown value "getCVar" ")
this would stop the player from screaming as if he is falling, when going to noclip state (which in the player animation states is perpetually falling)
I've tried everything:
the ninja way
Code:
if ( ( ( sys.getCVar("noclip") ) == 0 ) || !fall_scream_done )
{
current_scream_time = current_scream_time + 0.016;
}
the sure way
Code:
string noclipvar;
noclipvar = sys.getCVar("noclip");
if ( ( noclipvar == "0" ) || !fall_scream_done )
{
current_scream_time = current_scream_time + 0.016;
}
always the same error: " Unknown value "getCVar" "
do you happen to know a way to check in scripts if player is in noclip state?
is there a way to code the deaths of the player (just like on codes the deaths of the enemies, so I can code an specific death (the "player has cratered" death) and so use the crushed spine sound with it without using SDK?