U
utunnels
Guest
This file will be automatically included in all scripts if presents, except those that are imported using #import.
#define ENT_SELF 0 //Self.
...
/******Evaluation******/
#define EVAL_CHANCE_0 0 //0% chance.
#define EVAL_CHANCE_25 0.25 //25% chance.
#define EVAL_CHANCE_50 0.5 //50% chance.
#define EVAL_CHANCE_75 0.75 //75% chance.
#define EVAL_CHANCE_100 1 //100% chance.
#define EVAL_FALSE 0 //False.
#define EVAL_TRUE 1 //True.
...
#define SOUND_FILE_RAND -1 //Choose random file from sound group.
#define SOUND_DELAY_NONE 0
#define SOUND_DELAY_SHORT 100
#define SOUND_DELAY_MED 500
#define SOUND_DELAY_LONG 1000
#define SOUND_INVALID -1 //Attempt to load a sound file failed.
#define SOUND_LOOP_OFF 0 //Play sound without loop.
#define SOUND_LOOP_ON 1 //Play sound with loop.
#define SOUND_NOPLAY_DELAY -2 //Sound did not play due to delay restrictions.
#define SOUND_NOPLAY_RANDOM -3 //Sound did not play because random probability was not met.
#define SOUND_PRIORITY_NORMAL 0 //Play sound with default priority.
#define SOUND_SPEED_NORMAL 100 //Play sound at default speed.
#define SOUND_SUB_NONE 0 //Optional subfolder.
#define SOUND_VOLUME_MAX 200 //Channel volume maxium.
...
#define VOI_ATKM 26 //Attack grunt, medium.
...
int sound_from_group(void vEntity, char cSubFolder, int iGroup, int fSound, float fProbability, int iDelay, int iPriority, int iVolumeLeft, int iVolumeRight, int iSpeed)
{
/*
sound_from_group - http://www.caskeys.com/dc/?p=5254
License (must include to use) - http://www.caskeys.com/dc/?p=5067
Damon Vaughn Caskey
Play specfic or random sound from group.
Example: In this sample list of sound files below, leftmost 0 represents the group "death cry",
where the right are numbers are differing versions that may be specficly or randomly chosen.
0_0
0_1
0_2
0_3
Preconditions:
vEntity: Target entity. Used to get path and determine stereo location.
cSubFolder: Optional sub folder.
iGroup: Sound group (Attack, battle cry, etc.)
fSound: Sound within group. If -1, random sound is choosen.
fProbability: Probability of sound playing (0 = Never, 0.5 = 50%, 1 = Always).
iDelay: Forced time delay for playing sounds from a specfic group.
iPriority: Play priority.
iVolumeLeft: Left channel volume adjustment.
iVolumeRight: Right channel volume adjustment.
iSpeed: Play speed.
iLoop: Loop on/off.
*/
/* Initialize variables. */
char cSample, cPath; //Sample path, entity path.
int iGender; //Entity gender type.
int iLastGroup //
int iLastGroupTime;
/* Default vEntity as self. */
_DEFAULT_SELF
/* If the target entity is invalid, exit. */
if(!vEntity) return SOUND_INVALID_ENT;
/* If probability not met, exit. */
if(evaluate_probability(fProbability) == EVAL_FALSE) return SOUND_NOPLAY_RANDOM;
/* Populate variables. */
iLastGroup = getentityvar(vEntity, IDXE_SOUND_LAST_GROUP);
iLastGroupTime = getentityvar(vEntity, IDXE_SOUND_LAST_GROUP_TIME);
/* Requested sound group same as last played? */
if(iLastGroup == iGroup)
{
/* Time since last play within delay range? */
if(iLastGroupTime - _ELAPSED_TIME < iDelay)
{
/* Exit. */
return SOUND_NOPLAY_DELAY;
}
}
/* Get entity path. */
cPath = get_path(vEntity);
/* Auto (random sound from group) set? */
if(fSound==-1)
{
/* Clear sound index. */
fSound = 0;
/* Construct base sound path. */
cSample = sound_file_path_construct(cPath + "/sounds/", cSubFolder, iGroup);
/* Before choosing sound from group, we must know how many sounds in group are available. */
fSound = sound_file_count(cSample);
/*
If count is at least 1, a random int from 0 to number of known sounds will be generated and used
to chose which sound is played by concatenating generated number to file name.
If count is 0, the entity's model folder does not have any files matching sound group in its folder.
Instead, we will fall back to the main sound folder using throwdamage property to determine a sub folder of generic
alternates. An example would be an individual model not having its own specific death cry. In this case the main sounds
folder will be searched for a sub folder matching the model's throwdamage property to allow differentiation
of basic type (i.e. male vs. female). The death cry will then be randomly chosen from this generic folder. */
if (!fSound)
{
iGender = getentityproperty(vEntity, PROP_CUSTOM_GENDER_TYPE); //Gender type acts as head group.
fSound = 0; //Reset fSound.
/* Construct base sound path */
cSample = sound_file_path_construct("data/sounds/" + iGender + "/", cSubFolder, iGroup);
/* Before choosing sound from group, we must know how many sounds in group are available. */
fSound = sound_file_count(cSample);
/*
If count is at least 1, a random int from 0 to number of known sounds will be generated and used
to chose which sound is played by concatenating generated number to file name.
If count is 0, the throwdamage selected subfolder does not have any files matching requested sound
group. This time we will fall dirctly back to the main sound folder and search for matching sound files. */
if(fSound)
{
/* Construct random file name from possibilities. */
fSound = rand_range(0, --fSound); //Get random number from given range.
cSample += fSound + ".wav"; //Concatenate full sound path.
}
else
{
fSound = 0; //Reset fSound.
/* Construct base sound path */
cSample = sound_file_path_construct("data/sounds/", cSubFolder, iGroup);
/* Before choosing sound from group, we must know how many sounds in group are available. */
fSound = sound_file_count(cSample);
/*
If count is at least 1, a random int from 0 to number of known sounds will be generated and used
to chose which sound is played by concatenating generated number to file name.
At this point if count is yet again 0, we have exhausted all options to locate a file. Nothing
will be played. */
if(fSound)
{
/* Construct random file name from possibilities. */
fSound = rand_range(0, --fSound); //Get random number from given range.
cSample += fSound + ".wav"; //Concatenate full sound path.
}
}
}
else
{
/* Construct random file name from possibilities. */
fSound = rand_range(0, --fSound); //Get random number from given range.
cSample += fSound + ".wav"; //Concatenate full sound path.
}
}
else //Static sound call.
{
/* Construct base sound path */
cSample = sound_file_path_construct(cPath + "/sounds/", cSubFolder, iGroup);
cSample += fSound + ".wav";
if(loadsample(cSample, 1) == -1) //Verify sample path.
{
iGender = getentityproperty(vEntity, PROP_CUSTOM_GENDER_TYPE); //Gender type acts as head group.
/* Construct base sound path */
cSample = sound_file_path_construct("data/sounds/" + iGender + "/", cSubFolder, iGroup);
cSample += fSound + ".wav";
/* Verify sample path. */
if(loadsample(cSample, 1) == -1)
{
/* Construct base sound path */
cSample = sound_file_path_construct("data/sounds/", cSubFolder, iGroup);
cSample += fSound + ".wav";
}
}
}
/* Verify the final sample path. */
if(loadsample(cSample, 1) != SOUND_INVALID)
{
/* Play sound with location based stereo volume adjustment */
return play_location_base_sound(vEntity, cSample, iPriority, iVolumeLeft, iVolumeRight, iSpeed, iLoop, iTime);
}
/* Return ivalid sound index. */
return SOUND_INVALID;
}
...
frame data/chars/<x>/frame1.png
#50% of the time, randomly choose one of this model's "medium" attack grunts and play it with stereo volume based on screen position.
@cmd sound_from_group ENT_SELF SOUND_SUB_NONE VOI_ATKM SOUND_FILE_RAND EVAL_CHANCE_50, SOUND_DELAY_SHORT SOUND_PRIORITY_NORMAL SOUND_VOLUME_MAX SOUND_VOLUME_MAX SOUND_SPEED_NORMAL
frame data/chars/<x>/frame2.png
frame data/chars/<x>/frame3.png
frame data/chars/<x>/frame4.png
frame data/chars/<x>/frame1.png
#50% of the time, randomly choose one of this model's "medium" attack grunts and play it with stereo volume based on screen position.
@cmd sound_from_group 0 0 26 -1 0.5 100 100 200 200 100
frame data/chars/<x>/frame2.png
frame data/chars/<x>/frame3.png
frame data/chars/<x>/frame4.png
#include "data/scripts/defines.h"
#import "data/scripts/lib.c"