本文整理汇总了C++中crandom函数的典型用法代码示例。如果您正苦于以下问题:C++ crandom函数的具体用法?C++ crandom怎么用?C++ crandom使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了crandom函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: cashspawn_think
void cashspawn_think( edict_t *self )
{
edict_t *cash;
if ((num_cash_items > MAX_CASH_ITEMS) || (level.modeset == MATCHSETUP) || (level.modeset == MATCHCOUNT) || (level.modeset == PREGAME))
{
self->nextthink = level.time + self->delay;
return;
}
// spawn some money
cash = G_Spawn();
VectorCopy( self->s.origin, cash->s.origin );
cash->movetype = MOVETYPE_BOUNCE;
cash->solid = SOLID_TRIGGER;
AngleVectors( self->s.angles, cash->velocity, NULL, NULL );
VectorScale( cash->velocity, self->speed, cash->velocity );
// randomize the velocity a bit
VectorAdd( cash->velocity, tv( crandom()*self->speed*0.3, crandom()*self->speed*0.3, crandom()*self->speed*0.15 ), cash->velocity );
cash->s.renderfx2 |= RF2_NOSHADOW;
// FIXME: doh this doesn't work, need to spawn actual item's, so the HUD is updated automatically when picking up
if (!strcmp(self->type, "cashroll"))
{ // small dollar notes
cash->s.modelindex = gi.modelindex( "models/pu_icon/cash/tris.md2" );
cash->gravity = 0.1 + random()*0.5;
cash->think = cashroll_animate;
cash->nextthink = level.time + 0.1;
cash->s.angles[PITCH] = 10;
VectorSet( cash->avelocity, 0, 10000 * cash->gravity, 0 );
VectorSet( cash->mins, -4, -4, -15 );
VectorSet( cash->maxs, 4, 4, -13 );
cash->item = FindItem("Cash");
cash->currentcash = CASH_ROLL;
cash->touch = cash_touch;
cash->timestamp = level.time + 60;
cash->think = cashroll_animate;
cash->nextthink = level.time + 0.1;
}
else
{
cash->s.modelindex = gi.modelindex( "models/pu_icon/money/money_sm.md2" );
cash->gravity = 1.0;
VectorSet( cash->mins, -12, -12, -15 );
VectorSet( cash->maxs, 12, 12, 10 );
cash->item = FindItem("Small Cash Bag");
cash->currentcash = CASH_BAG;
cash->touch = cash_touch;
cash->think = cash_kill;
cash->nextthink = level.time + 60;
}
num_cash_items++;
self->nextthink = level.time + self->delay;
}
示例2: G_RunItem
/*
================
G_RunItem
================
*/
void G_RunItem( gentity_t *ent ) {
vec3_t origin;
trace_t tr;
int contents;
int mask;
// if groundentity has been set to -1, it may have been pushed off an edge
if ( ent->s.groundEntityNum == ENTITYNUM_NONE )
{
if ( ent->s.pos.trType != TR_GRAVITY )
{
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
}
}
if ( ent->s.pos.trType == TR_STATIONARY )
{
// check think function
G_RunThink( ent );
if ( !g_gravity->value )
{
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
ent->s.pos.trDelta[0] += crandom() * 40.0f; // I dunno, just do this??
ent->s.pos.trDelta[1] += crandom() * 40.0f;
ent->s.pos.trDelta[2] += random() * 20.0f;
}
return;
}
// get current position
EvaluateTrajectory( &ent->s.pos, level.time, origin );
// trace a line from the previous position to the current position
if ( ent->clipmask )
{
mask = ent->clipmask;
}
else
{
mask = MASK_SOLID|CONTENTS_PLAYERCLIP;//shouldn't be able to get anywhere player can't
}
int ignore = ENTITYNUM_NONE;
if ( ent->owner )
{
ignore = ent->owner->s.number;
}
else if ( ent->activator )
{
ignore = ent->activator->s.number;
}
gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ignore, mask, G2_NOCOLLIDE, 0 );
VectorCopy( tr.endpos, ent->currentOrigin );
if ( tr.startsolid )
{
tr.fraction = 0;
}
gi.linkentity( ent ); // FIXME: avoid this for stationary?
// check think function
G_RunThink( ent );
if ( tr.fraction == 1 )
{
if ( g_gravity->value <= 0 )
{
if ( ent->s.apos.trType != TR_LINEAR )
{
VectorCopy( ent->currentAngles, ent->s.apos.trBase );
ent->s.apos.trType = TR_LINEAR;
ent->s.apos.trDelta[1] = Q_flrand( -300, 300 );
ent->s.apos.trDelta[0] = Q_flrand( -10, 10 );
ent->s.apos.trDelta[2] = Q_flrand( -10, 10 );
ent->s.apos.trTime = level.time;
}
}
//friction in zero-G
if ( !g_gravity->value )
{
float friction = 0.975f;
/*friction -= ent->mass/1000.0f;
if ( friction < 0.1 )
{
friction = 0.1f;
}
*/
VectorScale( ent->s.pos.trDelta, friction, ent->s.pos.trDelta );
VectorCopy( ent->currentOrigin, ent->s.pos.trBase );
ent->s.pos.trTime = level.time;
//.........这里部分代码省略.........
示例3: CG_DamageFeedback
//.........这里部分代码省略.........
kick = 5;
}
if (kick > 10)
{
kick = 10;
}
// find a free slot
for (slot = 0; slot < MAX_VIEWDAMAGE; slot++)
{
if (cg.viewDamage[slot].damageTime + cg.viewDamage[slot].damageDuration < cg.time)
{
break;
}
}
if (slot == MAX_VIEWDAMAGE)
{
return; // no free slots, never override or splats will suddenly disappear
}
vd = &cg.viewDamage[slot];
// if yaw and pitch are both 255, make the damage always centered (falling, etc)
if (yawByte == 255 && pitchByte == 255)
{
vd->damageX = 0;
vd->damageY = 0;
cg.v_dmg_roll = 0;
cg.v_dmg_pitch = -kick;
}
else
{
// positional
pitch = pitchByte / 255.0 * 360;
yaw = yawByte / 255.0 * 360;
angles[PITCH] = pitch;
angles[YAW] = yaw;
angles[ROLL] = 0;
AngleVectors(angles, dir, NULL, NULL);
VectorSubtract(vec3_origin, dir, dir);
front = DotProduct(dir, cg.refdef.viewaxis[0]);
left = DotProduct(dir, cg.refdef.viewaxis[1]);
up = DotProduct(dir, cg.refdef.viewaxis[2]);
dir[0] = front;
dir[1] = left;
dir[2] = 0;
dist = VectorLength(dir);
if (dist < 0.1)
{
dist = 0.1;
}
cg.v_dmg_roll = kick * left;
cg.v_dmg_pitch = -kick * front;
if (front <= 0.1)
{
front = 0.1;
}
vd->damageX = crandom() * 0.3 + -left / front;
vd->damageY = crandom() * 0.3 + up / dist;
}
// clamp the position
if (vd->damageX > 1.0)
{
vd->damageX = 1.0;
}
if (vd->damageX < -1.0)
{
vd->damageX = -1.0;
}
if (vd->damageY > 1.0)
{
vd->damageY = 1.0;
}
if (vd->damageY < -1.0)
{
vd->damageY = -1.0;
}
// don't let the screen flashes vary as much
if (kick > 10)
{
kick = 10;
}
vd->damageValue = kick;
cg.v_dmg_time = cg.time + DAMAGE_TIME;
vd->damageTime = cg.snap->serverTime;
vd->damageDuration = kick * 50 * (1 + 2 * (!vd->damageX && !vd->damageY));
cg.damageTime = cg.snap->serverTime;
cg.damageIndex = slot;
}
示例4: Seeker_Strafe
//------------------------------------
void Seeker_Strafe( void )
{
int side;
vec3_t end, right, dir;
trace_t tr;
if ( random() > 0.7f || !NPC->enemy || !NPC->enemy->client )
{
// Do a regular style strafe
AngleVectors( NPC->client->renderInfo.eyeAngles, NULL, right, NULL );
// Pick a random strafe direction, then check to see if doing a strafe would be
// reasonably valid
side = ( rand() & 1 ) ? -1 : 1;
VectorMA( NPC->currentOrigin, SEEKER_STRAFE_DIS * side, right, end );
gi.trace( &tr, NPC->currentOrigin, NULL, NULL, end, NPC->s.number, MASK_SOLID, (EG2_Collision)0, 0 );
// Close enough
if ( tr.fraction > 0.9f )
{
float vel = SEEKER_STRAFE_VEL;
float upPush = SEEKER_UPWARD_PUSH;
if ( NPC->client->NPC_class != CLASS_BOBAFETT )
{
G_Sound( NPC, G_SoundIndex( "sound/chars/seeker/misc/hiss" ));
}
else
{
vel *= 3.0f;
upPush *= 4.0f;
}
VectorMA( NPC->client->ps.velocity, vel*side, right, NPC->client->ps.velocity );
// Add a slight upward push
NPC->client->ps.velocity[2] += upPush;
NPCInfo->standTime = level.time + 1000 + random() * 500;
}
}
else
{
// Do a strafe to try and keep on the side of their enemy
AngleVectors( NPC->enemy->client->renderInfo.eyeAngles, dir, right, NULL );
// Pick a random side
side = ( rand() & 1 ) ? -1 : 1;
float stDis = SEEKER_STRAFE_DIS;
if ( NPC->client->NPC_class == CLASS_BOBAFETT )
{
stDis *= 2.0f;
}
VectorMA( NPC->enemy->currentOrigin, stDis * side, right, end );
// then add a very small bit of random in front of/behind the player action
VectorMA( end, crandom() * 25, dir, end );
gi.trace( &tr, NPC->currentOrigin, NULL, NULL, end, NPC->s.number, MASK_SOLID, (EG2_Collision)0, 0 );
// Close enough
if ( tr.fraction > 0.9f )
{
VectorSubtract( tr.endpos, NPC->currentOrigin, dir );
dir[2] *= 0.25; // do less upward change
float dis = VectorNormalize( dir );
// Try to move the desired enemy side
VectorMA( NPC->client->ps.velocity, dis, dir, NPC->client->ps.velocity );
float upPush = SEEKER_UPWARD_PUSH;
if ( NPC->client->NPC_class != CLASS_BOBAFETT )
{
G_Sound( NPC, G_SoundIndex( "sound/chars/seeker/misc/hiss" ));
}
else
{
upPush *= 4.0f;
}
// Add a slight upward push
NPC->client->ps.velocity[2] += upPush;
NPCInfo->standTime = level.time + 2500 + random() * 500;
}
}
}
示例5: CG_ParticleSnowFlurry
/*
======================
CG_AddParticles
======================
*/
void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent)
{
cparticle_t *p;
qboolean turb = qtrue;
if (!pshader)
CG_Printf ("CG_ParticleSnowFlurry pshader == ZERO!\n");
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->color = 0;
p->alpha = 0.90f;
p->alphavel = 0;
p->start = cent->currentState.origin2[0];
p->end = cent->currentState.origin2[1];
p->endtime = cg.time + cent->currentState.time;
p->startfade = cg.time + cent->currentState.time2;
p->pshader = pshader;
if (rand()%100 > 90)
{
p->height = 32;
p->width = 32;
p->alpha = 0.10f;
}
else
{
p->height = 1;
p->width = 1;
}
p->vel[2] = -20;
p->type = P_WEATHER_FLURRY;
if (turb)
p->vel[2] = -10;
VectorCopy(cent->currentState.origin, p->org);
p->org[0] = p->org[0];
p->org[1] = p->org[1];
p->org[2] = p->org[2];
p->vel[0] = p->vel[1] = 0;
p->accel[0] = p->accel[1] = p->accel[2] = 0;
p->vel[0] += cent->currentState.angles[0] * 32 + (crandom() * 16);
p->vel[1] += cent->currentState.angles[1] * 32 + (crandom() * 16);
p->vel[2] += cent->currentState.angles[2];
if (turb)
{
p->accel[0] = crandom () * 16;
p->accel[1] = crandom () * 16;
}
}
示例6: and
/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON
This should be renamed trigger_timer...
Repeatedly fires its targets.
Can be turned on or off by using.
"wait" base time between triggering all targets, default is 1
"random" wait variance, default is 0
so, the basic time between firing is a random time between
(wait - random) and (wait + random)
*/
void func_timer_think( gentity_t *self ) {
G_UseTargets (self, self->activator);
// set time before next firing
self->nextthink = level.time + 1000 * ( self->wait + crandom() * self->random );
}
示例7: rocketThink
//.........这里部分代码省略.........
VectorCopy( ent->enemy->currentOrigin, org );
org[2] += (ent->enemy->mins[2] + ent->enemy->maxs[2]) * 0.5f;
if ( ent->enemy->client )
{
switch( ent->enemy->client->NPC_class )
{
case CLASS_ATST:
org[2] += 80;
break;
case CLASS_MARK1:
org[2] += 40;
break;
case CLASS_PROBE:
org[2] += 60;
break;
default:
break;
}
if ( !TIMER_Done( ent->enemy, "flee" ) )
{
TIMER_Set( ent->enemy, "rocketChasing", 500 );
}
}
VectorSubtract( org, ent->currentOrigin, targetdir );
VectorNormalize( targetdir );
// Now the rocket can't do a 180 in space, so we'll limit the turn to about 45 degrees.
dot = DotProduct( targetdir, ent->movedir );
// a dot of 1.0 means right-on-target.
if ( dot < 0.0f )
{
// Go in the direction opposite, start a 180.
CrossProduct( ent->movedir, up, right );
dot2 = DotProduct( targetdir, right );
if ( dot2 > 0 )
{
// Turn 45 degrees right.
VectorMA( ent->movedir, 0.3f*newDirMult, right, newdir );
}
else
{
// Turn 45 degrees left.
VectorMA(ent->movedir, -0.3f*newDirMult, right, newdir);
}
// Yeah we've adjusted horizontally, but let's split the difference vertically, so we kinda try to move towards it.
newdir[2] = ( (targetdir[2]*newDirMult) + (ent->movedir[2]*oldDirMult) ) * 0.5;
// slowing down coupled with fairly tight turns can lead us to orbit an enemy..looks bad so don't do it!
// vel *= 0.5f;
}
else if ( dot < 0.70f )
{
// Still a bit off, so we turn a bit softer
VectorMA( ent->movedir, 0.5f*newDirMult, targetdir, newdir );
}
else
{
// getting close, so turn a bit harder
VectorMA( ent->movedir, 0.9f*newDirMult, targetdir, newdir );
}
// add crazy drunkenness
for ( int i = 0; i < 3; i++ )
{
newdir[i] += crandom() * ent->random * 0.25f;
}
// decay the randomness
ent->random *= 0.9f;
if ( ent->enemy->client
&& ent->enemy->client->ps.groundEntityNum != ENTITYNUM_NONE )
{//tracking a client who's on the ground, aim at the floor...?
// Try to crash into the ground if we get close enough to do splash damage
float dis = Distance( ent->currentOrigin, org );
if ( dis < 128 )
{
// the closer we get, the more we push the rocket down, heh heh.
newdir[2] -= (1.0f - (dis / 128.0f)) * 0.6f;
}
}
VectorNormalize( newdir );
VectorScale( newdir, vel * 0.5f, ent->s.pos.trDelta );
VectorCopy( newdir, ent->movedir );
SnapVector( ent->s.pos.trDelta ); // save net bandwidth
VectorCopy( ent->currentOrigin, ent->s.pos.trBase );
ent->s.pos.trTime = level.time;
}
ent->nextthink = level.time + ROCKET_ALT_THINK_TIME; // Nothing at all spectacular happened, continue.
return;
}
示例8: mass
/*QUAKED func_explosive (0 .5 .8) ? Trigger_Spawn ANIMATED ANIMATED_FAST
Any brush that you want to explode or break apart. If you want an
ex0plosion, set dmg and it will do a radius explosion of that amount
at the center of the bursh.
If targeted it will not be shootable.
health defaults to 100.
mass defaults to 75. This determines how much debris is emitted when
it explodes. You get one large chunk per 100 of mass (up to 8) and
one small chunk per 25 of mass (up to 16). So 800 gives the most.
*/
void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
vec3_t origin;
vec3_t chunkorigin;
vec3_t size;
int count;
int mass;
// bmodel origins are (0 0 0), we need to adjust that here
VectorScale (self->size, 0.5, size);
VectorAdd (self->absmin, size, origin);
VectorCopy (origin, self->s.origin);
self->takedamage = DAMAGE_NO;
if (self->dmg)
T_RadiusDamage (self, attacker, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE);
VectorSubtract (self->s.origin, inflictor->s.origin, self->velocity);
VectorNormalize (self->velocity);
VectorScale (self->velocity, 150, self->velocity);
// start chunks towards the center
VectorScale (size, 0.5, size);
mass = self->mass;
if (!mass)
mass = 75;
// big chunks
if (mass >= 100)
{
count = mass / 100;
if (count > 8)
count = 8;
while(count--)
{
chunkorigin[0] = origin[0] + crandom() * size[0];
chunkorigin[1] = origin[1] + crandom() * size[1];
chunkorigin[2] = origin[2] + crandom() * size[2];
ThrowDebris (self, "models/objects/debris1/tris.md2", 1, chunkorigin);
}
}
// small chunks
count = mass / 25;
if (count > 16)
count = 16;
while(count--)
{
chunkorigin[0] = origin[0] + crandom() * size[0];
chunkorigin[1] = origin[1] + crandom() * size[1];
chunkorigin[2] = origin[2] + crandom() * size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", 2, chunkorigin);
}
G_UseTargets (self, attacker);
if (self->dmg)
BecomeExplosion1 (self);
else
G_FreeEdict (self);
}
示例9: soldier_fire
void soldier_fire (edict_t *self, int flash_number)
{
vec3_t start;
vec3_t forward, right, up;
vec3_t aim;
vec3_t dir;
vec3_t end;
float r, u;
int flash_index;
if ((self->s.skinnum % 6) < 2)
flash_index = blaster_flash[flash_number];
else if ((self->s.skinnum % 6) < 4)
flash_index = shotgun_flash[flash_number];
else
flash_index = machinegun_flash[flash_number];
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
if (flash_number == 5 || flash_number == 6)
{
VectorCopy (forward, aim);
}
else
{
VectorCopy (self->enemy->s.origin, end);
end[2] += self->enemy->viewheight;
// Lazarus fog reduction of accuracy
if(self->monsterinfo.visibility < FOG_CANSEEGOOD)
{
end[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
end[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
end[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
}
VectorSubtract (end, start, aim);
// Lazarus: Accuracy is skill level dependent
if(skill->value < 3)
{
vectoangles (aim, dir);
AngleVectors (dir, forward, right, up);
r = crandom()*(1000 - 333*skill->value);
u = crandom()*(500 - 167*skill->value);
VectorMA (start, 8192, forward, end);
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
VectorSubtract (end, start, aim);
}
VectorNormalize (aim);
}
if ((self->s.skinnum % 6) <= 1)
{
// Lazarus: make bolt speed skill level dependent
monster_fire_blaster (self, start, aim, 5, 600 + 100*skill->value, flash_index, EF_BLASTER, BLASTER_ORANGE);
}
else if ((self->s.skinnum % 6) <= 3)
{
monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index);
}
else
{
if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
self->monsterinfo.aiflags |= AI_HOLD_FRAME;
}
}
示例10: CG_RainParticleGenerate
static qboolean CG_RainParticleGenerate( cg_atmosphericParticle_t *particle, vec3_t currvec, float currweight )
{
// Attempt to 'spot' a raindrop somewhere below a sky texture.
float angle, distance;
float groundHeight, skyHeight;
// int msec = trap_Milliseconds();
// n_generatetime++;
angle = random() * 2*M_PI;
distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random();
particle->pos[0] = cg.refdef_current->vieworg[0] + sin(angle) * distance;
particle->pos[1] = cg.refdef_current->vieworg[1] + cos(angle) * distance;
// ydnar: choose a spawn point randomly between sky and ground
skyHeight = BG_GetSkyHeightAtPoint( particle->pos );
if( skyHeight == MAX_ATMOSPHERIC_HEIGHT )
return qfalse;
groundHeight = BG_GetSkyGroundHeightAtPoint( particle->pos );
if( groundHeight >= skyHeight )
return qfalse;
particle->pos[2] = groundHeight + random() * (skyHeight - groundHeight);
// make sure it doesn't fall from too far cause it then will go over our heads ('lower the ceiling')
if( cg_atmFx.baseHeightOffset > 0 ) {
if( particle->pos[2] - cg.refdef_current->vieworg[2] > cg_atmFx.baseHeightOffset ) {
particle->pos[2] = cg.refdef_current->vieworg[2] + cg_atmFx.baseHeightOffset;
if( particle->pos[2] < groundHeight ) {
return qfalse;
}
}
}
// ydnar: rain goes in bursts
{
float maxActiveDrops;
// every 10 seconds allow max raindrops
maxActiveDrops = 0.50 * cg_atmFx.numDrops + 0.001 * cg_atmFx.numDrops * (10000 - (cg.time % 10000));
if( cg_atmFx.oldDropsActive > maxActiveDrops )
return qfalse;
}
CG_SetParticleActive( particle, ACT_FALLING );
particle->colour[0] = 0.6 + 0.2 * random() * 0xFF;
particle->colour[1] = 0.6 + 0.2 * random() * 0xFF;
particle->colour[2] = 0.6 + 0.2 * random() * 0xFF;
VectorCopy( currvec, particle->delta );
particle->delta[2] += crandom() * 100;
VectorCopy( particle->delta, particle->deltaNormalized );
VectorNormalizeFast( particle->deltaNormalized );
particle->height = ATMOSPHERIC_RAIN_HEIGHT + crandom() * 100;
particle->weight = currweight;
particle->effectshader = &cg_atmFx.effectshaders[0];
// particle->effectshader = &cg_atmFx.effectshaders[ (int) (random() * ( cg_atmFx.numEffectShaders - 1 )) ];
// generatetime += trap_Milliseconds() - msec;
return( qtrue );
}
示例11: FireTotem_think
void FireTotem_think(edict_t *self, edict_t *caster)
{
int talentLevel;
float chance;
edict_t *target = NULL;
//Totem should not work underwater (gee I wonder why).
if(!self->waterlevel)
{
//Talent: Volcanic
talentLevel = getTalentLevel(caster, TALENT_VOLCANIC);
chance = 0.02 * talentLevel;
//Find players in radius and attack them.
while ((target = findclosestradius(target, self->s.origin, TOTEM_MAX_RANGE)) != NULL)
{
if (G_ValidTarget(self, target, true) && (self->s.origin[2]+64>target->s.origin[2]))
{
vec3_t forward, end;
int damage = FIRETOTEM_DAMAGE_BASE + self->monsterinfo.level * FIRETOTEM_DAMAGE_MULT;
int count = 10 + self->monsterinfo.level;
int speed = 600;
float val, dist;
qboolean fireball=false;
// copy target location
G_EntMidPoint(target, end);
// calculate distance to target
dist = distance(end, self->s.origin);
// move our target point based on projectile and enemy velocity
VectorMA(end, (float)dist/speed, target->velocity, end);
//Talent: Volcanic - chance to shoot a fireball
if (talentLevel > 0 && chance > random())
fireball = true;
// aim up
if (fireball)
val = ((dist/2048)*(dist/2048)*2048) + (end[2]-self->s.origin[2]);//4.4
else
val = ((dist/512)*(dist/512)*512) + (end[2]-self->s.origin[2]);
if (val < 0)
val = 0;
end[2] += val;
// calculate direction vector to target
VectorSubtract(end, self->s.origin, forward);
VectorNormalize(forward);
// don't fire in a perfectly straight line
forward[1] += 0.05*crandom();
// spawn flames
if (fireball)
fire_fireball(self, self->s.origin, forward, 200, 125, 600, 5, 20);//4.4
else
ThrowFlame(self, self->s.origin, forward, distance(self->s.origin, target->s.origin), speed, damage, GetRandom(2, 4));
self->lastsound = level.framenum;
// refire delay
self->delay = level.time + FRAMETIME;
}
}
}
}
示例12: NPC_BSGM_Attack
//.........这里部分代码省略.........
//NPCInfo->enemyCheckDebounceTime = level.time;//actually used here as a last actual LOS
}
else
{
if ( !NPCInfo->goalEntity )
{
NPCInfo->goalEntity = NPC->enemy;
}
if ( NPCInfo->goalEntity == NPC->enemy )
{//for now, always chase the enemy
move4 = qtrue;
}
}
//Check for movement to take care of
GM_CheckMoveState();
//See if we should override shooting decision with any special considerations
GM_CheckFireState();
if ( NPC->client->ps.weapon == WP_REPEATER && (NPCInfo->scriptFlags&SCF_ALT_FIRE) && shoot4 && TIMER_Done( NPC, "attackDelay" ) )
{
vec3_t muzzle;
vec3_t angles;
vec3_t target;
vec3_t velocity = {0,0,0};
vec3_t mins = {-REPEATER_ALT_SIZE,-REPEATER_ALT_SIZE,-REPEATER_ALT_SIZE}, maxs = {REPEATER_ALT_SIZE,REPEATER_ALT_SIZE,REPEATER_ALT_SIZE};
qboolean clearshot;
CalcEntitySpot( NPC, SPOT_WEAPON, muzzle );
VectorCopy( NPC->enemy->r.currentOrigin, target );
target[0] += flrand( -5, 5 )+(crandom()*(6-NPCInfo->currentAim)*2);
target[1] += flrand( -5, 5 )+(crandom()*(6-NPCInfo->currentAim)*2);
target[2] += flrand( -5, 5 )+(crandom()*(6-NPCInfo->currentAim)*2);
//Find the desired angles
clearshot = WP_LobFire( NPC, muzzle, target, mins, maxs, MASK_SHOT|CONTENTS_LIGHTSABER,
velocity, qtrue, NPC->s.number, NPC->enemy->s.number,
300, 1100, 1500, qtrue );
if ( VectorCompare( vec3_origin, velocity ) || (!clearshot&&enemyLOS4&&enemyCS4) )
{//no clear lob shot and no lob shot that will hit something breakable
if ( enemyLOS4 && enemyCS4 && TIMER_Done( NPC, "noRapid" ) )
{//have a clear straight shot, so switch to primary
NPCInfo->scriptFlags &= ~SCF_ALT_FIRE;
NPC->alt_fire = qfalse;
NPC_ChangeWeapon( WP_REPEATER );
//keep this weap for a bit
TIMER_Set( NPC, "noLob", Q_irand( 500, 1000 ) );
}
else
{
shoot4 = qfalse;
}
}
else
{
vectoangles( velocity, angles );
NPCInfo->desiredYaw = AngleNormalize360( angles[YAW] );
NPCInfo->desiredPitch = AngleNormalize360( angles[PITCH] );
VectorCopy( velocity, NPC->client->hiddenDir );
NPC->client->hiddenDist = VectorNormalize ( NPC->client->hiddenDir );
}
示例13: CG_Chunks
//.........这里部分代码省略.........
chunk = qtrue;
chunkModel = cgs.model_draw[customChunk];
}
}
if ( !chunk )
{
// No custom chunk. Pick a random chunk type at run-time so we don't get the same chunks
switch( chunkType )
{
case MAT_METAL2: //bluegrey
chunkModel = cgs.media.chunkModels[CHUNK_METAL2][Q_irand(0, 3)];
break;
case MAT_GREY_STONE://gray
chunkModel = cgs.media.chunkModels[CHUNK_ROCK1][Q_irand(0, 3)];
break;
case MAT_LT_STONE: //tan
chunkModel = cgs.media.chunkModels[CHUNK_ROCK2][Q_irand(0, 3)];
break;
case MAT_DRK_STONE://brown
chunkModel = cgs.media.chunkModels[CHUNK_ROCK3][Q_irand(0, 3)];
break;
case MAT_WHITE_METAL:
chunkModel = cgs.media.chunkModels[CHUNK_WHITE_METAL][Q_irand(0, 3)];
break;
case MAT_CRATE1://yellow multi-colored crate chunks
chunkModel = cgs.media.chunkModels[CHUNK_CRATE1][Q_irand(0, 3)];
break;
case MAT_CRATE2://red multi-colored crate chunks
chunkModel = cgs.media.chunkModels[CHUNK_CRATE2][Q_irand(0, 3)];
break;
case MAT_ELEC_METAL:
case MAT_GLASS_METAL:
case MAT_METAL://grey
chunkModel = cgs.media.chunkModels[CHUNK_METAL1][Q_irand(0, 3)];
break;
case MAT_METAL3:
if ( rand() & 1 )
{
chunkModel = cgs.media.chunkModels[CHUNK_METAL1][Q_irand(0, 3)];
}
else
{
chunkModel = cgs.media.chunkModels[CHUNK_METAL2][Q_irand(0, 3)];
}
break;
}
}
// It wouldn't look good to throw a bunch of RGB axis models...so make sure we have something to work with.
if ( chunkModel )
{
le = CG_AllocLocalEntity();
re = &le->refEntity;
re->hModel = chunkModel;
le->leType = LE_FRAGMENT;
le->endTime = cg.time + 1300 + random() * 900;
// spawn chunk roughly in the bbox of the thing...bias towards center in case thing blowing up doesn't complete fill its bbox.
for( j = 0; j < 3; j++ )
{
r = random() * 0.8f + 0.1f;
re->origin[j] = ( r * mins[j] + ( 1 - r ) * maxs[j] );
}
VectorCopy( re->origin, le->pos.trBase );
// Move out from center of thing, otherwise you can end up things moving across the brush in an undesirable direction. Visually looks wrong
VectorSubtract( re->origin, origin, dir );
VectorNormalize( dir );
VectorScale( dir, Q_flrand( speed * 0.5f, speed * 1.25f ) * speedMod, le->pos.trDelta );
// Angular Velocity
VectorSet( le->angles.trBase, random() * 360, random() * 360, random() * 360 );
le->angles.trDelta[0] = crandom();
le->angles.trDelta[1] = crandom();
le->angles.trDelta[2] = 0; // don't do roll
VectorScale( le->angles.trDelta, random() * 600.0f + 200.0f, le->angles.trDelta );
le->pos.trType = TR_GRAVITY;
le->angles.trType = TR_LINEAR;
le->pos.trTime = le->angles.trTime = cg.time;
le->bounceFactor = 0.2f + random() * 0.2f;
le->leFlags |= LEF_TUMBLE;
le->ownerGentNum = owner;
le->leBounceSoundType = bounce;
// Make sure that we have the desired start size set
le->radius = Q_flrand( baseScale * 0.75f, baseScale * 1.25f );
re->nonNormalizedAxes = qtrue;
AxisCopy( axisDefault, re->axis ); // could do an angles to axis, but this is cheaper and works ok
for( k = 0; k < 3; k++ )
{
VectorScale( re->axis[k], le->radius, re->axis[k] );
}
}
}
}
示例14: CG_ParticleDust
void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir)
{
float length;
float dist;
float crittersize;
vec3_t angles, forward;
vec3_t point;
cparticle_t *p;
int i;
dist = 0;
VectorNegate (dir, dir);
length = VectorLength (dir);
vectoangles (dir, angles);
AngleVectors (angles, forward, NULL, NULL);
crittersize = LARGESIZE;
if (length)
dist = length / crittersize;
if (dist < 1)
dist = 1;
VectorCopy (origin, point);
for (i=0; i<dist; i++)
{
VectorMA (point, crittersize, forward, point);
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->alpha = 5.0;
p->alphavel = 0;
p->roll = 0;
p->pshader = cgs.media.smokePuffShader;
// RF, stay around for long enough to expand and dissipate naturally
if (length)
p->endtime = cg.time + 4500 + (crandom() * 3500);
else
p->endtime = cg.time + 750 + (crandom() * 500);
p->startfade = cg.time;
p->width = LARGESIZE;
p->height = LARGESIZE;
// RF, expand while falling
p->endheight = LARGESIZE*3.0;
p->endwidth = LARGESIZE*3.0;
if (!length)
{
p->width *= 0.2f;
p->height *= 0.2f;
p->endheight = NORMALSIZE;
p->endwidth = NORMALSIZE;
}
p->type = P_SMOKE;
VectorCopy( point, p->org );
p->vel[0] = crandom()*6;
p->vel[1] = crandom()*6;
p->vel[2] = random()*20;
// RF, add some gravity/randomness
p->accel[0] = crandom()*3;
p->accel[1] = crandom()*3;
p->accel[2] = -PARTICLE_GRAVITY*0.4;
VectorClear( p->accel );
p->rotate = qfalse;
p->roll = rand()%179;
p->alpha = 0.75;
}
}
示例15: barrel_explode
void barrel_explode (edict_t *self)
{
vec3_t org;
float spd;
vec3_t save;
T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_BARREL);
VectorCopy (self->s.origin, save);
VectorMA (self->absmin, 0.5, self->size, self->s.origin);
// a few big chunks
spd = 1.5 * (float)self->dmg / 200.0;
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org);
// bottom corners
spd = 1.75 * (float)self->dmg / 200.0;
VectorCopy (self->absmin, org);
ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org);
VectorCopy (self->absmin, org);
org[0] += self->size[0];
ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org);
VectorCopy (self->absmin, org);
org[1] += self->size[1];
ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org);
VectorCopy (self->absmin, org);
org[0] += self->size[0];
org[1] += self->size[1];
ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org);
// a bunch of little chunks
spd = 2 * self->dmg / 200;
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
org[0] = self->s.origin[0] + crandom() * self->size[0];
org[1] = self->s.origin[1] + crandom() * self->size[1];
org[2] = self->s.origin[2] + crandom() * self->size[2];
ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org);
VectorCopy (save, self->s.origin);
if (self->groundentity)
BecomeExplosion2 (self);
else
BecomeExplosion1 (self);
}