Server: streamline gamerule progs interface
This commit is contained in:
parent
967ac0145b
commit
2db52608b1
9 changed files with 145 additions and 351 deletions
|
@ -90,12 +90,6 @@ public:
|
|||
virtual int MaxItemPerSlot(int);
|
||||
/** Overridable: Returns if NSMonster or NSTalkMonster entities can spawn. */
|
||||
virtual bool MonstersSpawn(void);
|
||||
/** Overridable: shim to handle application of direct damage. */
|
||||
nonvirtual void DamageApply(entity,entity,float,int,damageType_t);
|
||||
/** Checks if an entity can be attacked from a given position. */
|
||||
nonvirtual bool DamageCheckTrace(entity,vector);
|
||||
/** Overridable: shim to handle application of indirect radius damage. */
|
||||
nonvirtual void DamageRadius(vector,entity,float,float,bool,int);
|
||||
|
||||
/* end of a game */
|
||||
/** Called when intermission starts. Will send all current players to the intermission screen. */
|
||||
|
@ -147,3 +141,4 @@ private:
|
|||
NSGameRules g_grMode;
|
||||
|
||||
#define CGameRules NSGameRules
|
||||
#define RULEMAP(x, y, z) x.y = externvalue(x.m_ruleProgs, z); if (!x.y) { x.y = NSGameRules::y; }
|
||||
|
|
|
@ -18,10 +18,24 @@ var bool autocvar_sv_friendlyFire = false;
|
|||
var int autocvar_mp_td_dmgToKick = 300i;
|
||||
var int autocvar_mp_td_dmgToWarn = 200i;
|
||||
|
||||
#warning NSGameRule progs need to have their functions cached for speed reasons
|
||||
|
||||
void
|
||||
NSGameRules::NSGameRules(void)
|
||||
{
|
||||
forceinfokey(world, "teamplay", "0");
|
||||
forceinfokey(world, "teams", "");
|
||||
forceinfokey(world, "teamplay", "");
|
||||
forceinfokey(world, "coop", "");
|
||||
|
||||
/* clean up... */
|
||||
for (int teamID = 1; teamID < 1000; teamID++) {
|
||||
forceinfokey(world, sprintf("team_%i", teamID), "");
|
||||
forceinfokey(world, sprintf("teamscore_%i", teamID), "");
|
||||
forceinfokey(world, sprintf("teamcolor_%i", teamID), "");
|
||||
forceinfokey(world, sprintf("teamclosed_%i", teamID), "");
|
||||
forceinfokey(world, sprintf("teamspawn_%i", teamID), "");
|
||||
}
|
||||
|
||||
forceinfokey(world, sprintf("teamspawn_%d", TEAM_CONNECTING), "");
|
||||
forceinfokey(world, sprintf("teamspawn_%d", TEAM_UNASSIGNED), "info_player_start");
|
||||
forceinfokey(world, sprintf("teamspawn_%d", TEAM_SPECTATOR), "info_spectator_start");
|
||||
|
@ -55,7 +69,6 @@ NSGameRules::Restore(string strKey, string strValue)
|
|||
void
|
||||
NSGameRules::Input(entity eAct, string strInput, string strData)
|
||||
{
|
||||
RuleC_CallInput(m_ruleProgs, eAct, strInput, strData);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -69,21 +82,13 @@ NSGameRules::RestoreComplete(void)
|
|||
void
|
||||
NSGameRules::InitPostEnts(void)
|
||||
{
|
||||
RuleC_CallFunc(m_ruleProgs, world, "CodeCallback_StartGameType");
|
||||
}
|
||||
|
||||
/* logic */
|
||||
void
|
||||
NSGameRules::FrameStart(void)
|
||||
{
|
||||
//print("StartFrame!\n");
|
||||
|
||||
/* hack */
|
||||
if (time < 2.5f) {
|
||||
return;
|
||||
}
|
||||
|
||||
RuleC_CallFrame(m_ruleProgs, "CodeCallback_FrameStart");
|
||||
}
|
||||
bool
|
||||
NSGameRules::ConsoleCommand(NSClientPlayer pl, string cmd)
|
||||
|
@ -93,13 +98,11 @@ NSGameRules::ConsoleCommand(NSClientPlayer pl, string cmd)
|
|||
bool
|
||||
NSGameRules::ClientCommand(NSClient pl, string cmd)
|
||||
{
|
||||
return RuleC_CallString(m_ruleProgs, pl, cmd, "CodeCallback_ClientCommand");
|
||||
}
|
||||
|
||||
bool
|
||||
NSGameRules::ImpulseCommand(NSClient pl, float num)
|
||||
{
|
||||
return RuleC_CallFloat(m_ruleProgs, pl, num, "CodeCallback_ImpulseCommand");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -108,14 +111,11 @@ NSGameRules::PlayerConnect(NSClientPlayer pl)
|
|||
if (Plugin_PlayerConnect(pl) == false) {
|
||||
bprint(PRINT_HIGH, sprintf("%s^d connected.\n", pl.netname));
|
||||
}
|
||||
|
||||
RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerConnect");
|
||||
}
|
||||
void
|
||||
NSGameRules::PlayerDisconnect(NSClientPlayer pl)
|
||||
{
|
||||
bprint(PRINT_HIGH, sprintf("%s^d disconnected.\n", pl.netname));
|
||||
RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerDisconnect");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -131,18 +131,11 @@ NSGameRules::PlayerKill(NSClientPlayer pl)
|
|||
void
|
||||
NSGameRules::NPCDeath(NSActor npc, NSActor attacker, NSActor inflictor)
|
||||
{
|
||||
if (RuleC_CallDamage(m_ruleProgs, npc, attacker, inflictor, "", "CodeCallback_NPCKilled")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NSGameRules::PlayerDeath(NSClientPlayer pl, NSActor attacker, NSDict damageDecl)
|
||||
{
|
||||
if (RuleC_CallDamage(m_ruleProgs, pl, attacker, attacker, "", "CodeCallback_PlayerKilled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_OBITUARY);
|
||||
WriteString(MSG_MULTICAST, (attacker.netname) ? attacker.netname : attacker.classname);
|
||||
|
@ -169,18 +162,12 @@ NSGameRules::PlayerDeath(NSClientPlayer pl, NSActor attacker, NSDict damageDecl)
|
|||
void
|
||||
NSGameRules::PlayerPain(NSClientPlayer pl, NSActor attacker, NSDict damageDecl)
|
||||
{
|
||||
if (RuleC_CallDamage(m_ruleProgs, pl, attacker, attacker, "", "CodeCallback_PlayerDamage")) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* fallback code here, or rest implemented by sub-class */
|
||||
}
|
||||
|
||||
void
|
||||
NSGameRules::PlayerSpawn(NSClientPlayer pl)
|
||||
{
|
||||
RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerSpawn");
|
||||
|
||||
/* implemented by sub-class */
|
||||
}
|
||||
void
|
||||
|
@ -226,10 +213,6 @@ NSGameRules::SpectatorThink(NSClientSpectator pl)
|
|||
int
|
||||
NSGameRules::MaxItemPerSlot(int slot)
|
||||
{
|
||||
if (m_ruleProgs) {
|
||||
return RuleC_CallMaxItemsPerSlot(m_ruleProgs, slot, "CodeCallback_MaxItemPerSlot");
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -338,7 +321,7 @@ NSGameRules::MonstersSpawn(void)
|
|||
bool
|
||||
NSGameRules::IsTeamplay(void)
|
||||
{
|
||||
return (false);
|
||||
return (serverkeyfloat("teams") > 0);
|
||||
}
|
||||
bool
|
||||
NSGameRules::IsMultiplayer(void)
|
||||
|
@ -346,26 +329,6 @@ NSGameRules::IsMultiplayer(void)
|
|||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type)
|
||||
{
|
||||
NSError("Deprecated!");
|
||||
}
|
||||
|
||||
/* checks if we can hit an entity at 5 of the same spots */
|
||||
bool
|
||||
NSGameRules::DamageCheckTrace(entity t, vector vecHitPos)
|
||||
{
|
||||
NSError("Deprecated!");
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
NSGameRules::DamageRadius(vector org, entity attacker, float dmg, float r, bool checkCollision, int w)
|
||||
{
|
||||
NSError("Deprecated!");
|
||||
}
|
||||
|
||||
void
|
||||
NSGameRules::IntermissionEnd(void)
|
||||
{
|
||||
|
@ -393,13 +356,11 @@ NSGameRules::PlayerCanAttack(NSClientPlayer bp)
|
|||
bool
|
||||
NSGameRules::PlayerRequestRespawn(NSClientPlayer pl)
|
||||
{
|
||||
return RuleC_CallRequestSpawn(m_ruleProgs, pl, "CodeCallback_PlayerRequestRespawn");
|
||||
}
|
||||
|
||||
bool
|
||||
NSGameRules::PlayerRequestTeam(NSClientPlayer pl, int teamNum)
|
||||
{
|
||||
return RuleC_CallRequestTeam(m_ruleProgs, pl, teamNum, "CodeCallback_CallRequestTeam");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -453,6 +414,12 @@ NSGameRules::ChatMessageTeam(NSClient cl, string strMessage)
|
|||
string
|
||||
NSGameRules::Title(void)
|
||||
{
|
||||
string gameType = cvars.GetString("g_gametype");
|
||||
|
||||
if (STRING_SET(gameType)) {
|
||||
return gameType;
|
||||
}
|
||||
|
||||
return "Default";
|
||||
}
|
||||
|
||||
|
@ -477,6 +444,24 @@ NSGameRules::InitFromProgs(string pathToProgs)
|
|||
if (mainFunction) {
|
||||
externset(newRule.m_ruleProgs, this, "self");
|
||||
thread(mainFunction())
|
||||
|
||||
/* map progs functions to class methods */
|
||||
RULEMAP(newRule, ClientCommand, "CodeCallback_ClientCommand")
|
||||
RULEMAP(newRule, ConsoleCommand, "CodeCallback_ConsoleCommand")
|
||||
RULEMAP(newRule, FrameStart, "CodeCallback_FrameStart")
|
||||
RULEMAP(newRule, ImpulseCommand, "CodeCallback_ImpulseCommand")
|
||||
RULEMAP(newRule, InitPostEnts, "CodeCallback_StartGameType")
|
||||
RULEMAP(newRule, Input, "CodeCallback_Input")
|
||||
RULEMAP(newRule, NPCDeath, "CodeCallback_NPCKilled")
|
||||
RULEMAP(newRule, PlayerCanAttack, "CodeCallback_PlayerCanAttack")
|
||||
RULEMAP(newRule, PlayerConnect, "CodeCallback_PlayerConnect")
|
||||
RULEMAP(newRule, PlayerDeath, "CodeCallback_PlayerKilled")
|
||||
RULEMAP(newRule, PlayerDisconnect, "CodeCallback_PlayerDisconnect")
|
||||
RULEMAP(newRule, PlayerPain, "CodeCallback_PlayerDamage")
|
||||
RULEMAP(newRule, PlayerRequestRespawn, "CodeCallback_PlayerRequestRespawn")
|
||||
RULEMAP(newRule, PlayerRequestTeam, "CodeCallback_CallRequestTeam")
|
||||
RULEMAP(newRule, PlayerSpawn, "CodeCallback_PlayerSpawn")
|
||||
RULEMAP(newRule, Title, "CodeCallback_Title")
|
||||
} else {
|
||||
NSError("%S does not have a main function.", pathToProgs);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,17 @@ Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments)
|
|||
PutClientInServer();
|
||||
break;
|
||||
case "setpos":
|
||||
printf("%i %S\n", commandArguments, cmd);
|
||||
if (cvar("sv_cheats") == 1) {
|
||||
setorigin(sender, stov(argv(1)));
|
||||
if (commandArguments == 2) { /* setpos "0 0 0" */
|
||||
setorigin(sender, stov(argv(1)));
|
||||
} else if (commandArguments == 3) { /* setpos "0 0 0" "0 0 0" */
|
||||
setorigin(sender, stov(argv(1)));
|
||||
} else if (commandArguments == 4) { /* setpos 0 0 0 */
|
||||
setorigin(sender, [stof(argv(1)), stof(argv(2)), stof(argv(3))]);
|
||||
} else if (commandArguments == 7) { /* setpos 0 0 0 0 0 0 */
|
||||
setorigin(sender, [stof(argv(1)), stof(argv(2)), stof(argv(3))]);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -60,8 +69,7 @@ Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments)
|
|||
float timeleft;
|
||||
timeleft = cvar("timelimit") - (time / 60);
|
||||
timestring = Util_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
bprint(PRINT_CHAT, msg);
|
||||
bprint(PRINT_CHAT, sprintf("we have %s minutes remaining", timestring));
|
||||
break;
|
||||
case "listInventory":
|
||||
NSActor_ListInventory((NSActor)self);
|
||||
|
|
|
@ -19,17 +19,3 @@ void MapC_Init(void);
|
|||
void MapC_CallMainFunction(void);
|
||||
|
||||
void MapC_CallNamedFunction(entity, string);
|
||||
|
||||
bool RuleC_CallFunc(float, entity, string);
|
||||
bool RuleC_CallFrame(float, string);
|
||||
|
||||
bool RuleC_CallDamage(float, entity, entity, entity, string, string);
|
||||
|
||||
bool RuleC_CallRequestSpawn(float, entity, string);
|
||||
bool RuleC_CallRequestTeam(float, entity, int, string);
|
||||
|
||||
bool RuleC_CallString(float, entity, string, string);
|
||||
|
||||
bool RuleC_CallFloat(float, entity, float, string);
|
||||
int RuleC_CallMaxItemsPerSlot(float, int, string);
|
||||
void RuleC_CallInput(float, entity, string, string);
|
||||
|
|
|
@ -73,185 +73,3 @@ MapC_CallNamedFunction(entity functionActivator, string targetFunction)
|
|||
NSError("%s does not have a function %s.", mapname, targetFunction);
|
||||
}
|
||||
}
|
||||
|
||||
/* Gamerule specific Scripting, nicknamed 'RuleC'. */
|
||||
bool
|
||||
RuleC_CallFunc(float progsNum, entity pl, string funcName)
|
||||
{
|
||||
if (progsNum) {
|
||||
void(void) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
//externset(progsNum, pl, "self");
|
||||
self = pl;
|
||||
mainFunction();
|
||||
self = oldSelf;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
bool
|
||||
RuleC_CallFrame(float progsNum, string funcName)
|
||||
{
|
||||
if (progsNum) {
|
||||
void(void) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, frametime, "frametime");
|
||||
self = world;
|
||||
mainFunction();
|
||||
self = oldSelf;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool
|
||||
RuleC_CallDamage(float progsNum, entity target, entity inflictor, entity attacker, string weapon, string funcName)
|
||||
{
|
||||
if (progsNum) {
|
||||
void(entity inflictor, entity attacker, string weapon) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, target, "self");
|
||||
self = target;
|
||||
mainFunction(inflictor, attacker, weapon);
|
||||
self = oldSelf;
|
||||
forceinfokey(target, "*deaths", ftos(target.deaths));
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool
|
||||
RuleC_CallRequestSpawn(float progsNum, entity pl, string funcName)
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (progsNum) {
|
||||
bool(void) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, pl, "self");
|
||||
self = pl;
|
||||
returnValue = mainFunction();
|
||||
self = oldSelf;
|
||||
return (returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (returnValue);
|
||||
}
|
||||
|
||||
bool
|
||||
RuleC_CallRequestTeam(float progsNum, entity pl, int teamNum, string funcName)
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (progsNum) {
|
||||
bool(int) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, pl, "self");
|
||||
self = pl;
|
||||
returnValue = mainFunction(teamNum);
|
||||
self = oldSelf;
|
||||
return (returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (returnValue);
|
||||
}
|
||||
|
||||
bool
|
||||
RuleC_CallString(float progsNum, entity pl, string targetString, string funcName)
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (progsNum) {
|
||||
bool(string) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, pl, "self");
|
||||
self = pl;
|
||||
returnValue = mainFunction(targetString);
|
||||
self = oldSelf;
|
||||
return (returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (returnValue);
|
||||
}
|
||||
|
||||
bool
|
||||
RuleC_CallFloat(float progsNum, entity pl, float targetFloat, string funcName)
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (progsNum) {
|
||||
bool(float) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
entity oldSelf = self;
|
||||
externset(progsNum, pl, "self");
|
||||
self = pl;
|
||||
returnValue = mainFunction(targetFloat);
|
||||
self = oldSelf;
|
||||
return (returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (returnValue);
|
||||
}
|
||||
|
||||
int
|
||||
RuleC_CallMaxItemsPerSlot(float progsNum, int targetFloat, string funcName)
|
||||
{
|
||||
int returnValue = -1i;
|
||||
|
||||
if (progsNum) {
|
||||
int(int) mainFunction;
|
||||
mainFunction = externvalue(progsNum, funcName);
|
||||
|
||||
if (mainFunction) {
|
||||
returnValue = mainFunction(targetFloat);
|
||||
return (returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (returnValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RuleC_CallInput(float progsNum, entity activator, string inputName, string inputData)
|
||||
{
|
||||
if (progsNum) {
|
||||
void(entity, string, string) mainFunction;
|
||||
mainFunction = externvalue(progsNum, "CodeCallback_Input");
|
||||
|
||||
if (mainFunction) {
|
||||
mainFunction(activator, inputName, inputData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1747,6 +1747,12 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo
|
|||
|
||||
damageDecl.AddKey("location", vtos(hitLocation));
|
||||
|
||||
/* apply knockback, but only on death */
|
||||
float knockBack = damageDecl.GetFloat("knockback");
|
||||
if (knockBack >= 0) {
|
||||
AddVelocity(dmgDir * knockBack);
|
||||
}
|
||||
|
||||
/* they died */
|
||||
if (GetHealth() <= 0) {
|
||||
g_grMode.PlayerDeath(this, (NSActor)attacker, damageDecl);
|
||||
|
|
|
@ -89,11 +89,12 @@ private:
|
|||
/** Will transport an entity from its position to the exit position. */
|
||||
nonvirtual void TransportEntity(NSEntity);
|
||||
|
||||
#ifdef CLIENT
|
||||
vector m_vecTargetPos;
|
||||
vector m_vecTargetN;
|
||||
vector m_vecTargetS;
|
||||
vector m_vecTargetT;
|
||||
|
||||
#ifdef CLIENT
|
||||
float m_flSize;
|
||||
#endif
|
||||
|
||||
|
@ -117,4 +118,4 @@ private:
|
|||
|
||||
.float portalnum;
|
||||
.float impulse; //used as the radius for the solid_portal csg subtraction
|
||||
.bool isPortal;
|
||||
.bool isPortal;
|
||||
|
|
|
@ -32,13 +32,10 @@ NSPortal::NSPortal(void)
|
|||
m_brushNum = -1;
|
||||
m_bEnabled = false;
|
||||
isPortal = true;
|
||||
|
||||
#ifdef CLIENT
|
||||
m_vecTargetPos = g_vec_null;
|
||||
m_vecTargetN = g_vec_null;
|
||||
m_vecTargetS = g_vec_null;
|
||||
m_vecTargetT = g_vec_null;
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
|
||||
|
@ -150,15 +147,15 @@ NSPortal::PortalClose(void)
|
|||
/* invalidate the other portal's reference to this one, only
|
||||
if we're still actively linked. */
|
||||
if (m_ePortalTarget && m_ePortalTarget.m_ePortalTarget == this) {
|
||||
m_ePortalTarget.m_bEnabled = false;
|
||||
m_ePortalTarget.m_bEnabled = false;
|
||||
m_ePortalTarget.m_ePortalTarget = __NULL__;
|
||||
m_ePortalTarget._PortalUpdated();
|
||||
m_ePortalTarget._PortalUpdated();
|
||||
}
|
||||
|
||||
/* now kill our own reference */
|
||||
m_ePortalTarget = __NULL__;
|
||||
m_bEnabled = false;
|
||||
_PortalUpdated();
|
||||
_PortalUpdated();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -167,16 +164,17 @@ NSPortal::PortalLinkTo(NSPortal target, bool openPortal)
|
|||
m_ePortalTarget = target;
|
||||
|
||||
m_bEnabled = openPortal;
|
||||
|
||||
SendFlags = -1;
|
||||
_PortalUpdated();
|
||||
|
||||
if (m_ePortalTarget)
{
|
||||
m_ePortalTarget.m_ePortalTarget = this;
|
||||
m_ePortalTarget.m_bEnabled = openPortal;
|
||||
m_ePortalTarget.SendFlags = -1;
|
||||
m_ePortalTarget._PortalUpdated();
|
||||
}
|
||||
|
||||
SendFlags = -1;
|
||||
_PortalUpdated();
|
||||
|
||||
if (m_ePortalTarget)
|
||||
{
|
||||
m_ePortalTarget.m_ePortalTarget = this;
|
||||
m_ePortalTarget.m_bEnabled = openPortal;
|
||||
m_ePortalTarget.SendFlags = -1;
|
||||
m_ePortalTarget._PortalUpdated();
|
||||
}
|
||||
|
||||
return target ? true : false;
|
||||
}
|
||||
|
@ -208,22 +206,24 @@ void
|
|||
NSPortal::_PortalUpdated(void)
|
||||
{
|
||||
/* the displayed surface must be in a known position.
|
||||
we're not going to compensate for the model here, because I'm too lazy.
*/
|
||||
we're not going to compensate for the model here, because I'm too lazy.
|
||||
*/
|
||||
vector newAngles = angles;
|
||||
//newAngles[0] * -1;
|
||||
makevectors(newAngles);
|
||||
makevectors(newAngles);
|
||||
|
||||
m_vecPortalN = v_forward;
|
||||
m_vecPortalS = -v_right;
|
||||
m_vecPortalT = v_up;
|
||||
m_vecPortalPos = origin;
|
||||
|
||||
/* expand the size of the object along the plane, and set up a portal region.
*/
|
||||
movetype = MOVETYPE_NONE;
|
||||
m_vecPortalN = v_forward;
|
||||
m_vecPortalS = -v_right;
|
||||
m_vecPortalT = v_up;
|
||||
m_vecPortalPos = origin;
|
||||
|
||||
/* expand the size of the object along the plane, and set up a portal region.
|
||||
*/
|
||||
movetype = MOVETYPE_NONE;
|
||||
|
||||
if (m_bEnabled == true) {
|
||||
solid = SOLID_PORTAL;
|
||||
setmodel(this, modelnameforindex(m_flPortalModel));
|
||||
setmodel(this, modelnameforindex(m_flPortalModel));
|
||||
if (m_bWasEnabled == false) {
|
||||
m_bWasEnabled = true;
|
||||
#ifdef SERVER
|
||||
|
@ -244,81 +244,75 @@ NSPortal::_PortalUpdated(void)
|
|||
//modelindex = 0;
|
||||
}
|
||||
|
||||
/* determine size of major axis
*/
|
||||
float portalSize = max(size[0], size[1], size[2]);
|
||||
impulse = portalSize; /* let the engine know how wide the portal should be
*/
|
||||
|
||||
/* make sure the abs size contains the entire portal.
*/
|
||||
portalSize = sqrt(portalSize * portalSize * 2);
|
||||
mins -= portalSize * [1, 1, 1];
|
||||
maxs += portalSize * [1, 1, 1];
|
||||
setsize(this, mins, maxs);
|
||||
/* determine size of major axis
|
||||
*/
|
||||
float portalSize = max(size[0], size[1], size[2]);
|
||||
impulse = portalSize; /* let the engine know how wide the portal should be
|
||||
*/
|
||||
|
||||
/* make sure the abs size contains the entire portal.
|
||||
*/
|
||||
portalSize = sqrt(portalSize * portalSize * 2);
|
||||
mins -= portalSize * [1, 1, 1];
|
||||
maxs += portalSize * [1, 1, 1];
|
||||
setsize(this, mins, maxs);
|
||||
}
|
||||
|
||||
vector
|
||||
NSPortal::_DirectionTransform(vector v)
|
||||
{
|
||||
/* FIXME: this should include .angles stuff
*/
|
||||
vector tmp, r;
|
||||
tmp[0] = v * m_vecPortalN;
|
||||
tmp[1] = v * m_vecPortalS;
|
||||
tmp[2] = v * m_vecPortalT;
|
||||
|
||||
{
|
||||
/* FIXME: this should include .angles stuff
|
||||
*/
|
||||
vector tmp, r;
|
||||
tmp[0] = v * m_vecPortalN;
|
||||
tmp[1] = v * m_vecPortalS;
|
||||
tmp[2] = v * m_vecPortalT;
|
||||
|
||||
r = [0, 0, 0];
|
||||
|
||||
if (!m_ePortalTarget)
{
|
||||
#ifdef CSQC
|
||||
r += tmp[2] * m_vecTargetT;
|
||||
r -= tmp[1] * m_vecTargetS;
|
||||
r -= tmp[0] * m_vecTargetN;
|
||||
#else
|
||||
r += tmp[2] * this.m_vecPortalT;
|
||||
r -= tmp[1] * this.m_vecPortalS;
|
||||
r -= tmp[0] * this.m_vecPortalN;
|
||||
#endif
|
||||
}
else
{
|
||||
r += tmp[2] * m_ePortalTarget.m_vecPortalT;
|
||||
r -= tmp[1] * m_ePortalTarget.m_vecPortalS;
|
||||
r -= tmp[0] * m_ePortalTarget.m_vecPortalN;
|
||||
}
|
||||
if (!m_ePortalTarget) {
|
||||
r += tmp[2] * m_vecTargetT;
|
||||
r -= tmp[1] * m_vecTargetS;
|
||||
r -= tmp[0] * m_vecTargetN;
|
||||
} else {
|
||||
r += tmp[2] * m_ePortalTarget.m_vecPortalT;
|
||||
r -= tmp[1] * m_ePortalTarget.m_vecPortalS;
|
||||
r -= tmp[0] * m_ePortalTarget.m_vecPortalN;
|
||||
}
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
vector
|
||||
NSPortal::_OriginTransform(vector p)
|
||||
{
|
||||
if (!m_ePortalTarget)
{
|
||||
#ifdef CSQC
|
||||
return m_vecTargetPos - _DirectionTransform(m_vecPortalPos - p);
|
||||
#else
|
||||
return this.m_vecPortalPos - _DirectionTransform(m_vecPortalPos - p);
|
||||
#endif
|
||||
}
|
||||
NSPortal::_OriginTransform(vector p)
|
||||
{
|
||||
if (!m_ePortalTarget) {
|
||||
return m_vecPortalPos - _DirectionTransform(m_vecPortalPos - p);
|
||||
}
|
||||
|
||||
return m_ePortalTarget.m_vecPortalPos - _DirectionTransform(m_vecPortalPos - p);
|
||||
return m_ePortalTarget.m_vecPortalPos - _DirectionTransform(m_vecPortalPos - p);
|
||||
}
|
||||
|
||||
// need to generate forward/right/up vectors
|
||||
// return value is the new view origin.
|
||||
// trace_end_pos needs to contain the pvs origin.
|
||||
|
||||
// need to generate forward/right/up vectors
|
||||
// return value is the new view origin.
|
||||
// trace_end_pos needs to contain the pvs origin.
|
||||
vector
|
||||
NSPortal::camera_transform(vector originalOrg, vector originalAngles)
|
||||
{
|
||||
vector newCameraPos;
|
||||
|
||||
newCameraPos = _OriginTransform(originalOrg);
|
||||
v_forward = _DirectionTransform(v_forward);
|
||||
v_right = _DirectionTransform(v_right);
|
||||
v_up = _DirectionTransform(v_up);
|
||||
|
||||
//trace from the center of the target to the view, to set trace_endpos for the pvs origin
|
||||
if (m_ePortalTarget)
|
||||
traceline(m_ePortalTarget.m_vecPortalPos, newCameraPos, MOVE_NOMONSTERS, this);
|
||||
else
|
||||
trace_endpos = this.m_vecPortalPos;
|
||||
{
|
||||
vector newCameraPos;
|
||||
|
||||
return newCameraPos;
|
||||
newCameraPos = _OriginTransform(originalOrg);
|
||||
v_forward = _DirectionTransform(v_forward);
|
||||
v_right = _DirectionTransform(v_right);
|
||||
v_up = _DirectionTransform(v_up);
|
||||
|
||||
//trace from the center of the target to the view, to set trace_endpos for the pvs origin
|
||||
if (m_ePortalTarget)
|
||||
traceline(m_ePortalTarget.m_vecPortalPos, newCameraPos, MOVE_NOMONSTERS, this);
|
||||
else
|
||||
trace_endpos = this.m_vecPortalPos;
|
||||
|
||||
return newCameraPos;
|
||||
}
|
||||
|
||||
/* because when using custom player physics, the engine will not do us any favors
|
||||
|
|
|
@ -19,9 +19,10 @@ NSSurfacePropEntity::NSSurfacePropEntity(void)
|
|||
{
|
||||
m_flBurnNext = 0.0f;
|
||||
#ifdef SERVER
|
||||
max_health = 100;
|
||||
max_armor = 100;
|
||||
m_iPropData = -1i;
|
||||
m_iMaterial = -1i;
|
||||
max_health = 100;
|
||||
m_strOnBreak = __NULL__;
|
||||
m_eBurner= __NULL__;
|
||||
m_iBurnWeapon = 0i;
|
||||
|
@ -255,7 +256,7 @@ NSSurfacePropEntity::Damage(entity inflictor, entity attacker, NSDict damageDecl
|
|||
health = rint(health - damagePoints);
|
||||
|
||||
if (health <= 0) {
|
||||
/* apply knockback */
|
||||
/* apply knockback, but only on death */
|
||||
float knockBack = damageDecl.GetFloat("knockback");
|
||||
if (knockBack >= 0) {
|
||||
AddVelocity(dmgDir * knockBack);
|
||||
|
|
Loading…
Reference in a new issue