?? g_misc.c
字號:
activator = other->oldenemy;
else if (other->activator && other->activator->client)
activator = other->activator;
else
activator = other;
G_UseTargets (self, activator);
self->target = savetarget;
}
}
void SP_point_combat (edict_t *self)
{
if (deathmatch->value)
{
G_FreeEdict (self);
return;
}
self->solid = SOLID_TRIGGER;
self->touch = point_combat_touch;
VectorSet (self->mins, -8, -8, -16);
VectorSet (self->maxs, 8, 8, 16);
self->svflags = SVF_NOCLIENT;
gi.linkentity (self);
};
/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
Just for the debugging level. Don't use
*/
static int robotron[4];
void TH_viewthing(edict_t *ent)
{
ent->s.frame = (ent->s.frame + 1) % 7;
// ent->s.frame = (ent->s.frame + 1) % 9;
ent->nextthink = level.time + FRAMETIME;
// return;
if (ent->spawnflags)
{
if (ent->s.frame == 0)
{
ent->spawnflags = (ent->spawnflags + 1) % 4 + 1;
ent->s.modelindex = robotron[ent->spawnflags - 1];
}
}
}
void SP_viewthing(edict_t *ent)
{
gi.dprintf ("viewthing spawned\n");
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
ent->s.renderfx = RF_FRAMELERP;
VectorSet (ent->mins, -16, -16, -24);
VectorSet (ent->maxs, 16, 16, 32);
// ent->s.modelindex = gi.modelindex ("models/player_y/tris.md2");
ent->s.modelindex = gi.modelindex ("models/objects/banner/tris.md2");
gi.linkentity (ent);
ent->nextthink = level.time + 0.5;
ent->think = TH_viewthing;
return;
}
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
*/
void SP_info_null (edict_t *self)
{
G_FreeEdict (self);
};
/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for lightning.
*/
void SP_info_notnull (edict_t *self)
{
VectorCopy (self->s.origin, self->absmin);
VectorCopy (self->s.origin, self->absmax);
};
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300.
Default style is 0.
If targeted, will toggle between on and off.
Default _cone value is 10 (used to set size of light for spotlights)
*/
#define START_OFF 1
static void light_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (self->spawnflags & START_OFF)
{
gi.configstring (CS_LIGHTS+self->style, "m");
self->spawnflags &= ~START_OFF;
}
else
{
gi.configstring (CS_LIGHTS+self->style, "a");
self->spawnflags |= START_OFF;
}
}
void SP_light (edict_t *self)
{
// no targeted lights in deathmatch, because they cause global messages
if (!self->targetname || deathmatch->value)
{
G_FreeEdict (self);
return;
}
if (self->style >= 32)
{
self->use = light_use;
if (self->spawnflags & START_OFF)
gi.configstring (CS_LIGHTS+self->style, "a");
else
gi.configstring (CS_LIGHTS+self->style, "m");
}
}
/*QUAKED func_wall (0 .5 .8) ? TRIGGER_SPAWN TOGGLE START_ON ANIMATED ANIMATED_FAST
This is just a solid wall if not inhibited
TRIGGER_SPAWN the wall will not be present until triggered
it will then blink in to existance; it will
kill anything that was in it's way
TOGGLE only valid for TRIGGER_SPAWN walls
this allows the wall to be turned on and off
START_ON only valid for TRIGGER_SPAWN walls
the wall will initially be present
*/
void func_wall_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (self->solid == SOLID_NOT)
{
self->solid = SOLID_BSP;
self->svflags &= ~SVF_NOCLIENT;
KillBox (self);
}
else
{
self->solid = SOLID_NOT;
self->svflags |= SVF_NOCLIENT;
}
gi.linkentity (self);
if (!(self->spawnflags & 2))
self->use = NULL;
}
void SP_func_wall (edict_t *self)
{
self->movetype = MOVETYPE_PUSH;
gi.setmodel (self, self->model);
if (self->spawnflags & 8)
self->s.effects |= EF_ANIM_ALL;
if (self->spawnflags & 16)
self->s.effects |= EF_ANIM_ALLFAST;
// just a wall
if ((self->spawnflags & 7) == 0)
{
self->solid = SOLID_BSP;
gi.linkentity (self);
return;
}
// it must be TRIGGER_SPAWN
if (!(self->spawnflags & 1))
{
// gi.dprintf("func_wall missing TRIGGER_SPAWN\n");
self->spawnflags |= 1;
}
// yell if the spawnflags are odd
if (self->spawnflags & 4)
{
if (!(self->spawnflags & 2))
{
gi.dprintf("func_wall START_ON without TOGGLE\n");
self->spawnflags |= 2;
}
}
self->use = func_wall_use;
if (self->spawnflags & 4)
{
self->solid = SOLID_BSP;
}
else
{
self->solid = SOLID_NOT;
self->svflags |= SVF_NOCLIENT;
}
gi.linkentity (self);
}
/*QUAKED func_object (0 .5 .8) ? TRIGGER_SPAWN ANIMATED ANIMATED_FAST
This is solid bmodel that will fall if it's support it removed.
*/
void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
// only squash thing we fall on top of
if (!plane)
return;
if (plane->normal[2] < 1.0)
return;
if (other->takedamage == DAMAGE_NO)
return;
T_Damage (other, self, self, vec3_origin, self->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
}
void func_object_release (edict_t *self)
{
self->movetype = MOVETYPE_TOSS;
self->touch = func_object_touch;
}
void func_object_use (edict_t *self, edict_t *other, edict_t *activator)
{
self->solid = SOLID_BSP;
self->svflags &= ~SVF_NOCLIENT;
self->use = NULL;
KillBox (self);
func_object_release (self);
}
void SP_func_object (edict_t *self)
{
gi.setmodel (self, self->model);
self->mins[0] += 1;
self->mins[1] += 1;
self->mins[2] += 1;
self->maxs[0] -= 1;
self->maxs[1] -= 1;
self->maxs[2] -= 1;
if (!self->dmg)
self->dmg = 100;
if (self->spawnflags == 0)
{
self->solid = SOLID_BSP;
self->movetype = MOVETYPE_PUSH;
self->think = func_object_release;
self->nextthink = level.time + 2 * FRAMETIME;
}
else
{
self->solid = SOLID_NOT;
self->movetype = MOVETYPE_PUSH;
self->use = func_object_use;
self->svflags |= SVF_NOCLIENT;
}
if (self->spawnflags & 2)
self->s.effects |= EF_ANIM_ALL;
if (self->spawnflags & 4)
self->s.effects |= EF_ANIM_ALLFAST;
self->clipmask = MASK_MONSTERSOLID;
gi.linkentity (self);
}
/*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);
}
void func_explosive_use(edict_t *self, edict_t *other, edict_t *activator)
{
func_explosive_explode (self, self, other, self->health, vec3_origin);
}
void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator)
{
self->solid = SOLID_BSP;
self->svflags &= ~SVF_NOCLIENT;
self->use = NULL;
KillBox (self);
gi.linkentity (self);
}
void SP_func_explosive (edict_t *self)
{
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (self);
return;
}
self->movetype = MOVETYPE_PUSH;
gi.modelindex ("models/objects/debris1/tris.md2");
gi.modelindex ("models/objects/debris2/tris.md2");
gi.setmodel (self, self->model);
if (self->spawnflags & 1)
{
self->svflags |= SVF_NOCLIENT;
self->solid = SOLID_NOT;
self->use = func_explosive_spawn;
}
else
{
self->solid = SOLID_BSP;
if (self->targetname)
self->use = func_explosive_use;
}
if (self->spawnflags & 2)
self->s.effects |= EF_ANIM_ALL;
if (self->spawnflags & 4)
self->s.effects |= EF_ANIM_ALLFAST;
if (self->use != func_explosive_use)
{
if (!self->health)
self->health = 100;
self->die = func_explosive_explode;
self->takedamage = DAMAGE_YES;
}
gi.linkentity (self);
}
/*QUAKED misc_explobox (0 .5 .8) (-16 -16 0) (16 16 40)
Large exploding box. You can override its mass (100),
health (80), and dmg (150).
*/
void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
float ratio;
vec3_t v;
if ((!other->groundentity) || (other->groundentity == self))
return;
ratio = (float)other->mass / (float)self->mass;
VectorSubtract (self->s.origin, other->s.origin, v);
M_walkmove (self, vectoyaw(v), 20 * ratio * FRAMETIME);
}
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];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -