More entity documentation, rename some filesystem stuff.

This commit is contained in:
Marco Cawthorne 2025-01-29 04:37:35 -08:00
parent 9876ddea5a
commit e1060dc993
56 changed files with 754 additions and 114 deletions

View file

@ -11,12 +11,12 @@ using the usual `make` syntax:
make _target_ GAME=id1
Where `_target_` is to be substituted with a valid target.
The `GAME=` override decides which game directory to target.
Where `_target_` is to be substituted with a valid target. The `GAME=`
override decides which game directory to consider using.
Generally, you want to make a copy of either `id1`, `qw` or `data1`,
name it something original (say `foobar`) and then you would
pass `GAME=foobar` instead of `GAME=id1`.
name it something original (say `foobar`) and then you would pass
`GAME=foobar` instead of `GAME=id1`.
If the GAME variable isn't passed, `id1` is assumed.
@ -24,23 +24,21 @@ If the GAME variable isn't passed, `id1` is assumed.
### help
Will display some short help information on important targets
that are available.
Will display some short help information on important targets that
are available. Also the default result when no target is specified.
### all
Build all of the code, models, maps, textures and 2D graphics for
a given game.
### pak
Will build pak0.pak and pak1.pak files (shareware and registered archives) for your
game. Ensure you use the right Precache_* APIs so the tool knows which data belongs
to shareware and which to registered versions of your game.
Build all of the code, models, maps, textures and 2D graphics for a
given game. You probably want to run this sparingly (or on the first time).
### wad
Builds all texture wads for a given game.
Builds all texture wads for a given game. The textures are to
be placed within a sub-directory within your game's `texturesrc/`
directory. Each directory gets compiled into its own WAD. If you
want to target WAD3, simply place an empty file named `WAD3` within
the desired directory.
### maps
@ -48,7 +46,9 @@ Builds all the maps (and texture wads) for a given game.
### GAME/maps/mapname.bsp
Will compile GAME/maps/mapname.bsp. So if you were to run `make id1/maps/start.bsp`, that would be valid - as long as `id1/mapsrc/start.map` was to exist.
Will compile GAME/maps/mapname.bsp. So if you were to run
`make id1/maps/start.bsp`, that would be valid - as long as
`id1/mapsrc/start.map` was to exist.
### models
@ -56,20 +56,28 @@ Builds all models for a given game using FTEQW's iqmtool.
### defs
Builds an entities.def file for use in QED/Radiant and integrates it into whatever editors are present in the local installation.
Currently it will also build all available editors, but that will probably change.
Builds an entities.def file for use in QED/Radiant and integrates
it into the editors that are present in the local installation.
Currently it will also build all available editors, but that will
probably change.
### gfx
Builds all the 2D graphics (menu mainy) for a given game.
Builds all the 2D graphics (menu related, mainly) for a given game.
### palette
Rebuilds the palette for the given game. Reads from GAME/gfxsrc/palette.png and will ensure to build a new palette.lmp for use in the engine, as well as a colormap.lmp for software renderers as well as a palette.pal for use in WorldCraft based editors.
Rebuilds the palette for the given game. Reads from
GAME/gfxsrc/palette.png and will ensure to build a new palette.lmp for
use in the engine, as well as a colormap.lmp for software renderers
as well as a palette.pal for use in WorldCraft based editors.
You will probably want to rebuild all your other assets after this.
### update
Updates ThirdParty repos.
Updates tools + game repos.
### radiant
@ -77,13 +85,28 @@ Builds GtkRadiant and gives it with a launcher: ./radiant
### netradiant-custom
Builds NetRadiant-Custom, a popular alternative to the upstream GtkRadiant.
You can use this to update + rebuild a new version.
Will also place a launcher in your game directory: ./radiant
Builds NetRadiant-Custom, a popular alternative to the upstream
GtkRadiant. You can use this to update + rebuild a new version.
Will also place a launcher in your game directory: ./netradiant-custom
### launcher
Builds a launcher for your game. Will accept command-line arguments and will execute a config
file with your username if present. This way developers can stay out of each others way, even
on a non-versioned filesystem.
Builds a launcher for your game using FTEQW. Will accept command-line arguments
and will execute a config file with your username if present. This way
developers can stay out of each others way, even on a non-versioned
filesystem. This is for development purposes only.
### pak
Will build pak0.pak and pak1.pak files (shareware and registered
archives) for your game. Ensure you use the right Precache_* APIs so
the tool knows which data belongs to shareware and which to registered
versions of your game.
## Legal advice regarding pop.lmp
Do not ship Quake's gfx/pop.lmp. Vanilla engines will look for it, but
forks/source-ports will not. Feel free to compile your own proof-of-purchase
check in your own custom engine.

View file

@ -64,9 +64,15 @@ wads: imgtool palette
maps: wads
./Tools/build_maps.sh $(GAME)
$(GAME)/maps/%.bsp: qbsp qrad qvis
empty:
printf "\n"
$(GAME)/maps/%.bsp: qbsp qrad qvis empty
Tools/make_map.sh $(GAME) "$@"
$(GAME)/models/%.mdl: iqmtool empty
Tools/make_model.sh $(GAME) "$@"
models: iqmtool palette
./Tools/build_models.sh $(GAME)
@ -160,7 +166,7 @@ netradiant-custom:
launcher:
Tools/make_launcher.sh "./" "./fteqw -readonly -basedir ./ -netquake -game $(GAME) +exec $(USER).cfg" $(GAME).sh
defs: radiant netradiant-custom
defs:
Tools/make_mapdef.sh $(GAME)
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>" > "$(RADIANT_GAME)"
echo "<game" >> "$(RADIANT_GAME)"

34
id1/src/decor/flame.qc Normal file
View file

@ -0,0 +1,34 @@
class quakeFlame:ncDecor {
void quakeFlame( void );
virtual void Spawn( void );
};
void quakeFlame::quakeFlame( void ) {
}
void quakeFlame::Spawn( void ) {
StaticDecor( "progs/flame2.mdl", "ambience/fire1.wav" );
}
/*QUAKED light_flame_large_yellow (0 .5 0) (-10 -10 -20) (10 10 20)
# OVERVIEW
Large yellow flame. Respects the light values from the `light` entity.
*/
LINK_ENTITY_TO_CLASS(light_flame_large_yellow, quakeFlame)
/*QUAKED light_flame_small_yellow (0 .5 0) (-10 -10 -20) (10 10 20)
# OVERVIEW
Small yellow flame. Respects the light values from the `light` entity.
*/
LINK_ENTITY_TO_CLASS(light_flame_small_yellow, quakeFlame)
/*QUAKED light_flame_small_white (0 .5 0) (-10 -10 -20) (10 10 20)
# OVERVIEW
Small white flame. Respects the light values from the `light` entity.
*/
LINK_ENTITY_TO_CLASS(light_flame_small_white, quakeFlame)

20
id1/src/decor/globe.qc Normal file
View file

@ -0,0 +1,20 @@
class quakeLightGlobe:ncDecor {
void quakeLightGlobe( void );
virtual void Spawn( void );
};
void quakeLightGlobe::quakeLightGlobe( void ) {
}
void quakeLightGlobe::Spawn( void ) {
StaticDecor( "progs/s_light.spr", "" );
}
/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
# OVERVIEW
Sphere globe light. Respects the light values from the `light` entity.
*/
LINK_ENTITY_TO_CLASS(light_globe, quakeLightGlobe)

21
id1/src/decor/torch.qc Normal file
View file

@ -0,0 +1,21 @@
class quakeTorch:ncDecor
{
void quakeTorch( void );
virtual void Spawn( void );
};
void quakeTorch::quakeTorch( void ) {
}
void quakeTorch::Spawn( void ) {
StaticDecor( "progs/flame.mdl", "ambience/fire1.wav" );
}
/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
# OVERVIEW
Wall torch. Respects the light values from the `light` entity.
*/
LINK_ENTITY_TO_CLASS(light_torch_small_walltorch, quakeTorch)

165
id1/src/monsters/army.qc Normal file
View file

@ -0,0 +1,165 @@
enum
{
armyAnim_stand1,
armyAnim_stand2,
armyAnim_stand3,
armyAnim_stand4,
armyAnim_stand5,
armyAnim_stand6,
armyAnim_stand7,
armyAnim_stand8,
armyAnim_death1,
armyAnim_death2,
armyAnim_death3,
armyAnim_death4,
armyAnim_death5,
armyAnim_death6,
armyAnim_death7,
armyAnim_death8,
armyAnim_death9,
armyAnim_death10,
armyAnim_deathc1,
armyAnim_deathc2,
armyAnim_deathc3,
armyAnim_deathc4,
armyAnim_deathc5,
armyAnim_deathc6,
armyAnim_deathc7,
armyAnim_deathc8,
armyAnim_deathc9,
armyAnim_deathc10,
armyAnim_deathc11,
armyAnim_load1,
armyAnim_load2,
armyAnim_load3,
armyAnim_load4,
armyAnim_load5,
armyAnim_load6,
armyAnim_load7,
armyAnim_load8,
armyAnim_load9,
armyAnim_load10,
armyAnim_load11,
armyAnim_pain1,
armyAnim_pain2,
armyAnim_pain3,
armyAnim_pain4,
armyAnim_pain5,
armyAnim_pain6,
armyAnim_painb1,
armyAnim_painb2,
armyAnim_painb3,
armyAnim_painb4,
armyAnim_painb5,
armyAnim_painb6,
armyAnim_painb7,
armyAnim_painb8,
armyAnim_painb9,
armyAnim_painb10,
armyAnim_painb11,
armyAnim_painb12,
armyAnim_painb13,
armyAnim_painb14,
armyAnim_painc1,
armyAnim_painc2,
armyAnim_painc3,
armyAnim_painc4,
armyAnim_painc5,
armyAnim_painc6,
armyAnim_painc7,
armyAnim_painc8,
armyAnim_painc9,
armyAnim_painc10,
armyAnim_painc11,
armyAnim_painc12,
armyAnim_painc13,
armyAnim_run1,
armyAnim_run2,
armyAnim_run3,
armyAnim_run4,
armyAnim_run5,
armyAnim_run6,
armyAnim_run7,
armyAnim_run8,
armyAnim_shoot1,
armyAnim_shoot2,
armyAnim_shoot3,
armyAnim_shoot4,
armyAnim_shoot5,
armyAnim_shoot6,
armyAnim_shoot7,
armyAnim_shoot8,
armyAnim_shoot9,
armyAnim_prowl_1,
armyAnim_prowl_2,
armyAnim_prowl_3,
armyAnim_prowl_4,
armyAnim_prowl_5,
armyAnim_prowl_6,
armyAnim_prowl_7,
armyAnim_prowl_8,
armyAnim_prowl_9,
armyAnim_prowl_10,
armyAnim_prowl_11,
armyAnim_prowl_12,
armyAnim_prowl_13,
armyAnim_prowl_14,
armyAnim_prowl_15,
armyAnim_prowl_16,
armyAnim_prowl_17,
armyAnim_prowl_18,
armyAnim_prowl_19,
armyAnim_prowl_20,
armyAnim_prowl_21,
armyAnim_prowl_22,
armyAnim_prowl_23,
armyAnim_prowl_24,
};
class quakeSoldier:ncActor {
void quakeSoldier( void );
virtual void Precache( void );
virtual void Spawn( void );
};
void quakeSoldier::quakeSoldier( void ) {
}
void quakeSoldier::Precache( void ) {
ncEngine::Precache_Model( "progs/soldier.mdl" );
ncEngine::Precache_Model( "progs/gib1.mdl" );
ncEngine::Precache_Model( "progs/gib2.mdl" );
ncEngine::Precache_Model( "progs/gib3.mdl" );
ncEngine::Precache_Model( "progs/h_guard.mdl" );
ncEngine::Precache_Sound( "player/udeath.wav" );
ncEngine::Precache_Sound( "soldier/death1.wav" );
ncEngine::Precache_Sound( "soldier/idle.wav" );
ncEngine::Precache_Sound( "soldier/pain1.wav" );
ncEngine::Precache_Sound( "soldier/pain2.wav" );
ncEngine::Precache_Sound( "soldier/sattck1.wav" );
ncEngine::Precache_Sound( "soldier/sight1.wav" );
}
void quakeSoldier::Spawn( void ) {
SetModel( "progs/soldier.mdl" );
SetSize( VEC_HULL_MIN, VEC_HULL_MAX );
SetWalkCycle( armyAnim_run1, armyAnim_run8, 10.0f );
SetIdleCycle( armyAnim_stand1, armyAnim_stand8, 10.0f );
SetHealth( 30 );
}
/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 32) AMBUSH
# OVERVIEW
Soldier. Health: 30.
# KEYS
- "targetname" : Name
# SPAWNFLAGS
- AMBUSH (1) : Ambush!
*/
LINK_ENTITY_TO_CLASS(monster_army, quakeSoldier)

View file

@ -12,7 +12,11 @@ weapons/rocketlauncher.qc
weapons/shotgun.qc
weapons/supernailgun.qc
weapons/supershotgun.qc
monsters/army.qc
decor/flame.qc
decor/globe.qc
decor/torch.qc
items/quad.qc
rules.qc

View file

@ -0,0 +1,50 @@
/*QUAKED func_detail (0.5 0.5 0.9) ?
# OVERVIEW
Detail brush. Special compiler specific entity that
will be ignored by the vis compiler operations, but
the surrounding geometry may still be cut up.
# KEYS
- "_shadow" : When 0, will not cast a shadow.
*/
/*QUAKED func_detail_illusionary (0.5 0.5 0.9) ?
# OVERVIEW
Non-solid variant of func_detail.
# KEYS
- "_shadow" : When 1, will cast a shadow.
*/
/*QUAKED func_detail_wall (0.5 0.5 0.9) ?
# OVERVIEW
Detail brush that will not cut up geometry, unlike func_detail.
Will still clip surfaces away that are obscured, unlike func_detail_fence.
# KEYS
- "_shadow" : When 0, will not cast a shadow.
*/
/*QUAKED func_detail_fence (0.5 0.5 0.9) ?
# OVERVIEW
Detail brush. Special compiler specific entity that
will be ignored by the vis compiler operations.
# KEYS
- "_shadow" : When 0, will not cast a shadow.
*/
/*QUAKED func_illusionary_visblocker (0.5 0.5 0.9) ?
# OVERVIEW
Non-solid func_detail brush that still culls rendering behind it.
Much like liquid brushes pre WaterVis patches behaved.
# KEYS
- "_shadow" : When 1, will cast a shadow.
*/

View file

@ -1,31 +0,0 @@
class ncLight:ncEntity {
void ncLight( void );
nonvirtual float LightLevelForEntity( ncEntity );
};
void ncLight::ncLight( void ) {
}
#ifndef TARGET_HEXEN2
.float light_level;
#endif
float ncLight::LightLevelForEntity( ncEntity target ) {
float maxDistance = 150; /* Q1/H2 = linear falloff */
float currDistance = ncMath::VLen(GetOrigin() - target.GetOrigin());
if (currDistance > maxDistance)
return 0.0f;
ncEngine::TraceLine(GetOrigin(), target.GetOrigin(), FALSE, this);
if ( ( trace_ent == target ) || ( trace_fraction == 1.0f ) ) {
return maxDistance - currDistance;
} else {
return 0.0f;
}
}
LINK_ENTITY_TO_CLASS(light, ncLight)

View file

@ -4,10 +4,13 @@ func_door.qc
func_illusionary.qc
info_null.qc
info_player_start.qc
light.qc
trigger_auto.qc
trigger_changelevel.qc
trigger_teleport.qc
trigger_multiple.qc
trigger_once.qc
trigger_relay.qc
trigger_secret.qc
camera_node.qc
worldspawn.qc
#endlist

View file

@ -13,8 +13,7 @@ void idTriggerChangelevel::idTriggerChangelevel( void ) {
SetTouchCallback( ChangelevelTouched );
}
string idTriggerChangelevel::GetNextLevel( void )
{
string idTriggerChangelevel::GetNextLevel( void ) {
return map;
}

View file

View file

View file

@ -0,0 +1,77 @@
class ncTriggerMultiple:ncEntity {
void ncTriggerMultiple( void );
nonvirtual void TriggerVolumeTouched( ncEntity );
};
void ncTriggerMultiple::ncTriggerMultiple( void ) {
InitTrigger();
SetTouchCallback( TriggerVolumeTouched );
SPAWNDEFAULT( wait, 0.2f )
}
.float trigger_next;
void ncTriggerMultiple::TriggerVolumeTouched( ncEntity toucher ) {
vector moveDir = ncMath::AnglesToMoveDir( GetAngles() );
if ( trigger_next > time ) {
return;
}
if ( !toucher.IsPlayer() ) {
return;
}
if (moveDir != g_vec_null) {
if (ncMath::AnglesToForward(toucher.GetAngles()) * moveDir < 0.0f) {
return;
}
}
if (classname == "ncTriggerSecret") {
if (toucher.classname != "player") {
return;
}
found_secrets = found_secrets + 1;
ncNet::WriteByte( MSG_ALL, SVC_FOUNDSECRET );
ncNet::MultiCast( [0,0,0], MSG_ALL );
}
ActivateTargets();
toucher.CenterPrint(message);
/* remove */
if (wait == -1) {
Remove();
return;
}
trigger_next = time + wait;
}
/*QUAKED trigger_multiple (.5 .5 .5) ? TRIGGER_ONLY
# OVERVIEW
Variable sized trigger volume.
# KEYS
- "targetname" : Name.
- "target" : Name of entities to activate.
- "health" : If set will need to be be destroyed to be activated, and will have this much health.
- "wait" : Waiting period until it can activate again. 0.2 is the default.
- "delay" : Delay before activating its targets.
- "killtarget" : Removes these entities upon use.
- "angle" : Activator has to face this direction in order to activate.
- "message" : Print this message upon use.
- "sounds" : One of the following:
1) Secret Sound: misc/secret.wav
2) Chat Sound: misc/talk.wav
3) Trigger: misc/trigger1.wav
# SPAWNFLAGS
- TRIGGER_ONLY (1) : Cannot touch this trigger volume.
*/
LINK_ENTITY_TO_CLASS(trigger_multiple, ncTriggerMultiple)

View file

@ -0,0 +1,32 @@
class ncTriggerOnce:ncTriggerMultiple {
void ncTriggerOnce( void );
};
void ncTriggerOnce::ncTriggerOnce( void ) {
wait = -1;
}
/*QUAKED trigger_once (.5 .5 .5) ? TRIGGER_ONLY
# OVERVIEW
Variable sized trigger volume.
Triggers once, then removes itself.
# KEYS
- "targetname" : Name.
- "target" : Name of entities to trigger.
- "health" : If set will need to be be destroyed to be triggered, and will have this much health.
- "killtarget" : Removes these entities upon use.
- "angle" : Activator has to face this direction in order to trigger.
- "message" : Print this message upon use.
- "sounds" : One of the following:
1) Secret Sound: misc/secret.wav
2) Chat Sound: misc/talk.wav
3) Trigger: misc/trigger1.wav
# SPAWNFLAGS
- TRIGGER_ONLY (1) : Cannot touch this trigger volume.
*/
LINK_ENTITY_TO_CLASS(trigger_once, ncTriggerOnce)

View file

View file

View file

@ -0,0 +1,28 @@
class ncTriggerRelay:ncEntity {
void ncTriggerRelay( void );
};
void ncTriggerRelay::ncTriggerRelay( void ) {
InitTrigger();
SetTriggerCallback( ActivateTargets );
}
/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
# OVERVIEW
Point trigger.
# KEYS
- "targetname" : Name.
- "target" : Name of entities to activate.
- "delay" : Delay before activating its targets.
- "killtarget" : Removes these entities upon use.
- "message" : Print this message upon use.
- "sounds" : One of the following:
1) Secret Sound: misc/secret.wav
2) Chat Sound: misc/talk.wav
3) Trigger: misc/trigger1.wav
*/
LINK_ENTITY_TO_CLASS(trigger_relay, ncTriggerRelay)

View file

@ -0,0 +1,35 @@
class ncTriggerSecret:ncTriggerMultiple {
void ncTriggerSecret( void );
};
void ncTriggerSecret::ncTriggerSecret( void ) {
SPAWNDEFAULT( message, "You found a secret area!" )
SPAWNDEFAULT( sounds, 1 )
wait = -1;
total_secrets = total_secrets + 1;
}
/*QUAKED trigger_secret (.5 .5 .5) ? TRIGGER_ONLY
# OVERVIEW
Variable sized trigger volume.
Triggers once, then removes itself.
# KEYS
- "targetname" : Name.
- "target" : Name of entities to trigger.
- "health" : If set will need to be be destroyed to be triggered, and will have this much health.
- "killtarget" : Removes these entities upon use.
- "angle" : Activator has to face this direction in order to trigger.
- "message" : Print this message upon use.
- "sounds" : One of the following:
1) Secret Sound: misc/secret.wav
2) Chat Sound: misc/talk.wav
3) Trigger: misc/trigger1.wav
# SPAWNFLAGS
- TRIGGER_ONLY (1) : Cannot touch this trigger volume.
*/
LINK_ENTITY_TO_CLASS(trigger_secret, ncTriggerSecret)

View file

View file

@ -169,6 +169,7 @@ void ClientKill( void ) {
void ClientConnect( void ) {
Class_Player();
self.classname = "player";
g_gameRules.PlayerConnects( ( ncPlayer ) self );
}

View file

@ -1,3 +1,6 @@
.movementType_t ncActor_movementType;
void ncActor::ncActor ( void ) {
}
@ -8,3 +11,8 @@ void ncActor::_InternalPostSpawn ( void ) {
SetSolid( SOLID_SLIDEBOX );
SetMovetype( MOVETYPE_STEP );
}
void ncActor::SetMovementType ( movementType_t newMovement ) {
/* monsters are auto-aim by default */
ncActor_movementType = newMovement;
}

14
src/system/Actor.qh Normal file
View file

@ -0,0 +1,14 @@
typedef enum
{
MOVEMENTTYPE_GROUND,
MOVEMENTTYPE_FLOATING,
MOVEMENTTYPE_SUBMERGED,
} movementType_t;
class ncActor : ncEntity {
void ncActor( void );
virtual void _InternalPostSpawn( void );
nonvirtual void SetMovementType( movementType_t );
};

18
src/system/Decor.qc Normal file
View file

@ -0,0 +1,18 @@
void ncDecor::ncDecor( void ) {
}
void ncDecor::StaticDecor( string modelPath, string ambientSound ) {
if (ambientSound != "" && ambientSound != __NULL__) {
ncEngine::Precache_Sound( ambientSound );
ambientsound( GetOrigin(), ambientSound, 0.5, ATTN_STATIC );
}
if (modelPath != "" && modelPath != __NULL__) {
ncEngine::Precache_Model( modelPath );
SetModel( modelPath );
}
MakeStatic();
}

6
src/system/Decor.qh Normal file
View file

@ -0,0 +1,6 @@
class ncDecor:ncEntity {
void ncDecor( void );
nonvirtual void StaticDecor(string, string);
};

View file

@ -41,7 +41,9 @@ void ncEntity::PreThink( void ) {
}
void ncEntity::Trigger( ncEntity activatorEntity, triggerstate_t triggerType ) {
if (TriggerCallback) {
TriggerCallback(activatorEntity, triggerType);
}
}
/* set functions */
@ -717,6 +719,16 @@ bool ncEntity::WithinBounds( ncEntity check ) {
return ( true );
}
.float delay;
void ncEntity::ActivateTargets( void )
{
static void ActivateTargets_Done( void ) {
TriggerTargets( this, TRIGGERSTATE_AUTO );
}
ScheduleThink(ActivateTargets_Done, delay);
}
void ncEntity::TriggerTargets( ncEntity activator, triggerstate_t triggertype )
{
string targetIdent = GetTarget();
@ -799,6 +811,11 @@ void ncEntity::PlayWeaponFrameSequence( float firstFrame, float lastFrame, float
weapon_animation_manager.PlayWeaponFrameSequence( firstFrame, lastFrame, frameDelay);
}
#ifndef TARGET_HEXEN2
.float light_level;
#endif
/* wannabe thief */
void ncEntity::CalculateLightLevel( void )
{

View file

@ -284,6 +284,7 @@ public:
/** Trigger all targets with their `targetname` set as the entity it's `target`. */
nonvirtual void TriggerTargets( ncEntity, triggerstate_t );
nonvirtual void ActivateTargets( void );
/** Overridable: When the entity has initialized, it will execute this method. */
virtual void Spawn( void );

98
src/system/Light.qc Normal file
View file

@ -0,0 +1,98 @@
.float style;
void ncLight::ncLight( void ) {
if (GetTargetname() == "") {
Remove();
return;
}
if (GetLightStyle() >= 32) {
SetTriggerCallback(ToggleLight);
if (spawnflags & 1) {
lightstyle(GetLightStyle(), "a");
} else {
lightstyle(GetLightStyle(), "m");
}
}
}
float ncLight::GetLightStyle( void ) {
return style;
}
void ncLight::ToggleLight( void ) {
if (spawnflags & 1) {
lightstyle(GetLightStyle(), "m");
spawnflags = spawnflags - 1;
} else {
lightstyle(GetLightStyle(), "a");
spawnflags = spawnflags + 1;
}
}
float ncLight::LightLevelForEntity( ncEntity target ) {
float maxDistance = 150; /* Q1/H2 = linear falloff */
float currDistance = ncMath::VLen(GetOrigin() - target.GetOrigin());
if (currDistance > maxDistance)
return 0.0f;
ncEngine::TraceLine(GetOrigin(), target.GetOrigin(), FALSE, this);
if ( ( trace_ent == target ) || ( trace_fraction == 1.0f ) ) {
return maxDistance - currDistance;
} else {
return 0.0f;
}
}
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) OFF
# OVERVIEW
Point light.
When activated, will toggle off/on.
# KEYS
- "light" : Intensity. Default is 300.
- "style" : Light style animation to use.
# TYRUTILS KEYS
- "wait" : Scaler for the distance with which the light fades.
- "delay" : Attenuation formular. See Notes.
- "_falloff" : Distance at which the light is 0.
- "_color" : Color values. Will output .lit file.
- "_sun" : Boolean value, set to 1 to turn this light into a sun light.
- "_anglescale" : Controls the attenuation of light coming from an angle.
# TYRUTILS SAMPLING KEYS
- "_samples" : Number of lights to spawn. Only useful with "_deviance".
- "_deviance" : Offset between samples. To smoothen out the lightmap.
# TYRUTILS LIGHT EMITTING SURFACE KEYS
- "_surface" : Name of the WAD texture that emits light.
- "_surface_offset" : Offset at which to spawn lights above the surface.
- "_surface_spotlight" : Turn the surface light into a spotlight.
# TYRUTILS TEXTURE PROJECTION KEYS
- "_project_texture" : Name of the WAD texture will be cast.
- "_project_mangle" : Euler angles specifying the direction of the projection.
- "_project_fov" : Field of view for the texture projection. 90 is the default.
# TYRUTILS SPOTLIGHT KEYS
Using the two below will turn the light into a spotlight.
- "target" : Spotlight mode: Will aim at the named entity when set.
- "mangle" : Spotlight mode: Specify euler-angles for a spotlight direction.
- "angle" : Spotlight cone angle.
- "_softangle" : Inner spotlight cone angle.
# TYRUTILS AMBIENT OCCLUSION KEYS
Mainly useful when this light acts as a "_sun". But can override ambient occlusion settings for individual lights also.
- "_dirt" : Override the global setting for this light, except when it's a sun.
- "_dirtscale" : Overrides the global setting for the ambient occlusion darkness scaler.
# TYRUTILS RADIOSITY KEYS
- "_bouncescale" : Scaler for the light contribution of this light when doing radiosity.
*/
LINK_ENTITY_TO_CLASS(light, ncLight)

7
src/system/Light.qh Normal file
View file

@ -0,0 +1,7 @@
class ncLight:ncEntity {
void ncLight( void );
nonvirtual void ToggleLight( void );
nonvirtual float GetLightStyle( void );
nonvirtual float LightLevelForEntity( ncEntity );
};

View file

@ -16,6 +16,23 @@ vector ncMath::Normalize( vector v ) {
return normalize( v );
}
vector ncMath::AnglesToMoveDir( vector v ) {
vector vecMoveDir = g_vec_null;
/* editor angle */
if (v == [0,-1,0]) {
vecMoveDir = [0,0,1];
} else if (v == [0,-2,0]) {
vecMoveDir = [0,0,-1];
} else {
/* manually specified angle */
ncMath::MakeVectors(v);
vecMoveDir = v_forward;
}
return vecMoveDir;
}
float ncMath::VLen( vector v ) {
return vlen( v );
}

View file

@ -19,6 +19,7 @@ class ncMath {
nonvirtual float Acos( float );
nonvirtual float Sqrt( float );
nonvirtual float Clamp( float, float, float );
nonvirtual vector AnglesToMoveDir( vector v );
};
const float MATH_PI = 3.141592653589793;

View file

@ -3,22 +3,9 @@ void ncMover::ncMover( void ) {
}
vector ncMover::GetDirectionalPosition(vector vecAngle, float flLip) {
vector vecMoveDir = g_vec_null;
vector vecPos = g_vec_null;
/* editor angle */
if (vecAngle == [0,-1,0]) {
vecMoveDir = [0,0,1];
} else if (vecAngle == [0,-2,0]) {
vecMoveDir = [0,0,-1];
} else {
/* manually specified angle */
ncMath::MakeVectors(vecAngle);
vecMoveDir = v_forward;
}
vector vecMoveDir = ncMath::AnglesToMoveDir(vecAngle);
float movementWidth = ncMath::Fabs(vecMoveDir * size);
vecPos = (GetOrigin() + vecMoveDir * (movementWidth - flLip));
vector vecPos = (GetOrigin() + vecMoveDir * (movementWidth - flLip));
return vecPos;
}

View file

@ -1,17 +1,19 @@
#includelist
ncEntity.qh
ncEngine.qh
ncMath.qh
ncActor.qh
ncItem.qh
ncPlayer.qh
ncRules.qh
ncMover.qh
ncFX.qh
ncCamera.qh
ncHud.qh
ncNet.qh
ncAnimationManager.qh
ncProjectile.qh
Entity.qh
Engine.qh
Math.qh
Actor.qh
Item.qh
Player.qh
Rules.qh
Mover.qh
FX.qh
Camera.qh
Hud.qh
Net.qh
AnimationManager.qh
Projectile.qh
Decor.qh
Light.qh
classes.qh
#endlist

View file

@ -1,5 +0,0 @@
class ncActor : ncEntity {
void ncActor( void );
virtual void _InternalPostSpawn( void );
};

View file

@ -1,17 +1,19 @@
#includelist
ncEngine.qc
ncEntity.qc
ncActor.qc
ncPlayer.qc
ncRules.qc
ncItem.qc
ncMover.qc
ncFX.qc
ncCamera.qc
ncMath.qc
ncHud.qc
ncNet.qc
ncAnimationManager.qc
ncProjectile.qc
Engine.qc
Entity.qc
Actor.qc
Player.qc
Rules.qc
Item.qc
Mover.qc
FX.qc
Camera.qc
Math.qc
Hud.qc
Net.qc
AnimationManager.qc
Projectile.qc
Decor.qc
Light.qc
classes.qc
#endlist