Compare commits

...

3 Commits

41 changed files with 202 additions and 68 deletions

View File

@ -880,6 +880,7 @@ INPUT = src/ \
Documentation/Launching.md \ Documentation/Launching.md \
Documentation/Filesystem.md \ Documentation/Filesystem.md \
Documentation/Networking.md \ Documentation/Networking.md \
Documentation/EntityGuide.md \
Documentation/Classes.md \ Documentation/Classes.md \
Documentation/Materials/MatOverview.md \ Documentation/Materials/MatOverview.md \
Documentation/Materials/MatCommands.md \ Documentation/Materials/MatCommands.md \

View File

@ -4,7 +4,7 @@
ed_for_def() ed_for_def()
{ {
printf -- "" > "/tmp/def_name" printf -- "" > "/tmp/def_name"
printf -- "" > "/tmp/def_color" printf -- "1 0 1" > "/tmp/def_color"
printf -- "" > "/tmp/def_mins" printf -- "" > "/tmp/def_mins"
printf -- "" > "/tmp/def_mins" printf -- "" > "/tmp/def_mins"
printf -- "" > "/tmp/def_maxs" printf -- "" > "/tmp/def_maxs"
@ -64,6 +64,14 @@ do
printf -- "$VAL" > "/tmp/def_usage" printf -- "$VAL" > "/tmp/def_usage"
fi fi
if [ "$KEY" == "netname" ]
then
if [ -z "$(cat "/tmp/def_usage")" ]
then
printf -- "$VAL" > "/tmp/def_usage"
fi
fi
if [ "$KEY" == "editor_model" ] if [ "$KEY" == "editor_model" ]
then then
printf -- "$VAL" > "/tmp/def_model" printf -- "$VAL" > "/tmp/def_model"

View File

@ -50,6 +50,19 @@ seta r_skipDetail 0 // Skip rendering of detail textures on surfaces.
seta r_skipEnvmap 0 // Skip rendering of environment/cube maps on surfaces. seta r_skipEnvmap 0 // Skip rendering of environment/cube maps on surfaces.
seta r_skipFullbright 0 // Skip rendering of fullbright textures on surfaces. seta r_skipFullbright 0 // Skip rendering of fullbright textures on surfaces.
seta r_skipNormal 0 // Skip rendering of normal/bump maps on surfaces. seta r_skipNormal 0 // Skip rendering of normal/bump maps on surfaces.
seta r_showDlights 0 // Show debug info for dynamic light entities.
seta r_showPhysicsInfo 0 // Show debug info for NSPhysicsEntity entities.
seta r_showRenderInfo 0 // Show debug info for NSRenderableEntity entities.
seta r_showSkeleton 0 // Shows joints for skeletal entities.
seta r_showTexts 0 // Shows debug info for game_text messages.
seta r_showView 0 // Shows debug info for NSView objects.
seta r_showViewCone 0 // Shows view cone for actors and other similar entities.
// teamplay related cvars
seta sv_friendlyFire 0 // When set to 1, players/actors/bots belonging to the same team can damage each other
seta mp_td_dmgToKick 300 // Specifies how much damage one player has to inflict to others players before getting kicked.
seta mp_td_dmgToWarn 200 // Specifies how much damage one player has to inflict to others players before getting warned.
alias mp_friendlyfire sv_friendlyFire
// aliases for the older commands (may be removed some day) // aliases for the older commands (may be removed some day)
alias cl_autojump pm_autoJump alias cl_autojump pm_autoJump

View File

@ -343,7 +343,7 @@ func_button::MoverStartsMoving(void)
void void
func_button::Trigger(entity act, triggermode_t state) func_button::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
UseOutput(act, m_strOnUseLocked); UseOutput(act, m_strOnUseLocked);

View File

@ -487,7 +487,7 @@ func_door::MoverStartsMoving(void)
void void
func_door::Trigger(entity act, triggermode_t triggerstate) func_door::Trigger(entity act, triggermode_t triggerstate)
{ {
if (GetMaster() == 0) if (GetMaster(act) == 0)
return; return;
if (m_flNextTrigger > time) { if (m_flNextTrigger > time) {
@ -520,7 +520,7 @@ func_door::Touch(entity eToucher)
if (HasSpawnFlags(SF_MOV_USE) == true) if (HasSpawnFlags(SF_MOV_USE) == true)
return; return;
if (m_iLocked || !GetMaster()) { if (m_iLocked || !GetMaster(eToucher)) {
if (m_flSoundWait < time) if (m_flSoundWait < time)
Sound_Play(this, CHAN_VOICE, m_strLockedSfx); Sound_Play(this, CHAN_VOICE, m_strLockedSfx);

View File

@ -411,7 +411,7 @@ func_door_rotating::MoverStartsMoving(void)
void void
func_door_rotating::Trigger(entity act, triggermode_t state) func_door_rotating::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) { if (GetMaster(act) == FALSE) {
return; return;
} }
@ -465,7 +465,7 @@ func_door_rotating::Touch(entity eToucher)
return; return;
} }
if (m_iLocked || !GetMaster()) { if (m_iLocked || !GetMaster(eToucher)) {
if (m_flSoundWait < time) if (m_flSoundWait < time)
Sound_Play(this, CHAN_VOICE, m_strLockedSfx); Sound_Play(this, CHAN_VOICE, m_strLockedSfx);

View File

@ -89,6 +89,7 @@ private:
float m_flDamage; float m_flDamage;
float m_flHeight; float m_flHeight;
float m_flStartSpeed; float m_flStartSpeed;
float m_flCurrentSpeed;
float m_flBank; float m_flBank;
string m_strMoveSnd; string m_strMoveSnd;
string m_strStopSnd; string m_strStopSnd;
@ -182,6 +183,9 @@ void
func_tracktrain::SpawnKey(string strKey, string strValue) func_tracktrain::SpawnKey(string strKey, string strValue)
{ {
switch (strKey) { switch (strKey) {
case "speed":
m_flSpeed = ReadFloat(strValue);
break;
case "startspeed": case "startspeed":
m_flStartSpeed = stof(strValue); m_flStartSpeed = stof(strValue);
break; break;
@ -237,7 +241,7 @@ func_tracktrain::Respawn(void)
SetModel(GetSpawnModel()); SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin()); SetOrigin(GetSpawnOrigin());
m_flSpeed = m_flStartSpeed; m_flCurrentSpeed = m_flStartSpeed;
ScheduleThink(AfterSpawn, 0.0f); ScheduleThink(AfterSpawn, 0.0f);
SetTriggerTarget(m_oldstrTarget); SetTriggerTarget(m_oldstrTarget);
@ -296,7 +300,7 @@ func_tracktrain::PathMove(void)
vecWorldPos = origin; vecWorldPos = origin;
vecVelocity = (eNode.origin + [0,0,m_flHeight]) - vecWorldPos; vecVelocity = (eNode.origin + [0,0,m_flHeight]) - vecWorldPos;
flTravelTime = (vlen(vecVelocity) / m_flSpeed); flTravelTime = (vlen(vecVelocity) / m_flCurrentSpeed);
if (!flTravelTime) { if (!flTravelTime) {
print("^1func_tracktrain::^3PathMove^7: Distance short, going next\n"); print("^1func_tracktrain::^3PathMove^7: Distance short, going next\n");
@ -399,7 +403,9 @@ func_tracktrain::PathNext(void)
/* if speed is 0, retain current speed */ /* if speed is 0, retain current speed */
if (eNode.m_flSpeed > 0) if (eNode.m_flSpeed > 0)
m_flSpeed = eNode.m_flSpeed; m_flCurrentSpeed = eNode.m_flSpeed;
else
m_flCurrentSpeed = m_flSpeed;
m_flWait = eNode.m_flWait; m_flWait = eNode.m_flWait;
target = eNode.target; target = eNode.target;
@ -447,7 +453,9 @@ func_tracktrain::AfterSpawn(void)
/* if speed is 0, retain current speed */ /* if speed is 0, retain current speed */
if (eNode.m_flSpeed > 0) if (eNode.m_flSpeed > 0)
m_flSpeed = eNode.m_flSpeed; m_flCurrentSpeed = eNode.m_flSpeed;
else
m_flCurrentSpeed = m_flSpeed;
m_flWait = eNode.m_flWait; m_flWait = eNode.m_flWait;
target = eNode.target; target = eNode.target;

View File

@ -60,6 +60,8 @@ func_train:NSRenderableEntity
float m_flWait; float m_flWait;
float m_flSpeed; float m_flSpeed;
float m_flDamage; float m_flDamage;
float m_flCurrentSpeed;
string m_strMoveSnd; string m_strMoveSnd;
string m_strStopSnd; string m_strStopSnd;
@ -87,7 +89,7 @@ void
func_train::func_train(void) func_train::func_train(void)
{ {
m_flWait = 0.0f; m_flWait = 0.0f;
m_flSpeed = 100.0f; /* FIXME: This is all decided by the first path_corner pretty much */ m_flSpeed = 0.0f; /* FIXME: This is all decided by the first path_corner pretty much */
m_flDamage = 0.0f; m_flDamage = 0.0f;
m_strMoveSnd = __NULL__; m_strMoveSnd = __NULL__;
m_strStopSnd = __NULL__; m_strStopSnd = __NULL__;
@ -141,6 +143,9 @@ func_train::SpawnKey(string strKey, string strValue)
case "snd_stop": case "snd_stop":
m_strStopSnd = strValue; m_strStopSnd = strValue;
break; break;
case "speed":
m_flSpeed = ReadFloat(strValue);
break;
/* compatibility */ /* compatibility */
case "movesnd": case "movesnd":
m_strMoveSnd = sprintf("func_train.move_%i", stoi(strValue) + 1i); m_strMoveSnd = sprintf("func_train.move_%i", stoi(strValue) + 1i);
@ -217,12 +222,15 @@ func_train::SoundStop(void)
void void
func_train::PathMove(void) func_train::PathMove(void)
{ {
entity eNode; path_corner eNode;
float flTravelTime; float flTravelTime;
vector vecVelocity; vector vecVelocity;
vector vecWorldPos; vector vecWorldPos;
eNode = find(world, ::targetname, target); if (!target)
return;
eNode = (path_corner)find(world, ::targetname, target);
if (!eNode) { if (!eNode) {
return; return;
@ -230,7 +238,7 @@ func_train::PathMove(void)
vecWorldPos = WorldSpaceCenter(); vecWorldPos = WorldSpaceCenter();
vecVelocity = (eNode.origin - vecWorldPos); vecVelocity = (eNode.origin - vecWorldPos);
flTravelTime = (vlen(vecVelocity) / m_flSpeed); flTravelTime = (vlen(vecVelocity) / m_flCurrentSpeed);
if (!flTravelTime) { if (!flTravelTime) {
print("^1func_train::^3PathMove^7: Distance short, going next\n"); print("^1func_train::^3PathMove^7: Distance short, going next\n");
@ -240,6 +248,7 @@ func_train::PathMove(void)
} }
SoundMove(); SoundMove();
NSLog("Travelling at %f up/s", m_flSpeed);
SetVelocity(vecVelocity * (1 / flTravelTime)); SetVelocity(vecVelocity * (1 / flTravelTime));
ScheduleThink(PathNext, flTravelTime); ScheduleThink(PathNext, flTravelTime);
@ -268,6 +277,10 @@ void
func_train::PathNext(void) func_train::PathNext(void)
{ {
path_corner eNode; path_corner eNode;
if (!target)
return;
eNode = (path_corner)find(world, ::targetname, target); eNode = (path_corner)find(world, ::targetname, target);
if (!eNode) { if (!eNode) {
@ -277,9 +290,15 @@ func_train::PathNext(void)
SetOrigin(eNode.origin - (mins + maxs) * 0.5); SetOrigin(eNode.origin - (mins + maxs) * 0.5);
PathDone(); PathDone();
if (eNode.m_flSpeed > 0.0f) {
m_flCurrentSpeed = eNode.m_flSpeed;
} else {
m_flCurrentSpeed = m_flSpeed;
}
/* if speed is 0, retain current speed */ /* if speed is 0, retain current speed */
if (eNode.m_flSpeed > 0) //if (eNode.m_flSpeed > 0.0f)
m_flSpeed = eNode.m_flSpeed; //m_flSpeed = eNode.m_flSpeed;
m_flWait = eNode.m_flWait; m_flWait = eNode.m_flWait;
SetTriggerTarget(eNode.target); SetTriggerTarget(eNode.target);

View File

@ -123,6 +123,7 @@ game_counter::Respawn(void)
void void
game_counter::SetCount(int value) game_counter::SetCount(int value)
{ {
NSLog("%s's count set to %i", targetname, value);
m_iCounted = value; m_iCounted = value;
} }
@ -135,14 +136,20 @@ game_counter::GetCount(void)
void void
game_counter::Trigger(entity act, triggermode_t state) game_counter::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
NSLog("%s's incremented by 1", targetname);
m_iCounted++; m_iCounted++;
if (m_iCounted < m_iMaxCount) if (m_iCounted < m_iMaxCount)
return; return;
NSLog("%s's triggering %s", targetname, target);
//print(sprintf("%s %s %i %i\n", classname, targetname, m_iCounted, m_iMaxCount ));
//error(sprintf("%s %i %i\n", act.classname, m_iCounted, m_iMaxCount ));
UseTargets(act, TRIG_TOGGLE, m_flDelay);
if (HasSpawnFlags(GMCNT_REMOVE)) if (HasSpawnFlags(GMCNT_REMOVE))
Destroy(); Destroy();
else if (HasSpawnFlags(GMCNT_RESET)) else if (HasSpawnFlags(GMCNT_RESET))
@ -150,5 +157,4 @@ game_counter::Trigger(entity act, triggermode_t state)
else else
m_iValue = 1; m_iValue = 1;
UseTargets(act, TRIG_TOGGLE, m_flDelay);
} }

View File

@ -55,7 +55,7 @@ private:
void void
game_counter_set::game_counter_set(void) game_counter_set::game_counter_set(void)
{ {
m_iCount = 0; m_iCount = 0i;
} }
void void
@ -82,7 +82,7 @@ game_counter_set::SpawnKey(string strKey, string strValue)
{ {
switch (strKey) { switch (strKey) {
case "frags": case "frags":
m_iCount = stoi(strValue); m_iCount = ReadInt(strValue);
break; break;
default: default:
super::SpawnKey(strKey, strValue); super::SpawnKey(strKey, strValue);
@ -98,9 +98,11 @@ game_counter_set::Respawn(void)
void void
game_counter_set::Trigger(entity act, triggermode_t state) game_counter_set::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
NSLog("%s's manipulating %s to be %i", targetname, target, m_iCount);
/* apply the value to all the relevant game_counter entities */ /* apply the value to all the relevant game_counter entities */
for (entity f = world; (f = find(f, ::targetname, target));) { for (entity f = world; (f = find(f, ::targetname, target));) {
game_counter targ; game_counter targ;

View File

@ -42,7 +42,7 @@ game_end::game_end(void)
void void
game_end::Trigger(entity activatingEntity, triggermode_t triggerMode) game_end::Trigger(entity activatingEntity, triggermode_t triggerMode)
{ {
if (GetMaster() == FALSE) { if (GetMaster(activatingEntity) == FALSE) {
return; return;
} }

View File

@ -85,7 +85,7 @@ game_player_hurt::Restore(string strKey, string strValue)
void void
game_player_hurt::Trigger(entity activatingEntity, triggermode_t triggerMode) game_player_hurt::Trigger(entity activatingEntity, triggermode_t triggerMode)
{ {
if (GetMaster() == FALSE) { if (GetMaster(activatingEntity) == FALSE) {
return; return;
} }
if (!(activatingEntity.flags & FL_CLIENT)) { if (!(activatingEntity.flags & FL_CLIENT)) {

View File

@ -51,7 +51,7 @@ game_player_team::Trigger(entity entityActivator, triggermode_t state)
NSClientPlayer targetPlayer = __NULL__; NSClientPlayer targetPlayer = __NULL__;
game_team_master toRead = __NULL__; game_team_master toRead = __NULL__;
if (GetMaster() == FALSE) { if (GetMaster(entityActivator) == FALSE) {
return; return;
} }

View File

@ -86,7 +86,7 @@ game_score::Trigger(entity entityActivator, triggermode_t state)
{ {
int toAdd = m_iPoints; int toAdd = m_iPoints;
if (GetMaster() == FALSE) { if (GetMaster(entityActivator) == FALSE) {
return; return;
} }

View File

@ -42,7 +42,7 @@ public:
virtual void SpawnKey(string, string); virtual void SpawnKey(string, string);
virtual void Input(entity, string, string); virtual void Input(entity, string, string);
virtual void Trigger(entity, triggermode_t); virtual void Trigger(entity, triggermode_t);
virtual int GetValue(entity);
nonvirtual void SetTeamIndex(int); nonvirtual void SetTeamIndex(int);
nonvirtual int GetTeamIndex(void); nonvirtual int GetTeamIndex(void);
@ -99,7 +99,7 @@ game_team_master::SpawnKey(string keyName, string setValue)
void void
game_team_master::Trigger(entity entityActivator, triggermode_t state) game_team_master::Trigger(entity entityActivator, triggermode_t state)
{ {
if (GetMaster() == FALSE) { if (GetMaster(entityActivator) == FALSE) {
return; return;
} }
@ -125,6 +125,15 @@ game_team_master::Input(entity entityActivator, string inputName, string dataFie
} }
} }
int
game_team_master::GetValue(entity queryingEntity)
{
if (queryingEntity.team == (float)m_iTeamIndex)
return TRUE;
return FALSE;
}
void void
game_team_master::SetTeamIndex(int newIndex) game_team_master::SetTeamIndex(int newIndex)
{ {

View File

@ -48,7 +48,7 @@ game_team_set::Trigger(entity activatorEntity, triggermode_t state)
{ {
game_team_master toChange = __NULL__; game_team_master toChange = __NULL__;
if (GetMaster() == FALSE) { if (GetMaster(activatorEntity) == FALSE) {
return; return;
} }

View File

@ -301,7 +301,7 @@ multi_manager::Trigger(entity act, triggermode_t state)
UseTargets(wow.m_eActivator, TRIG_TOGGLE, 0.0f); UseTargets(wow.m_eActivator, TRIG_TOGGLE, 0.0f);
} }
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
m_iValue = TRUE; m_iValue = TRUE;

View File

@ -37,7 +37,7 @@ public:
virtual void Respawn(void); virtual void Respawn(void);
virtual int QueryTargets(void); virtual int QueryTargets(void);
virtual int GetValue(void); virtual int GetValue(entity);
virtual void Trigger(entity, triggermode_t); virtual void Trigger(entity, triggermode_t);
}; };
@ -68,7 +68,7 @@ multisource::Trigger(entity act, triggermode_t unused)
} }
int int
multisource::GetValue(void) multisource::GetValue(entity queryingEntity)
{ {
return QueryTargets(); return QueryTargets();
} }
@ -92,7 +92,7 @@ multisource::QueryTargets(void)
if (cvar("developer") == 1) { if (cvar("developer") == 1) {
dprint("[^1MULTISOURCE^7] "); dprint("[^1MULTISOURCE^7] ");
dprint(tTemp.classname); dprint(tTemp.classname);
if (tTemp.GetValue() == FALSE) { if (tTemp.GetValue(this) == FALSE) {
dprint(" is ^1OFF^7, name: "); dprint(" is ^1OFF^7, name: ");
out = FALSE; out = FALSE;
} else { } else {
@ -102,7 +102,7 @@ multisource::QueryTargets(void)
dprint("\n"); dprint("\n");
} else { } else {
/* exit out immediately as there's no point unless in-dev */ /* exit out immediately as there's no point unless in-dev */
if (tTemp.GetValue() == FALSE) { if (tTemp.GetValue(this) == FALSE) {
return (0); return (0);
} }
} }

View File

@ -69,7 +69,7 @@ void
path_corner::path_corner(void) path_corner::path_corner(void)
{ {
m_iFired = 0i; m_iFired = 0i;
m_flSpeed = 100.0f; m_flSpeed = 0.0f;
m_flYawSpeed = 0.0f; m_flYawSpeed = 0.0f;
m_flWait = 1.0f; m_flWait = 1.0f;
} }
@ -110,16 +110,16 @@ path_corner::SpawnKey(string strKey, string strValue)
{ {
switch (strKey) { switch (strKey) {
case "speed": case "speed":
m_flSpeed = stof(strValue); m_flSpeed = ReadFloat(strValue);
break; break;
case "yaw_speed": case "yaw_speed":
m_flYawSpeed = stof(strValue); m_flYawSpeed = ReadFloat(strValue);
break; break;
case "wait": case "wait":
m_flWait = stof(strValue); m_flWait = ReadFloat(strValue);
break; break;
case "message": case "message":
m_strMessage = strValue; m_strMessage = ReadString(strValue);
break; break;
default: default:
super::SpawnKey(strKey, strValue); super::SpawnKey(strKey, strValue);

View File

@ -219,7 +219,7 @@ point_trigger::Input(entity eAct, string strInput, string strData)
void void
point_trigger::Touch(entity eToucher) point_trigger::Touch(entity eToucher)
{ {
if (GetMaster() == false) if (GetMaster(eToucher) == false)
return; return;
if (m_bEnabled == false) if (m_bEnabled == false)
return; return;

View File

@ -132,7 +132,7 @@ random_speaker::Respawn(void)
void void
random_speaker::Trigger(entity act, triggermode_t state) random_speaker::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
switch (state) { switch (state) {

View File

@ -123,7 +123,7 @@ random_trigger::Trigger(entity act, triggermode_t state)
{ {
float r; float r;
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
r = time + m_flMinTime + random(m_flRandMin, m_flRandMax); r = time + m_flMinTime + random(m_flRandMin, m_flRandMax);

View File

@ -104,7 +104,7 @@ targ_speaker::Respawn(void)
void void
targ_speaker::Trigger(entity act, triggermode_t state) targ_speaker::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
sound(this, CHAN_AUTO, m_strSample, m_flVolume, ATTN_NORM); sound(this, CHAN_AUTO, m_strSample, m_flVolume, ATTN_NORM);

View File

@ -86,7 +86,7 @@ trigger_autosave::Respawn(void)
void void
trigger_autosave::Touch(entity eToucher) trigger_autosave::Touch(entity eToucher)
{ {
if (GetMaster() == FALSE) if (GetMaster(eToucher) == FALSE)
return; return;
/* saved text */ /* saved text */

View File

@ -279,7 +279,7 @@ trigger_changelevel::Change(void)
void void
trigger_changelevel::Trigger(entity act, triggermode_t unused) trigger_changelevel::Trigger(entity act, triggermode_t unused)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
/* disable meself */ /* disable meself */

View File

@ -111,7 +111,7 @@ trigger_counter::Trigger(entity act, triggermode_t state)
return; return;
if (HasSpawnFlags(TRCNT_NOCLIENTS) && act.flags & FL_CLIENT) if (HasSpawnFlags(TRCNT_NOCLIENTS) && act.flags & FL_CLIENT)
return; return;
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
m_iCounted++; m_iCounted++;

View File

@ -50,7 +50,7 @@ trigger_endsection::Respawn(void)
void void
trigger_endsection::Trigger(entity act, triggermode_t state) trigger_endsection::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
localcmd("disconnect\n"); localcmd("disconnect\n");

View File

@ -157,7 +157,7 @@ trigger_look::Touch(entity eToucher)
float dot; float dot;
entity lt; entity lt;
if (GetMaster() == FALSE) if (GetMaster(eToucher) == FALSE)
return; return;
if (!(eToucher.flags & FL_CLIENT)) { if (!(eToucher.flags & FL_CLIENT)) {

View File

@ -204,7 +204,7 @@ trigger_multiple::Input(entity entityActivator, string inputName, string dataFie
void void
trigger_multiple::Touch(entity eToucher) trigger_multiple::Touch(entity eToucher)
{ {
if (GetMaster() == FALSE) if (GetMaster(eToucher) == FALSE)
return; return;
if (m_bEnabled == false) if (m_bEnabled == false)
@ -218,6 +218,8 @@ trigger_multiple::Touch(entity eToucher)
return; return;
if (!HasSpawnFlags(TM_PUSHABLES) && eToucher.classname == "func_pushable") if (!HasSpawnFlags(TM_PUSHABLES) && eToucher.classname == "func_pushable")
return; return;
if (eToucher.solid == SOLID_TRIGGER)
return;
} else if (CanBeTriggeredBy(eToucher) == false) { } else if (CanBeTriggeredBy(eToucher) == false) {
return; return;
} }

View File

@ -173,7 +173,7 @@ trigger_once::Touch(entity eToucher)
{ {
bool isPushable = (substring(eToucher.classname, 0, 5) == "func_") ? true : false; bool isPushable = (substring(eToucher.classname, 0, 5) == "func_") ? true : false;
if (GetMaster() == FALSE) if (GetMaster(eToucher) == FALSE)
return; return;
if (m_bEnabled == false) if (m_bEnabled == false)

View File

@ -55,7 +55,7 @@ trigger_playerfreeze::Respawn(void)
void void
trigger_playerfreeze::Trigger(entity act, triggermode_t state) trigger_playerfreeze::Trigger(entity act, triggermode_t state)
{ {
if (GetMaster() == FALSE) if (GetMaster(act) == FALSE)
return; return;
m_iValue = 1 - m_iValue; m_iValue = 1 - m_iValue;

View File

@ -168,7 +168,7 @@ trigger_teleport::Respawn(void)
void void
trigger_teleport::Touch(entity eToucher) trigger_teleport::Touch(entity eToucher)
{ {
if (GetMaster() == FALSE) if (GetMaster(eToucher) == FALSE)
return; return;
if (m_bEnabled == false) if (m_bEnabled == false)
return; return;

View File

@ -45,6 +45,7 @@ void
trigger_transition::Respawn(void) trigger_transition::Respawn(void)
{ {
InitBrushTrigger(); InitBrushTrigger();
SetSolid(SOLID_NOT);
} }
void void

View File

@ -34,7 +34,8 @@ typedef enum
MAPINFO_NAME, /**< (string) Name of the map. E.g. e1m1 */ MAPINFO_NAME, /**< (string) Name of the map. E.g. e1m1 */
MAPINFO_TITLE, /**< (string) Title of the map. E.g. "Abyss of Cake" */ MAPINFO_TITLE, /**< (string) Title of the map. E.g. "Abyss of Cake" */
MAPINFO_AUTHOR, /**< (string) Author of the map. E.g. "John Doe" */ MAPINFO_AUTHOR, /**< (string) Author of the map. E.g. "John Doe" */
MAPINFO_TYPE /**< (string) Type of map.*/ MAPINFO_TYPE, /**< (string) Type of map.*/
MAPINFO_PREVIEW /**< (string) URL to a preview of the map. __NULL__ if not available. Will look for level previews inside levelshots/ and maps/ with any file extensions supported by the engine and whitelisted within the cvar 'r_imageextensions'.*/
} mapType_t; } mapType_t;
/** Initialize the map library, MapLibrary_GetMapCount() will return the amount of maps available. */ /** Initialize the map library, MapLibrary_GetMapCount() will return the amount of maps available. */

View File

@ -20,6 +20,7 @@ typedef struct
string title; string title;
string author; string author;
string type; string type;
string preview;
} mapLibrary_t; } mapLibrary_t;
mapLibrary_t *g_mapLibrary; mapLibrary_t *g_mapLibrary;
@ -65,6 +66,31 @@ MapLibrary_MapInGameDir(string fileName, string gameDir)
return list; return list;
} }
static string
MapLibrary_FindPreview(string mapFile)
{
string imageExtensions = strcat(cvar_string("r_imageextensions"), " mat");
int imageFormats = (int)tokenize(imageExtensions);
string previewFile = "";
string mapName = substring(mapFile, 0, strlen(mapFile) - 4);
/* cycle through all possible extensions */
for (int i = 0; i < imageFormats; i++) {
previewFile = strcat("levelshots/", mapName, ".", argv(i));
if (whichpack(previewFile)) {
return previewFile;
}
previewFile = strcat("maps/", mapName, ".", argv(i));
if (whichpack(previewFile)) {
return previewFile;
}
}
return __NULL__;
}
void void
MapLibrary_Init(void) MapLibrary_Init(void)
{ {
@ -137,6 +163,8 @@ MapLibrary_Init(void)
g_mapLibrary[c].title = mapFile; g_mapLibrary[c].title = mapFile;
g_mapLibrary[c].author = "Unknown"; g_mapLibrary[c].author = "Unknown";
g_mapLibrary[c].type = "Unknown"; g_mapLibrary[c].type = "Unknown";
g_mapLibrary[c].preview = MapLibrary_FindPreview(mapFile);
c++; c++;
} }
} }
@ -172,6 +200,9 @@ MapLibrary_GetInfo(int mapID, mapType_t infoType)
case MAPINFO_TYPE: case MAPINFO_TYPE:
return g_mapLibrary[mapID].type; return g_mapLibrary[mapID].type;
break; break;
case MAPINFO_PREVIEW:
return g_mapLibrary[mapID].preview;
break;
default: default:
return __NULL__; return __NULL__;
} }

View File

@ -15,6 +15,8 @@
*/ */
var bool autocvar_sv_friendlyFire = false; var bool autocvar_sv_friendlyFire = false;
var int autocvar_mp_td_dmgToKick = 300i;
var int autocvar_mp_td_dmgToWarn = 200i;
void void
NSGameRules::NSGameRules(void) NSGameRules::NSGameRules(void)
@ -265,6 +267,8 @@ NSGameRules::IsMultiplayer(void)
void void
NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type) NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type)
{ {
bool isFriendlyFire = false;
/* Damage */ /* Damage */
NSSurfacePropEntity eTarget = (NSSurfacePropEntity)t; NSSurfacePropEntity eTarget = (NSSurfacePropEntity)t;
@ -280,13 +284,19 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type
if (eTarget.flags & FL_CLIENT && eTarget.flags & FL_GODMODE) if (eTarget.flags & FL_CLIENT && eTarget.flags & FL_GODMODE)
return; return;
/* friendly fire */ /* friendly fire check */
if (autocvar_sv_friendlyFire == false) if (t != c) {
if (t != c) if (IsTeamplay()) {
if (IsTeamplay()) { if (t.flags & FL_CLIENT && c.flags & FL_CLIENT) {
if (t.flags & FL_CLIENT && c.flags & FL_CLIENT) if (t.team == c.team) {
if (t.team == c.team) if (autocvar_sv_friendlyFire == false) {
return; return;
} else {
isFriendlyFire = true;
}
}
}
}
} }
/* already dead, please avoid recursion */ /* already dead, please avoid recursion */
@ -346,6 +356,27 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type
NSLog("\tFlags: %i", g_dmg_iFlags); NSLog("\tFlags: %i", g_dmg_iFlags);
NSLog("\tWeapon: %i", g_dmg_iWeapon); NSLog("\tWeapon: %i", g_dmg_iWeapon);
/* friendly fire penalty */
if (isFriendlyFire) {
int lastDmg = 0i;
NSClientPlayer plC = (NSClientPlayer)c;
lastDmg = plC.m_iFriendlyDMG;
plC.m_iFriendlyDMG += dmg;
/* kick the client. */
if (plC.m_iFriendlyDMG >= autocvar_mp_td_dmgToKick) {
NSLog("Kicking %S due to team damage rules.", plC.netname);
dropclient(plC);
} else if (plC.m_iFriendlyDMG >= autocvar_mp_td_dmgToWarn) {
if (lastDmg < autocvar_mp_td_dmgToKick) {
// warn player here
sprint(plC, PRINT_CHAT, "Keep attacking teammates and you will be kicked!\n");
}
}
bprint(PRINT_CHAT, sprintf("%s ^7attacked a teammate.\n", c.netname));
}
if (dmg > 0 || flArmor > 0) { if (dmg > 0 || flArmor > 0) {
vector dmg_origin; vector dmg_origin;

View File

@ -26,7 +26,7 @@ public:
void NSBrushTrigger(void); void NSBrushTrigger(void);
/* overrides */ /* overrides */
virtual int GetValue(void); virtual int GetValue(entity);
/** Sets up a brush trigger volume based on the brush information. */ /** Sets up a brush trigger volume based on the brush information. */
nonvirtual void InitBrushTrigger(void); nonvirtual void InitBrushTrigger(void);

View File

@ -20,7 +20,7 @@ NSBrushTrigger::NSBrushTrigger(void)
} }
int int
NSBrushTrigger::GetValue(void) NSBrushTrigger::GetValue(entity queryingEntity)
{ {
if (GetSolid() == SOLID_NOT) { if (GetSolid() == SOLID_NOT) {
return (1); return (1);

View File

@ -172,6 +172,8 @@ private:
float pb_angle_delta; float pb_angle_delta;
float pb_player_delta; float pb_player_delta;
vector pb_last_angles; vector pb_last_angles;
int m_iFriendlyDMG;
#endif #endif
}; };

View File

@ -101,7 +101,7 @@ public:
/* master feature */ /* master feature */
/** Returns what we will pass onto other's `::GetMaster()` calls if we're their master. */ /** Returns what we will pass onto other's `::GetMaster()` calls if we're their master. */
/* multisource overrides this, so keep virtual */ /* multisource overrides this, so keep virtual */
virtual int GetValue(void); virtual int GetValue(entity);
/** When called will trigger its legacy targets with a given delay. */ /** When called will trigger its legacy targets with a given delay. */
nonvirtual void UseTargets(entity,int,float); nonvirtual void UseTargets(entity,int,float);
@ -109,8 +109,8 @@ public:
/** Sets the legacy target for this entity. */ /** Sets the legacy target for this entity. */
nonvirtual void SetTriggerTarget(string); nonvirtual void SetTriggerTarget(string);
/** Returns whether our master allows us to be triggered. */ /** Returns whether our master allows us to be triggered. The argument specifies who's requesting the info for the master. Required for game_team_master to verify against players. */
nonvirtual int GetMaster(void); nonvirtual int GetMaster(entity);
/** Returns the value of a given env_global property */ /** Returns the value of a given env_global property */
nonvirtual globalstate_t GetGlobalValue(string); nonvirtual globalstate_t GetGlobalValue(string);

View File

@ -140,7 +140,7 @@ NSTrigger::SetTriggerTarget(string name)
} }
int int
NSTrigger::GetValue(void) NSTrigger::GetValue(entity queryingEntity)
{ {
return m_iValue; return m_iValue;
} }
@ -157,7 +157,7 @@ NSTrigger::GetGlobalValue(string strName)
} }
int int
NSTrigger::GetMaster(void) NSTrigger::GetMaster(entity queryingEntity)
{ {
NSTrigger t; NSTrigger t;
@ -177,14 +177,14 @@ NSTrigger::GetMaster(void)
return (1); return (1);
} }
if (t.GetValue() == 1) if (t.GetValue(queryingEntity) == 1)
NSLog("^2%s::^3GetMaster^7: %s learns %s ^2POSITIVE", NSLog("^2%s::^3GetMaster^7: %s learns %s ^2POSITIVE",
classname, targetname, m_strMaster); classname, targetname, m_strMaster);
else else
NSLog("^2%s::^3GetMaster^7: %s learns %s ^1NEGATIVE", NSLog("^2%s::^3GetMaster^7: %s learns %s ^1NEGATIVE",
classname, targetname, m_strMaster); classname, targetname, m_strMaster);
return t.GetValue(); return t.GetValue(queryingEntity);
} }
string string