mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2024-11-14 08:31:04 +00:00
Added CL_ShutdownLocal() in cl_main.c.
Changed func_door_secret in missionpack DLL to have the correct die function (door_secret_die) if health is set. Moved misc, model_*, and target entity code to new source files g_misc_laz.c, g_misc_nm.c, g_model.c, and g_target_laz.c in missionpack DLL.
This commit is contained in:
parent
c9e3575516
commit
bcf678286b
19 changed files with 5037 additions and 4890 deletions
|
@ -2236,6 +2236,90 @@ void CL_InitLocal (void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_ShutdownLocal
|
||||
=================
|
||||
*/
|
||||
void CL_ShutdownLocal (void)
|
||||
{
|
||||
if (!local_initialized)
|
||||
return;
|
||||
|
||||
Cmd_RemoveCommand ("cmd");
|
||||
Cmd_RemoveCommand ("pause");
|
||||
Cmd_RemoveCommand ("pingservers");
|
||||
Cmd_RemoveCommand ("skins");
|
||||
|
||||
Cmd_RemoveCommand ("userinfo");
|
||||
Cmd_RemoveCommand ("snd_restart");
|
||||
|
||||
Cmd_RemoveCommand ("changing");
|
||||
Cmd_RemoveCommand ("disconnect");
|
||||
Cmd_RemoveCommand ("record");
|
||||
Cmd_RemoveCommand ("stop");
|
||||
|
||||
Cmd_RemoveCommand ("quit");
|
||||
|
||||
Cmd_RemoveCommand ("connect");
|
||||
Cmd_RemoveCommand ("reconnect");
|
||||
|
||||
Cmd_RemoveCommand ("rcon");
|
||||
|
||||
// Cmd_RemoveCommand ("packet"); // this is dangerous to leave in
|
||||
|
||||
Cmd_RemoveCommand ("setenv");
|
||||
|
||||
Cmd_RemoveCommand ("precache");
|
||||
|
||||
Cmd_RemoveCommand ("download");
|
||||
|
||||
Cmd_RemoveCommand ("writeconfig");
|
||||
|
||||
Cmd_RemoveCommand ("aacskey");
|
||||
|
||||
// Chat Ignore from R1Q2/Q2Pro
|
||||
Cmd_RemoveCommand ("ignorenick");
|
||||
Cmd_RemoveCommand ("unignorenick");
|
||||
Cmd_RemoveCommand ("ignoretext");
|
||||
Cmd_RemoveCommand ("unignoretext");
|
||||
// end R1Q2/Q2Pro Chat Ignore
|
||||
|
||||
#ifdef LOC_SUPPORT // Xile/NiceAss LOC
|
||||
Cmd_RemoveCommand ("loc_add");
|
||||
Cmd_RemoveCommand ("loc_del");
|
||||
Cmd_RemoveCommand ("loc_save");
|
||||
Cmd_RemoveCommand ("loc_help");
|
||||
#endif // LOC_SUPPORT
|
||||
|
||||
Cmd_RemoveCommand ("wave");
|
||||
Cmd_RemoveCommand ("inven");
|
||||
Cmd_RemoveCommand ("kill");
|
||||
Cmd_RemoveCommand ("use");
|
||||
Cmd_RemoveCommand ("drop");
|
||||
Cmd_RemoveCommand ("say");
|
||||
Cmd_RemoveCommand ("say_team");
|
||||
Cmd_RemoveCommand ("info");
|
||||
Cmd_RemoveCommand ("prog");
|
||||
Cmd_RemoveCommand ("give");
|
||||
Cmd_RemoveCommand ("god");
|
||||
Cmd_RemoveCommand ("notarget");
|
||||
Cmd_RemoveCommand ("noclip");
|
||||
Cmd_RemoveCommand ("invuse");
|
||||
Cmd_RemoveCommand ("invprev");
|
||||
Cmd_RemoveCommand ("invnext");
|
||||
Cmd_RemoveCommand ("invdrop");
|
||||
Cmd_RemoveCommand ("weapnext");
|
||||
Cmd_RemoveCommand ("weapprev");
|
||||
|
||||
// Chat Ignore from R1Q2/Q2Pro
|
||||
CL_RemoveAllChatIgnores (&cl_chatNickIgnores);
|
||||
CL_RemoveAllChatIgnores (&cl_chatTextIgnores);
|
||||
// end R1Q2/Q2Pro Chat Ignore
|
||||
|
||||
local_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -2896,6 +2980,7 @@ void CL_Shutdown (void)
|
|||
sec = Sys_Milliseconds();
|
||||
// end delay
|
||||
|
||||
CL_ShutdownLocal (); // added Local shutdown
|
||||
IN_Shutdown ();
|
||||
VID_Shutdown();
|
||||
|
||||
|
|
|
@ -3499,6 +3499,7 @@ void train_move_children (edict_t *self)
|
|||
{
|
||||
VectorAdd (ent->s.angles, ent->org_angles, angles);
|
||||
G_SetMovedir (angles, ent->movedir);
|
||||
|
||||
// Knightmare- these entities need special calculations
|
||||
if (!strcmp(ent->classname, "monster_turret") || !strcmp(ent->classname, "turret_wall"))
|
||||
// if ( (ent->class_id == ENTITY_MONSTER_TURRET) || (ent->class_id == ENTITY_TURRET_WALL) )
|
||||
|
@ -3776,7 +3777,7 @@ void train_remove_children (edict_t *self)
|
|||
if (!ent->inuse)
|
||||
return;
|
||||
if (!strcmp(ent->movewith, self->targetname))
|
||||
{ //recursively remove each child's children
|
||||
{ // recursively remove each child's children
|
||||
train_remove_children (ent);
|
||||
G_FreeEdict(ent);
|
||||
}
|
||||
|
@ -4263,7 +4264,7 @@ void train_rotate (edict_t *self)
|
|||
//gi.bprintf (PRINT_HIGH, "train cy: %i iy: %i ys: %i\n", cur_yaw, idl_yaw, ys);
|
||||
|
||||
train_speed = VectorLength (self->enemy->velocity);
|
||||
if (train_speed == 0) //Don't rotate if we're stopped
|
||||
if (train_speed == 0) // Don't rotate if we're stopped
|
||||
VectorClear (self->enemy->avelocity);
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
@ -4362,7 +4363,7 @@ again:
|
|||
// Set speed before train_next is called
|
||||
// Knightmare- this is only used for Rogue maps
|
||||
// train speed changes are handled differently
|
||||
if ( (ent->speed) && (level.maptype == MAPTYPE_ROGUE))
|
||||
if ( (ent->speed) && (level.maptype == MAPTYPE_ROGUE) )
|
||||
{
|
||||
self->speed = ent->speed;
|
||||
self->moveinfo.speed = ent->speed;
|
||||
|
@ -4422,9 +4423,9 @@ again:
|
|||
// Rroff rotating
|
||||
if (self->spawnflags & TRAIN_ROTATE && !(ent->spawnflags & 2))
|
||||
{
|
||||
// VectorSubtract (ent->s.origin, self->s.origin, v);
|
||||
// self->ideal_yaw = vectoyaw(v);
|
||||
// self->ideal_pitch = vectopitch(v);
|
||||
// VectorSubtract (ent->s.origin, self->s.origin, v);
|
||||
// self->ideal_yaw = vectoyaw(v);
|
||||
// self->ideal_pitch = vectopitch(v);
|
||||
if (self->spawnflags & TRAIN_ORIGIN) { // Knightmare- func_train_origin support
|
||||
VectorSubtract(ent->s.origin, self->s.origin, v);
|
||||
}
|
||||
|
@ -4512,8 +4513,8 @@ void train_resume (edict_t *self)
|
|||
if (self->spawnflags & TRAIN_ROT_CONST)
|
||||
{
|
||||
self->avelocity[0] = self->pitch_speed;
|
||||
self->avelocity[1] = self->yaw_speed;
|
||||
self->avelocity[2] = self->roll_speed;
|
||||
self->avelocity[1] = self->yaw_speed;
|
||||
self->avelocity[2] = self->roll_speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5201,9 +5202,10 @@ void door_secret_done (edict_t *self)
|
|||
{
|
||||
if (!(self->targetname) || (self->spawnflags & SECRET_ALWAYS_SHOOT))
|
||||
{
|
||||
// Knightmare- setting health to anything other than 0
|
||||
// makes the die function never get called!
|
||||
self->health = 0;
|
||||
// Knightmare- restore user-set health here
|
||||
// now that the correct die function is set
|
||||
// self->health = 0;
|
||||
self->health = self->max_health;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
}
|
||||
self->moveinfo.state = STATE_LOWEST; // Knightmare added
|
||||
|
@ -5246,7 +5248,6 @@ void door_secret_blocked (edict_t *self, edict_t *other)
|
|||
|
||||
void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
// gi.dprintf("door_secret_die\n");
|
||||
self->takedamage = DAMAGE_NO;
|
||||
door_secret_use (self, attacker, attacker);
|
||||
}
|
||||
|
@ -5259,15 +5260,15 @@ void SP_func_door_secret (edict_t *ent)
|
|||
|
||||
if ( (level.maptype == MAPTYPE_CUSTOM) && (ent->sounds > 4) && (ent->sounds < 100) ) // custom sounds
|
||||
{
|
||||
ent->moveinfo.sound_start = gi.soundindex (va("doors/dr%02i_strt.wav", ent->sounds));
|
||||
ent->moveinfo.sound_middle = gi.soundindex (va("doors/dr%02i_mid.wav", ent->sounds));
|
||||
ent->moveinfo.sound_end = gi.soundindex (va("doors/dr%02i_end.wav", ent->sounds));
|
||||
ent->moveinfo.sound_start = gi.soundindex (va("doors/dr%02i_strt.wav", ent->sounds));
|
||||
ent->moveinfo.sound_middle = gi.soundindex (va("doors/dr%02i_mid.wav", ent->sounds));
|
||||
ent->moveinfo.sound_end = gi.soundindex (va("doors/dr%02i_end.wav", ent->sounds));
|
||||
}
|
||||
else if (ent->sounds != 1)
|
||||
{
|
||||
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
|
||||
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
|
||||
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
|
||||
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
|
||||
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
|
||||
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5289,9 +5290,12 @@ void SP_func_door_secret (edict_t *ent)
|
|||
|
||||
if (!(ent->targetname) || (ent->spawnflags & SECRET_ALWAYS_SHOOT))
|
||||
{
|
||||
// Knightmare- setting health to anything other than 0
|
||||
// makes the die function never get called!
|
||||
ent->health = 0;
|
||||
// Knightmare- we can allow user-set health here
|
||||
// now that the correct die function is set
|
||||
// ent->health = 0;
|
||||
if (!ent->health)
|
||||
ent->health = 1;
|
||||
ent->max_health = ent->health;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = door_secret_die;
|
||||
}
|
||||
|
@ -5336,7 +5340,8 @@ void SP_func_door_secret (edict_t *ent)
|
|||
if (ent->health)
|
||||
{
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = door_killed;
|
||||
// ent->die = door_killed;
|
||||
ent->die = door_secret_die; // Knightmare- this had the wrong die function set!
|
||||
ent->max_health = ent->health;
|
||||
}
|
||||
else if (ent->targetname && ent->message)
|
||||
|
@ -6009,7 +6014,7 @@ void swinging_door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
ent->nextthink = level.time + ent->moveinfo.wait;
|
||||
return;
|
||||
}
|
||||
check_reverse_rotation(ent,point);
|
||||
check_reverse_rotation (ent, point);
|
||||
if (!(ent->flags & FL_TEAMSLAVE))
|
||||
{
|
||||
if (ent->moveinfo.sound_start)
|
||||
|
|
|
@ -1859,6 +1859,65 @@
|
|||
{"thing_think", (byte *)thing_think},
|
||||
{"thing_restore_leader", (byte *)thing_restore_leader},
|
||||
{"SpawnThing", (byte *)SpawnThing},
|
||||
{"SP_target_locator", (byte *)SP_target_locator},
|
||||
{"target_locator_init", (byte *)target_locator_init},
|
||||
{"SP_target_failure", (byte *)SP_target_failure},
|
||||
{"use_target_failure", (byte *)use_target_failure},
|
||||
{"target_failure_fade_lights", (byte *)target_failure_fade_lights},
|
||||
{"target_failure_think", (byte *)target_failure_think},
|
||||
{"target_failure_player_die", (byte *)target_failure_player_die},
|
||||
{"target_failure_wipe", (byte *)target_failure_wipe},
|
||||
{"SP_target_animation", (byte *)SP_target_animation},
|
||||
{"target_animation_use", (byte *)target_animation_use},
|
||||
{"target_animate", (byte *)target_animate},
|
||||
{"SP_target_monitor", (byte *)SP_target_monitor},
|
||||
{"use_target_monitor", (byte *)use_target_monitor},
|
||||
{"target_monitor_move", (byte *)target_monitor_move},
|
||||
{"target_monitor_off", (byte *)target_monitor_off},
|
||||
{"SP_target_attractor", (byte *)SP_target_attractor},
|
||||
{"use_target_attractor", (byte *)use_target_attractor},
|
||||
{"target_attractor_think", (byte *)target_attractor_think},
|
||||
{"target_attractor_think_single", (byte *)target_attractor_think_single},
|
||||
{"SP_target_clone", (byte *)SP_target_clone},
|
||||
{"target_clone_use", (byte *)target_clone_use},
|
||||
{"clone", (byte *)clone},
|
||||
{"SP_target_rocks", (byte *)SP_target_rocks},
|
||||
{"target_rocks_use", (byte *)target_rocks_use},
|
||||
{"ThrowRock", (byte *)ThrowRock},
|
||||
{"SP_target_fade", (byte *)SP_target_fade},
|
||||
{"use_target_fade", (byte *)use_target_fade},
|
||||
{"SP_target_sky", (byte *)SP_target_sky},
|
||||
{"target_sky_use", (byte *)target_sky_use},
|
||||
{"SP_target_skill", (byte *)SP_target_skill},
|
||||
{"use_target_skill", (byte *)use_target_skill},
|
||||
{"SP_target_cd", (byte *)SP_target_cd},
|
||||
{"target_cd_use", (byte *)target_cd_use},
|
||||
{"SP_target_rotation", (byte *)SP_target_rotation},
|
||||
{"target_rotation_use", (byte *)target_rotation_use},
|
||||
{"SP_target_change", (byte *)SP_target_change},
|
||||
{"target_change_use", (byte *)target_change_use},
|
||||
{"SP_target_movewith", (byte *)SP_target_movewith},
|
||||
{"target_movewith_use", (byte *)target_movewith_use},
|
||||
{"SP_target_effect", (byte *)SP_target_effect},
|
||||
{"target_effect_think", (byte *)target_effect_think},
|
||||
{"target_effect_use", (byte *)target_effect_use},
|
||||
{"target_effect_widowbeam", (byte *)target_effect_widowbeam},
|
||||
{"target_effect_tunnel_sparks", (byte *)target_effect_tunnel_sparks},
|
||||
{"target_effect_explosion", (byte *)target_effect_explosion},
|
||||
{"target_effect_sparks", (byte *)target_effect_sparks},
|
||||
{"target_effect_lightning", (byte *)target_effect_lightning},
|
||||
{"target_effect_trail", (byte *)target_effect_trail},
|
||||
{"target_effect_splash", (byte *)target_effect_splash},
|
||||
{"target_effect_steam", (byte *)target_effect_steam},
|
||||
{"target_effect_at", (byte *)target_effect_at},
|
||||
{"SP_target_global_text", (byte *)SP_target_global_text},
|
||||
{"target_global_text_use", (byte *)target_global_text_use},
|
||||
{"SP_target_set_effect", (byte *)SP_target_set_effect},
|
||||
{"target_set_effect_use", (byte *)target_set_effect_use},
|
||||
{"SP_target_command", (byte *)SP_target_command},
|
||||
{"target_command_use", (byte *)target_command_use},
|
||||
{"SP_target_monsterbattle", (byte *)SP_target_monsterbattle},
|
||||
{"use_target_monsterbattle", (byte *)use_target_monsterbattle},
|
||||
{"SP_target_earthquake", (byte *)SP_target_earthquake},
|
||||
{"target_earthquake_use", (byte *)target_earthquake_use},
|
||||
{"target_earthquake_think", (byte *)target_earthquake_think},
|
||||
|
@ -2111,71 +2170,12 @@
|
|||
{"trigger_teleport_use", (byte *)trigger_teleport_use},
|
||||
{"trigger_teleport_touch", (byte *)trigger_teleport_touch},
|
||||
{"SP_info_teleport_destination", (byte *)SP_info_teleport_destination},
|
||||
{"SP_target_locator", (byte *)SP_target_locator},
|
||||
{"target_locator_init", (byte *)target_locator_init},
|
||||
{"SP_target_failure", (byte *)SP_target_failure},
|
||||
{"use_target_failure", (byte *)use_target_failure},
|
||||
{"target_failure_fade_lights", (byte *)target_failure_fade_lights},
|
||||
{"target_failure_think", (byte *)target_failure_think},
|
||||
{"target_failure_player_die", (byte *)target_failure_player_die},
|
||||
{"target_failure_wipe", (byte *)target_failure_wipe},
|
||||
{"SP_target_animation", (byte *)SP_target_animation},
|
||||
{"target_animation_use", (byte *)target_animation_use},
|
||||
{"target_animate", (byte *)target_animate},
|
||||
{"SP_target_monitor", (byte *)SP_target_monitor},
|
||||
{"use_target_monitor", (byte *)use_target_monitor},
|
||||
{"target_monitor_move", (byte *)target_monitor_move},
|
||||
{"target_monitor_off", (byte *)target_monitor_off},
|
||||
{"SP_target_attractor", (byte *)SP_target_attractor},
|
||||
{"use_target_attractor", (byte *)use_target_attractor},
|
||||
{"target_attractor_think", (byte *)target_attractor_think},
|
||||
{"target_attractor_think_single", (byte *)target_attractor_think_single},
|
||||
{"SP_target_clone", (byte *)SP_target_clone},
|
||||
{"target_clone_use", (byte *)target_clone_use},
|
||||
{"clone", (byte *)clone},
|
||||
{"SP_target_rocks", (byte *)SP_target_rocks},
|
||||
{"target_rocks_use", (byte *)target_rocks_use},
|
||||
{"ThrowRock", (byte *)ThrowRock},
|
||||
{"SP_target_fade", (byte *)SP_target_fade},
|
||||
{"use_target_fade", (byte *)use_target_fade},
|
||||
{"SP_target_sky", (byte *)SP_target_sky},
|
||||
{"target_sky_use", (byte *)target_sky_use},
|
||||
{"SP_target_skill", (byte *)SP_target_skill},
|
||||
{"use_target_skill", (byte *)use_target_skill},
|
||||
{"SP_target_cd", (byte *)SP_target_cd},
|
||||
{"target_cd_use", (byte *)target_cd_use},
|
||||
{"SP_target_rotation", (byte *)SP_target_rotation},
|
||||
{"target_rotation_use", (byte *)target_rotation_use},
|
||||
{"SP_target_change", (byte *)SP_target_change},
|
||||
{"target_change_use", (byte *)target_change_use},
|
||||
{"SP_target_movewith", (byte *)SP_target_movewith},
|
||||
{"target_movewith_use", (byte *)target_movewith_use},
|
||||
{"SP_target_effect", (byte *)SP_target_effect},
|
||||
{"target_effect_think", (byte *)target_effect_think},
|
||||
{"target_effect_use", (byte *)target_effect_use},
|
||||
{"target_effect_widowbeam", (byte *)target_effect_widowbeam},
|
||||
{"target_effect_tunnel_sparks", (byte *)target_effect_tunnel_sparks},
|
||||
{"target_effect_explosion", (byte *)target_effect_explosion},
|
||||
{"target_effect_sparks", (byte *)target_effect_sparks},
|
||||
{"target_effect_lightning", (byte *)target_effect_lightning},
|
||||
{"target_effect_trail", (byte *)target_effect_trail},
|
||||
{"target_effect_splash", (byte *)target_effect_splash},
|
||||
{"target_effect_steam", (byte *)target_effect_steam},
|
||||
{"target_effect_at", (byte *)target_effect_at},
|
||||
{"SP_target_global_text", (byte *)SP_target_global_text},
|
||||
{"target_global_text_use", (byte *)target_global_text_use},
|
||||
{"SP_target_set_effect", (byte *)SP_target_set_effect},
|
||||
{"target_set_effect_use", (byte *)target_set_effect_use},
|
||||
{"SP_target_command", (byte *)SP_target_command},
|
||||
{"target_command_use", (byte *)target_command_use},
|
||||
{"SP_target_orb", (byte *)SP_target_orb},
|
||||
{"orb_think", (byte *)orb_think},
|
||||
{"SP_target_blacklight", (byte *)SP_target_blacklight},
|
||||
{"blacklight_think", (byte *)blacklight_think},
|
||||
{"SP_target_killplayers", (byte *)SP_target_killplayers},
|
||||
{"target_killplayers_use", (byte *)target_killplayers_use},
|
||||
{"SP_target_monsterbattle", (byte *)SP_target_monsterbattle},
|
||||
{"use_target_monsterbattle", (byte *)use_target_monsterbattle},
|
||||
{"SP_target_anger", (byte *)SP_target_anger},
|
||||
{"target_anger_use", (byte *)target_anger_use},
|
||||
{"SP_target_steam", (byte *)SP_target_steam},
|
||||
|
@ -2292,6 +2292,13 @@
|
|||
{"M_SetDeath", (byte *)M_SetDeath},
|
||||
{"FadeDieSink", (byte *)FadeDieSink},
|
||||
{"FadeSink", (byte *)FadeSink},
|
||||
{"SP_model_train_origin", (byte *)SP_model_train_origin},
|
||||
{"SP_model_train", (byte *)SP_model_train},
|
||||
{"model_train_animator", (byte *)model_train_animator},
|
||||
{"SP_model_spawn", (byte *)SP_model_spawn},
|
||||
{"model_die", (byte *)model_die},
|
||||
{"model_spawn_use", (byte *)model_spawn_use},
|
||||
{"modelspawn_think", (byte *)modelspawn_think},
|
||||
{"SP_misc_q1_fireball", (byte *)SP_misc_q1_fireball},
|
||||
{"q1_fireball_fly", (byte *)q1_fireball_fly},
|
||||
{"q1_fireball_touch", (byte *)q1_fireball_touch},
|
||||
|
@ -2314,6 +2321,14 @@
|
|||
{"bubble_touch", (byte *)bubble_touch},
|
||||
{"SP_misc_q1_zombie_crucified", (byte *)SP_misc_q1_zombie_crucified},
|
||||
{"misc_zombie_crucified_think", (byte *)misc_zombie_crucified_think},
|
||||
{"SP_monster_coco_monkey", (byte *)SP_monster_coco_monkey},
|
||||
{"monster_coco_monkey_think", (byte *)monster_coco_monkey_think},
|
||||
{"SP_light_flame2s", (byte *)SP_light_flame2s},
|
||||
{"SP_light_flame2", (byte *)SP_light_flame2},
|
||||
{"SP_light_flame1s", (byte *)SP_light_flame1s},
|
||||
{"SP_light_flame1", (byte *)SP_light_flame1},
|
||||
{"light_flame_spawn", (byte *)light_flame_spawn},
|
||||
{"light_flame_use", (byte *)light_flame_use},
|
||||
{"PatchDeadSoldier", (byte *)PatchDeadSoldier},
|
||||
{"SP_target_fountain", (byte *)SP_target_fountain},
|
||||
{"target_fountain_delayed_use", (byte *)target_fountain_delayed_use},
|
||||
|
@ -2332,14 +2347,6 @@
|
|||
{"SP_misc_light", (byte *)SP_misc_light},
|
||||
{"misc_light_use", (byte *)misc_light_use},
|
||||
{"misc_light_think", (byte *)misc_light_think},
|
||||
{"SP_monster_coco_monkey", (byte *)SP_monster_coco_monkey},
|
||||
{"monster_coco_monkey_think", (byte *)monster_coco_monkey_think},
|
||||
{"SP_light_flame2s", (byte *)SP_light_flame2s},
|
||||
{"SP_light_flame2", (byte *)SP_light_flame2},
|
||||
{"SP_light_flame1s", (byte *)SP_light_flame1s},
|
||||
{"SP_light_flame1", (byte *)SP_light_flame1},
|
||||
{"light_flame_spawn", (byte *)light_flame_spawn},
|
||||
{"light_flame_use", (byte *)light_flame_use},
|
||||
{"SP_misc_gekk_writhe", (byte *)SP_misc_gekk_writhe},
|
||||
{"misc_gekk_writhe_use", (byte *)misc_gekk_writhe_use},
|
||||
{"misc_gekk_writhe_think", (byte *)misc_gekk_writhe_think},
|
||||
|
@ -2488,13 +2495,6 @@
|
|||
{"VelocityForDamage", (byte *)VelocityForDamage},
|
||||
{"SP_func_areaportal", (byte *)SP_func_areaportal},
|
||||
{"Use_Areaportal", (byte *)Use_Areaportal},
|
||||
{"SP_model_train_origin", (byte *)SP_model_train_origin},
|
||||
{"SP_model_train", (byte *)SP_model_train},
|
||||
{"model_train_animator", (byte *)model_train_animator},
|
||||
{"SP_model_spawn", (byte *)SP_model_spawn},
|
||||
{"model_die", (byte *)model_die},
|
||||
{"model_spawn_use", (byte *)model_spawn_use},
|
||||
{"modelspawn_think", (byte *)modelspawn_think},
|
||||
{"Cmd_Trigger_f", (byte *)Cmd_Trigger_f},
|
||||
{"SP_light_flame", (byte *)SP_light_flame},
|
||||
{"bigflame_think", (byte *)bigflame_think},
|
||||
|
|
|
@ -176,563 +176,3 @@ void Cmd_Trigger_f (edict_t *ent)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================
|
||||
Spawning a user defined model
|
||||
|
||||
=============================
|
||||
*/
|
||||
|
||||
//ed - added all these spawnflags and stuff
|
||||
|
||||
/*QUAKED model_spawn (1 0 0) (-8 -8 -8) (8 8 8) x TOGGLE NOT_IR PLAYER NO_MODEL ANIM_ONCE
|
||||
Spawns a user defined model, you can specify whether its solid, if so how big the box is, and apply nearly
|
||||
any effect to the entity.
|
||||
|
||||
Spawnflags:
|
||||
TOGGLE Start active, when triggered become inactive
|
||||
NOT_IR The model won't be tinted red when the player has IR goggles on
|
||||
PLAYER Set this if you want to use a player model
|
||||
NO_MODEL Don't use a model. Usefull for placing particle effects and dynamic lights on their own
|
||||
ANIM__ONCE Only play the animation once
|
||||
-----------------------
|
||||
Key/Value pairs:
|
||||
"style" Specifies the animation type to use.
|
||||
0: None (unless startframe and framenumbers are used)
|
||||
1: ANIM01 - cycle between frames 0 and 1 at 2 hz
|
||||
2: ANIM23 - cycle between frames 2 and 3 at 2 hz
|
||||
3: ANIM_ALL - cycle through all frames at 2 hz
|
||||
4: ANIM_ALLFAST - cycle through all frames at 10 hz
|
||||
|
||||
Note: The animation flags override startframe and framenumbers settings you may have enterered. ANIM_ALL and ANIM_ALLFAST don't do what you might think - rather than setting a framerate, these apparently cause the model to cycle through its ENTIRE sequence of animations in 0.5 or 0.1 seconds... which for monster and player models is of course not possible. Looks exceptionally goofy.
|
||||
|
||||
"usermodel" The model to load (models/ is already coded)
|
||||
"startframe" The starting frame : default 0
|
||||
"framenumbers" The number of frames you want to display after startframe
|
||||
"skinnum" The skin number to use, default 0
|
||||
"health" If non-zero and solidstate is 3 or 4 (solid), the entity will be shootable. When destroyed, it blows up with a no-damage explosion.
|
||||
"solidstate"
|
||||
1 - not solid at all. These models do not obey any sort of physics. If you place them up in the air or embedded in a wall they will stay there and be perfectly happy about it.
|
||||
2 - solid. These models will "droptofloor" when spawned. If the health value is set they may be damaged.
|
||||
3 - solid. Same as above but not affected by gravity. Model will remain in the same location.
|
||||
4 - not solid but affected by gravity. Model will "droptofloor" when spawned.
|
||||
NOTE : if you want the model to be solid then you must enter vector values into the following fields :
|
||||
"bleft" = the point that is at the bottom left of the models bounding box in a model editor
|
||||
"tright" = the point that is at the top left of the models bounding box in a model editor
|
||||
|
||||
"effects"
|
||||
1: ROTATE Rotate like a weapon
|
||||
2: GIB
|
||||
8: BLASTER Yellowish orange glow plus particles
|
||||
16: ROCKET Rocket trail
|
||||
32: GRENADE Grenade trail
|
||||
64: HYPERBLASTER BLASTER w/o the particles
|
||||
128: BFG Big green ball
|
||||
256: COLOR_SHELL
|
||||
512: POWERSCREEN Green power shield
|
||||
16384: FLIES Ewwww
|
||||
32768: QUAD Blue shell
|
||||
65536: PENT Red shell
|
||||
131072: TELEPORTER Teleporter particles
|
||||
262144: FLAG1 Red glow
|
||||
524288: FLAG2 Blue glow
|
||||
1048576: IONRIPPER
|
||||
2097152: GREENGIB
|
||||
4194304: BLUE_HB Blue hyperblaster glow
|
||||
8388608: SPINNING_LIGHTS Red spinning lights
|
||||
16777216: PLASMA
|
||||
33554432: TRAP
|
||||
67108864: TRACKER
|
||||
134217728: DOUBLE Yellow shell
|
||||
268435456: SPHERETRANS Transparent
|
||||
536870912: TAGTRAIL
|
||||
1073741824: HALF_DAMAGE
|
||||
2147483648: TRACKER_TRAIL
|
||||
|
||||
"renderfx"
|
||||
1: MINLIGHT Never completely dark
|
||||
2: VIEWERMODEL
|
||||
4: WEAPONMODEL
|
||||
8: FULLBRIGHT
|
||||
16: DEPTHHACK
|
||||
32: TRANSLUCENT Transparent
|
||||
64: FRAMELERP
|
||||
128: BEAM
|
||||
512: GLOW Pulsating glow of normal Q2 pickup items
|
||||
1024: SHELL_RED
|
||||
2048: SHELL_GREEN
|
||||
4096: SHELL_BLUE
|
||||
32768: IR_VISIBLE
|
||||
65536: SHELL_DOUBLE
|
||||
131072: SHELL_HALF_DAMAGE White shell
|
||||
262144: USE_DISGUISE
|
||||
"movewith" Targetname of the entity to move with
|
||||
*/
|
||||
|
||||
#define TOGGLE 2
|
||||
#define NOT_IR 4
|
||||
#define PLAYER_MODEL 8
|
||||
#define NO_MODEL 16
|
||||
#define ANIM_ONCE 32
|
||||
|
||||
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator);
|
||||
|
||||
void modelspawn_think (edict_t *self)
|
||||
{
|
||||
self->s.frame++;
|
||||
if (self->s.frame >= self->framenumbers)
|
||||
{
|
||||
self->s.frame = self->startframe;
|
||||
if (self->spawnflags & ANIM_ONCE)
|
||||
{
|
||||
model_spawn_use(self,world,world);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
gi.linkentity(self);
|
||||
if (!strcmp(self->classname, "model_train"))
|
||||
train_move_children (self);
|
||||
}
|
||||
|
||||
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->delay) // we started off
|
||||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
self->delay = 0;
|
||||
if (self->framenumbers > 1)
|
||||
{
|
||||
self->think = modelspawn_think;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.sound = self->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
self->s.attenuation = self->attenuation;
|
||||
#endif
|
||||
}
|
||||
else // we started active
|
||||
{
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->delay = 1;
|
||||
self->use = model_spawn_use;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
self->s.sound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
if (self->deathtarget)
|
||||
{
|
||||
self->target = self->deathtarget;
|
||||
G_UseTargets (self, attacker);
|
||||
}
|
||||
train_kill_children(self);
|
||||
BecomeExplosion1(self);
|
||||
}
|
||||
|
||||
#define ANIM_MASK (EF_ANIM01|EF_ANIM23|EF_ANIM_ALL|EF_ANIM_ALLFAST)
|
||||
|
||||
void SP_model_spawn (edict_t *ent)
|
||||
{
|
||||
char modelname[256];
|
||||
|
||||
// paranoia check
|
||||
if ((!ent->usermodel) && (!ent->spawnflags & NO_MODEL) && !(ent->spawnflags & PLAYER_MODEL))
|
||||
{
|
||||
gi.dprintf("%s without a model and without NO_MODEL spawnflag at %s\n", ent->classname, vtos(ent->s.origin));
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_MODEL_SPAWN;
|
||||
|
||||
switch (ent->solidstate)
|
||||
{
|
||||
case 1 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 2 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_TOSS; break;
|
||||
case 3 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 4 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_TOSS; break;
|
||||
default: ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
}
|
||||
|
||||
if (ent->solid != SOLID_NOT )
|
||||
{
|
||||
if (ent->health > 0)
|
||||
{
|
||||
ent->die = model_die;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ent->style)
|
||||
{
|
||||
case 1 : ent->s.effects |= EF_ANIM01; break;
|
||||
case 2 : ent->s.effects |= EF_ANIM23; break;
|
||||
case 3 : ent->s.effects |= EF_ANIM_ALL; break;
|
||||
case 4 : ent->s.effects |= EF_ANIM_ALLFAST; break;
|
||||
}
|
||||
|
||||
// DWH: Rather than use one value (renderfx) we use the
|
||||
// actual values for effects and renderfx. All may
|
||||
// be combined.
|
||||
ent->s.effects |= ent->effects;
|
||||
ent->s.renderfx |= ent->renderfx;
|
||||
|
||||
if (ent->startframe < 0)
|
||||
ent->startframe = 0;
|
||||
if (!ent->framenumbers)
|
||||
ent->framenumbers = 1;
|
||||
// Change framenumbers to last frame to play
|
||||
ent->framenumbers += ent->startframe;
|
||||
|
||||
if (!VectorLength(ent->bleft) && ent->solid == SOLID_BBOX)
|
||||
{
|
||||
gi.dprintf("%s solid with no bleft vector at %s, using default (-16,-16,-16)\n", ent->classname, vtos(ent->s.origin));
|
||||
VectorSet(ent->bleft, -16, -16, -16);
|
||||
}
|
||||
VectorCopy (ent->bleft, ent->mins);
|
||||
|
||||
if (!VectorLength(ent->tright) && ent->solid == SOLID_BBOX)
|
||||
{
|
||||
gi.dprintf("%s solid with no tright vector at %, using default (16,16,16)\n", ent->classname, vtos(ent->s.origin));
|
||||
VectorSet(ent->tright, 16, 16, 16);
|
||||
}
|
||||
VectorCopy (ent->tright, ent->maxs);
|
||||
|
||||
if (ent->solid != SOLID_NOT)
|
||||
ent->clipmask = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER;
|
||||
|
||||
if (ent->spawnflags & NO_MODEL)
|
||||
{ // For rendering effects to work, we MUST use a model
|
||||
ent->s.modelindex = gi.modelindex ("sprites/point.sp2");
|
||||
ent->movetype = MOVETYPE_NOCLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->spawnflags & PLAYER_MODEL)
|
||||
{
|
||||
if (!ent->usermodel || !strlen(ent->usermodel))
|
||||
ent->s.modelindex = MAX_MODELS-1; //was 255
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,"tris.md2"))
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s/tris.md2", ent->usermodel);
|
||||
ent->s.modelindex = gi.modelindex(modelname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,".sp2")) {
|
||||
// Knightmare- check for "sprites/" already in path
|
||||
if ( !strncmp(ent->usermodel, "sprites/", 8) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "sprites/%s", ent->usermodel);
|
||||
}
|
||||
else {
|
||||
// Knightmare- check for "models/" already in path
|
||||
if ( !strncmp(ent->usermodel, "models/", 7) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "models/%s", ent->usermodel);
|
||||
}
|
||||
ent->s.modelindex = gi.modelindex (modelname);
|
||||
}
|
||||
if (ent->startframe < 0)
|
||||
{
|
||||
gi.dprintf("model_spawn with startframe less than 0 at %s\n", vtos(ent->s.origin));
|
||||
ent->startframe = 0;
|
||||
}
|
||||
ent->s.frame = ent->startframe;
|
||||
}
|
||||
|
||||
if (st.noise)
|
||||
ent->noise_index = gi.soundindex (st.noise);
|
||||
//ent->s.sound = ent->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
ent->s.attenuation = ent->attenuation;
|
||||
#endif
|
||||
|
||||
if (ent->skinnum) // Knightmare- selectable skin
|
||||
ent->s.skinnum = ent->skinnum;
|
||||
|
||||
if (ent->spawnflags & ANIM_ONCE)
|
||||
ent->spawnflags |= TOGGLE;
|
||||
|
||||
if (ent->spawnflags & TOGGLE)
|
||||
{ // Knightmare- allow starting off (but not for model_train)
|
||||
if ( (strcmp(ent->classname, "model_train") != 0) && (ent->delay != 0) ) {
|
||||
ent->delay = 1;
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
}
|
||||
else {
|
||||
ent->delay = 0;
|
||||
}
|
||||
ent->use = model_spawn_use;
|
||||
}
|
||||
|
||||
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
|
||||
{
|
||||
ent->think = modelspawn_think;
|
||||
ent->nextthink = level.time + 2*FRAMETIME;
|
||||
}
|
||||
|
||||
if (ent->spawnflags & NOT_IR)
|
||||
ent->s.renderfx &= ~RF_IR_VISIBLE;
|
||||
else
|
||||
ent->s.renderfx |= RF_IR_VISIBLE;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
/*QUAKED model_train (1 0 0) (-8 -8 -8) (8 8 8) START_ON TOGGLE BLOCK_STOPS PLAYER NO_MODEL ROTATE ROT_CONST SMOOTH
|
||||
A moving model. The "team" key allows you to team train entities together.
|
||||
|
||||
Spawnflags:
|
||||
PLAYER Set this if you want to use a player model
|
||||
NO_MODEL Don't use a model. Usefull for placing particle effects and dynamic lights on their own
|
||||
SPLINE: If set, the func_train will follow a spline curve between path_corners. What this means is you can create near perfectly smooth curvilinear paths with a handful of path_corners. The train will constantly turn to face the direction it is moving (unless yaw_speed and pitch_speed are negative values). For a couple of examples, see the rottrain and lcraft example maps (available on the downloads page.) The shape of the spline curve is controlled by the location and pitch and yaw angles of the train's path_corners. Train roll angle will vary linearly between path_corner roll angle values (the third component of the angles vector).
|
||||
-----------------------
|
||||
Key/Value pairs:
|
||||
"style" Specifies the animation type to use.
|
||||
0: None (unless startframe and framenumbers are used)
|
||||
1: ANIM01 - cycle between frames 0 and 1 at 2 hz
|
||||
2: ANIM23 - cycle between frames 2 and 3 at 2 hz
|
||||
3: ANIM_ALL - cycle through all frames at 2 hz
|
||||
4: ANIM_ALLFAST - cycle through all frames at 10 hz
|
||||
|
||||
Note: The animation flags override startframe and framenumbers settings you may have enterered. ANIM_ALL and ANIM_ALLFAST don't do what you might think - rather than setting a framerate, these apparently cause the model to cycle through its ENTIRE sequence of animations in 0.5 or 0.1 seconds... which for monster and player models is of course not possible. Looks exceptionally goofy.
|
||||
|
||||
"usermodel" The model to load (models/ is already coded)
|
||||
"startframe" The starting frame : default 0
|
||||
"framenumbers" The number of frames you want to display after startframe
|
||||
"skinnum" The skin number to use, default 0
|
||||
"health" If non-zero and solidstate is 3 or 4 (solid), the entity will be shootable. When destroyed, it blows up with a no-damage explosion.
|
||||
"target" first path_corner"
|
||||
"team" func_train or func_rotating
|
||||
"solidstate"
|
||||
1 = Not solid (default)
|
||||
2 = Bounding box
|
||||
NOTE : if you want the model to be solid then you must enter vector values into the following fields :
|
||||
"bleft" = the point that is at the bottom left of the models bounding box in a model editor
|
||||
"tright" = the point that is at the top left of the models bounding box in a model editor
|
||||
|
||||
"speed" How fast the model should move
|
||||
"accel" Acceleration
|
||||
"decel" Deceleration
|
||||
|
||||
"pitch_speed" (Nose up & Down) in degrees per second (defualt 20)
|
||||
"yaw_speed" (Side-to-side "wiggle") in degrees per second (default 20)
|
||||
"roll_speed" (Banking) in degrees per second toward the next path corner's set roll
|
||||
"dmg" default 2, damage to inflict when blocked
|
||||
"noise" Sound model makes while moving(path/file.wav)
|
||||
"effects"
|
||||
1: ROTATE Rotate like a weapon
|
||||
2: GIB
|
||||
8: BLASTER Yellowish orange glow plus particles
|
||||
16: ROCKET Rocket trail
|
||||
32: GRENADE Grenade trail
|
||||
64: HYPERBLASTER BLASTER w/o the particles
|
||||
128: BFG Big green ball
|
||||
256: COLOR_SHELL
|
||||
512: POWERSCREEN Green power shield
|
||||
16384: FLIES Ewwww
|
||||
32768: QUAD Blue shell
|
||||
65536: PENT Red shell
|
||||
131072: TELEPORTER Teleporter particles
|
||||
262144: FLAG1 Red glow
|
||||
524288: FLAG2 Blue glow
|
||||
1048576: IONRIPPER
|
||||
2097152: GREENGIB
|
||||
4194304: BLUE_HB Blue hyperblaster glow
|
||||
8388608: SPINNING_LIGHTS Red spinning lights
|
||||
16777216: PLASMA
|
||||
33554432: TRAP
|
||||
67108864: TRACKER
|
||||
134217728: DOUBLE Yellow shell
|
||||
268435456: SPHERETRANS Transparent
|
||||
536870912: TAGTRAIL
|
||||
1073741824: HALF_DAMAGE
|
||||
2147483648: TRACKER_TRAIL
|
||||
|
||||
"renderfx"
|
||||
1: MINLIGHT Never completely dark
|
||||
2: VIEWERMODEL
|
||||
4: WEAPONMODEL
|
||||
8: FULLBRIGHT
|
||||
16: DEPTHHACK
|
||||
32: TRANSLUCENT Transparent
|
||||
64: FRAMELERP
|
||||
128: BEAM
|
||||
512: GLOW Pulsating glow of normal Q2 pickup items
|
||||
1024: SHELL_RED
|
||||
2048: SHELL_GREEN
|
||||
4096: SHELL_BLUE
|
||||
32768: IR_VISIBLE
|
||||
65536: SHELL_DOUBLE
|
||||
131072: SHELL_HALF_DAMAGE White shell
|
||||
262144: USE_DISGUISE
|
||||
|
||||
To have other entities move with the model train, set the door pieces' movewith values to the same as the train's targetname and they will move in
|
||||
unison, and also still be able to move relative to the train themselves, and can be attached and detached using target_movewith.
|
||||
NOTE: All the pieces must be created after the model train entity, otherwise they will move ahead of it.
|
||||
*/
|
||||
|
||||
#define MODEL_TRAIN_START_ON 1
|
||||
#define MODEL_TRAIN_TOGGLE 2
|
||||
#define MODEL_TRAIN_BLOCK_STOPS 4
|
||||
#define MODEL_TRAIN_ROTATE 32
|
||||
#define MODEL_TRAIN_ROT_CONST 64
|
||||
#define TRAIN_ANIM 32
|
||||
#define TRAIN_ANIM_FAST 64
|
||||
#define MODEL_TRAIN_SMOOTH 128
|
||||
|
||||
#define TRAIN_ROTATE 8
|
||||
#define TRAIN_ROT_CONST 16
|
||||
#define TRAIN_SPLINE 8192
|
||||
|
||||
void model_train_animator(edict_t *animator)
|
||||
{
|
||||
edict_t *train;
|
||||
|
||||
train = animator->owner;
|
||||
if (!train || !train->inuse)
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
if (Q_stricmp(train->classname, "model_train"))
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
if (VectorLength(train->velocity) == 0)
|
||||
return;
|
||||
train->s.frame++;
|
||||
if (train->s.frame >= train->framenumbers)
|
||||
train->s.frame = train->startframe;
|
||||
gi.linkentity(train);
|
||||
}
|
||||
|
||||
void SP_model_train (edict_t *self)
|
||||
{
|
||||
SP_model_spawn (self);
|
||||
|
||||
self->class_id = ENTITY_MODEL_TRAIN;
|
||||
|
||||
// Reset s.sound, which SP_model_spawn may have turned on
|
||||
self->moveinfo.sound_middle = self->s.sound;
|
||||
self->s.sound = 0;
|
||||
|
||||
if (!self->inuse) return;
|
||||
|
||||
// Reset some things from SP_model_spawn
|
||||
self->delay = 0;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
|
||||
self->s.sound = self->noise_index;
|
||||
|
||||
if (self->health)
|
||||
{
|
||||
self->die = model_die;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
if (self->framenumbers > self->startframe+1)
|
||||
{
|
||||
edict_t *animator;
|
||||
animator = G_Spawn();
|
||||
animator->owner = self;
|
||||
animator->think = model_train_animator;
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.frame = self->startframe;
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
|
||||
// Really gross stuff here... translate model_spawn spawnflags
|
||||
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
|
||||
// already been checked in SP_model_spawn and are never re-used,
|
||||
// so it's OK to overwrite those.
|
||||
if (self->spawnflags & MODEL_TRAIN_ROTATE)
|
||||
{
|
||||
self->spawnflags &= ~MODEL_TRAIN_ROTATE;
|
||||
self->spawnflags |= TRAIN_ROTATE;
|
||||
|
||||
}
|
||||
if (self->spawnflags & MODEL_TRAIN_ROT_CONST)
|
||||
{
|
||||
self->spawnflags &= ~MODEL_TRAIN_ROT_CONST;
|
||||
self->spawnflags |= TRAIN_ROT_CONST;
|
||||
}
|
||||
//Knightmare- change both rotate flags to spline flag
|
||||
if ((self->spawnflags & TRAIN_ROTATE) && (self->spawnflags &TRAIN_ROT_CONST))
|
||||
{
|
||||
self->spawnflags &= ~TRAIN_ROTATE;
|
||||
self->spawnflags &= ~TRAIN_ROT_CONST;
|
||||
self->spawnflags |= TRAIN_SPLINE;
|
||||
}
|
||||
if (self->style == 3)
|
||||
self->spawnflags |= TRAIN_ANIM; // 32
|
||||
if (self->style == 4)
|
||||
self->spawnflags |= TRAIN_ANIM_FAST; // 64
|
||||
|
||||
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
|
||||
// Move_Final rather than slowing down (if necessary) for one
|
||||
// frame.
|
||||
if (self->spawnflags & MODEL_TRAIN_SMOOTH)
|
||||
self->smooth_movement = 1;
|
||||
else
|
||||
self->smooth_movement = 0;
|
||||
|
||||
self->blocked = train_blocked;
|
||||
if (self->spawnflags & MODEL_TRAIN_BLOCK_STOPS)
|
||||
self->dmg = 0;
|
||||
else
|
||||
{
|
||||
if (!self->dmg)
|
||||
self->dmg = 100;
|
||||
}
|
||||
|
||||
if (!self->speed)
|
||||
self->speed = 100;
|
||||
|
||||
// Mappack
|
||||
if (!self->accel)
|
||||
self->moveinfo.accel = self->speed;
|
||||
else
|
||||
self->moveinfo.accel = self->accel;
|
||||
if (!self->decel)
|
||||
self->moveinfo.decel = self->speed;
|
||||
else
|
||||
self->moveinfo.decel = self->decel;
|
||||
self->moveinfo.speed = self->speed;
|
||||
|
||||
self->use = train_use;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
if (self->target)
|
||||
{
|
||||
// start trains on the second frame, to make sure their targets have had
|
||||
// a chance to spawn
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = func_train_find;
|
||||
}
|
||||
else
|
||||
gi.dprintf ("model_train without a target at %s\n", vtos(self->s.origin));
|
||||
|
||||
}
|
||||
|
||||
void SP_model_train_origin (edict_t *self)
|
||||
{
|
||||
self->spawnflags |= TRAIN_ORIGIN;
|
||||
SP_model_train (self);
|
||||
}
|
||||
|
|
|
@ -4668,964 +4668,3 @@ void SP_misc_gekk_writhe (edict_t *self)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Coconut Monkey 3 Flame entities
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
#define FLAME_START_OFF 1
|
||||
void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||||
|
||||
/*static*/ void light_flame_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->solid == SOLID_NOT)
|
||||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
gi.configstring (CS_LIGHTS+self->style, "m");
|
||||
self->spawnflags &= ~FLAME_START_OFF;
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
gi.configstring (CS_LIGHTS+self->style, "a");
|
||||
self->spawnflags |= FLAME_START_OFF;
|
||||
self->solid = SOLID_NOT;
|
||||
}
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
||||
void light_flame_spawn (edict_t *self)
|
||||
{
|
||||
self->s.effects = EF_ANIM_ALLFAST;
|
||||
self->s.renderfx |= RF_NOSHADOW;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->touch = hurt_touch;
|
||||
if (!self->dmg)
|
||||
self->dmg = 5;
|
||||
|
||||
self->noise_index = gi.soundindex ("world/electro.wav");
|
||||
|
||||
if (self->style >= 32)
|
||||
{
|
||||
if (self->spawnflags & FLAME_START_OFF)
|
||||
{
|
||||
gi.configstring (CS_LIGHTS+self->style, "a");
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->solid = SOLID_NOT;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.configstring (CS_LIGHTS+self->style, "m");
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
}
|
||||
self->use = light_flame_use;
|
||||
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
||||
void SP_light_flame1 (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame1.sp2");
|
||||
VectorSet(self->mins,-48,-48,-32);
|
||||
VectorSet(self->maxs, 48, 48, 64);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame1s (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame1s.sp2");
|
||||
VectorSet(self->mins,-16,-16,-16);
|
||||
VectorSet(self->maxs, 16, 16, 32);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame2 (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame2.sp2");
|
||||
VectorSet(self->mins,-48,-48,-32);
|
||||
VectorSet(self->maxs, 48, 48, 64);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame2s (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame2s.sp2");
|
||||
VectorSet(self->mins,-16,-16,-16);
|
||||
VectorSet(self->maxs, 16, 16, 32);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Coconut Monkey
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
void monster_coco_monkey_think (edict_t *self)
|
||||
{
|
||||
if (++self->s.frame > 19)
|
||||
self->s.frame = 0;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
void SP_monster_coco_monkey (edict_t *self)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
G_FreeEdict (self);
|
||||
return;
|
||||
}
|
||||
self->movetype = MOVETYPE_TOSS;
|
||||
self->solid = SOLID_BBOX;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("models/monsters/coco/tris.md2");
|
||||
self->s.renderfx |= RF_IR_VISIBLE;
|
||||
VectorSet(self->mins,-16,-16,-40);
|
||||
VectorSet(self->maxs, 16, 16, 48);
|
||||
self->s.origin[2] += 10;
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = monster_coco_monkey_think;
|
||||
self->common_name = "Coconut Monkey";
|
||||
|
||||
self->class_id = ENTITY_MONSTER_COCO_MONKEY;
|
||||
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Lazarus new entities
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
void misc_light_think (edict_t *self)
|
||||
{
|
||||
if (self->spawnflags & START_OFF)
|
||||
return;
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_FLASHLIGHT);
|
||||
gi.WritePosition (self->s.origin);
|
||||
gi.WriteShort (self - g_edicts);
|
||||
gi.multicast (self->s.origin, MULTICAST_PVS);
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void misc_light_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->spawnflags & START_OFF)
|
||||
{
|
||||
self->spawnflags &= ~START_OFF;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
else
|
||||
self->spawnflags |= START_OFF;
|
||||
}
|
||||
|
||||
void SP_misc_light (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_MISC_LIGHT;
|
||||
|
||||
self->use = misc_light_use;
|
||||
if (self->movewith)
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
else
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->think = misc_light_think;
|
||||
if (!(self->spawnflags & START_OFF))
|
||||
self->nextthink = level.time + 2*FRAMETIME;
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
TARGET_PRECIPITATION
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
#define SF_WEATHER_STARTON 1
|
||||
#define SF_WEATHER_SPLASH 2
|
||||
#define SF_WEATHER_GRAVITY_BOUNCE 4
|
||||
#define SF_WEATHER_FIRE_ONCE 8
|
||||
#define SF_WEATHER_START_FADE 16
|
||||
#define STYLE_WEATHER_RAIN 0
|
||||
#define STYLE_WEATHER_BIGRAIN 1
|
||||
#define STYLE_WEATHER_SNOW 2
|
||||
#define STYLE_WEATHER_LEAF 3
|
||||
#define STYLE_WEATHER_USER 4
|
||||
|
||||
void drop_add_to_chain(edict_t *drop)
|
||||
{
|
||||
edict_t *owner = drop->owner;
|
||||
edict_t *parent;
|
||||
|
||||
if (!owner || !owner->inuse || !(owner->spawnflags & SF_WEATHER_STARTON))
|
||||
{
|
||||
G_FreeEdict(drop);
|
||||
return;
|
||||
}
|
||||
parent = owner;
|
||||
while (parent->child)
|
||||
parent = parent->child;
|
||||
parent->child = drop;
|
||||
drop->child = NULL;
|
||||
drop->svflags |= SVF_NOCLIENT;
|
||||
drop->s.effects &= ~EF_SPHERETRANS;
|
||||
drop->s.renderfx &= ~RF_TRANSLUCENT;
|
||||
VectorClear(drop->velocity);
|
||||
VectorClear(drop->avelocity);
|
||||
gi.linkentity(drop);
|
||||
}
|
||||
|
||||
void drop_splash(edict_t *drop)
|
||||
{
|
||||
vec3_t up = {0,0,1};
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_LASER_SPARKS);
|
||||
gi.WriteByte (drop->owner->mass2);
|
||||
gi.WritePosition (drop->s.origin);
|
||||
gi.WriteDir (up);
|
||||
gi.WriteByte (drop->owner->sounds);
|
||||
gi.multicast (drop->s.origin, MULTICAST_PVS);
|
||||
drop_add_to_chain(drop);
|
||||
}
|
||||
|
||||
void leaf_fade2(edict_t *ent)
|
||||
{
|
||||
ent->count++;
|
||||
if (ent->count == 1)
|
||||
{
|
||||
ent->s.effects |= EF_SPHERETRANS;
|
||||
ent->nextthink=level.time+0.5;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
else
|
||||
drop_add_to_chain(ent);
|
||||
}
|
||||
|
||||
void leaf_fade (edict_t *ent)
|
||||
{
|
||||
ent->s.renderfx = RF_TRANSLUCENT;
|
||||
ent->think = leaf_fade2;
|
||||
ent->nextthink = level.time+0.5;
|
||||
ent->count = 0;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
void drop_touch(edict_t *drop, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (drop->owner->spawnflags & SF_WEATHER_START_FADE)
|
||||
return;
|
||||
else if (drop->fadeout > 0)
|
||||
{
|
||||
if ( (drop->spawnflags & SF_WEATHER_GRAVITY_BOUNCE) && (drop->owner->gravity > 0))
|
||||
{
|
||||
drop->movetype = MOVETYPE_DEBRIS;
|
||||
drop->gravity = drop->owner->gravity;
|
||||
}
|
||||
drop->think = leaf_fade;
|
||||
drop->nextthink = level.time + drop->fadeout;
|
||||
}
|
||||
else if (drop->spawnflags & SF_WEATHER_SPLASH)
|
||||
drop_splash(drop);
|
||||
else
|
||||
drop_add_to_chain(drop);
|
||||
}
|
||||
|
||||
void spawn_precipitation(edict_t *self, vec3_t org, vec3_t dir, float speed)
|
||||
{
|
||||
edict_t *drop;
|
||||
|
||||
if (self->child)
|
||||
{
|
||||
// Then we already have a currently unused, invisible drop available
|
||||
drop = self->child;
|
||||
self->child = drop->child;
|
||||
drop->child = NULL;
|
||||
drop->svflags &= ~SVF_NOCLIENT;
|
||||
drop->groundentity = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
drop = G_Spawn();
|
||||
if (self->style == STYLE_WEATHER_BIGRAIN)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/drop/heavy.md2");
|
||||
else if (self->style == STYLE_WEATHER_SNOW)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/snow/tris.md2");
|
||||
else if (self->style == STYLE_WEATHER_LEAF)
|
||||
{
|
||||
float r=random();
|
||||
if (r < 0.33)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf1/tris.md2");
|
||||
else if (r < 0.66)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf2/tris.md2");
|
||||
else
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf3/tris.md2");
|
||||
VectorSet(drop->mins,-1,-1,-1);
|
||||
VectorSet(drop->maxs, 1, 1, 1);
|
||||
}
|
||||
else if (self->style == STYLE_WEATHER_USER)
|
||||
drop->s.modelindex = gi.modelindex(self->usermodel);
|
||||
else
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/drop/tris.md2");
|
||||
drop->classname = "rain drop";
|
||||
}
|
||||
if (self->gravity > 0.0f || self->attenuation > 0 )
|
||||
drop->movetype = MOVETYPE_DEBRIS;
|
||||
else
|
||||
drop->movetype = MOVETYPE_RAIN;
|
||||
|
||||
drop->touch = drop_touch;
|
||||
if (self->style == STYLE_WEATHER_USER)
|
||||
drop->clipmask = MASK_MONSTERSOLID;
|
||||
else if ((self->fadeout > 0) && (self->gravity == 0.0f))
|
||||
drop->clipmask = MASK_SOLID | CONTENTS_WATER;
|
||||
else
|
||||
drop->clipmask = MASK_MONSTERSOLID | CONTENTS_WATER;
|
||||
drop->solid = SOLID_BBOX;
|
||||
drop->svflags = SVF_DEADMONSTER;
|
||||
VectorSet(drop->mins, -1, -1, -1);
|
||||
VectorSet(drop->maxs, 1, 1, 1);
|
||||
|
||||
if (self->spawnflags & SF_WEATHER_GRAVITY_BOUNCE)
|
||||
drop->gravity = self->gravity;
|
||||
else
|
||||
drop->gravity = 0.0f;
|
||||
drop->attenuation = self->attenuation;
|
||||
drop->mass = self->mass;
|
||||
drop->spawnflags = self->spawnflags;
|
||||
drop->fadeout = self->fadeout;
|
||||
drop->owner = self;
|
||||
|
||||
VectorCopy (org, drop->s.origin);
|
||||
vectoangles(dir, drop->s.angles);
|
||||
drop->s.angles[PITCH] -= 90;
|
||||
VectorScale (dir, speed, drop->velocity);
|
||||
if (self->style == STYLE_WEATHER_LEAF)
|
||||
{
|
||||
drop->avelocity[PITCH] = crandom() * 360;
|
||||
drop->avelocity[YAW] = crandom() * 360;
|
||||
drop->avelocity[ROLL] = crandom() * 360;
|
||||
}
|
||||
else if (self->style == STYLE_WEATHER_USER)
|
||||
{
|
||||
drop->s.effects = self->effects;
|
||||
drop->s.renderfx = self->renderfx;
|
||||
drop->avelocity[PITCH] = crandom() * self->pitch_speed;
|
||||
drop->avelocity[YAW] = crandom() * self->yaw_speed;
|
||||
drop->avelocity[ROLL] = crandom() * self->roll_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
drop->s.effects |= EF_SPHERETRANS;
|
||||
drop->avelocity[YAW] = self->yaw_speed;
|
||||
}
|
||||
if (self->spawnflags & SF_WEATHER_START_FADE)
|
||||
{
|
||||
drop->think = leaf_fade;
|
||||
drop->nextthink = level.time + self->fadeout;
|
||||
}
|
||||
gi.linkentity(drop);
|
||||
}
|
||||
|
||||
void target_precipitation_think (edict_t *self)
|
||||
{
|
||||
vec3_t center;
|
||||
vec3_t org;
|
||||
int r, i;
|
||||
float u, v, z;
|
||||
float temp;
|
||||
qboolean can_see_me;
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
// Don't start raining until player is in the game. The following
|
||||
// takes care of both initial map load conditions and restored saved games.
|
||||
// This is a gross abuse of groundentity_linkcount. Sue me.
|
||||
if (g_edicts[1].linkcount == self->groundentity_linkcount)
|
||||
return;
|
||||
else
|
||||
self->groundentity_linkcount = g_edicts[1].linkcount;
|
||||
// Don't spawn drops if player can't see us. This SEEMS like an obvious
|
||||
// thing to do, but can cause visual problems if mapper isn't careful.
|
||||
// For example, placing target_precipitation where it isn't in the PVS
|
||||
// of the player's current position, but the result (rain) IS in the
|
||||
// PVS. In any case, this step is necessary to prevent overflows when
|
||||
// player suddenly encounters rain.
|
||||
can_see_me = false;
|
||||
for (i=1; i<=game.maxclients && !can_see_me; i++)
|
||||
{
|
||||
if (!g_edicts[i].inuse) continue;
|
||||
if (gi.inPVS(g_edicts[i].s.origin,self->s.origin))
|
||||
can_see_me = true;
|
||||
}
|
||||
if (!can_see_me) return;
|
||||
|
||||
// Count is models/second. We accumulate a probability of a model
|
||||
// falling this frame in ->density. Yeah its a misnomer but density isn't
|
||||
// used for anything else so it works fine.
|
||||
|
||||
temp = 0.1*(self->density + crandom()*self->random);
|
||||
r = (int)(temp);
|
||||
if (r > 0)
|
||||
self->density = self->count + (temp-(float)r)*10;
|
||||
else
|
||||
self->density += (temp*10);
|
||||
if (r < 1) return;
|
||||
|
||||
VectorAdd(self->bleft,self->tright,center);
|
||||
VectorMA(self->s.origin,0.5,center,center);
|
||||
|
||||
for (i=0; i<r; i++)
|
||||
{
|
||||
u = crandom() * (self->tright[0] - self->bleft[0])/2;
|
||||
v = crandom() * (self->tright[1] - self->bleft[1])/2;
|
||||
z = crandom() * (self->tright[2] - self->bleft[2])/2;
|
||||
|
||||
VectorCopy(center, org);
|
||||
|
||||
org[0] += u;
|
||||
org[1] += v;
|
||||
org[2] += z;
|
||||
|
||||
spawn_precipitation(self, org, self->movedir, self->speed);
|
||||
}
|
||||
}
|
||||
|
||||
void target_precipitation_use (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
// already on; turn it off
|
||||
ent->nextthink = 0;
|
||||
ent->spawnflags &= ~SF_WEATHER_STARTON;
|
||||
if (ent->child)
|
||||
{
|
||||
edict_t *child, *parent;
|
||||
child = ent->child;
|
||||
ent->child = NULL;
|
||||
while (child)
|
||||
{
|
||||
parent = child;
|
||||
child = parent->child;
|
||||
G_FreeEdict(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->density = ent->count;
|
||||
ent->think = target_precipitation_think;
|
||||
ent->spawnflags |= SF_WEATHER_STARTON;
|
||||
ent->think(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void target_precipitation_delayed_use (edict_t *self)
|
||||
{
|
||||
// Since target_precipitation tends to be a processor hog,
|
||||
// for START_ON we wait until the player has spawned into the
|
||||
// game to ease the startup burden somewhat
|
||||
if (g_edicts[1].linkcount)
|
||||
{
|
||||
self->think = target_precipitation_think;
|
||||
self->think(self);
|
||||
}
|
||||
else
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
void SP_target_precipitation (edict_t *ent)
|
||||
{
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_TARGET_PRECIPITATION;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
ent->think = target_precipitation_delayed_use;
|
||||
ent->nextthink = level.time + 1;
|
||||
}
|
||||
|
||||
if (ent->style == STYLE_WEATHER_USER)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufSize;
|
||||
|
||||
if (!ent->usermodel)
|
||||
{
|
||||
gi.dprintf("target_precipitation style=user\nwith no usermodel.\n");
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// Knightmare- check for "models/" or "sprites/" already in path
|
||||
if ( strncmp(ent->usermodel, "models/", 7) && strncmp(ent->usermodel, "sprites/", 8) )
|
||||
{
|
||||
bufSize = strlen(ent->usermodel)+10;
|
||||
buffer = gi.TagMalloc(bufSize, TAG_LEVEL);
|
||||
if (strstr(ent->usermodel,".sp2"))
|
||||
Com_sprintf(buffer, bufSize, "sprites/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(buffer, bufSize, "models/%s", ent->usermodel);
|
||||
ent->usermodel = buffer;
|
||||
}
|
||||
|
||||
if (st.gravity)
|
||||
ent->gravity = atof(st.gravity);
|
||||
else
|
||||
ent->gravity = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->gravity = 0.0f;
|
||||
ent->attenuation = 0.0f;
|
||||
}
|
||||
|
||||
// If not rain or "user", turn off splash. Yeah I know goofy mapper
|
||||
// might WANT splash, but we're enforcing good taste here :)
|
||||
if (ent->style > STYLE_WEATHER_BIGRAIN && ent->style != STYLE_WEATHER_USER)
|
||||
ent->spawnflags &= ~SF_WEATHER_SPLASH;
|
||||
|
||||
ent->use = target_precipitation_use;
|
||||
|
||||
if (!ent->count)
|
||||
ent->count = 1;
|
||||
|
||||
if (!ent->sounds)
|
||||
ent->sounds = 2; // blue splash
|
||||
|
||||
if (!ent->mass2)
|
||||
ent->mass2 = 8; // 8 particles in splash
|
||||
|
||||
if ((ent->style < STYLE_WEATHER_RAIN) || (ent->style > STYLE_WEATHER_USER))
|
||||
ent->style = STYLE_WEATHER_RAIN; // single rain drop model
|
||||
|
||||
if (ent->speed <= 0)
|
||||
{
|
||||
switch (ent->style)
|
||||
{
|
||||
case STYLE_WEATHER_SNOW: ent->speed = 50; break;
|
||||
case STYLE_WEATHER_LEAF: ent->speed = 50; break;
|
||||
default: ent->speed = 300;
|
||||
}
|
||||
}
|
||||
|
||||
if ((VectorLength(ent->bleft) == 0.) && (VectorLength(ent->tright) == 0.))
|
||||
{
|
||||
// Default distribution places raindrops vertically for
|
||||
// full coverage, to help avoid "lumps"
|
||||
VectorSet(ent->bleft,-512,-512, -ent->speed*0.05);
|
||||
VectorSet(ent->tright,512, 512, ent->speed*0.05);
|
||||
}
|
||||
|
||||
if (VectorLength(ent->s.angles) > 0)
|
||||
G_SetMovedir(ent->s.angles,ent->movedir);
|
||||
else
|
||||
VectorSet(ent->movedir,0,0,-1);
|
||||
|
||||
ent->density = ent->count;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// TARGET_FOUNTAIN is identical to TARGET_PRECIPITATION, with these exceptions:
|
||||
// ALL styles are "user-defined" (no predefined rain, snow, etc.)
|
||||
// Models are spawned from a point source, and bleft/tright form a box within
|
||||
// which the target point is found.
|
||||
//=============================================================================
|
||||
void target_fountain_think (edict_t *self)
|
||||
{
|
||||
vec3_t center;
|
||||
vec3_t org;
|
||||
vec3_t dir;
|
||||
int r, i;
|
||||
float u, v, z;
|
||||
float temp;
|
||||
qboolean can_see_me;
|
||||
|
||||
if (!(self->spawnflags & SF_WEATHER_FIRE_ONCE))
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
// Don't start raining until player is in the game. The following
|
||||
// takes care of both initial map load conditions and restored saved games.
|
||||
// This is a gross abuse of groundentity_linkcount. Sue me.
|
||||
if (g_edicts[1].linkcount == self->groundentity_linkcount)
|
||||
return;
|
||||
else
|
||||
self->groundentity_linkcount = g_edicts[1].linkcount;
|
||||
// Don't spawn drops if player can't see us. This SEEMS like an obvious
|
||||
// thing to do, but can cause visual problems if mapper isn't careful.
|
||||
// For example, placing target_precipitation where it isn't in the PVS
|
||||
// of the player's current position, but the result (rain) IS in the
|
||||
// PVS. In any case, this step is necessary to prevent overflows when
|
||||
// player suddenly encounters rain.
|
||||
can_see_me = false;
|
||||
for (i=1; i<=game.maxclients && !can_see_me; i++)
|
||||
{
|
||||
if (!g_edicts[i].inuse) continue;
|
||||
if (gi.inPVS(g_edicts[i].s.origin,self->s.origin))
|
||||
can_see_me = true;
|
||||
}
|
||||
if (!can_see_me) return;
|
||||
|
||||
// Count is models/second. We accumulate a probability of a model
|
||||
// falling this frame in ->density. Yeah its a misnomer but density isn't
|
||||
// used for anything else so it works fine.
|
||||
|
||||
temp = 0.1*(self->density + crandom()*self->random);
|
||||
r = (int)(temp);
|
||||
if (r > 0)
|
||||
self->density = self->count;
|
||||
else
|
||||
self->density += (temp*10);
|
||||
if (r < 1) return;
|
||||
|
||||
VectorAdd(self->bleft,self->tright,center);
|
||||
VectorMA(self->s.origin,0.5,center,center);
|
||||
|
||||
for (i=0; i<r; i++)
|
||||
{
|
||||
u = crandom() * (self->tright[0] - self->bleft[0])/2;
|
||||
v = crandom() * (self->tright[1] - self->bleft[1])/2;
|
||||
z = crandom() * (self->tright[2] - self->bleft[2])/2;
|
||||
|
||||
VectorCopy(center, org);
|
||||
|
||||
org[0] += u;
|
||||
org[1] += v;
|
||||
org[2] += z;
|
||||
VectorSubtract(org,self->s.origin,dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
spawn_precipitation(self, self->s.origin, dir, self->speed);
|
||||
}
|
||||
}
|
||||
|
||||
void target_fountain_use (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if ((ent->spawnflags & SF_WEATHER_STARTON) && !(ent->spawnflags & SF_WEATHER_FIRE_ONCE))
|
||||
{
|
||||
// already on; turn it off
|
||||
ent->nextthink = 0;
|
||||
ent->spawnflags &= ~SF_WEATHER_STARTON;
|
||||
if (ent->child)
|
||||
{
|
||||
edict_t *child, *parent;
|
||||
child = ent->child;
|
||||
ent->child = NULL;
|
||||
while (child)
|
||||
{
|
||||
parent = child;
|
||||
child = parent->child;
|
||||
G_FreeEdict(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->density = ent->count;
|
||||
ent->think = target_fountain_think;
|
||||
ent->spawnflags |= SF_WEATHER_STARTON;
|
||||
ent->think(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void target_fountain_delayed_use (edict_t *self)
|
||||
{
|
||||
// Since target_fountain tends to be a processor hog,
|
||||
// for START_ON we wait until the player has spawned into the
|
||||
// game to ease the startup burden somewhat
|
||||
if (g_edicts[1].linkcount)
|
||||
{
|
||||
self->think = target_fountain_think;
|
||||
self->think(self);
|
||||
}
|
||||
else
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void SP_target_fountain (edict_t *ent)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufSize;
|
||||
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_TARGET_FOUNTAIN;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
ent->think = target_fountain_delayed_use;
|
||||
ent->nextthink = level.time + 1;
|
||||
}
|
||||
|
||||
ent->style = STYLE_WEATHER_USER;
|
||||
if (!ent->usermodel)
|
||||
{
|
||||
gi.dprintf("target_fountain with no usermodel.\n");
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// Knightmare- check for "models/" or "sprites/" already in path
|
||||
if ( strncmp(ent->usermodel, "models/", 7) && strncmp(ent->usermodel, "sprites/", 8) )
|
||||
{
|
||||
bufSize = strlen(ent->usermodel)+10;
|
||||
buffer = gi.TagMalloc(bufSize, TAG_LEVEL);
|
||||
if (strstr(ent->usermodel,".sp2"))
|
||||
Com_sprintf(buffer, bufSize, "sprites/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(buffer, bufSize, "models/%s", ent->usermodel);
|
||||
ent->usermodel = buffer;
|
||||
}
|
||||
|
||||
if (st.gravity)
|
||||
ent->gravity = atof(st.gravity);
|
||||
else
|
||||
ent->gravity = 0.0f;
|
||||
|
||||
ent->use = target_fountain_use;
|
||||
|
||||
if (!ent->count)
|
||||
ent->count = 1;
|
||||
|
||||
if (!ent->sounds)
|
||||
ent->sounds = 2; // blue splash
|
||||
|
||||
if (!ent->mass2)
|
||||
ent->mass2 = 8; // 8 particles in splash
|
||||
|
||||
if (ent->speed <= 0)
|
||||
ent->speed = 300;
|
||||
|
||||
if ((VectorLength(ent->bleft) == 0.) && (VectorLength(ent->tright) == 0.))
|
||||
{
|
||||
// Default distribution places raindrops vertically for
|
||||
// full coverage, to help avoid "lumps"
|
||||
VectorSet(ent->bleft,-32, -32, 64);
|
||||
VectorSet(ent->tright,32, 32,128);
|
||||
}
|
||||
|
||||
ent->density = ent->count;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
//
|
||||
/*=============================================================================
|
||||
|
||||
MISC_DEADSOLDIER MODEL PATCH
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
#define NUM_SKINS 16
|
||||
#define MAX_SKINNAME 64
|
||||
#define DEADSOLDIER_MODEL "models/deadbods/dude/tris.md2"
|
||||
|
||||
#include "pak.h"
|
||||
|
||||
int PatchDeadSoldier (void)
|
||||
{
|
||||
cvar_t *gamedir;
|
||||
char skins[NUM_SKINS][MAX_SKINNAME]; // skin entries
|
||||
char infilename[MAX_OSPATH];
|
||||
char outfilename[MAX_OSPATH];
|
||||
char tempname[MAX_OSPATH];
|
||||
int j;
|
||||
// char *p;
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
dmdl_t model; // model header
|
||||
byte *data; // model data
|
||||
int datasize; // model data size (bytes)
|
||||
int newoffset; // model data offset (after skins)
|
||||
|
||||
// get game (moddir) name
|
||||
gamedir = gi.cvar("game", "", 0);
|
||||
if (!*gamedir->string)
|
||||
return 0; // we're in baseq2
|
||||
|
||||
// Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string,DEADSOLDIER_MODEL);
|
||||
Com_sprintf (tempname, sizeof(tempname), DEADSOLDIER_MODEL);
|
||||
SavegameDirRelativePath (tempname, outfilename, sizeof(outfilename));
|
||||
if (outfile = fopen (outfilename, "rb"))
|
||||
{
|
||||
// output file already exists, move along
|
||||
fclose (outfile);
|
||||
// gi.dprintf ("PatchDeadSoldier: Could not save %s, file already exists\n", outfilename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < NUM_SKINS; j++)
|
||||
memset (skins[j], 0, MAX_SKINNAME);
|
||||
|
||||
Com_sprintf (skins[0], sizeof(skins[0]), "models/deadbods/dude/dead1.pcx");
|
||||
Com_sprintf (skins[1], sizeof(skins[1]), "players/male/cipher.pcx");
|
||||
Com_sprintf (skins[2], sizeof(skins[2]), "players/male/claymore.pcx");
|
||||
Com_sprintf (skins[3], sizeof(skins[3]), "players/male/flak.pcx");
|
||||
Com_sprintf (skins[4], sizeof(skins[4]), "players/male/grunt.pcx");
|
||||
Com_sprintf (skins[5], sizeof(skins[5]), "players/male/howitzer.pcx");
|
||||
Com_sprintf (skins[6], sizeof(skins[6]), "players/male/major.pcx");
|
||||
Com_sprintf (skins[7], sizeof(skins[7]), "players/male/nightops.pcx");
|
||||
Com_sprintf (skins[8], sizeof(skins[8]), "players/male/pointman.pcx");
|
||||
Com_sprintf (skins[9], sizeof(skins[9]), "players/male/psycho.pcx");
|
||||
Com_sprintf (skins[10], sizeof(skins[10]), "players/male/rampage.pcx");
|
||||
Com_sprintf (skins[11], sizeof(skins[11]), "players/male/razor.pcx");
|
||||
Com_sprintf (skins[12], sizeof(skins[12]), "players/male/recon.pcx");
|
||||
Com_sprintf (skins[13], sizeof(skins[13]), "players/male/scout.pcx");
|
||||
Com_sprintf (skins[14], sizeof(skins[14]), "players/male/sniper.pcx");
|
||||
Com_sprintf (skins[15], sizeof(skins[15]), "players/male/viper.pcx");
|
||||
|
||||
|
||||
// load original model
|
||||
Com_sprintf (infilename, sizeof(infilename), "baseq2/%s", DEADSOLDIER_MODEL);
|
||||
if ( !(infile = fopen (infilename, "rb")) )
|
||||
{
|
||||
// If file doesn't exist on user's hard disk, it must be in
|
||||
// pak0.pak
|
||||
|
||||
pak_header_t pakheader;
|
||||
pak_item_t pakitem;
|
||||
FILE *fpak;
|
||||
int k, numitems;
|
||||
|
||||
fpak = fopen("baseq2/pak0.pak","rb");
|
||||
if (!fpak)
|
||||
{
|
||||
cvar_t *cddir;
|
||||
char pakfile[MAX_OSPATH];
|
||||
|
||||
cddir = gi.cvar("cddir", "", 0);
|
||||
Com_sprintf(pakfile, sizeof(pakfile), "%s/baseq2/pak0.pak",cddir->string);
|
||||
fpak = fopen(pakfile,"rb");
|
||||
if (!fpak)
|
||||
{
|
||||
gi.dprintf("PatchDeadSoldier: Cannot find pak0.pak\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fread(&pakheader,1,sizeof(pak_header_t),fpak);
|
||||
numitems = pakheader.dsize/sizeof(pak_item_t);
|
||||
fseek(fpak,pakheader.dstart,SEEK_SET);
|
||||
data = NULL;
|
||||
for (k=0; k<numitems && !data; k++)
|
||||
{
|
||||
fread(&pakitem,1,sizeof(pak_item_t),fpak);
|
||||
if (!Q_stricmp(pakitem.name,DEADSOLDIER_MODEL))
|
||||
{
|
||||
fseek(fpak,pakitem.start,SEEK_SET);
|
||||
fread(&model, sizeof(dmdl_t), 1, fpak);
|
||||
datasize = model.ofs_end - model.ofs_skins;
|
||||
if ( !(data = malloc (datasize)) ) // make sure freed locally
|
||||
{
|
||||
fclose(fpak);
|
||||
gi.dprintf ("PatchDeadSoldier: Could not allocate memory for model\n");
|
||||
return 0;
|
||||
}
|
||||
fread (data, sizeof (byte), datasize, fpak);
|
||||
}
|
||||
}
|
||||
fclose(fpak);
|
||||
if (!data)
|
||||
{
|
||||
gi.dprintf("PatchDeadSoldier: Could not find %s in baseq2/pak0.pak\n",DEADSOLDIER_MODEL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fread (&model, sizeof (dmdl_t), 1, infile);
|
||||
|
||||
datasize = model.ofs_end - model.ofs_skins;
|
||||
if ( !(data = malloc (datasize)) ) // make sure freed locally
|
||||
{
|
||||
gi.dprintf ("PatchMonsterModel: Could not allocate memory for model\n");
|
||||
return 0;
|
||||
}
|
||||
fread (data, sizeof (byte), datasize, infile);
|
||||
|
||||
fclose (infile);
|
||||
}
|
||||
|
||||
// update model info
|
||||
model.num_skins = NUM_SKINS;
|
||||
|
||||
// Already had 1 skin, so new offset doesn't include that one
|
||||
// newoffset = (model.num_skins-1) * MAX_SKINNAME;
|
||||
newoffset = model.num_skins * MAX_SKINNAME;
|
||||
model.ofs_st += newoffset;
|
||||
model.ofs_tris += newoffset;
|
||||
model.ofs_frames += newoffset;
|
||||
model.ofs_glcmds += newoffset;
|
||||
model.ofs_end += newoffset;
|
||||
|
||||
// save new model
|
||||
/* Com_sprintf (outfilename, sizeof(outfilename), "%s/models", gamedir->string); // make some dirs if needed
|
||||
_mkdir (outfilename);
|
||||
Com_strcat (outfilename, sizeof(outfilename), "/deadbods");
|
||||
_mkdir (outfilename);
|
||||
Com_strcat (outfilename, sizeof(outfilename), "/dude");
|
||||
_mkdir (outfilename);
|
||||
Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string, DEADSOLDIER_MODEL);
|
||||
p = strstr(outfilename,"/tris.md2");
|
||||
*p = 0;
|
||||
_mkdir (outfilename);
|
||||
Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string, DEADSOLDIER_MODEL);
|
||||
*/
|
||||
Com_sprintf (tempname, sizeof(tempname), DEADSOLDIER_MODEL);
|
||||
SavegameDirRelativePath (tempname, outfilename, sizeof(outfilename));
|
||||
CreatePath (outfilename);
|
||||
|
||||
if ( !(outfile = fopen (outfilename, "wb")) )
|
||||
{
|
||||
// file couldn't be created for some other reason
|
||||
gi.dprintf ("PatchDeadSoldier: Could not save %s\n", outfilename);
|
||||
free (data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite (&model, sizeof (dmdl_t), 1, outfile);
|
||||
// fwrite (skins, sizeof (char), model.num_skins*MAX_SKINNAME, outfile);
|
||||
fwrite (skins, sizeof (char), newoffset, outfile);
|
||||
// data += MAX_SKINNAME;
|
||||
fwrite (data, sizeof (byte), datasize, outfile);
|
||||
|
||||
fclose (outfile);
|
||||
gi.dprintf ("PatchDeadSoldier: Saved %s\n", outfilename);
|
||||
free (data); // crashes here
|
||||
return 1;
|
||||
}
|
||||
|
|
827
missionpack/g_misc_laz.c
Normal file
827
missionpack/g_misc_laz.c
Normal file
|
@ -0,0 +1,827 @@
|
|||
// g_misc_laz.c
|
||||
// misc entities for the Lazarus mod
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
#define START_OFF 1
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Lazarus new entities
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
void misc_light_think (edict_t *self)
|
||||
{
|
||||
if (self->spawnflags & START_OFF)
|
||||
return;
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_FLASHLIGHT);
|
||||
gi.WritePosition (self->s.origin);
|
||||
gi.WriteShort (self - g_edicts);
|
||||
gi.multicast (self->s.origin, MULTICAST_PVS);
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void misc_light_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->spawnflags & START_OFF)
|
||||
{
|
||||
self->spawnflags &= ~START_OFF;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
else
|
||||
self->spawnflags |= START_OFF;
|
||||
}
|
||||
|
||||
void SP_misc_light (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_MISC_LIGHT;
|
||||
|
||||
self->use = misc_light_use;
|
||||
if (self->movewith)
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
else
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->think = misc_light_think;
|
||||
if (!(self->spawnflags & START_OFF))
|
||||
self->nextthink = level.time + 2*FRAMETIME;
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
TARGET_PRECIPITATION
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
#define SF_WEATHER_STARTON 1
|
||||
#define SF_WEATHER_SPLASH 2
|
||||
#define SF_WEATHER_GRAVITY_BOUNCE 4
|
||||
#define SF_WEATHER_FIRE_ONCE 8
|
||||
#define SF_WEATHER_START_FADE 16
|
||||
#define STYLE_WEATHER_RAIN 0
|
||||
#define STYLE_WEATHER_BIGRAIN 1
|
||||
#define STYLE_WEATHER_SNOW 2
|
||||
#define STYLE_WEATHER_LEAF 3
|
||||
#define STYLE_WEATHER_USER 4
|
||||
|
||||
void drop_add_to_chain(edict_t *drop)
|
||||
{
|
||||
edict_t *owner = drop->owner;
|
||||
edict_t *parent;
|
||||
|
||||
if (!owner || !owner->inuse || !(owner->spawnflags & SF_WEATHER_STARTON))
|
||||
{
|
||||
G_FreeEdict(drop);
|
||||
return;
|
||||
}
|
||||
parent = owner;
|
||||
while (parent->child)
|
||||
parent = parent->child;
|
||||
parent->child = drop;
|
||||
drop->child = NULL;
|
||||
drop->svflags |= SVF_NOCLIENT;
|
||||
drop->s.effects &= ~EF_SPHERETRANS;
|
||||
drop->s.renderfx &= ~RF_TRANSLUCENT;
|
||||
VectorClear(drop->velocity);
|
||||
VectorClear(drop->avelocity);
|
||||
gi.linkentity(drop);
|
||||
}
|
||||
|
||||
void drop_splash(edict_t *drop)
|
||||
{
|
||||
vec3_t up = {0,0,1};
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_LASER_SPARKS);
|
||||
gi.WriteByte (drop->owner->mass2);
|
||||
gi.WritePosition (drop->s.origin);
|
||||
gi.WriteDir (up);
|
||||
gi.WriteByte (drop->owner->sounds);
|
||||
gi.multicast (drop->s.origin, MULTICAST_PVS);
|
||||
drop_add_to_chain(drop);
|
||||
}
|
||||
|
||||
void leaf_fade2(edict_t *ent)
|
||||
{
|
||||
ent->count++;
|
||||
if (ent->count == 1)
|
||||
{
|
||||
ent->s.effects |= EF_SPHERETRANS;
|
||||
ent->nextthink=level.time+0.5;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
else
|
||||
drop_add_to_chain(ent);
|
||||
}
|
||||
|
||||
void leaf_fade (edict_t *ent)
|
||||
{
|
||||
ent->s.renderfx = RF_TRANSLUCENT;
|
||||
ent->think = leaf_fade2;
|
||||
ent->nextthink = level.time+0.5;
|
||||
ent->count = 0;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
void drop_touch(edict_t *drop, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (drop->owner->spawnflags & SF_WEATHER_START_FADE)
|
||||
return;
|
||||
else if (drop->fadeout > 0)
|
||||
{
|
||||
if ( (drop->spawnflags & SF_WEATHER_GRAVITY_BOUNCE) && (drop->owner->gravity > 0))
|
||||
{
|
||||
drop->movetype = MOVETYPE_DEBRIS;
|
||||
drop->gravity = drop->owner->gravity;
|
||||
}
|
||||
drop->think = leaf_fade;
|
||||
drop->nextthink = level.time + drop->fadeout;
|
||||
}
|
||||
else if (drop->spawnflags & SF_WEATHER_SPLASH)
|
||||
drop_splash(drop);
|
||||
else
|
||||
drop_add_to_chain(drop);
|
||||
}
|
||||
|
||||
void spawn_precipitation(edict_t *self, vec3_t org, vec3_t dir, float speed)
|
||||
{
|
||||
edict_t *drop;
|
||||
|
||||
if (self->child)
|
||||
{
|
||||
// Then we already have a currently unused, invisible drop available
|
||||
drop = self->child;
|
||||
self->child = drop->child;
|
||||
drop->child = NULL;
|
||||
drop->svflags &= ~SVF_NOCLIENT;
|
||||
drop->groundentity = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
drop = G_Spawn();
|
||||
if (self->style == STYLE_WEATHER_BIGRAIN)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/drop/heavy.md2");
|
||||
else if (self->style == STYLE_WEATHER_SNOW)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/snow/tris.md2");
|
||||
else if (self->style == STYLE_WEATHER_LEAF)
|
||||
{
|
||||
float r=random();
|
||||
if (r < 0.33)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf1/tris.md2");
|
||||
else if (r < 0.66)
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf2/tris.md2");
|
||||
else
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/leaf3/tris.md2");
|
||||
VectorSet(drop->mins,-1,-1,-1);
|
||||
VectorSet(drop->maxs, 1, 1, 1);
|
||||
}
|
||||
else if (self->style == STYLE_WEATHER_USER)
|
||||
drop->s.modelindex = gi.modelindex(self->usermodel);
|
||||
else
|
||||
drop->s.modelindex = gi.modelindex ("models/objects/drop/tris.md2");
|
||||
drop->classname = "rain drop";
|
||||
}
|
||||
if (self->gravity > 0.0f || self->attenuation > 0 )
|
||||
drop->movetype = MOVETYPE_DEBRIS;
|
||||
else
|
||||
drop->movetype = MOVETYPE_RAIN;
|
||||
|
||||
drop->touch = drop_touch;
|
||||
if (self->style == STYLE_WEATHER_USER)
|
||||
drop->clipmask = MASK_MONSTERSOLID;
|
||||
else if ((self->fadeout > 0) && (self->gravity == 0.0f))
|
||||
drop->clipmask = MASK_SOLID | CONTENTS_WATER;
|
||||
else
|
||||
drop->clipmask = MASK_MONSTERSOLID | CONTENTS_WATER;
|
||||
drop->solid = SOLID_BBOX;
|
||||
drop->svflags = SVF_DEADMONSTER;
|
||||
VectorSet(drop->mins, -1, -1, -1);
|
||||
VectorSet(drop->maxs, 1, 1, 1);
|
||||
|
||||
if (self->spawnflags & SF_WEATHER_GRAVITY_BOUNCE)
|
||||
drop->gravity = self->gravity;
|
||||
else
|
||||
drop->gravity = 0.0f;
|
||||
drop->attenuation = self->attenuation;
|
||||
drop->mass = self->mass;
|
||||
drop->spawnflags = self->spawnflags;
|
||||
drop->fadeout = self->fadeout;
|
||||
drop->owner = self;
|
||||
|
||||
VectorCopy (org, drop->s.origin);
|
||||
vectoangles(dir, drop->s.angles);
|
||||
drop->s.angles[PITCH] -= 90;
|
||||
VectorScale (dir, speed, drop->velocity);
|
||||
if (self->style == STYLE_WEATHER_LEAF)
|
||||
{
|
||||
drop->avelocity[PITCH] = crandom() * 360;
|
||||
drop->avelocity[YAW] = crandom() * 360;
|
||||
drop->avelocity[ROLL] = crandom() * 360;
|
||||
}
|
||||
else if (self->style == STYLE_WEATHER_USER)
|
||||
{
|
||||
drop->s.effects = self->effects;
|
||||
drop->s.renderfx = self->renderfx;
|
||||
drop->avelocity[PITCH] = crandom() * self->pitch_speed;
|
||||
drop->avelocity[YAW] = crandom() * self->yaw_speed;
|
||||
drop->avelocity[ROLL] = crandom() * self->roll_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
drop->s.effects |= EF_SPHERETRANS;
|
||||
drop->avelocity[YAW] = self->yaw_speed;
|
||||
}
|
||||
if (self->spawnflags & SF_WEATHER_START_FADE)
|
||||
{
|
||||
drop->think = leaf_fade;
|
||||
drop->nextthink = level.time + self->fadeout;
|
||||
}
|
||||
gi.linkentity(drop);
|
||||
}
|
||||
|
||||
void target_precipitation_think (edict_t *self)
|
||||
{
|
||||
vec3_t center;
|
||||
vec3_t org;
|
||||
int r, i;
|
||||
float u, v, z;
|
||||
float temp;
|
||||
qboolean can_see_me;
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
// Don't start raining until player is in the game. The following
|
||||
// takes care of both initial map load conditions and restored saved games.
|
||||
// This is a gross abuse of groundentity_linkcount. Sue me.
|
||||
if (g_edicts[1].linkcount == self->groundentity_linkcount)
|
||||
return;
|
||||
else
|
||||
self->groundentity_linkcount = g_edicts[1].linkcount;
|
||||
// Don't spawn drops if player can't see us. This SEEMS like an obvious
|
||||
// thing to do, but can cause visual problems if mapper isn't careful.
|
||||
// For example, placing target_precipitation where it isn't in the PVS
|
||||
// of the player's current position, but the result (rain) IS in the
|
||||
// PVS. In any case, this step is necessary to prevent overflows when
|
||||
// player suddenly encounters rain.
|
||||
can_see_me = false;
|
||||
for (i=1; i<=game.maxclients && !can_see_me; i++)
|
||||
{
|
||||
if (!g_edicts[i].inuse) continue;
|
||||
if (gi.inPVS(g_edicts[i].s.origin,self->s.origin))
|
||||
can_see_me = true;
|
||||
}
|
||||
if (!can_see_me) return;
|
||||
|
||||
// Count is models/second. We accumulate a probability of a model
|
||||
// falling this frame in ->density. Yeah its a misnomer but density isn't
|
||||
// used for anything else so it works fine.
|
||||
|
||||
temp = 0.1*(self->density + crandom()*self->random);
|
||||
r = (int)(temp);
|
||||
if (r > 0)
|
||||
self->density = self->count + (temp-(float)r)*10;
|
||||
else
|
||||
self->density += (temp*10);
|
||||
if (r < 1) return;
|
||||
|
||||
VectorAdd(self->bleft,self->tright,center);
|
||||
VectorMA(self->s.origin,0.5,center,center);
|
||||
|
||||
for (i=0; i<r; i++)
|
||||
{
|
||||
u = crandom() * (self->tright[0] - self->bleft[0])/2;
|
||||
v = crandom() * (self->tright[1] - self->bleft[1])/2;
|
||||
z = crandom() * (self->tright[2] - self->bleft[2])/2;
|
||||
|
||||
VectorCopy(center, org);
|
||||
|
||||
org[0] += u;
|
||||
org[1] += v;
|
||||
org[2] += z;
|
||||
|
||||
spawn_precipitation(self, org, self->movedir, self->speed);
|
||||
}
|
||||
}
|
||||
|
||||
void target_precipitation_use (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
// already on; turn it off
|
||||
ent->nextthink = 0;
|
||||
ent->spawnflags &= ~SF_WEATHER_STARTON;
|
||||
if (ent->child)
|
||||
{
|
||||
edict_t *child, *parent;
|
||||
child = ent->child;
|
||||
ent->child = NULL;
|
||||
while (child)
|
||||
{
|
||||
parent = child;
|
||||
child = parent->child;
|
||||
G_FreeEdict(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->density = ent->count;
|
||||
ent->think = target_precipitation_think;
|
||||
ent->spawnflags |= SF_WEATHER_STARTON;
|
||||
ent->think(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void target_precipitation_delayed_use (edict_t *self)
|
||||
{
|
||||
// Since target_precipitation tends to be a processor hog,
|
||||
// for START_ON we wait until the player has spawned into the
|
||||
// game to ease the startup burden somewhat
|
||||
if (g_edicts[1].linkcount)
|
||||
{
|
||||
self->think = target_precipitation_think;
|
||||
self->think(self);
|
||||
}
|
||||
else
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
void SP_target_precipitation (edict_t *ent)
|
||||
{
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_TARGET_PRECIPITATION;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
ent->think = target_precipitation_delayed_use;
|
||||
ent->nextthink = level.time + 1;
|
||||
}
|
||||
|
||||
if (ent->style == STYLE_WEATHER_USER)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufSize;
|
||||
|
||||
if (!ent->usermodel)
|
||||
{
|
||||
gi.dprintf("target_precipitation style=user\nwith no usermodel.\n");
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// Knightmare- check for "models/" or "sprites/" already in path
|
||||
if ( strncmp(ent->usermodel, "models/", 7) && strncmp(ent->usermodel, "sprites/", 8) )
|
||||
{
|
||||
bufSize = strlen(ent->usermodel)+10;
|
||||
buffer = gi.TagMalloc(bufSize, TAG_LEVEL);
|
||||
if (strstr(ent->usermodel,".sp2"))
|
||||
Com_sprintf(buffer, bufSize, "sprites/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(buffer, bufSize, "models/%s", ent->usermodel);
|
||||
ent->usermodel = buffer;
|
||||
}
|
||||
|
||||
if (st.gravity)
|
||||
ent->gravity = atof(st.gravity);
|
||||
else
|
||||
ent->gravity = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->gravity = 0.0f;
|
||||
ent->attenuation = 0.0f;
|
||||
}
|
||||
|
||||
// If not rain or "user", turn off splash. Yeah I know goofy mapper
|
||||
// might WANT splash, but we're enforcing good taste here :)
|
||||
if (ent->style > STYLE_WEATHER_BIGRAIN && ent->style != STYLE_WEATHER_USER)
|
||||
ent->spawnflags &= ~SF_WEATHER_SPLASH;
|
||||
|
||||
ent->use = target_precipitation_use;
|
||||
|
||||
if (!ent->count)
|
||||
ent->count = 1;
|
||||
|
||||
if (!ent->sounds)
|
||||
ent->sounds = 2; // blue splash
|
||||
|
||||
if (!ent->mass2)
|
||||
ent->mass2 = 8; // 8 particles in splash
|
||||
|
||||
if ((ent->style < STYLE_WEATHER_RAIN) || (ent->style > STYLE_WEATHER_USER))
|
||||
ent->style = STYLE_WEATHER_RAIN; // single rain drop model
|
||||
|
||||
if (ent->speed <= 0)
|
||||
{
|
||||
switch (ent->style)
|
||||
{
|
||||
case STYLE_WEATHER_SNOW: ent->speed = 50; break;
|
||||
case STYLE_WEATHER_LEAF: ent->speed = 50; break;
|
||||
default: ent->speed = 300;
|
||||
}
|
||||
}
|
||||
|
||||
if ((VectorLength(ent->bleft) == 0.) && (VectorLength(ent->tright) == 0.))
|
||||
{
|
||||
// Default distribution places raindrops vertically for
|
||||
// full coverage, to help avoid "lumps"
|
||||
VectorSet(ent->bleft,-512,-512, -ent->speed*0.05);
|
||||
VectorSet(ent->tright,512, 512, ent->speed*0.05);
|
||||
}
|
||||
|
||||
if (VectorLength(ent->s.angles) > 0)
|
||||
G_SetMovedir(ent->s.angles,ent->movedir);
|
||||
else
|
||||
VectorSet(ent->movedir,0,0,-1);
|
||||
|
||||
ent->density = ent->count;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// TARGET_FOUNTAIN is identical to TARGET_PRECIPITATION, with these exceptions:
|
||||
// ALL styles are "user-defined" (no predefined rain, snow, etc.)
|
||||
// Models are spawned from a point source, and bleft/tright form a box within
|
||||
// which the target point is found.
|
||||
//=============================================================================
|
||||
void target_fountain_think (edict_t *self)
|
||||
{
|
||||
vec3_t center;
|
||||
vec3_t org;
|
||||
vec3_t dir;
|
||||
int r, i;
|
||||
float u, v, z;
|
||||
float temp;
|
||||
qboolean can_see_me;
|
||||
|
||||
if (!(self->spawnflags & SF_WEATHER_FIRE_ONCE))
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
// Don't start raining until player is in the game. The following
|
||||
// takes care of both initial map load conditions and restored saved games.
|
||||
// This is a gross abuse of groundentity_linkcount. Sue me.
|
||||
if (g_edicts[1].linkcount == self->groundentity_linkcount)
|
||||
return;
|
||||
else
|
||||
self->groundentity_linkcount = g_edicts[1].linkcount;
|
||||
// Don't spawn drops if player can't see us. This SEEMS like an obvious
|
||||
// thing to do, but can cause visual problems if mapper isn't careful.
|
||||
// For example, placing target_precipitation where it isn't in the PVS
|
||||
// of the player's current position, but the result (rain) IS in the
|
||||
// PVS. In any case, this step is necessary to prevent overflows when
|
||||
// player suddenly encounters rain.
|
||||
can_see_me = false;
|
||||
for (i=1; i<=game.maxclients && !can_see_me; i++)
|
||||
{
|
||||
if (!g_edicts[i].inuse) continue;
|
||||
if (gi.inPVS(g_edicts[i].s.origin,self->s.origin))
|
||||
can_see_me = true;
|
||||
}
|
||||
if (!can_see_me) return;
|
||||
|
||||
// Count is models/second. We accumulate a probability of a model
|
||||
// falling this frame in ->density. Yeah its a misnomer but density isn't
|
||||
// used for anything else so it works fine.
|
||||
|
||||
temp = 0.1*(self->density + crandom()*self->random);
|
||||
r = (int)(temp);
|
||||
if (r > 0)
|
||||
self->density = self->count;
|
||||
else
|
||||
self->density += (temp*10);
|
||||
if (r < 1) return;
|
||||
|
||||
VectorAdd(self->bleft,self->tright,center);
|
||||
VectorMA(self->s.origin,0.5,center,center);
|
||||
|
||||
for (i=0; i<r; i++)
|
||||
{
|
||||
u = crandom() * (self->tright[0] - self->bleft[0])/2;
|
||||
v = crandom() * (self->tright[1] - self->bleft[1])/2;
|
||||
z = crandom() * (self->tright[2] - self->bleft[2])/2;
|
||||
|
||||
VectorCopy(center, org);
|
||||
|
||||
org[0] += u;
|
||||
org[1] += v;
|
||||
org[2] += z;
|
||||
VectorSubtract(org,self->s.origin,dir);
|
||||
VectorNormalize(dir);
|
||||
|
||||
spawn_precipitation(self, self->s.origin, dir, self->speed);
|
||||
}
|
||||
}
|
||||
|
||||
void target_fountain_use (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if ((ent->spawnflags & SF_WEATHER_STARTON) && !(ent->spawnflags & SF_WEATHER_FIRE_ONCE))
|
||||
{
|
||||
// already on; turn it off
|
||||
ent->nextthink = 0;
|
||||
ent->spawnflags &= ~SF_WEATHER_STARTON;
|
||||
if (ent->child)
|
||||
{
|
||||
edict_t *child, *parent;
|
||||
child = ent->child;
|
||||
ent->child = NULL;
|
||||
while (child)
|
||||
{
|
||||
parent = child;
|
||||
child = parent->child;
|
||||
G_FreeEdict(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->density = ent->count;
|
||||
ent->think = target_fountain_think;
|
||||
ent->spawnflags |= SF_WEATHER_STARTON;
|
||||
ent->think(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void target_fountain_delayed_use (edict_t *self)
|
||||
{
|
||||
// Since target_fountain tends to be a processor hog,
|
||||
// for START_ON we wait until the player has spawned into the
|
||||
// game to ease the startup burden somewhat
|
||||
if (g_edicts[1].linkcount)
|
||||
{
|
||||
self->think = target_fountain_think;
|
||||
self->think(self);
|
||||
}
|
||||
else
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void SP_target_fountain (edict_t *ent)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufSize;
|
||||
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_TARGET_FOUNTAIN;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
if (ent->spawnflags & SF_WEATHER_STARTON)
|
||||
{
|
||||
ent->think = target_fountain_delayed_use;
|
||||
ent->nextthink = level.time + 1;
|
||||
}
|
||||
|
||||
ent->style = STYLE_WEATHER_USER;
|
||||
if (!ent->usermodel)
|
||||
{
|
||||
gi.dprintf("target_fountain with no usermodel.\n");
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// Knightmare- check for "models/" or "sprites/" already in path
|
||||
if ( strncmp(ent->usermodel, "models/", 7) && strncmp(ent->usermodel, "sprites/", 8) )
|
||||
{
|
||||
bufSize = strlen(ent->usermodel)+10;
|
||||
buffer = gi.TagMalloc(bufSize, TAG_LEVEL);
|
||||
if (strstr(ent->usermodel,".sp2"))
|
||||
Com_sprintf(buffer, bufSize, "sprites/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(buffer, bufSize, "models/%s", ent->usermodel);
|
||||
ent->usermodel = buffer;
|
||||
}
|
||||
|
||||
if (st.gravity)
|
||||
ent->gravity = atof(st.gravity);
|
||||
else
|
||||
ent->gravity = 0.0f;
|
||||
|
||||
ent->use = target_fountain_use;
|
||||
|
||||
if (!ent->count)
|
||||
ent->count = 1;
|
||||
|
||||
if (!ent->sounds)
|
||||
ent->sounds = 2; // blue splash
|
||||
|
||||
if (!ent->mass2)
|
||||
ent->mass2 = 8; // 8 particles in splash
|
||||
|
||||
if (ent->speed <= 0)
|
||||
ent->speed = 300;
|
||||
|
||||
if ((VectorLength(ent->bleft) == 0.) && (VectorLength(ent->tright) == 0.))
|
||||
{
|
||||
// Default distribution places raindrops vertically for
|
||||
// full coverage, to help avoid "lumps"
|
||||
VectorSet(ent->bleft,-32, -32, 64);
|
||||
VectorSet(ent->tright,32, 32,128);
|
||||
}
|
||||
|
||||
ent->density = ent->count;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
//
|
||||
/*=============================================================================
|
||||
|
||||
MISC_DEADSOLDIER MODEL PATCH
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
#define NUM_SKINS 16
|
||||
#define MAX_SKINNAME 64
|
||||
#define DEADSOLDIER_MODEL "models/deadbods/dude/tris.md2"
|
||||
|
||||
#include "pak.h"
|
||||
|
||||
int PatchDeadSoldier (void)
|
||||
{
|
||||
cvar_t *gamedir;
|
||||
char skins[NUM_SKINS][MAX_SKINNAME]; // skin entries
|
||||
char infilename[MAX_OSPATH];
|
||||
char outfilename[MAX_OSPATH];
|
||||
char tempname[MAX_OSPATH];
|
||||
int j;
|
||||
// char *p;
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
dmdl_t model; // model header
|
||||
byte *data; // model data
|
||||
int datasize; // model data size (bytes)
|
||||
int newoffset; // model data offset (after skins)
|
||||
|
||||
// get game (moddir) name
|
||||
gamedir = gi.cvar("game", "", 0);
|
||||
if (!*gamedir->string)
|
||||
return 0; // we're in baseq2
|
||||
|
||||
// Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string,DEADSOLDIER_MODEL);
|
||||
Com_sprintf (tempname, sizeof(tempname), DEADSOLDIER_MODEL);
|
||||
SavegameDirRelativePath (tempname, outfilename, sizeof(outfilename));
|
||||
if (outfile = fopen (outfilename, "rb"))
|
||||
{
|
||||
// output file already exists, move along
|
||||
fclose (outfile);
|
||||
// gi.dprintf ("PatchDeadSoldier: Could not save %s, file already exists\n", outfilename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < NUM_SKINS; j++)
|
||||
memset (skins[j], 0, MAX_SKINNAME);
|
||||
|
||||
Com_sprintf (skins[0], sizeof(skins[0]), "models/deadbods/dude/dead1.pcx");
|
||||
Com_sprintf (skins[1], sizeof(skins[1]), "players/male/cipher.pcx");
|
||||
Com_sprintf (skins[2], sizeof(skins[2]), "players/male/claymore.pcx");
|
||||
Com_sprintf (skins[3], sizeof(skins[3]), "players/male/flak.pcx");
|
||||
Com_sprintf (skins[4], sizeof(skins[4]), "players/male/grunt.pcx");
|
||||
Com_sprintf (skins[5], sizeof(skins[5]), "players/male/howitzer.pcx");
|
||||
Com_sprintf (skins[6], sizeof(skins[6]), "players/male/major.pcx");
|
||||
Com_sprintf (skins[7], sizeof(skins[7]), "players/male/nightops.pcx");
|
||||
Com_sprintf (skins[8], sizeof(skins[8]), "players/male/pointman.pcx");
|
||||
Com_sprintf (skins[9], sizeof(skins[9]), "players/male/psycho.pcx");
|
||||
Com_sprintf (skins[10], sizeof(skins[10]), "players/male/rampage.pcx");
|
||||
Com_sprintf (skins[11], sizeof(skins[11]), "players/male/razor.pcx");
|
||||
Com_sprintf (skins[12], sizeof(skins[12]), "players/male/recon.pcx");
|
||||
Com_sprintf (skins[13], sizeof(skins[13]), "players/male/scout.pcx");
|
||||
Com_sprintf (skins[14], sizeof(skins[14]), "players/male/sniper.pcx");
|
||||
Com_sprintf (skins[15], sizeof(skins[15]), "players/male/viper.pcx");
|
||||
|
||||
|
||||
// load original model
|
||||
Com_sprintf (infilename, sizeof(infilename), "baseq2/%s", DEADSOLDIER_MODEL);
|
||||
if ( !(infile = fopen (infilename, "rb")) )
|
||||
{
|
||||
// If file doesn't exist on user's hard disk, it must be in
|
||||
// pak0.pak
|
||||
|
||||
pak_header_t pakheader;
|
||||
pak_item_t pakitem;
|
||||
FILE *fpak;
|
||||
int k, numitems;
|
||||
|
||||
fpak = fopen("baseq2/pak0.pak","rb");
|
||||
if (!fpak)
|
||||
{
|
||||
cvar_t *cddir;
|
||||
char pakfile[MAX_OSPATH];
|
||||
|
||||
cddir = gi.cvar("cddir", "", 0);
|
||||
Com_sprintf(pakfile, sizeof(pakfile), "%s/baseq2/pak0.pak",cddir->string);
|
||||
fpak = fopen(pakfile,"rb");
|
||||
if (!fpak)
|
||||
{
|
||||
gi.dprintf("PatchDeadSoldier: Cannot find pak0.pak\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fread(&pakheader,1,sizeof(pak_header_t),fpak);
|
||||
numitems = pakheader.dsize/sizeof(pak_item_t);
|
||||
fseek(fpak,pakheader.dstart,SEEK_SET);
|
||||
data = NULL;
|
||||
for (k=0; k<numitems && !data; k++)
|
||||
{
|
||||
fread(&pakitem,1,sizeof(pak_item_t),fpak);
|
||||
if (!Q_stricmp(pakitem.name,DEADSOLDIER_MODEL))
|
||||
{
|
||||
fseek(fpak,pakitem.start,SEEK_SET);
|
||||
fread(&model, sizeof(dmdl_t), 1, fpak);
|
||||
datasize = model.ofs_end - model.ofs_skins;
|
||||
if ( !(data = malloc (datasize)) ) // make sure freed locally
|
||||
{
|
||||
fclose(fpak);
|
||||
gi.dprintf ("PatchDeadSoldier: Could not allocate memory for model\n");
|
||||
return 0;
|
||||
}
|
||||
fread (data, sizeof (byte), datasize, fpak);
|
||||
}
|
||||
}
|
||||
fclose(fpak);
|
||||
if (!data)
|
||||
{
|
||||
gi.dprintf("PatchDeadSoldier: Could not find %s in baseq2/pak0.pak\n",DEADSOLDIER_MODEL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fread (&model, sizeof (dmdl_t), 1, infile);
|
||||
|
||||
datasize = model.ofs_end - model.ofs_skins;
|
||||
if ( !(data = malloc (datasize)) ) // make sure freed locally
|
||||
{
|
||||
gi.dprintf ("PatchMonsterModel: Could not allocate memory for model\n");
|
||||
return 0;
|
||||
}
|
||||
fread (data, sizeof (byte), datasize, infile);
|
||||
|
||||
fclose (infile);
|
||||
}
|
||||
|
||||
// update model info
|
||||
model.num_skins = NUM_SKINS;
|
||||
|
||||
// Already had 1 skin, so new offset doesn't include that one
|
||||
// newoffset = (model.num_skins-1) * MAX_SKINNAME;
|
||||
newoffset = model.num_skins * MAX_SKINNAME;
|
||||
model.ofs_st += newoffset;
|
||||
model.ofs_tris += newoffset;
|
||||
model.ofs_frames += newoffset;
|
||||
model.ofs_glcmds += newoffset;
|
||||
model.ofs_end += newoffset;
|
||||
|
||||
// save new model
|
||||
/* Com_sprintf (outfilename, sizeof(outfilename), "%s/models", gamedir->string); // make some dirs if needed
|
||||
_mkdir (outfilename);
|
||||
Com_strcat (outfilename, sizeof(outfilename), "/deadbods");
|
||||
_mkdir (outfilename);
|
||||
Com_strcat (outfilename, sizeof(outfilename), "/dude");
|
||||
_mkdir (outfilename);
|
||||
Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string, DEADSOLDIER_MODEL);
|
||||
p = strstr(outfilename,"/tris.md2");
|
||||
*p = 0;
|
||||
_mkdir (outfilename);
|
||||
Com_sprintf (outfilename, sizeof(outfilename), "%s/%s", gamedir->string, DEADSOLDIER_MODEL);
|
||||
*/
|
||||
Com_sprintf (tempname, sizeof(tempname), DEADSOLDIER_MODEL);
|
||||
SavegameDirRelativePath (tempname, outfilename, sizeof(outfilename));
|
||||
CreatePath (outfilename);
|
||||
|
||||
if ( !(outfile = fopen (outfilename, "wb")) )
|
||||
{
|
||||
// file couldn't be created for some other reason
|
||||
gi.dprintf ("PatchDeadSoldier: Could not save %s\n", outfilename);
|
||||
free (data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite (&model, sizeof (dmdl_t), 1, outfile);
|
||||
// fwrite (skins, sizeof (char), model.num_skins*MAX_SKINNAME, outfile);
|
||||
fwrite (skins, sizeof (char), newoffset, outfile);
|
||||
// data += MAX_SKINNAME;
|
||||
fwrite (data, sizeof (byte), datasize, outfile);
|
||||
|
||||
fclose (outfile);
|
||||
gi.dprintf ("PatchDeadSoldier: Saved %s\n", outfilename);
|
||||
free (data); // crashes here
|
||||
return 1;
|
||||
}
|
145
missionpack/g_misc_nm.c
Normal file
145
missionpack/g_misc_nm.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
// g_misc_nm.c
|
||||
// misc entities for Neil Manke's Q2 maps
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Coconut Monkey 3 Flame entities
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
#define FLAME_START_OFF 1
|
||||
void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||||
|
||||
void light_flame_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->solid == SOLID_NOT)
|
||||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
gi.configstring (CS_LIGHTS+self->style, "m");
|
||||
self->spawnflags &= ~FLAME_START_OFF;
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
gi.configstring (CS_LIGHTS+self->style, "a");
|
||||
self->spawnflags |= FLAME_START_OFF;
|
||||
self->solid = SOLID_NOT;
|
||||
}
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
||||
void light_flame_spawn (edict_t *self)
|
||||
{
|
||||
self->s.effects = EF_ANIM_ALLFAST;
|
||||
self->s.renderfx |= RF_NOSHADOW;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->touch = hurt_touch;
|
||||
if (!self->dmg)
|
||||
self->dmg = 5;
|
||||
|
||||
self->noise_index = gi.soundindex ("world/electro.wav");
|
||||
|
||||
if (self->style >= 32)
|
||||
{
|
||||
if (self->spawnflags & FLAME_START_OFF)
|
||||
{
|
||||
gi.configstring (CS_LIGHTS+self->style, "a");
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->solid = SOLID_NOT;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.configstring (CS_LIGHTS+self->style, "m");
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
}
|
||||
self->use = light_flame_use;
|
||||
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
||||
void SP_light_flame1 (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame1.sp2");
|
||||
VectorSet(self->mins,-48,-48,-32);
|
||||
VectorSet(self->maxs, 48, 48, 64);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame1s (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame1s.sp2");
|
||||
VectorSet(self->mins,-16,-16,-16);
|
||||
VectorSet(self->maxs, 16, 16, 32);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame2 (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame2.sp2");
|
||||
VectorSet(self->mins,-48,-48,-32);
|
||||
VectorSet(self->maxs, 48, 48, 64);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
void SP_light_flame2s (edict_t *self)
|
||||
{
|
||||
self->class_id = ENTITY_LIGHT_FLAME_CM;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("sprites/s_flame2s.sp2");
|
||||
VectorSet(self->mins,-16,-16,-16);
|
||||
VectorSet(self->maxs, 16, 16, 32);
|
||||
light_flame_spawn (self);
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
Coconut Monkey
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
void monster_coco_monkey_think (edict_t *self)
|
||||
{
|
||||
if (++self->s.frame > 19)
|
||||
self->s.frame = 0;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
void SP_monster_coco_monkey (edict_t *self)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
G_FreeEdict (self);
|
||||
return;
|
||||
}
|
||||
self->movetype = MOVETYPE_TOSS;
|
||||
self->solid = SOLID_BBOX;
|
||||
|
||||
self->s.modelindex = gi.modelindex ("models/monsters/coco/tris.md2");
|
||||
self->s.renderfx |= RF_IR_VISIBLE;
|
||||
VectorSet(self->mins,-16,-16,-40);
|
||||
VectorSet(self->maxs, 16, 16, 48);
|
||||
self->s.origin[2] += 10;
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = monster_coco_monkey_think;
|
||||
self->common_name = "Coconut Monkey";
|
||||
|
||||
self->class_id = ENTITY_MONSTER_COCO_MONKEY;
|
||||
|
||||
gi.linkentity (self);
|
||||
}
|
563
missionpack/g_model.c
Normal file
563
missionpack/g_model.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
// g_model.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
/*
|
||||
=============================
|
||||
Spawning a user defined model
|
||||
|
||||
=============================
|
||||
*/
|
||||
|
||||
//ed - added all these spawnflags and stuff
|
||||
|
||||
/*QUAKED model_spawn (1 0 0) (-8 -8 -8) (8 8 8) x TOGGLE NOT_IR PLAYER NO_MODEL ANIM_ONCE
|
||||
Spawns a user defined model, you can specify whether its solid, if so how big the box is, and apply nearly
|
||||
any effect to the entity.
|
||||
|
||||
Spawnflags:
|
||||
TOGGLE Start active, when triggered become inactive
|
||||
NOT_IR The model won't be tinted red when the player has IR goggles on
|
||||
PLAYER Set this if you want to use a player model
|
||||
NO_MODEL Don't use a model. Usefull for placing particle effects and dynamic lights on their own
|
||||
ANIM__ONCE Only play the animation once
|
||||
-----------------------
|
||||
Key/Value pairs:
|
||||
"style" Specifies the animation type to use.
|
||||
0: None (unless startframe and framenumbers are used)
|
||||
1: ANIM01 - cycle between frames 0 and 1 at 2 hz
|
||||
2: ANIM23 - cycle between frames 2 and 3 at 2 hz
|
||||
3: ANIM_ALL - cycle through all frames at 2 hz
|
||||
4: ANIM_ALLFAST - cycle through all frames at 10 hz
|
||||
|
||||
Note: The animation flags override startframe and framenumbers settings you may have enterered. ANIM_ALL and ANIM_ALLFAST don't do what you might think - rather than setting a framerate, these apparently cause the model to cycle through its ENTIRE sequence of animations in 0.5 or 0.1 seconds... which for monster and player models is of course not possible. Looks exceptionally goofy.
|
||||
|
||||
"usermodel" The model to load (models/ is already coded)
|
||||
"startframe" The starting frame : default 0
|
||||
"framenumbers" The number of frames you want to display after startframe
|
||||
"skinnum" The skin number to use, default 0
|
||||
"health" If non-zero and solidstate is 3 or 4 (solid), the entity will be shootable. When destroyed, it blows up with a no-damage explosion.
|
||||
"solidstate"
|
||||
1 - not solid at all. These models do not obey any sort of physics. If you place them up in the air or embedded in a wall they will stay there and be perfectly happy about it.
|
||||
2 - solid. These models will "droptofloor" when spawned. If the health value is set they may be damaged.
|
||||
3 - solid. Same as above but not affected by gravity. Model will remain in the same location.
|
||||
4 - not solid but affected by gravity. Model will "droptofloor" when spawned.
|
||||
NOTE : if you want the model to be solid then you must enter vector values into the following fields :
|
||||
"bleft" = the point that is at the bottom left of the models bounding box in a model editor
|
||||
"tright" = the point that is at the top left of the models bounding box in a model editor
|
||||
|
||||
"effects"
|
||||
1: ROTATE Rotate like a weapon
|
||||
2: GIB
|
||||
8: BLASTER Yellowish orange glow plus particles
|
||||
16: ROCKET Rocket trail
|
||||
32: GRENADE Grenade trail
|
||||
64: HYPERBLASTER BLASTER w/o the particles
|
||||
128: BFG Big green ball
|
||||
256: COLOR_SHELL
|
||||
512: POWERSCREEN Green power shield
|
||||
16384: FLIES Ewwww
|
||||
32768: QUAD Blue shell
|
||||
65536: PENT Red shell
|
||||
131072: TELEPORTER Teleporter particles
|
||||
262144: FLAG1 Red glow
|
||||
524288: FLAG2 Blue glow
|
||||
1048576: IONRIPPER
|
||||
2097152: GREENGIB
|
||||
4194304: BLUE_HB Blue hyperblaster glow
|
||||
8388608: SPINNING_LIGHTS Red spinning lights
|
||||
16777216: PLASMA
|
||||
33554432: TRAP
|
||||
67108864: TRACKER
|
||||
134217728: DOUBLE Yellow shell
|
||||
268435456: SPHERETRANS Transparent
|
||||
536870912: TAGTRAIL
|
||||
1073741824: HALF_DAMAGE
|
||||
2147483648: TRACKER_TRAIL
|
||||
|
||||
"renderfx"
|
||||
1: MINLIGHT Never completely dark
|
||||
2: VIEWERMODEL
|
||||
4: WEAPONMODEL
|
||||
8: FULLBRIGHT
|
||||
16: DEPTHHACK
|
||||
32: TRANSLUCENT Transparent
|
||||
64: FRAMELERP
|
||||
128: BEAM
|
||||
512: GLOW Pulsating glow of normal Q2 pickup items
|
||||
1024: SHELL_RED
|
||||
2048: SHELL_GREEN
|
||||
4096: SHELL_BLUE
|
||||
32768: IR_VISIBLE
|
||||
65536: SHELL_DOUBLE
|
||||
131072: SHELL_HALF_DAMAGE White shell
|
||||
262144: USE_DISGUISE
|
||||
"movewith" Targetname of the entity to move with
|
||||
*/
|
||||
|
||||
#define TOGGLE 2
|
||||
#define NOT_IR 4
|
||||
#define PLAYER_MODEL 8
|
||||
#define NO_MODEL 16
|
||||
#define ANIM_ONCE 32
|
||||
|
||||
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator);
|
||||
|
||||
void modelspawn_think (edict_t *self)
|
||||
{
|
||||
self->s.frame++;
|
||||
if (self->s.frame >= self->framenumbers)
|
||||
{
|
||||
self->s.frame = self->startframe;
|
||||
if (self->spawnflags & ANIM_ONCE)
|
||||
{
|
||||
model_spawn_use(self,world,world);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
gi.linkentity(self);
|
||||
if (!strcmp(self->classname, "model_train"))
|
||||
train_move_children (self);
|
||||
}
|
||||
|
||||
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->delay) // we started off
|
||||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
self->delay = 0;
|
||||
if (self->framenumbers > 1)
|
||||
{
|
||||
self->think = modelspawn_think;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.sound = self->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
self->s.attenuation = self->attenuation;
|
||||
#endif
|
||||
}
|
||||
else // we started active
|
||||
{
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->delay = 1;
|
||||
self->use = model_spawn_use;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
self->s.sound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
if (self->deathtarget)
|
||||
{
|
||||
self->target = self->deathtarget;
|
||||
G_UseTargets (self, attacker);
|
||||
}
|
||||
train_kill_children(self);
|
||||
BecomeExplosion1(self);
|
||||
}
|
||||
|
||||
#define ANIM_MASK (EF_ANIM01|EF_ANIM23|EF_ANIM_ALL|EF_ANIM_ALLFAST)
|
||||
|
||||
void SP_model_spawn (edict_t *ent)
|
||||
{
|
||||
char modelname[256];
|
||||
|
||||
// paranoia check
|
||||
if ((!ent->usermodel) && (!ent->spawnflags & NO_MODEL) && !(ent->spawnflags & PLAYER_MODEL))
|
||||
{
|
||||
gi.dprintf("%s without a model and without NO_MODEL spawnflag at %s\n", ent->classname, vtos(ent->s.origin));
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->class_id = ENTITY_MODEL_SPAWN;
|
||||
|
||||
switch (ent->solidstate)
|
||||
{
|
||||
case 1 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 2 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_TOSS; break;
|
||||
case 3 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 4 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_TOSS; break;
|
||||
default: ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
}
|
||||
|
||||
if (ent->solid != SOLID_NOT )
|
||||
{
|
||||
if (ent->health > 0)
|
||||
{
|
||||
ent->die = model_die;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ent->style)
|
||||
{
|
||||
case 1 : ent->s.effects |= EF_ANIM01; break;
|
||||
case 2 : ent->s.effects |= EF_ANIM23; break;
|
||||
case 3 : ent->s.effects |= EF_ANIM_ALL; break;
|
||||
case 4 : ent->s.effects |= EF_ANIM_ALLFAST; break;
|
||||
}
|
||||
|
||||
// DWH: Rather than use one value (renderfx) we use the
|
||||
// actual values for effects and renderfx. All may
|
||||
// be combined.
|
||||
ent->s.effects |= ent->effects;
|
||||
ent->s.renderfx |= ent->renderfx;
|
||||
|
||||
if (ent->startframe < 0)
|
||||
ent->startframe = 0;
|
||||
if (!ent->framenumbers)
|
||||
ent->framenumbers = 1;
|
||||
// Change framenumbers to last frame to play
|
||||
ent->framenumbers += ent->startframe;
|
||||
|
||||
if (!VectorLength(ent->bleft) && ent->solid == SOLID_BBOX)
|
||||
{
|
||||
gi.dprintf("%s solid with no bleft vector at %s, using default (-16,-16,-16)\n", ent->classname, vtos(ent->s.origin));
|
||||
VectorSet(ent->bleft, -16, -16, -16);
|
||||
}
|
||||
VectorCopy (ent->bleft, ent->mins);
|
||||
|
||||
if (!VectorLength(ent->tright) && ent->solid == SOLID_BBOX)
|
||||
{
|
||||
gi.dprintf("%s solid with no tright vector at %, using default (16,16,16)\n", ent->classname, vtos(ent->s.origin));
|
||||
VectorSet(ent->tright, 16, 16, 16);
|
||||
}
|
||||
VectorCopy (ent->tright, ent->maxs);
|
||||
|
||||
if (ent->solid != SOLID_NOT)
|
||||
ent->clipmask = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER;
|
||||
|
||||
if (ent->spawnflags & NO_MODEL)
|
||||
{ // For rendering effects to work, we MUST use a model
|
||||
ent->s.modelindex = gi.modelindex ("sprites/point.sp2");
|
||||
ent->movetype = MOVETYPE_NOCLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->spawnflags & PLAYER_MODEL)
|
||||
{
|
||||
if (!ent->usermodel || !strlen(ent->usermodel))
|
||||
ent->s.modelindex = MAX_MODELS-1; //was 255
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,"tris.md2"))
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s/tris.md2", ent->usermodel);
|
||||
ent->s.modelindex = gi.modelindex(modelname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,".sp2")) {
|
||||
// Knightmare- check for "sprites/" already in path
|
||||
if ( !strncmp(ent->usermodel, "sprites/", 8) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "sprites/%s", ent->usermodel);
|
||||
}
|
||||
else {
|
||||
// Knightmare- check for "models/" already in path
|
||||
if ( !strncmp(ent->usermodel, "models/", 7) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "models/%s", ent->usermodel);
|
||||
}
|
||||
ent->s.modelindex = gi.modelindex (modelname);
|
||||
}
|
||||
if (ent->startframe < 0)
|
||||
{
|
||||
gi.dprintf("model_spawn with startframe less than 0 at %s\n", vtos(ent->s.origin));
|
||||
ent->startframe = 0;
|
||||
}
|
||||
ent->s.frame = ent->startframe;
|
||||
}
|
||||
|
||||
if (st.noise)
|
||||
ent->noise_index = gi.soundindex (st.noise);
|
||||
//ent->s.sound = ent->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
ent->s.attenuation = ent->attenuation;
|
||||
#endif
|
||||
|
||||
if (ent->skinnum) // Knightmare- selectable skin
|
||||
ent->s.skinnum = ent->skinnum;
|
||||
|
||||
if (ent->spawnflags & ANIM_ONCE)
|
||||
ent->spawnflags |= TOGGLE;
|
||||
|
||||
if (ent->spawnflags & TOGGLE)
|
||||
{ // Knightmare- allow starting off (but not for model_train)
|
||||
if ( (strcmp(ent->classname, "model_train") != 0) && (ent->delay != 0) ) {
|
||||
ent->delay = 1;
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
}
|
||||
else {
|
||||
ent->delay = 0;
|
||||
}
|
||||
ent->use = model_spawn_use;
|
||||
}
|
||||
|
||||
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
|
||||
{
|
||||
ent->think = modelspawn_think;
|
||||
ent->nextthink = level.time + 2*FRAMETIME;
|
||||
}
|
||||
|
||||
if (ent->spawnflags & NOT_IR)
|
||||
ent->s.renderfx &= ~RF_IR_VISIBLE;
|
||||
else
|
||||
ent->s.renderfx |= RF_IR_VISIBLE;
|
||||
|
||||
gi.linkentity (ent);
|
||||
}
|
||||
|
||||
/*QUAKED model_train (1 0 0) (-8 -8 -8) (8 8 8) START_ON TOGGLE BLOCK_STOPS PLAYER NO_MODEL ROTATE ROT_CONST SMOOTH
|
||||
A moving model. The "team" key allows you to team train entities together.
|
||||
|
||||
Spawnflags:
|
||||
PLAYER Set this if you want to use a player model
|
||||
NO_MODEL Don't use a model. Usefull for placing particle effects and dynamic lights on their own
|
||||
SPLINE: If set, the func_train will follow a spline curve between path_corners. What this means is you can create near perfectly smooth curvilinear paths with a handful of path_corners. The train will constantly turn to face the direction it is moving (unless yaw_speed and pitch_speed are negative values). For a couple of examples, see the rottrain and lcraft example maps (available on the downloads page.) The shape of the spline curve is controlled by the location and pitch and yaw angles of the train's path_corners. Train roll angle will vary linearly between path_corner roll angle values (the third component of the angles vector).
|
||||
-----------------------
|
||||
Key/Value pairs:
|
||||
"style" Specifies the animation type to use.
|
||||
0: None (unless startframe and framenumbers are used)
|
||||
1: ANIM01 - cycle between frames 0 and 1 at 2 hz
|
||||
2: ANIM23 - cycle between frames 2 and 3 at 2 hz
|
||||
3: ANIM_ALL - cycle through all frames at 2 hz
|
||||
4: ANIM_ALLFAST - cycle through all frames at 10 hz
|
||||
|
||||
Note: The animation flags override startframe and framenumbers settings you may have enterered. ANIM_ALL and ANIM_ALLFAST don't do what you might think - rather than setting a framerate, these apparently cause the model to cycle through its ENTIRE sequence of animations in 0.5 or 0.1 seconds... which for monster and player models is of course not possible. Looks exceptionally goofy.
|
||||
|
||||
"usermodel" The model to load (models/ is already coded)
|
||||
"startframe" The starting frame : default 0
|
||||
"framenumbers" The number of frames you want to display after startframe
|
||||
"skinnum" The skin number to use, default 0
|
||||
"health" If non-zero and solidstate is 3 or 4 (solid), the entity will be shootable. When destroyed, it blows up with a no-damage explosion.
|
||||
"target" first path_corner"
|
||||
"team" func_train or func_rotating
|
||||
"solidstate"
|
||||
1 = Not solid (default)
|
||||
2 = Bounding box
|
||||
NOTE : if you want the model to be solid then you must enter vector values into the following fields :
|
||||
"bleft" = the point that is at the bottom left of the models bounding box in a model editor
|
||||
"tright" = the point that is at the top left of the models bounding box in a model editor
|
||||
|
||||
"speed" How fast the model should move
|
||||
"accel" Acceleration
|
||||
"decel" Deceleration
|
||||
|
||||
"pitch_speed" (Nose up & Down) in degrees per second (defualt 20)
|
||||
"yaw_speed" (Side-to-side "wiggle") in degrees per second (default 20)
|
||||
"roll_speed" (Banking) in degrees per second toward the next path corner's set roll
|
||||
"dmg" default 2, damage to inflict when blocked
|
||||
"noise" Sound model makes while moving(path/file.wav)
|
||||
"effects"
|
||||
1: ROTATE Rotate like a weapon
|
||||
2: GIB
|
||||
8: BLASTER Yellowish orange glow plus particles
|
||||
16: ROCKET Rocket trail
|
||||
32: GRENADE Grenade trail
|
||||
64: HYPERBLASTER BLASTER w/o the particles
|
||||
128: BFG Big green ball
|
||||
256: COLOR_SHELL
|
||||
512: POWERSCREEN Green power shield
|
||||
16384: FLIES Ewwww
|
||||
32768: QUAD Blue shell
|
||||
65536: PENT Red shell
|
||||
131072: TELEPORTER Teleporter particles
|
||||
262144: FLAG1 Red glow
|
||||
524288: FLAG2 Blue glow
|
||||
1048576: IONRIPPER
|
||||
2097152: GREENGIB
|
||||
4194304: BLUE_HB Blue hyperblaster glow
|
||||
8388608: SPINNING_LIGHTS Red spinning lights
|
||||
16777216: PLASMA
|
||||
33554432: TRAP
|
||||
67108864: TRACKER
|
||||
134217728: DOUBLE Yellow shell
|
||||
268435456: SPHERETRANS Transparent
|
||||
536870912: TAGTRAIL
|
||||
1073741824: HALF_DAMAGE
|
||||
2147483648: TRACKER_TRAIL
|
||||
|
||||
"renderfx"
|
||||
1: MINLIGHT Never completely dark
|
||||
2: VIEWERMODEL
|
||||
4: WEAPONMODEL
|
||||
8: FULLBRIGHT
|
||||
16: DEPTHHACK
|
||||
32: TRANSLUCENT Transparent
|
||||
64: FRAMELERP
|
||||
128: BEAM
|
||||
512: GLOW Pulsating glow of normal Q2 pickup items
|
||||
1024: SHELL_RED
|
||||
2048: SHELL_GREEN
|
||||
4096: SHELL_BLUE
|
||||
32768: IR_VISIBLE
|
||||
65536: SHELL_DOUBLE
|
||||
131072: SHELL_HALF_DAMAGE White shell
|
||||
262144: USE_DISGUISE
|
||||
|
||||
To have other entities move with the model train, set the door pieces' movewith values to the same as the train's targetname and they will move in
|
||||
unison, and also still be able to move relative to the train themselves, and can be attached and detached using target_movewith.
|
||||
NOTE: All the pieces must be created after the model train entity, otherwise they will move ahead of it.
|
||||
*/
|
||||
|
||||
#define MODEL_TRAIN_START_ON 1
|
||||
#define MODEL_TRAIN_TOGGLE 2
|
||||
#define MODEL_TRAIN_BLOCK_STOPS 4
|
||||
#define MODEL_TRAIN_ROTATE 32
|
||||
#define MODEL_TRAIN_ROT_CONST 64
|
||||
#define TRAIN_ANIM 32
|
||||
#define TRAIN_ANIM_FAST 64
|
||||
#define MODEL_TRAIN_SMOOTH 128
|
||||
|
||||
#define TRAIN_ROTATE 8
|
||||
#define TRAIN_ROT_CONST 16
|
||||
#define TRAIN_SPLINE 8192
|
||||
|
||||
void model_train_animator(edict_t *animator)
|
||||
{
|
||||
edict_t *train;
|
||||
|
||||
train = animator->owner;
|
||||
if (!train || !train->inuse)
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
if (Q_stricmp(train->classname, "model_train"))
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
if (VectorLength(train->velocity) == 0)
|
||||
return;
|
||||
train->s.frame++;
|
||||
if (train->s.frame >= train->framenumbers)
|
||||
train->s.frame = train->startframe;
|
||||
gi.linkentity(train);
|
||||
}
|
||||
|
||||
void SP_model_train (edict_t *self)
|
||||
{
|
||||
SP_model_spawn (self);
|
||||
|
||||
self->class_id = ENTITY_MODEL_TRAIN;
|
||||
|
||||
// Reset s.sound, which SP_model_spawn may have turned on
|
||||
self->moveinfo.sound_middle = self->s.sound;
|
||||
self->s.sound = 0;
|
||||
|
||||
if (!self->inuse) return;
|
||||
|
||||
// Reset some things from SP_model_spawn
|
||||
self->delay = 0;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
|
||||
self->s.sound = self->noise_index;
|
||||
|
||||
if (self->health)
|
||||
{
|
||||
self->die = model_die;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
if (self->framenumbers > self->startframe+1)
|
||||
{
|
||||
edict_t *animator;
|
||||
animator = G_Spawn();
|
||||
animator->owner = self;
|
||||
animator->think = model_train_animator;
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.frame = self->startframe;
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
|
||||
// Really gross stuff here... translate model_spawn spawnflags
|
||||
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
|
||||
// already been checked in SP_model_spawn and are never re-used,
|
||||
// so it's OK to overwrite those.
|
||||
if (self->spawnflags & MODEL_TRAIN_ROTATE)
|
||||
{
|
||||
self->spawnflags &= ~MODEL_TRAIN_ROTATE;
|
||||
self->spawnflags |= TRAIN_ROTATE;
|
||||
|
||||
}
|
||||
if (self->spawnflags & MODEL_TRAIN_ROT_CONST)
|
||||
{
|
||||
self->spawnflags &= ~MODEL_TRAIN_ROT_CONST;
|
||||
self->spawnflags |= TRAIN_ROT_CONST;
|
||||
}
|
||||
//Knightmare- change both rotate flags to spline flag
|
||||
if ((self->spawnflags & TRAIN_ROTATE) && (self->spawnflags &TRAIN_ROT_CONST))
|
||||
{
|
||||
self->spawnflags &= ~TRAIN_ROTATE;
|
||||
self->spawnflags &= ~TRAIN_ROT_CONST;
|
||||
self->spawnflags |= TRAIN_SPLINE;
|
||||
}
|
||||
if (self->style == 3)
|
||||
self->spawnflags |= TRAIN_ANIM; // 32
|
||||
if (self->style == 4)
|
||||
self->spawnflags |= TRAIN_ANIM_FAST; // 64
|
||||
|
||||
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
|
||||
// Move_Final rather than slowing down (if necessary) for one
|
||||
// frame.
|
||||
if (self->spawnflags & MODEL_TRAIN_SMOOTH)
|
||||
self->smooth_movement = 1;
|
||||
else
|
||||
self->smooth_movement = 0;
|
||||
|
||||
self->blocked = train_blocked;
|
||||
if (self->spawnflags & MODEL_TRAIN_BLOCK_STOPS)
|
||||
self->dmg = 0;
|
||||
else
|
||||
{
|
||||
if (!self->dmg)
|
||||
self->dmg = 100;
|
||||
}
|
||||
|
||||
if (!self->speed)
|
||||
self->speed = 100;
|
||||
|
||||
// Mappack
|
||||
if (!self->accel)
|
||||
self->moveinfo.accel = self->speed;
|
||||
else
|
||||
self->moveinfo.accel = self->accel;
|
||||
if (!self->decel)
|
||||
self->moveinfo.decel = self->speed;
|
||||
else
|
||||
self->moveinfo.decel = self->decel;
|
||||
self->moveinfo.speed = self->speed;
|
||||
|
||||
self->use = train_use;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
if (self->target)
|
||||
{
|
||||
// start trains on the second frame, to make sure their targets have had
|
||||
// a chance to spawn
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = func_train_find;
|
||||
}
|
||||
else
|
||||
gi.dprintf ("model_train without a target at %s\n", vtos(self->s.origin));
|
||||
|
||||
}
|
||||
|
||||
void SP_model_train_origin (edict_t *self)
|
||||
{
|
||||
self->spawnflags |= TRAIN_ORIGIN;
|
||||
SP_model_train (self);
|
||||
}
|
File diff suppressed because it is too large
Load diff
3176
missionpack/g_target_laz.c
Normal file
3176
missionpack/g_target_laz.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -711,7 +711,7 @@ void G_FreeEdict (edict_t *ed)
|
|||
}*/
|
||||
|
||||
if (ed->speaker) // recursively remove train's speaker entity
|
||||
G_FreeEdict(ed->speaker);
|
||||
G_FreeEdict (ed->speaker);
|
||||
|
||||
// Knightmare- stop target_playback
|
||||
if (ed->classname && (strlen(ed->classname) > 0) && !strcmp(ed->classname, "target_playback"))
|
||||
|
|
|
@ -737,7 +737,7 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s
|
|||
VectorScale (aimdir, speed, grenade->velocity);
|
||||
VectorMA (grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity);
|
||||
VectorMA (grenade->velocity, crandom() * 10.0, right, grenade->velocity);
|
||||
//Knightmare- add player's base velocity to grenade
|
||||
// Knightmare- add player's base velocity to grenade
|
||||
if (add_velocity_throw->value && self->client)
|
||||
VectorAdd (grenade->velocity, self->velocity, grenade->velocity);
|
||||
else if (self->groundentity)
|
||||
|
|
|
@ -363,7 +363,7 @@ void dog_dead (edict_t *self)
|
|||
M_FlyCheck (self);
|
||||
|
||||
// Lazarus monster fade
|
||||
if(world->effects & FX_WORLDSPAWN_CORPSEFADE)
|
||||
if (world->effects & FX_WORLDSPAWN_CORPSEFADE)
|
||||
{
|
||||
self->think = FadeDieSink;
|
||||
self->nextthink = level.time+corpse_fadetime->value;
|
||||
|
@ -425,7 +425,7 @@ void dog_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
|
|||
self->deadflag = DEAD_DEAD;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
|
||||
if(random() < 0.5)
|
||||
if (random() < 0.5)
|
||||
self->monsterinfo.currentmove = &dog_move_death1;
|
||||
else
|
||||
self->monsterinfo.currentmove = &dog_move_death2;
|
||||
|
@ -452,6 +452,9 @@ void SP_monster_dog (edict_t *self)
|
|||
sound_attack = gi.soundindex ("dog/dattack1.wav");
|
||||
sound_sight = gi.soundindex ("dog/dsight.wav");
|
||||
sound_idle = gi.soundindex ("dog/idle.wav");
|
||||
|
||||
// precache gibs
|
||||
gi.modelindex ("mmodels/monsters/dog/h_dog.md2");
|
||||
|
||||
self->movetype = MOVETYPE_STEP;
|
||||
self->solid = SOLID_BBOX;
|
||||
|
@ -467,11 +470,11 @@ void SP_monster_dog (edict_t *self)
|
|||
VectorSet (self->mins, -16, -16, -24);
|
||||
VectorSet (self->maxs, 16, 16, 8);
|
||||
|
||||
if(!self->health)
|
||||
if (!self->health)
|
||||
self->health = 50;
|
||||
if(!self->gib_health)
|
||||
if (!self->gib_health)
|
||||
self->gib_health = -100;
|
||||
if(!self->mass)
|
||||
if (!self->mass)
|
||||
self->mass = 80;
|
||||
|
||||
self->pain = dog_pain;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Generated by ModelEd
|
||||
// DOG
|
||||
// Dog
|
||||
|
||||
#define FRAME_attack1 0
|
||||
#define FRAME_attack2 1
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Generated by ModelEd
|
||||
// FREDDIE
|
||||
|
||||
#define FRAME_run1 0
|
||||
|
|
|
@ -31,25 +31,25 @@
|
|||
#define FRAME_perch28 27
|
||||
#define FRAME_perch29 28
|
||||
#define FRAME_perch30 29
|
||||
#define FRAME_walk1 30
|
||||
#define FRAME_walk2 31
|
||||
#define FRAME_walk3 32
|
||||
#define FRAME_walk4 33
|
||||
#define FRAME_walk5 34
|
||||
#define FRAME_walk6 35
|
||||
#define FRAME_walk7 36
|
||||
#define FRAME_walk8 37
|
||||
#define FRAME_walk9 38
|
||||
#define FRAME_walk1 30
|
||||
#define FRAME_walk2 31
|
||||
#define FRAME_walk3 32
|
||||
#define FRAME_walk4 33
|
||||
#define FRAME_walk5 34
|
||||
#define FRAME_walk6 35
|
||||
#define FRAME_walk7 36
|
||||
#define FRAME_walk8 37
|
||||
#define FRAME_walk9 38
|
||||
#define FRAME_walk10 39
|
||||
#define FRAME_soar1 40
|
||||
#define FRAME_soar2 41
|
||||
#define FRAME_soar3 42
|
||||
#define FRAME_soar4 43
|
||||
#define FRAME_soar5 44
|
||||
#define FRAME_soar6 45
|
||||
#define FRAME_soar7 46
|
||||
#define FRAME_soar8 47
|
||||
#define FRAME_soar9 48
|
||||
#define FRAME_soar1 40
|
||||
#define FRAME_soar2 41
|
||||
#define FRAME_soar3 42
|
||||
#define FRAME_soar4 43
|
||||
#define FRAME_soar5 44
|
||||
#define FRAME_soar6 45
|
||||
#define FRAME_soar7 46
|
||||
#define FRAME_soar8 47
|
||||
#define FRAME_soar9 48
|
||||
#define FRAME_soar10 49
|
||||
#define FRAME_soar11 50
|
||||
#define FRAME_soar12 51
|
||||
|
@ -83,18 +83,18 @@
|
|||
#define FRAME_soar40 79
|
||||
#define FRAME_soar41 80
|
||||
#define FRAME_soar42 81
|
||||
#define FRAME_pain1 82
|
||||
#define FRAME_pain2 83
|
||||
#define FRAME_pain3 84
|
||||
#define FRAME_pain4 85
|
||||
#define FRAME_pain1 82
|
||||
#define FRAME_pain2 83
|
||||
#define FRAME_pain3 84
|
||||
#define FRAME_pain4 85
|
||||
#define FRAME_soarpain1 86
|
||||
#define FRAME_soarpain2 87
|
||||
#define FRAME_soarpain3 88
|
||||
#define FRAME_soarpain4 89
|
||||
#define FRAME_die1 90
|
||||
#define FRAME_die2 91
|
||||
#define FRAME_die3 92
|
||||
#define FRAME_die4 93
|
||||
#define FRAME_die1 90
|
||||
#define FRAME_die2 91
|
||||
#define FRAME_die3 92
|
||||
#define FRAME_die4 93
|
||||
#define FRAME_soardie1 94
|
||||
#define FRAME_soardie2 95
|
||||
#define FRAME_soardie3 96
|
||||
|
@ -118,74 +118,74 @@
|
|||
#define FRAME_soardie21 114
|
||||
#define FRAME_soardie22 115
|
||||
#define FRAME_soardie23 116
|
||||
#define FRAME_soardie24 117
|
||||
#define FRAME_soardie25 118
|
||||
#define FRAME_soardie26 119
|
||||
#define FRAME_soardie27 120
|
||||
#define FRAME_soardie28 121
|
||||
#define FRAME_soardie29 122
|
||||
#define FRAME_soardie30 123
|
||||
#define FRAME_takeoff1 124
|
||||
#define FRAME_takeoff2 125
|
||||
#define FRAME_takeoff3 126
|
||||
#define FRAME_takeoff4 127
|
||||
#define FRAME_takeoff5 128
|
||||
#define FRAME_takeoff6 129
|
||||
#define FRAME_fly1 130
|
||||
#define FRAME_fly2 131
|
||||
#define FRAME_fly3 132
|
||||
#define FRAME_fly4 133
|
||||
#define FRAME_fly5 134
|
||||
#define FRAME_melee1 135
|
||||
#define FRAME_melee2 136
|
||||
#define FRAME_melee3 137
|
||||
#define FRAME_melee4 138
|
||||
#define FRAME_land1 139
|
||||
#define FRAME_land2 140
|
||||
#define FRAME_land3 141
|
||||
#define FRAME_land4 142
|
||||
#define FRAME_land5 143
|
||||
#define FRAME_land6 144
|
||||
#define FRAME_land7 145
|
||||
#define FRAME_land8 146
|
||||
#define FRAME_land9 147
|
||||
#define FRAME_land10 148
|
||||
#define FRAME_land11 149
|
||||
#define FRAME_land12 150
|
||||
#define FRAME_land13 151
|
||||
#define FRAME_skin 152
|
||||
#define FRAME_bankR1 153
|
||||
#define FRAME_bankR2 154
|
||||
#define FRAME_bankR3 155
|
||||
#define FRAME_bankR4 156
|
||||
#define FRAME_bankR5 157
|
||||
#define FRAME_bankR6 158
|
||||
#define FRAME_bankR7 159
|
||||
#define FRAME_bankR8 160
|
||||
#define FRAME_bankR9 161
|
||||
#define FRAME_bankR10 162
|
||||
#define FRAME_bankL1 163
|
||||
#define FRAME_bankL2 164
|
||||
#define FRAME_bankL3 165
|
||||
#define FRAME_bankL4 166
|
||||
#define FRAME_bankL5 167
|
||||
#define FRAME_bankL6 168
|
||||
#define FRAME_bankL7 169
|
||||
#define FRAME_bankL8 170
|
||||
#define FRAME_bankL9 171
|
||||
#define FRAME_bankL10 172
|
||||
#define FRAME_TEMPLATE1 173
|
||||
#define FRAME_soardie24 117
|
||||
#define FRAME_soardie25 118
|
||||
#define FRAME_soardie26 119
|
||||
#define FRAME_soardie27 120
|
||||
#define FRAME_soardie28 121
|
||||
#define FRAME_soardie29 122
|
||||
#define FRAME_soardie30 123
|
||||
#define FRAME_takeoff1 124
|
||||
#define FRAME_takeoff2 125
|
||||
#define FRAME_takeoff3 126
|
||||
#define FRAME_takeoff4 127
|
||||
#define FRAME_takeoff5 128
|
||||
#define FRAME_takeoff6 129
|
||||
#define FRAME_fly1 130
|
||||
#define FRAME_fly2 131
|
||||
#define FRAME_fly3 132
|
||||
#define FRAME_fly4 133
|
||||
#define FRAME_fly5 134
|
||||
#define FRAME_melee1 135
|
||||
#define FRAME_melee2 136
|
||||
#define FRAME_melee3 137
|
||||
#define FRAME_melee4 138
|
||||
#define FRAME_land1 139
|
||||
#define FRAME_land2 140
|
||||
#define FRAME_land3 141
|
||||
#define FRAME_land4 142
|
||||
#define FRAME_land5 143
|
||||
#define FRAME_land6 144
|
||||
#define FRAME_land7 145
|
||||
#define FRAME_land8 146
|
||||
#define FRAME_land9 147
|
||||
#define FRAME_land10 148
|
||||
#define FRAME_land11 149
|
||||
#define FRAME_land12 150
|
||||
#define FRAME_land13 151
|
||||
#define FRAME_skin 152
|
||||
#define FRAME_bankR1 153
|
||||
#define FRAME_bankR2 154
|
||||
#define FRAME_bankR3 155
|
||||
#define FRAME_bankR4 156
|
||||
#define FRAME_bankR5 157
|
||||
#define FRAME_bankR6 158
|
||||
#define FRAME_bankR7 159
|
||||
#define FRAME_bankR8 160
|
||||
#define FRAME_bankR9 161
|
||||
#define FRAME_bankR10 162
|
||||
#define FRAME_bankL1 163
|
||||
#define FRAME_bankL2 164
|
||||
#define FRAME_bankL3 165
|
||||
#define FRAME_bankL4 166
|
||||
#define FRAME_bankL5 167
|
||||
#define FRAME_bankL6 168
|
||||
#define FRAME_bankL7 169
|
||||
#define FRAME_bankL8 170
|
||||
#define FRAME_bankL9 171
|
||||
#define FRAME_bankL10 172
|
||||
#define FRAME_TEMPLATE1 173
|
||||
#define FRAME_perchSAFE1 174
|
||||
#define FRAME_flySAFE1 175
|
||||
#define FRAME_flySAFE2 176
|
||||
#define FRAME_flySAFE3 177
|
||||
#define FRAME_flySAFE4 178
|
||||
#define FRAME_flySAFE5 179
|
||||
#define FRAME_flySAFE6 180
|
||||
#define FRAME_flySAFE7 181
|
||||
#define FRAME_flySAFE8 182
|
||||
#define FRAME_flySAFE9 183
|
||||
#define FRAME_flySAFE10 184
|
||||
#define FRAME_flySAFE1 175
|
||||
#define FRAME_flySAFE2 176
|
||||
#define FRAME_flySAFE3 177
|
||||
#define FRAME_flySAFE4 178
|
||||
#define FRAME_flySAFE5 179
|
||||
#define FRAME_flySAFE6 180
|
||||
#define FRAME_flySAFE7 181
|
||||
#define FRAME_flySAFE8 182
|
||||
#define FRAME_flySAFE9 183
|
||||
#define FRAME_flySAFE10 184
|
||||
#define FRAME_takeoffSAFE1 185
|
||||
#define FRAME_takeoffSAFE2 186
|
||||
#define FRAME_takeoffSAFE3 187
|
||||
|
|
|
@ -169,10 +169,22 @@ SOURCE=.\g_misc.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_misc_laz.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_misc_nm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_misc_q1.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_model.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_monster.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -245,6 +257,10 @@ SOURCE=.\g_target.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_target_laz.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_thing.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -491,10 +491,22 @@
|
|||
RelativePath="g_misc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_misc_laz.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_misc_nm.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_misc_q1.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_model.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="g_monster.c"
|
||||
>
|
||||
|
@ -567,6 +579,10 @@
|
|||
RelativePath="g_target.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_target_laz.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="g_thing.c"
|
||||
>
|
||||
|
|
|
@ -923,7 +923,7 @@ void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
// Knightmare- the missing quadfire sounds
|
||||
if (ent->client->quadfire_framenum > level.framenum)
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/quadfire3.wav"), 1, ATTN_NORM, 0);
|
||||
fire (ent, ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2) );
|
||||
fire (ent, ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1438,7 +1438,7 @@ ROCKET
|
|||
======================================================================
|
||||
*/
|
||||
|
||||
edict_t *rocket_target(edict_t *self, vec3_t start, vec3_t forward)
|
||||
edict_t *rocket_target (edict_t *self, vec3_t start, vec3_t forward)
|
||||
{
|
||||
float bd, d;
|
||||
int i;
|
||||
|
|
Loading…
Reference in a new issue