From 649ed825adefaca2946f99fc65ac5a38308f05ac Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Sat, 2 Mar 2024 00:40:08 -0800 Subject: [PATCH] Big commit, work over various triggers. Clean up debug prints and make them more consistent. Warnings are in yellow, while errors are in red. New cvar: g_developerTimestamp will display timestamps next to debug messages originating from the game-logic. Set g_developer to 1 to see them. A lot of useful into, such as which entity id messages originate from should aid in debugging quite a bit. SP level transitions should also be more reliable now in terms of transferring entities and the like. Some levels have awkward transition areas and you might find yourself jumping between levels frequently. Workarounds are in the works. --- base/manifest.fmf | 13 + base/src/server/progs.src | 1 + build_game.sh | 4 + src/botlib/{bot.h => NSBot.h} | 2 +- src/botlib/{bot.qc => NSBot.qc} | 20 +- src/botlib/bot_combat.qc | 2 +- src/botlib/cvar.h | 42 --- src/botlib/defs.h | 85 ++++- src/botlib/include.src | 2 +- src/botlib/profiles.h | 42 --- src/botlib/profiles.qc | 20 +- src/botlib/route.qc | 21 +- src/botlib/way.qc | 184 ++------- src/client/NSInteractiveSurface.qc | 2 +- src/client/NSRadar.qc | 6 +- src/client/cmd.qc | 78 ++-- src/client/defs.h | 1 + src/client/detailtex.qc | 6 +- src/client/efx.qc | 14 +- src/client/entities.qc | 3 +- src/client/entry.qc | 26 +- src/client/fade.qc | 5 +- src/client/font.qc | 6 +- src/client/shake.qc | 22 +- src/client/sky.qc | 2 +- src/client/titles.qc | 9 +- src/client/view.qc | 27 +- src/client/way.qc | 15 +- src/gs-entbase/client/env_cubemap.qc | 7 +- src/gs-entbase/client/env_sound.qc | 2 +- src/gs-entbase/server/cycler.qc | 1 + src/gs-entbase/server/cycler_sprite.qc | 3 +- src/gs-entbase/server/env_physexplosion.qc | 2 +- src/gs-entbase/server/env_render.qc | 12 +- src/gs-entbase/server/func_breakable.qc | 24 +- src/gs-entbase/server/func_guntarget.qc | 4 +- src/gs-entbase/server/func_plat.qc | 16 + src/gs-entbase/server/func_pushable.qc | 4 +- src/gs-entbase/server/func_trackchange.qc | 12 +- src/gs-entbase/server/func_tracktrain.qc | 19 +- src/gs-entbase/server/func_train.qc | 12 +- src/gs-entbase/server/game_counter.qc | 6 +- src/gs-entbase/server/game_counter_set.qc | 2 +- src/gs-entbase/server/game_player_equip.qc | 5 +- src/gs-entbase/server/game_player_team.qc | 2 +- src/gs-entbase/server/game_team_set.qc | 2 +- src/gs-entbase/server/logic_auto.qc | 2 +- src/gs-entbase/server/logic_case.qc | 4 +- src/gs-entbase/server/logic_timer.qc | 4 +- src/gs-entbase/server/math_counter.qc | 11 + src/gs-entbase/server/monstermaker.qc | 67 ++-- src/gs-entbase/server/multi_manager.qc | 4 +- src/gs-entbase/server/multisource.qc | 4 +- src/gs-entbase/server/path_corner.qc | 6 +- src/gs-entbase/server/path_track.qc | 5 +- src/gs-entbase/server/phys_convert.qc | 2 +- src/gs-entbase/server/prop_door_rotating.qc | 2 +- src/gs-entbase/server/random_speaker.qc | 10 +- src/gs-entbase/server/scripted_sentence.qc | 111 +++++- src/gs-entbase/server/stubs.qc | 4 +- src/gs-entbase/server/target_cdaudio.qc | 4 +- src/gs-entbase/server/trigger_auto.qc | 5 +- src/gs-entbase/server/trigger_autosave.qc | 3 +- src/gs-entbase/server/trigger_cdaudio.qc | 3 +- src/gs-entbase/server/trigger_changelevel.qc | 18 +- src/gs-entbase/server/trigger_changetarget.qc | 3 +- src/gs-entbase/server/trigger_counter.qc | 4 +- src/gs-entbase/server/trigger_hurt.qc | 4 +- src/gs-entbase/server/trigger_look.qc | 2 +- src/gs-entbase/server/trigger_once.qc | 4 +- src/gs-entbase/server/trigger_relay.qc | 4 +- src/gs-entbase/server/trigger_teleport.qc | 6 +- src/gs-entbase/server/trigger_transition.qc | 73 ++-- src/gs-entbase/shared/ambient_generic.qc | 8 +- src/gs-entbase/shared/decals.qc | 3 +- src/gs-entbase/shared/env_glow.qc | 4 +- src/gs-entbase/shared/env_muzzleflash.qc | 6 +- src/gs-entbase/shared/func_vehicle.qc | 4 +- src/gs-entbase/shared/phys_rope.qc | 2 +- src/gs-entbase/shared/point_spotlight.qc | 6 +- src/gs-entbase/shared/prop_rope.qc | 2 +- src/gs-entbase/shared/trigger_camera.qc | 103 ++++-- src/gs-entbase/shared/worldspawn.qc | 13 +- src/menu-fn/entry.qc | 12 +- src/menu-fn/layout_script.qc | 2 +- src/platform/gamelibrary.qc | 29 +- src/platform/maplibrary.qc | 4 +- src/platform/master.qc | 9 +- src/server/NSGameRules.qc | 21 +- src/server/defs.h | 1 + src/server/entityDef.qc | 46 ++- src/server/entry.qc | 68 ++-- src/server/mapcycle.qc | 9 +- src/server/maptweaks.qc | 5 + src/server/nodes.qc | 81 ++-- src/server/plugins.qc | 9 +- src/server/skill.qc | 9 +- src/server/way.h | 1 + src/shared/NSBrushTrigger.qc | 2 +- src/shared/NSClient.h | 15 +- src/shared/NSClient.qc | 29 +- src/shared/NSClientPlayer.qc | 2 +- src/shared/NSClientSpectator.qc | 2 +- src/shared/NSDebris.qc | 18 +- src/shared/NSEntity.h | 12 +- src/shared/NSEntity.qc | 43 ++- src/shared/NSIO.h | 46 ++- src/shared/NSIO.qc | 23 +- src/shared/NSItem.qc | 2 +- src/shared/NSMonster.h | 12 +- src/shared/NSMonster.qc | 61 +-- src/shared/NSMoverEntity.qc | 10 +- src/shared/NSNavAI.h | 2 +- src/shared/NSNavAI.qc | 30 +- src/shared/NSPhysicsConstraint.qc | 10 +- src/shared/NSPhysicsEntity.qc | 15 +- src/shared/NSPointTrigger.qc | 2 +- src/shared/NSPortal.h | 32 +- src/shared/NSPortal.qc | 117 +++++- src/shared/NSProjectile.h | 4 +- src/shared/NSProjectile.qc | 6 +- src/shared/NSRenderableEntity.qc | 18 +- src/shared/NSSpraylogo.qc | 2 +- src/shared/NSSquadMonster.qc | 8 +- src/shared/NSSurfacePropEntity.h | 14 +- src/shared/NSSurfacePropEntity.qc | 149 +++++--- src/shared/NSTalkMonster.qc | 20 +- src/shared/NSTimer.qc | 4 +- src/shared/NSTrigger.h | 5 +- src/shared/NSTrigger.qc | 46 +-- src/shared/NSVehicle.h | 12 +- src/shared/NSVehicle.qc | 5 +- src/shared/cloader.h | 82 ++--- src/shared/cloader.qc | 116 +++--- src/shared/colors.h | 2 +- src/shared/damage.h | 2 +- src/shared/decalgroups.h | 4 +- src/shared/decalgroups.qc | 24 +- src/shared/defs.h | 21 +- src/shared/entities.h | 4 +- src/shared/events.h | 2 +- src/shared/global.h | 117 +++++- src/shared/materials.h | 348 +++++++++--------- src/shared/materials.qc | 20 +- src/shared/math.h | 2 +- src/shared/math.qc | 2 +- src/shared/motd.h | 4 +- src/shared/motd.qc | 7 +- src/shared/platform.h | 6 +- src/shared/player_pmove.qc | 2 +- src/shared/pmove.qc | 2 +- src/shared/pmove_custom.qc | 4 +- src/shared/propdata.qc | 47 ++- src/shared/sentences.qc | 35 +- src/shared/sound.h | 34 +- src/shared/sound.qc | 47 +-- src/shared/surfaceproperties.qc | 23 +- src/shared/util.h | 19 +- src/shared/util.qc | 22 +- src/shared/weapons.qc | 2 +- 160 files changed, 1990 insertions(+), 1409 deletions(-) create mode 100644 base/manifest.fmf rename src/botlib/{bot.h => NSBot.h} (98%) rename src/botlib/{bot.qc => NSBot.qc} (96%) delete mode 100644 src/botlib/cvar.h delete mode 100644 src/botlib/profiles.h create mode 100644 src/gs-entbase/server/math_counter.qc diff --git a/base/manifest.fmf b/base/manifest.fmf new file mode 100644 index 00000000..0de042b5 --- /dev/null +++ b/base/manifest.fmf @@ -0,0 +1,13 @@ +FTEMANIFEST 1 +NAME "Test Game" +GAME base +BASEGAME platform +BASEGAME base + +// you don't really want to change these +RTCBROKER master.frag-net.com:27950 +PROTOCOLNAME "Nuclide" +MAINCONFIG nuclide.cfg +DOWNLOADSURL "" + +-exec platform_default.cfg diff --git a/base/src/server/progs.src b/base/src/server/progs.src index 41f5a55b..8fceff31 100644 --- a/base/src/server/progs.src +++ b/base/src/server/progs.src @@ -10,6 +10,7 @@ ../../../src/shared/fteextensions.qc ../../../src/shared/defs.h ../../../src/server/defs.h +../../../src/botlib/botinfo.h ../../../src/gs-entbase/server.src ../../../src/gs-entbase/shared.src diff --git a/build_game.sh b/build_game.sh index e0a3ffb8..d0da0043 100755 --- a/build_game.sh +++ b/build_game.sh @@ -11,6 +11,10 @@ safe_copy() radiant_build() { + if [ "$SKIP_RADIANT" = "1" ]; then + exit 0 + fi + ./make_mapdef.sh "$1" # copy files over to RADIANT diff --git a/src/botlib/bot.h b/src/botlib/NSBot.h similarity index 98% rename from src/botlib/bot.h rename to src/botlib/NSBot.h index a56e7304..af6884d1 100644 --- a/src/botlib/bot.h +++ b/src/botlib/NSBot.h @@ -39,7 +39,7 @@ typedef enum BOT_STATE_FLEEING /**< this is for when the AI should just get as far away as possible */ } botstate_t; -/** Base class for the Bot AI. +/** A virtual multiplayer opponent. Base class for all bots. */ class NSBot:player { diff --git a/src/botlib/bot.qc b/src/botlib/NSBot.qc similarity index 96% rename from src/botlib/bot.qc rename to src/botlib/NSBot.qc index 4f64e1d2..52d99979 100644 --- a/src/botlib/bot.qc +++ b/src/botlib/NSBot.qc @@ -193,8 +193,7 @@ NSBot::CheckRoute(void) /* we're inside the radius */ if (flDist <= flRadius) { - NSLog("^2NSBot::^3CheckRoute^7: " \ - "%s reached node\n", this.targetname); + BotEntLog("%s reached node", this.netname); m_iCurNode--; /* if we're inside an actual node (not a virtual one */ @@ -218,8 +217,7 @@ NSBot::CheckRoute(void) /* can we walk directly to our target destination? */ if (trace_fraction == 1.0) { - print("^2NSBot::^3CheckRoute^7: " \ - "Walking directly to last node\n"); + BotEntLog("Walking directly to last node."); m_iCurNode = -1; } } @@ -245,7 +243,7 @@ NSBot::CheckRoute(void) /* after one second, also give up the route */ if (m_flNodeGiveup >= 1.0f || m_iCurNode <= BOTROUTE_END) { - print("taking too long! giving up!\n"); + BotEntLog("Taking too long! Giving up!"); RouteClear(); } else if (m_flNodeGiveup >= 0.5f) { /* attempt a jump after half a second */ @@ -279,7 +277,7 @@ NSBot::RunAI(void) input_angles = [0,0,0]; /* attempt to respawn when dead */ - if (IsDead() == true) { + if (IsDead() == true || health <= 0) { RouteClear(); WeaponAttack(); SetEnemy(__NULL__); @@ -294,7 +292,7 @@ NSBot::RunAI(void) if (!m_iNodes && autocvar_bot_aimless == 0) { CreateObjective(); - NSLog("NSBot::RunAI: %s is calculating first bot route", + BotEntLog("%S is calculating first bot route", this.netname); /* our route probably has not been processed yet */ @@ -430,14 +428,12 @@ NSBot::RunAI(void) if (m_eTarget && enemyVisible && m_flEnemyDist < 256) { /* we are far away, inch closer */ aimPos = m_eTarget.origin; - //printf("going to target\n"); } else { goRoute = true; } } else if (m_wtWeaponType == WPNTYPE_THROW) { if ((m_eTarget && enemyVisible && !enemyDistant) && m_flEnemyDist < 512) { aimPos = m_eTarget.origin; - //printf("going to target\n"); } else { goRoute = true; } @@ -448,10 +444,8 @@ NSBot::RunAI(void) if (goRoute) { if (m_iCurNode <= BOTROUTE_DESTINATION) { aimPos = m_vecLastNode; - //printf("going to last node\n"); } else { aimPos = m_pRoute[m_iCurNode].dest; - //printf("going to next node\n"); } } else { RouteClear(); @@ -511,7 +505,7 @@ NSBot::PostFrame(void) /* we've picked something new up */ if (m_iOldItems != g_items) { Weapons_SwitchBest(this); - print(sprintf("%s is now using %s (%d)\n", netname, g_weapons[activeweapon].name, activeweapon)); + BotEntLog("%S is now using %S (%d)", netname, g_weapons[activeweapon].name, activeweapon); m_iOldItems = g_items; } #endif @@ -553,7 +547,7 @@ bot_spawner_think(void) int minClientsCvar = (int)cvar("bot_minClients"); /* if -1, we are not managing _anything_ */ - if (minClientsCvar == -1) { + if (minClientsCvar == -1i) { self.nextthink = time + 5.0f; return; } diff --git a/src/botlib/bot_combat.qc b/src/botlib/bot_combat.qc index f3af9d2c..df03cfc7 100644 --- a/src/botlib/bot_combat.qc +++ b/src/botlib/bot_combat.qc @@ -169,7 +169,7 @@ BotLib_Alert(vector pos, float radius, float t) continue; /* we've heard a noise. investigate the location */ - print(sprintf("bot alerted by noise at %v\n", pos)); + BotLog("Bot %S (%d) alerted by noise at %v", f.netname, num_for_edict(f), pos); f.RouteClear(); f.RouteToPosition(pos); } diff --git a/src/botlib/cvar.h b/src/botlib/cvar.h deleted file mode 100644 index 1f2c06da..00000000 --- a/src/botlib/cvar.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2023 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -var int autocvar_bot_aimless = FALSE; - -var int autocvar_nav_linksize = 256; -var int autocvar_nav_radius = 8; - -var bool autocvar_bot_crouch = false; -var bool autocvar_bot_walk = false; -var bool autocvar_bot_stop = false; -var bool autocvar_bot_dont_shoot = false; - -var bool autocvar_bot_join_after_player = false; -var float autocvar_bot_join_delay = 0.0f; -var int autocvar_bot_quota = 0i; -var string autocvar_bot_quota_mode = "normal"; -var string autocvar_bot_chatter = "normal"; - -typedef enum -{ - BOTSKILL_EASY = 1, - BOTSKILL_MEDIUM, - BOTSKILL_HARD -} botskill_t; - -var botskill_t autocvar_bot_skill = BOTSKILL_MEDIUM; - -var string autocvar_bot_prefix = ""; diff --git a/src/botlib/defs.h b/src/botlib/defs.h index 79d7186b..30556043 100644 --- a/src/botlib/defs.h +++ b/src/botlib/defs.h @@ -14,10 +14,85 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "bot.h" -#include "botinfo.h" -#include "cvar.h" -#include "profiles.h" - +#include "NSBot.h" vector Route_SelectDestination( NSBot target ); + +var int autocvar_bot_aimless = FALSE; + +var int autocvar_nav_linksize = 256; +var int autocvar_nav_radius = 8; + +var bool autocvar_bot_crouch = false; +var bool autocvar_bot_walk = false; +var bool autocvar_bot_stop = false; +var bool autocvar_bot_dont_shoot = false; + +var bool autocvar_bot_join_after_player = false; +var float autocvar_bot_join_delay = 0.0f; +var int autocvar_bot_quota = 0i; +var string autocvar_bot_quota_mode = "normal"; +var string autocvar_bot_chatter = "normal"; +var bool autocvar_bot_developer = false; + +void +_BotLog(string functionName, string msg) +{ + print(sprintf("%f ^xF05%s ^7: %s\n", time, functionName, msg)); +} + +/** Logs an bot system specific log message. + The console variable `bot_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define BotLog(...) if (autocvar_bot_developer) _BotLog(__FUNC__, sprintf(__VA_ARGS__)) + +void +_BotEntLog(string className, string functionName, float edictNum, string warnMessage) +{ + print(sprintf("%f ^xF05%s (id: %d) ^7: %s\n", time, functionName, edictNum, warnMessage)); +} + +/** Logs an bot specific entity class log message. + The console variable `bot_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define BotEntLog(...) if (autocvar_bot_developer) _BotEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) + +typedef enum +{ + BOTSKILL_EASY = 1, + BOTSKILL_MEDIUM, + BOTSKILL_HARD +} botskill_t; + +var botskill_t autocvar_bot_skill = BOTSKILL_MEDIUM; + +var string autocvar_bot_prefix = ""; + +/* BotScript + script/bots.txt + + Listing of various bot profiles + where infokeys can be set and interpreted + by the game-logic at will. + + The `name` keys has to _always_ be present. + The `funname` key is optional. + + Name acts as both an identifier as well + as a nickname when `funname` is not present. + + Anything else is considered to be extra. +*/ + +typedef struct +{ + string m_strName; + string m_strNetName; + string m_strExtra; +} botScript_t; + +#define BOTSCRIPT_MAX 32 +botScript_t g_bots[BOTSCRIPT_MAX]; +var int g_botScriptCount; \ No newline at end of file diff --git a/src/botlib/include.src b/src/botlib/include.src index f08b4660..e6ee6691 100644 --- a/src/botlib/include.src +++ b/src/botlib/include.src @@ -3,7 +3,7 @@ #includelist defs.h profiles.qc -bot.qc +NSBot.qc bot_chat.qc bot_combat.qc route.qc diff --git a/src/botlib/profiles.h b/src/botlib/profiles.h deleted file mode 100644 index 3c4e4ed9..00000000 --- a/src/botlib/profiles.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2023 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/* BotScript - script/bots.txt - - Listing of various bot profiles - where infokeys can be set and interpreted - by the game-logic at will. - - The `name` keys has to _always_ be present. - The `funname` key is optional. - - Name acts as both an identifier as well - as a nickname when `funname` is not present. - - Anything else is considered to be extra. -*/ - -typedef struct -{ - string m_strName; - string m_strNetName; - string m_strExtra; -} botScript_t; - -#define BOTSCRIPT_MAX 32 -botScript_t g_bots[BOTSCRIPT_MAX]; -var int g_botScriptCount; \ No newline at end of file diff --git a/src/botlib/profiles.qc b/src/botlib/profiles.qc index 1bbe4524..8b4d26e1 100644 --- a/src/botlib/profiles.qc +++ b/src/botlib/profiles.qc @@ -29,7 +29,7 @@ Bot_ExistsInServer(string botName) } bool -Bot_AddBot_f(string botName) +Bot_AddBot_f(string botName, float teamValue, float spawnDelay, string newName) { int extraCount = 0i; int foundID = -1i; @@ -43,7 +43,7 @@ Bot_AddBot_f(string botName) } if (!g_nodes_present) { - print("^1BotScript_Add^7: Can't add bot. No waypoints.\n"); + NSError("Can't add bot. No nodes."); return (false); } @@ -56,7 +56,7 @@ Bot_AddBot_f(string botName) } if (foundID == -1i) { - print("^1BotScript_Add^7: Named profile not found.\n"); + NSError("Named profile %S not found.", botName); return (false); } @@ -64,7 +64,7 @@ Bot_AddBot_f(string botName) self = spawnclient(); if (!self) { - print("^1BotScript_Add^7: Can't add bot. Server is full\n"); + NSError("Unable to add bot. Server is full."); self = oldSelf; return (false); } @@ -111,11 +111,11 @@ BotProfile_AddRandom(void) /* every bot exists already */ if (spawnBot == -1i) { - print("^1BotProfile_AddRandom^7: Not enough profiles available.\n"); + NSError("Not enough profiles available."); return (false); } - Bot_AddBot_f(g_bots[spawnBot].m_strName); + Bot_AddBot_f(g_bots[spawnBot].m_strName, 0, 0.0f, __NULL__); return (true); } @@ -127,6 +127,8 @@ BotProfile_Init(void) botScript_t currentDef; int braceDepth = 0i; + InitStart(); + currentDef.m_strName = ""; currentDef.m_strNetName = ""; currentDef.m_strExtra = ""; @@ -140,6 +142,7 @@ BotProfile_Init(void) botScript = fopen("scripts/bots.txt", FILE_READ); if (botScript < 0) { + NSError("Missing file scripts/bots.txt"); return; } @@ -197,14 +200,15 @@ BotProfile_Init(void) } fclose(botScript); - print(sprintf("%i bots parsed\n", g_botScriptCount)); + NSLog("...%i bots parsed.", g_botScriptCount); + InitEnd(); } void Bot_ListBotProfiles_f(void) { if (!g_botScriptCount) { - print("no bot profiles found.\n"); + NSError("No bot profiles available."); return; } diff --git a/src/botlib/route.qc b/src/botlib/route.qc index 01db0844..28eb94d8 100644 --- a/src/botlib/route.qc +++ b/src/botlib/route.qc @@ -169,7 +169,7 @@ Route_SelectDestination(NSBot target) if (rules.IsTeamplay()) { /* we have the goal item, so capture it */ if (target.flags & FL_GOALITEM) { - print(sprintf("%s going for capture\n", target.netname)); + BotLog("%s going for capture", target.netname); dest = Route_SelectNearestTeam(BOTINFO_TEAM_GOALCAPTURE, target.origin, target.team); /* we may have to go to our teams' goal item then */ @@ -177,7 +177,7 @@ Route_SelectDestination(NSBot target) dest = Route_SelectNearestTeam(BOTINFO_TEAM_GOALITEM, target.origin, target.team); } } else { - print(sprintf("%s hunting for goal item\n", target.netname)); + BotLog("%s hunting for goal item", target.netname); dest = Route_SelectNearestEnemyTeam(BOTINFO_TEAM_GOALITEM, target.origin, target.team); } @@ -187,13 +187,12 @@ Route_SelectDestination(NSBot target) } /* by now, they need something else to do involving goal items probably */ - - print(sprintf("%s can't figure out where to go for the goal\n", target.netname)); + BotLog("%s can't figure out where to go for the goal", target.netname); } /* if we're low on health, look for health items */ if (target.health < 50) { - print(sprintf("%s going for health\n", target.netname)); + BotLog("%s going for health", target.netname); dest = Route_SelectNearest(BOTINFO_HEALTH, target.origin, target.m_vecLastPOI); if (dest != __NULL__) { @@ -201,13 +200,13 @@ Route_SelectDestination(NSBot target) return dest.origin + [0,0,32]; } - print(sprintf("%s can't figure out where to go for health\n", target.netname)); + BotLog("%s can't figure out where to go for health", target.netname); } /* armor is always a good idea to have */ if (random() < 0.25) if (target.armor < 50) { - print(sprintf("%s going for armor\n", target.netname)); + BotLog("%s going for armor", target.netname); dest = Route_SelectNearest(BOTINFO_ARMOR, target.origin, target.m_vecLastPOI); if (dest != __NULL__) { @@ -215,13 +214,13 @@ Route_SelectDestination(NSBot target) return dest.origin + [0,0,32]; } - print(sprintf("%s can't figure out where to go for armor\n", target.netname)); + BotLog("%s can't figure out where to go for armor", target.netname); } /* go for ammo, or weapon */ if (random() < 0.25) if (!dest) { - print(sprintf("%s going for ammo/weapon\n", target.netname)); + BotLog("%s going for ammo/weapon", target.netname); if (random() < 0.5) dest = Route_SelectFarthest(BOTINFO_WEAPON, target.origin, target.m_vecLastPOI); @@ -233,7 +232,7 @@ Route_SelectDestination(NSBot target) return dest.origin + [0,0,32]; } - print(sprintf("%s can't figure out where to go for ammo/weapon\n", target.netname)); + BotLog("%s can't figure out where to go for ammo/weapon", target.netname); } if (random() < 0.25) @@ -255,7 +254,7 @@ Route_SelectDestination(NSBot target) } /* if all else fails... select a random spot */ - print(sprintf("%s found nothing, going for random PoI\n", target.netname)); + BotLog("%s found nothing, going for random PoI", target.netname); dest = Route_SelectRandomSpot(); target.m_eDestination = dest; return (dest.origin); diff --git a/src/botlib/way.qc b/src/botlib/way.qc index 07c82519..935e5483 100644 --- a/src/botlib/way.qc +++ b/src/botlib/way.qc @@ -234,7 +234,7 @@ Way_SetRadius(int iID, float flRadValue) } void -Way_FlagJump(void) +Way_LinkFlag(int linkFlag) { if (g_waylink_status == 0) { g_way1 = Way_FindClosestNode(self.origin); @@ -256,41 +256,7 @@ Way_FlagJump(void) Way_LinkNodes(&g_pWaypoints[g_way1], &g_pWaypoints[g_way2]); for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) { if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) { - g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_JUMP; - env_message_single(self, "^2Jump-linked the two points!\n"); - } - } - } else { - env_message_single(self, "^1Failed to link, the two points are the same!\n"); - } - g_way1 = g_way2 = -1; - } -} - -void -Way_FlagCrouch(void) -{ - if (g_waylink_status == 0) { - g_way1 = Way_FindClosestNode(self.origin); - - if (g_way1 == -1i) - return; - - g_waylink_status = 1; - env_message_single(self, "^2Selected first waypoint!\n"); - } else if (g_waylink_status == 1) { - g_way2 = Way_FindClosestNode(self.origin); - - if (g_way2 == -1i) - return; - - g_waylink_status = 0; - - if (g_way1 != g_way2) { - Way_LinkNodes(&g_pWaypoints[g_way1], &g_pWaypoints[g_way2]); - for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) { - if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) { - g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_CROUCH; + g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= linkFlag; env_message_single(self, "^2Crouch-linked the two points!\n"); } } @@ -301,108 +267,6 @@ Way_FlagCrouch(void) } } -void -Way_FlagWalk(void) -{ - if (g_waylink_status == 0) { - g_way1 = Way_FindClosestNode(self.origin); - - if (g_way1 == -1i) - return; - - g_waylink_status = 1; - env_message_single(self, "^2Selected first waypoint!\n"); - } else if (g_waylink_status == 1) { - g_way2 = Way_FindClosestNode(self.origin); - - if (g_way2 == -1i) - return; - - g_waylink_status = 0; - - if (g_way1 != g_way2) { - Way_LinkNodes(&g_pWaypoints[g_way1], &g_pWaypoints[g_way2]); - for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) { - if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) { - g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_WALK; - env_message_single(self, "^2Walk-linked the two points!\n"); - } - } - } else { - env_message_single(self, "^1Failed to link, the two points are the same!\n"); - } - g_way1 = g_way2 = -1; - } -} - -void -Way_FlagAim(void) -{ - if (g_waylink_status == 0) { - g_way1 = Way_FindClosestNode(self.origin); - - if (g_way1 == -1i) - return; - - g_waylink_status = 1; - env_message_single(self, "^2Selected first waypoint!\n"); - } else if (g_waylink_status == 1) { - g_way2 = Way_FindClosestNode(self.origin); - - if (g_way2 == -1i) - return; - - g_waylink_status = 0; - - if (g_way1 != g_way2) { - Way_LinkNodes(&g_pWaypoints[g_way1], &g_pWaypoints[g_way2]); - for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) { - if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) { - g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_AIM; - env_message_single(self, "^2Aim-linked the two points!\n"); - } - } - } else { - env_message_single(self, "^1Failed to link, the two points are the same!\n"); - } - g_way1 = g_way2 = -1; - } -} - -void -Way_FlagUse(void) -{ - if (g_waylink_status == 0) { - g_way1 = Way_FindClosestNode(self.origin); - - if (g_way1 == -1i) - return; - - g_waylink_status = 1; - env_message_single(self, "^2Selected first waypoint!\n"); - } else if (g_waylink_status == 1) { - g_way2 = Way_FindClosestNode(self.origin); - - if (g_way2 == -1i) - return; - - g_waylink_status = 0; - - if (g_way1 != g_way2) { - Way_LinkNodes(&g_pWaypoints[g_way1], &g_pWaypoints[g_way2]); - for (int b = 0i; b < g_pWaypoints[g_way1].m_numNeighbours; b++) { - if (g_pWaypoints[g_way1].m_pNeighbour[b].m_iNode == g_way2) { - g_pWaypoints[g_way1].m_pNeighbour[b].m_iFlags |= LF_USER; - env_message_single(self, "^2Use-linked the two points!\n"); - } - } - } else { - env_message_single(self, "^1Failed to link, the two points are the same!\n"); - } - g_way1 = g_way2 = -1; - } -} - void Way_Unlink(void) { @@ -631,8 +495,7 @@ Way_DrawDebugInfo(void) } int iNearest = Way_FindClosestNode(self.origin); - makevectors(self.v_angle); - R_BeginPolygon("", 0, 0); + makevectors([-90, 0, 0]); for (int i = 0i; i < g_iWaypoints; i++) { waypoint_t *w = g_pWaypoints + i; @@ -643,10 +506,24 @@ Way_DrawDebugInfo(void) rgb = [0,1,0]; } - R_PolygonVertex(org + v_right * 4 - v_up * 4, [1,1], rgb, 1); - R_PolygonVertex(org - v_right * 4 - v_up * 4, [0,1], rgb, 1); - R_PolygonVertex(org - v_right * 4 + v_up * 4, [0,0], rgb, 1); - R_PolygonVertex(org + v_right * 4 + v_up * 4, [1,0], rgb, 1); + R_BeginPolygon("", 0, 0); + R_PolygonVertex(org + v_right * 2 - v_up * 2, [1,1], rgb, 1); + R_PolygonVertex(org - v_right * 2 - v_up * 2, [0,1], rgb, 1); + R_EndPolygon(); + + R_BeginPolygon("", 0, 0); + R_PolygonVertex(org - v_right * 2 - v_up * 2, [0,1], rgb, 1); + R_PolygonVertex(org - v_right * 2 + v_up * 2, [0,0], rgb, 1); + R_EndPolygon(); + + R_BeginPolygon("", 0, 0); + R_PolygonVertex(org - v_right * 2 + v_up * 2, [0,0], rgb, 1); + R_PolygonVertex(org + v_right * 2 + v_up * 2, [1,0], rgb, 1); + R_EndPolygon(); + + R_BeginPolygon("", 0, 0); + R_PolygonVertex(org + v_right * 2 + v_up * 2, [1,0], rgb, 1); + R_PolygonVertex(org + v_right * 2 - v_up * 2, [1,1], rgb, 1); R_EndPolygon(); } @@ -707,6 +584,9 @@ Way_DrawDebugInfo(void) R_EndPolygon(); } + /* spheres need view angle */ + makevectors(self.v_angle); + R_BeginPolygon("", 0, 0); for (int i = 0i; i < g_iWaypoints; i++) { vector rgb; @@ -814,20 +694,8 @@ Way_Cmd(void) g_pWaypoints[i].m_vecOrigin[2] *= -1; } break; - case "linkjump": - Way_FlagJump(); - break; - case "linkcrouch": - Way_FlagCrouch(); - break; - case "linkwalk": - Way_FlagWalk(); - break; - case "linkaim": - Way_FlagAim(); - break; - case "linkuse": - Way_FlagUse(); + case "flag": + Way_LinkFlag(stoi(argv(2))); break; case "unlink1": Way_Unlink(); diff --git a/src/client/NSInteractiveSurface.qc b/src/client/NSInteractiveSurface.qc index 291c94b9..97634aa3 100644 --- a/src/client/NSInteractiveSurface.qc +++ b/src/client/NSInteractiveSurface.qc @@ -268,7 +268,7 @@ NSInteractiveSurface::NSInteractiveSurface(void) m_flScale = 0.25f; m_flUseDistance = 64; m_strSurfaceMat = sprintf("UISurface%d", num_for_edict(this)); - print(sprintf("Surface mat: %S\n", m_strSurfaceMat)); + EntLog("UI surface material: %S\n", m_strSurfaceMat); drawmask = MASK_ENGINE; m_bCached = false; isCSQC = true; diff --git a/src/client/NSRadar.qc b/src/client/NSRadar.qc index c2acbf30..9f411ef4 100644 --- a/src/client/NSRadar.qc +++ b/src/client/NSRadar.qc @@ -302,8 +302,7 @@ NSRadar::InitFromHLTVScript(string fileName) r_uploadimage("overview", width, height, (void *)imgData); memfree(imgData); newRadar.m_strMaterial = "overview"; - - print("Overview loaded.\n"); + NSLog("Map overview available."); return newRadar; } @@ -369,7 +368,6 @@ NSRadar::InitFromSourceHLTVScript(string fileName) vector imageSize = drawgetimagesize(newRadar.m_strMaterial); imageSize *= newRadar.m_flScale; newRadar.CalculateVerticesSource(imageSize[0], imageSize[1]); - - print("Overview loaded.\n"); + NSLog("Map overview available."); return newRadar; } \ No newline at end of file diff --git a/src/client/cmd.qc b/src/client/cmd.qc index b7827f40..60138c3c 100644 --- a/src/client/cmd.qc +++ b/src/client/cmd.qc @@ -207,14 +207,14 @@ CMD_ListTitles(void) int i = 0i; for (i = 0; i < g_titles_count; i++) { - print(sprintf("%s, (x: %d, y: %d)\n", - g_titles[i].m_strName, g_titles[i].m_flPosX, g_titles[i].m_flPosY)); - print(sprintf("\teffect: %i, fade-in: %f, fade-out: %f\n", - g_titles[i].m_iEffect, g_titles[i].m_flFadeIn, g_titles[i].m_flFadeOut)); - print(sprintf("\thold-time: %f, fx-time: %f\n", - g_titles[i].m_flHoldTime, g_titles[i].m_flFXTime)); - print(sprintf("\tcolor 1: %v, color 2: %v\n", - g_titles[i].m_vecColor1, g_titles[i].m_vecColor2)); + printf("%s, (x: %d, y: %d)\n", + g_titles[i].m_strName, g_titles[i].m_flPosX, g_titles[i].m_flPosY); + printf("\teffect: %i, fade-in: %f, fade-out: %f\n", + g_titles[i].m_iEffect, g_titles[i].m_flFadeIn, g_titles[i].m_flFadeOut); + printf("\thold-time: %f, fx-time: %f\n", + g_titles[i].m_flHoldTime, g_titles[i].m_flFXTime); + printf("\tcolor 1: %v, color 2: %v\n", + g_titles[i].m_vecColor1, g_titles[i].m_vecColor2); } print(sprintf("\t%i total titles loaded\n", g_titles_count)); } @@ -226,12 +226,12 @@ CMD_ListModelFramegroups(void) float modelIndex = getmodelindex(modelName); string temp = ""; - print(sprintf("// model: %S\n", modelName)); + printf("// model: %S\n", modelName); print("typedef enum {\n"); for (int i = 0; i < modelframecount(modelIndex); i++) { temp = frametoname(modelIndex, i); - print(sprintf("\t%s = %i,\n", strtoupper(temp), i)); + printf("\t%s = %i,\n", strtoupper(temp), i); } print("} framegroups_e;\n"); } @@ -271,7 +271,7 @@ Cmd_Parse(string sCMD) case "listServerSoundDef": localcmd("sv listSoundDef\n"); break; - case "cleardecals": + case "clearDecals": CMD_Cleardecals(); break; case "testPointLight": @@ -437,28 +437,28 @@ Cmd_Parse(string sCMD) localcmd(sprintf("sv addBot %s\n", argv(1))); break; case "killAllBots": - localcmd(sprintf("sv killAllBots %s\n", argv(1))); + localcmd("sv killAllBots\n"); break; case "resetAllBotsGoals": - localcmd(sprintf("sv resetAllBotsGoals %s\n", argv(1))); + localcmd("sv resetAllBotsGoals\n"); break; case "killClass": localcmd(sprintf("sv killClass %s\n", argv(1))); break; case "killMovables": - localcmd(sprintf("sv killMovables %s\n", argv(1))); + localcmd("sv killMovables\n"); break; case "trigger": localcmd(sprintf("sv trigger %s\n", argv(1))); break; case "input": - localcmd(sprintf("sv input %s\n", argv(1))); + localcmd(sprintf("sv input %s %s %s\n", argv(1), argv(2), argv(3))); break; case "listBotProfiles": - localcmd(sprintf("sv listBotProfiles %s\n", argv(1))); + localcmd("sv listBotProfiles\n"); break; case "listTargets": - localcmd(sprintf("sv listTargets %s\n", argv(1))); + localcmd("sv listTargets\n"); break; case "teleport": localcmd(sprintf("sv teleport %s\n", argv(1))); @@ -467,12 +467,35 @@ Cmd_Parse(string sCMD) localcmd(sprintf("sv teleportToClass %s\n", argv(1))); break; case "respawnEntities": - localcmd(sprintf("sv respawnEntities %s\n", argv(1))); + localcmd("sv respawnEntities\n"); break; - case "spawn": + case "spawnDef": localcmd(sprintf("sv spawn %s\n", argv(1))); break; + + case "nodeAdd": + localcmd(sprintf("sv way addsingle %s\n", argv(1))); + break; + case "nodeDel": + localcmd(sprintf("sv way delete %s\n", argv(1))); + break; + case "nodeFlags": + localcmd(sprintf("sv way link %s\n", argv(1))); + break; + case "nodeLink": + localcmd(sprintf("sv way connect1 %s\n", argv(1))); + break; + case "nodeRadius": + localcmd(sprintf("sv way radius %s\n", argv(1))); + break; + case "nodeOffset": + localcmd(sprintf("sv way move %s\n", argv(1))); + break; + case "nodeUnlink": + localcmd(sprintf("sv way unlink1 %s\n", argv(1))); + break; + default: return (false); } @@ -489,7 +512,7 @@ Register our commands for Nuclide void Cmd_Init(void) { - print("--------- Initializing Cmds ----------\n"); + InitStart(); /* developer/debug commands */ registercommand("listFramegroups"); @@ -512,10 +535,19 @@ Cmd_Init(void) registercommand("teleport"); registercommand("teleportToClass"); registercommand("respawnEntities"); - registercommand("spawn"); + registercommand("spawnDef"); registercommand("listBotProfiles"); - registercommand("cleardecals"); + /* nav editing */ + registercommand("nodeAdd"); + registercommand("nodeDel"); + registercommand("nodeFlags"); + registercommand("nodeLink"); + registercommand("nodeRadius"); + registercommand("nodeOffset"); + registercommand("nodeUnlink"); + + registercommand("clearDecals"); registercommand("testLight"); registercommand("testPointLight"); registercommand("getpos"); @@ -586,4 +618,6 @@ Cmd_Init(void) registercommand("-menu_left"); registercommand("+menu_right"); registercommand("-menu_right"); + + InitEnd(); } diff --git a/src/client/defs.h b/src/client/defs.h index 0d29fa7e..93512370 100644 --- a/src/client/defs.h +++ b/src/client/defs.h @@ -175,6 +175,7 @@ void View_PlayAnimation(int); void View_EnableViewmodel(void); void View_DisableViewmodel(void); +void View_SetViewmodelSkin(float); /** Draws a non-filled rectangle with a specified outline. */ void drawrect(vector pos, vector sz, float thickness, vector rgb, float al, optional float dfl) diff --git a/src/client/detailtex.qc b/src/client/detailtex.qc index 29d2bc82..98f8b736 100644 --- a/src/client/detailtex.qc +++ b/src/client/detailtex.qc @@ -74,12 +74,10 @@ DetailTex_Reload(void) if (!autocvar(r_detailtextures, 0, "High-res detail texture overlays for selected maps")) return; - print("--------- Initializing DetailTex ----------\n"); - fh = fopen(strcat("maps/", mapname, "_detail.txt"), FILE_READ); if (fh < 0) { - print(sprintf("DeailTex definition not found for %s.\n", mapname)); + NSError("DeailTex definition missing for %s.", mapname); return; } @@ -93,7 +91,7 @@ DetailTex_Reload(void) n++; } - print(sprintf("DeailTex initialized with %i entries.\n", n)); + NSLog("DeailTex initialized with %i entries.", n); fclose(fh); g_detail_initialized = 1; } diff --git a/src/client/efx.qc b/src/client/efx.qc index 705b4a4e..6c33aa9d 100644 --- a/src/client/efx.qc +++ b/src/client/efx.qc @@ -96,7 +96,8 @@ EFX_Load(string efx_file) g_efx_name = (string *)memrealloc(g_efx_name, sizeof(string), i, g_efx_count); #else if (g_efx_count > EFXDATA_MAX) { - error(sprintf("EFX_Load: Reached EFXDATA_MAX (%d)\n", EFXDATA_MAX)); + NSError("EFX_Load: Reached EFXDATA_MAX (%d)", EFXDATA_MAX); + return (0); } #endif @@ -210,7 +211,7 @@ EFX_Load(string efx_file) } } - print(sprintf("parsed EFXDef file %s\n", efx_file)); + NSLog("parsed EFXDef file %S", efx_file); fclose(fh); return i; } @@ -318,7 +319,7 @@ EFX_UpdateListener(NSView playerView) } g_flEFXTime += clframetime; #else - NSLog("EFX_UpdateListener: Changed style to %s (%i)", + SndLog("Changed style to %s (%i)", g_efx_name[g_iEFX], g_iEFX); old_dsp = g_iEFX; @@ -332,14 +333,14 @@ EFX_Init(void) int efx_default; int efx_underwater; - print("--------- Initializing EFXDefs ----------\n"); + InitStart(); #ifndef EFXDATA_DYNAMIC g_efx = (reverbinfo_t *)memalloc(sizeof(reverbinfo_t) * EFXDATA_MAX); g_efx_name = (string *)memalloc(sizeof(string) * EFXDATA_MAX); - print(sprintf("allocated %d bytes for EFXDefs.\n", (sizeof(string) * EFXDATA_MAX) + (sizeof(reverbinfo_t) * EFXDATA_MAX))); + NSLog("...allocated %d bytes for EFXDefs.", (sizeof(string) * EFXDATA_MAX) + (sizeof(reverbinfo_t) * EFXDATA_MAX)); #else - print("dynamic allocation for EFXDefs enabled.\n"); + NSLog("...dynamic allocation for EFXDefs enabled."); #endif efx_default = EFX_Load("default"); @@ -354,6 +355,7 @@ EFX_Init(void) setup_reverb(12, &g_efx[g_iEFX], sizeof(reverbinfo_t)); setup_reverb(10, &g_efx[efx_underwater], sizeof(reverbinfo_t)); + InitEnd(); } void diff --git a/src/client/entities.qc b/src/client/entities.qc index fe637766..8fdcb76c 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -236,7 +236,6 @@ void Entities_RendererRestarted(void) { int c = 0; - print("--------- Reloading Entity Resources ----------\n"); for (entity b = world; (b = findfloat(b, ::isCSQC, TRUE));) { NSEntity pf = (NSEntity) b; @@ -244,5 +243,5 @@ Entities_RendererRestarted(void) c++; } - print(sprintf("resource reload called on %i entities\n", c)); + NSLog("...resource reload called on %i entities", c); } diff --git a/src/client/entry.qc b/src/client/entry.qc index 170bfe3c..b2db52ac 100644 --- a/src/client/entry.qc +++ b/src/client/entry.qc @@ -35,9 +35,9 @@ Also called when map changes happen. void CSQC_Init(float apilevel, string enginename, float engineversion) { - print("--------- Initializing Client Game ----------\n"); - print("Built: " __DATE__ " " __TIME__"\n"); - print("QCC: " __QCCVER__ "\n"); + InitPrint("Initializing Client Game"); + NSLog("Built: %s %s", __DATE__, __TIME__); + NSLog("QCC: %s", __QCCVER__); for (int i = 0; i < 4; i++) { g_viewSeats[i] = spawn(NSView); @@ -90,7 +90,7 @@ CSQC_Init(float apilevel, string enginename, float engineversion) Sound_Precache("Player.WeaponSelectionClose"); /* end msg */ - print("Client game initialized.\n"); + NSLog("Client game initialized."); /* because the engine will do really bad hacks to our models otherwise. e.g. R6284 */ cvar_set("r_fullbrightSkins", "0"); @@ -108,7 +108,7 @@ somewhere in csprogs.dat to ensure their resources are reloaded properly. void CSQC_RendererRestarted(string rstr) { - print("--------- Reloading Graphical Resources ----------\n"); + InitStart(); /* Fonts */ Font_Load("fonts/font16.font", FONT_16); @@ -146,8 +146,7 @@ CSQC_RendererRestarted(string rstr) g_shellchromeshader = shaderforname("shellchrome", sprintf("{\ndeformVertexes bulge 1.25 1.25 0\n{\nmap %s\ntcMod scroll -0.1 0.1\ntcGen environment\nrgbGen entity\n}\n}", "textures/sfx/reflection.tga")); g_shellchromeshader_cull = shaderforname("shellchrome2", sprintf("{\ncull back\ndeformVertexes bulge 1.5 1.5 0\n{\nmap %s\ntcMod scroll -0.1 0.1\ntcGen environment\nrgbGen entity\n}\n}", "textures/sfx/reflection.tga")); - /* end msg */ - print("Graphical resources reloaded\n"); + InitEnd(); } /** Always call this instead of renderscene(); ! @@ -548,7 +547,8 @@ ourselves if need be. void CSQC_WorldLoaded(void) { - print("--------- Initializing Client World ----------\n"); + InitStart(); + //DetailTex_Init(); /* Primarily for the flashlight */ @@ -567,11 +567,11 @@ CSQC_WorldLoaded(void) break; } if (strTokenized != "{") { - print("^1[WARNING] ^7Bad entity data\n"); + NSWarning("Bad entity data"); break; } if (!Entities_ParseLump()) { - print("^1[WARNING] ^7Bad entity data\n"); + NSWarning("Bad entity data"); break; } } @@ -586,7 +586,7 @@ CSQC_WorldLoaded(void) /* wad files will most likely have loaded now */ DecalGroups_Precache(); - print("Client world initialized.\n"); + InitEnd(); } /** Called when a server tells us an active entity gets removed. @@ -626,12 +626,12 @@ that is the last thing that will be called. void CSQC_Shutdown(void) { - print("--------- Shutting Client Game ----------\n"); + InitPrint("Shutting Client Game"); Decal_Shutdown(); Sentences_Shutdown(); Titles_Shutdown(); Sound_Shutdown(); PropData_Shutdown(); EFX_Shutdown(); - print("Client game shutdown.\n"); + NSLog("Client game shutdown."); } diff --git a/src/client/fade.qc b/src/client/fade.qc index 199e6e73..0bf5acb9 100644 --- a/src/client/fade.qc +++ b/src/client/fade.qc @@ -53,16 +53,15 @@ Fade_Update (int x, int y, int w, int h) if (pSeat->m_iFadeActive == FALSE) { return; } + pSeat->m_flFadeAlpha = 1.0f; + if (pSeat->m_flFadeStyle & EVF_FADEDROM) { - pSeat->m_flFadeAlpha = 1.0f; if (pSeat->m_flFadeTime > pSeat->m_flFadeDuration) { pSeat->m_flFadeAlpha -= (pSeat->m_flFadeTime - pSeat->m_flFadeDuration) * (1.0 / pSeat->m_flFadeHold); } } else { if (pSeat->m_flFadeTime < pSeat->m_flFadeDuration) { pSeat->m_flFadeAlpha = pSeat->m_flFadeTime * (1.0 / pSeat->m_flFadeDuration); - } else { - pSeat->m_flFadeAlpha = (pSeat->m_flFadeTime - pSeat->m_flFadeDuration) * (1.0 / pSeat->m_flFadeHold); } } diff --git a/src/client/font.qc b/src/client/font.qc index 88818834..6998f0db 100644 --- a/src/client/font.qc +++ b/src/client/font.qc @@ -76,14 +76,14 @@ Font_Load(string strFile, font_s &fntNew) } fclose(fileFont); } else { - error(sprintf("cannot load font file %s!", strFile)); + NSError("Missing file %s", strFile); } if (!fntNew.iScaleX || !fntNew.iScaleY) { - error(sprintf("no valid size defined for %s!", strFile)); + NSError("Invalid size defined for %s", strFile); } - print(sprintf("loaded font definition for %s\n", strFile)); + NSLog("Loaded font definition for %s", strFile); if (strRenderSize != "") { fntNew.iID = (int)loadfont("", strFontPath, strRenderSize, -1, 0, 0); diff --git a/src/client/shake.qc b/src/client/shake.qc index ffa784a5..fda44bf7 100644 --- a/src/client/shake.qc +++ b/src/client/shake.qc @@ -14,15 +14,29 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define SHAKE_YAW_DEGREES 5.0f +#define SHAKE_YAW_HERTZ 15.0f +#define SHAKE_PITCH_DEGREES 5.0f +#define SHAKE_PITCH_HERTZ 5.0f +#define SHAKE_ROLL_DEGREES 5.0f +#define SHAKE_ROLL_HERTZ 5.0f + void Shake_Update(NSClientPlayer pl) { if (pSeat->m_flShakeDuration > 0.0) { + float shakeMultiplier = (pSeat->m_flShakeDuration / pSeat->m_flShakeTime); + float sineWave1 = (sin(time * SHAKE_PITCH_HERTZ) * SHAKE_PITCH_DEGREES) * shakeMultiplier; + float sineWave2 = (sin(time * SHAKE_YAW_HERTZ) * SHAKE_YAW_DEGREES) * shakeMultiplier; + float sineWave3 = (sin(time * SHAKE_ROLL_HERTZ) * SHAKE_ROLL_DEGREES) * shakeMultiplier; vector vecShake = [0,0,0]; - vecShake[0] += random() * 3; - vecShake[1] += random() * 3; - vecShake[2] += random() * 3; - pl.punchangle += (vecShake * pSeat->m_flShakeAmp) * (pSeat->m_flShakeDuration / pSeat->m_flShakeTime); + vecShake[0] += random() * 1.5; + vecShake[1] += random() * 1.5; + vecShake[2] += random() * 1.5; + vecShake[0] += sineWave1; + vecShake[1] += sineWave2; + vecShake[2] += sineWave3; + pl.punchangle += (vecShake * pSeat->m_flShakeAmp) * shakeMultiplier; pSeat->m_flShakeDuration -= clframetime; } } diff --git a/src/client/sky.qc b/src/client/sky.qc index 01929f4f..d664dc08 100644 --- a/src/client/sky.qc +++ b/src/client/sky.qc @@ -39,6 +39,6 @@ Sky_Update(int force) return; localcmd(sprintf("sky \"%s\"\n", skyPath)); - print(sprintf("sky update applying %s.\n", skyPath)); + NSLog("sky update applying %s.", skyPath); } } diff --git a/src/client/titles.qc b/src/client/titles.qc index 058b0569..fb26a9e6 100644 --- a/src/client/titles.qc +++ b/src/client/titles.qc @@ -121,14 +121,15 @@ Titles_Init(void) int braced; int id = 0; - print("--------- Initializing TitlesDef ----------\n"); + InitStart(); Titles_Shutdown(); fs_titles = fopen("titles.txt", FILE_READ); if (fs_titles < 0) { - print("^1could NOT load titles.txt\n"); + NSError("missing titles.txt"); + InitEnd(); return; } @@ -165,7 +166,7 @@ Titles_Init(void) } } - print(sprintf("read %i titleDefs (%i bytes).\n", g_titles_count, sizeof(titles_t) * g_titles_count)); + NSLog("read %i titleDefs (%i bytes).", g_titles_count, sizeof(titles_t) * g_titles_count); g_titles = memalloc(sizeof(titles_t) * g_titles_count); fseek(fs_titles, 0); @@ -256,6 +257,8 @@ Titles_Init(void) } } fclose(fs_titles); + + InitEnd(); } diff --git a/src/client/view.qc b/src/client/view.qc index edba7c80..b423f56e 100644 --- a/src/client/view.qc +++ b/src/client/view.qc @@ -127,6 +127,8 @@ View_ForceChange(player pl, int targetWeapon) View_ClearEvents(); View_DisableViewmodel(); View_SetMuzzleflash(0); + m_eViewModel.frame1time = 0.0f; + m_eViewModelL.frame1time = 0.0f; } /* @@ -286,7 +288,7 @@ View_DrawViewModel(void) #endif /* only draw the model when it's 'enabled'... */ - if (m_eViewModel.alpha != 0.0f) { + if (m_eViewModel.IsHidden() == false) { setorigin(m_eViewModel, m_eViewModel.origin); setorigin(m_eViewModelL, m_eViewModel.origin); @@ -359,15 +361,26 @@ View_GetAnimation(void) void View_EnableViewmodel(void) { - pSeat->m_eViewModel.alpha = - pSeat->m_eViewModelL.alpha = 1.0f; + NSRenderableEntity viewModel; + viewModel = (NSRenderableEntity)pSeat->m_eViewModel; + viewModel.Show(); + viewModel = (NSRenderableEntity)pSeat->m_eViewModelL; + viewModel.Show(); } void View_DisableViewmodel(void) { - pSeat->m_eViewModel.alpha = - pSeat->m_eViewModelL.alpha = 0.0f; - pSeat->m_eViewModel.frame1time = - pSeat->m_eViewModelL.frame1time = 0.0f; + NSRenderableEntity viewModel; + viewModel = (NSRenderableEntity)pSeat->m_eViewModel; + viewModel.Hide(); + viewModel = (NSRenderableEntity)pSeat->m_eViewModelL; + viewModel.Hide(); +} + +void +View_SetViewmodelSkin(float skinValue) +{ + pSeat->m_eViewModel.skin = + pSeat->m_eViewModelL.skin = skinValue; } diff --git a/src/client/way.qc b/src/client/way.qc index cd0eb0ac..4103f539 100644 --- a/src/client/way.qc +++ b/src/client/way.qc @@ -112,7 +112,7 @@ Way_Init(void) "3.\tFlag ^1WALK^7 (2 steps)\n" \ "4.\tFlag ^4AIM^7 (2 steps)\n" \ "5.\tFlag ^4USE^7 (2 steps)\n" \ - "\n" \ + "6.\tFlag ^6HAZARDOUS^7 (2 steps)\n" \ "\n" \ "\n" \ "9.\tBack\n"; @@ -293,19 +293,22 @@ WAY_FLAGS(int n) { switch (n) { case 1: - localcmd("sv way linkjump\n"); + localcmd("sv way flag 2\n"); break; case 2: - localcmd("sv way linkcrouch\n"); + localcmd("sv way flag 4\n"); break; case 3: - localcmd("sv way linkwalk\n"); + localcmd("sv way flag 16\n"); break; case 4: - localcmd("sv way linkaim\n"); + localcmd("sv way flag 32\n"); break; case 5: - localcmd("sv way linkuse\n"); + localcmd("sv way flag 64\n"); + break; + case 6: + localcmd("sv way flag 128\n"); break; case 9: Textmenu_Call("WAY_MENU"); diff --git a/src/gs-entbase/client/env_cubemap.qc b/src/gs-entbase/client/env_cubemap.qc index ffc5e905..a5e119ec 100644 --- a/src/gs-entbase/client/env_cubemap.qc +++ b/src/gs-entbase/client/env_cubemap.qc @@ -94,7 +94,7 @@ CMap_Shoot(void) string strReflectcube; if (self.owner) { env_cubemap tmp = (env_cubemap) self.owner; - print("^3Cubemap processing...\n"); + NSLog("Generating cubemap '%v' (%dx%d)", g_vecCubePos, g_dCubeSize, g_dCubeSize); g_vecCubePos = tmp.origin; g_dCubeSize = (float)tmp.m_iSize; @@ -114,7 +114,7 @@ CMap_Shoot(void) self.think = CMap_Check; self.nextthink = time + 0.25f; } else { - print("^2Cubemaps done...\n"); + NSLog("Generating level cubemaps done."); localcmd("r_skipEnvmap 0\n"); localcmd("vid_reload\n"); g_iCubeProcess = FALSE; @@ -161,7 +161,8 @@ CMap_Build(void) localcmd("r_hdr_irisadaptation 0\n"); localcmd("r_postprocshader \"\"0\n"); localcmd("r_skipEnvmap 1\n"); - print("^4Building cubemaps...\n"); + + NSLog("Building cubemaps...\n"); g_eCubeCycle = spawn(); g_eCubeCycle.owner = find(world, classname, "env_cubemap"); diff --git a/src/gs-entbase/client/env_sound.qc b/src/gs-entbase/client/env_sound.qc index 02509832..f8606196 100644 --- a/src/gs-entbase/client/env_sound.qc +++ b/src/gs-entbase/client/env_sound.qc @@ -99,7 +99,7 @@ env_sound::SpawnKey(string strField, string strKey) int efx_alias = stoi(strKey); if (efx_alias >= g_hlefx.length) { - NSEntWarning("invalid roomtype!"); + EntWarning("invalid roomtype!"); m_iRoomType = 0; } else m_iRoomType = EFX_Load(g_hlefx[efx_alias]); diff --git a/src/gs-entbase/server/cycler.qc b/src/gs-entbase/server/cycler.qc index ba439d75..6b4b214c 100644 --- a/src/gs-entbase/server/cycler.qc +++ b/src/gs-entbase/server/cycler.qc @@ -67,5 +67,6 @@ cycler::Pain(void) } else { SetFrame(GetFrame() + 1); } + SetHealth(9999); } diff --git a/src/gs-entbase/server/cycler_sprite.qc b/src/gs-entbase/server/cycler_sprite.qc index 973cac19..359d0835 100644 --- a/src/gs-entbase/server/cycler_sprite.qc +++ b/src/gs-entbase/server/cycler_sprite.qc @@ -16,7 +16,7 @@ /*!QUAKED cycler_sprite (1 0 0) (-8 -8 -8) (8 8 8) # OVERVIEW -Decorative, does nothing yet. +Decorative sprite cycler. # KEYS - "targetname" : Name @@ -24,6 +24,7 @@ Decorative, does nothing yet. - "killtarget" : Target to kill when triggered. - "angles" : Sets the pitch, yaw and roll angles of the model. - "model" : Model file that will be displayed by the entity. +- "framerate" : TODO: Frame rate of the sprite, in frames per second. # TRIVIA This entity was introduced in Half-Life (1998). diff --git a/src/gs-entbase/server/env_physexplosion.qc b/src/gs-entbase/server/env_physexplosion.qc index 269b70a5..38f8e61c 100644 --- a/src/gs-entbase/server/env_physexplosion.qc +++ b/src/gs-entbase/server/env_physexplosion.qc @@ -142,7 +142,7 @@ env_physexplosion::TriggerExplosion(void) physEnt = (NSPhysicsEntity)find(world, ::targetname, m_strTargetEntity); if (!physEnt) { - NSEntWarning("Target set, but not found!"); + EntWarning("Target set, but not found!"); return; } diff --git a/src/gs-entbase/server/env_render.qc b/src/gs-entbase/server/env_render.qc index 95e90ecc..a26965e7 100644 --- a/src/gs-entbase/server/env_render.qc +++ b/src/gs-entbase/server/env_render.qc @@ -97,22 +97,22 @@ env_render::Trigger(entity act, triggermode_t state) (e = find(e, ::targetname, target));) { NSRenderableEntity trigger = (NSRenderableEntity)e; - NSLog("^2env_render::^3Trigger^7: with spawnflags %d", spawnflags); - NSLog("\tTarget: %s", target); + EntLog("Triggering with spawnflags %d", spawnflags); + EntLog("\tTarget: %s", target); if (!HasSpawnFlags(SF_NORENDERMODE)) { - NSLog("\tMode change from %d to %d", trigger.m_iRenderMode, m_iRenderMode); + EntLog("\tMode change from %d to %d", trigger.m_iRenderMode, m_iRenderMode); trigger.SetRenderMode(m_iRenderMode); } if (!HasSpawnFlags(SF_NORENDERCOLOR)) { - NSLog("\tColor change from %v to %v", trigger.m_vecRenderColor, m_vecRenderColor); + EntLog("\tColor change from %v to %v", trigger.m_vecRenderColor, m_vecRenderColor); trigger.SetRenderColor(m_vecRenderColor); } if (!HasSpawnFlags(SF_NORENDERAMT)) { - NSLog("\tAmt change from %d to %d", trigger.m_flRenderAmt, m_flRenderAmt); + EntLog("\tAmt change from %d to %d", trigger.m_flRenderAmt, m_flRenderAmt); trigger.SetRenderAmt(m_flRenderAmt); } if (!HasSpawnFlags(SF_NORENDERFX)) { - NSLog("\tFX change from %d to %d", trigger.m_iRenderFX, m_iRenderFX); + EntLog("\tFX change from %d to %d", trigger.m_iRenderFX, m_iRenderFX); trigger.SetRenderFX(m_iRenderFX); } } diff --git a/src/gs-entbase/server/func_breakable.qc b/src/gs-entbase/server/func_breakable.qc index 14ed1f67..a5f46879 100644 --- a/src/gs-entbase/server/func_breakable.qc +++ b/src/gs-entbase/server/func_breakable.qc @@ -23,7 +23,7 @@ enumflags enum { - BREAKMT_GLASS, + BREAKMT_GLASS = 0, BREAKMT_WOOD, BREAKMT_METAL, BREAKMT_FLESH, @@ -161,9 +161,9 @@ func_breakable::func_breakable(void) /* func_breakable defaults to glass */ if (classname == "func_breakable") { - material = 0; + material = BREAKMT_GLASS; } else { - material = 1; + material = BREAKMT_WOOD; } } @@ -176,6 +176,7 @@ func_breakable::Save(float handle) SaveFloat(handle, "m_flExplodeRad", m_flExplodeRad); SaveString(handle, "m_strBreakSpawn", m_strBreakSpawn); SaveBool(handle, "m_bCanTouch", m_bCanTouch); + SaveFloat(handle, "material", material); } void @@ -197,6 +198,9 @@ func_breakable::Restore(string strKey, string strValue) case "m_bCanTouch": m_bCanTouch = ReadBool(strValue); break; + case "material": + material = ReadFloat(strValue); + break; default: super::Restore(strKey, strValue); } @@ -207,7 +211,7 @@ func_breakable::SpawnKey(string strKey, string strValue) { switch (strKey) { case "material": - material = stof(strValue); + material = ReadFloat(strValue); break; case "explodemagnitude": m_flExplodeMag = stof(strValue); @@ -218,7 +222,7 @@ func_breakable::SpawnKey(string strKey, string strValue) if (oid >= funcbreakable_objtable.length) { m_strBreakSpawn = ""; - NSEntWarning("spawnobject %i out of bounds", oid); + EntWarning("spawnobject %i out of bounds", oid); } else { m_strBreakSpawn = funcbreakable_objtable[oid]; } @@ -288,8 +292,9 @@ func_breakable::Pain(void) painSound = GetSurfaceData(SURFDATA_SND_BULLETIMPACT); - if (painSound) + if (painSound) { StartSoundDef(painSound, CHAN_VOICE, true); + } } @@ -354,16 +359,17 @@ func_breakable::Death(void) vector vecDir = vectoangles(WorldSpaceCenter() - g_dmg_vecLocation); string sndBreak = GetSurfaceData(SURFDATA_SND_BREAK); string breakModel = GetPropData(PROPINFO_BREAKMODEL); + int gibCount = (int)bound(5, vlen(size) / 10, 32); if (breakModel != "") - BreakModel_Spawn(absmin, absmax, vecDir, g_dmg_iDamage * 2.5, vlen(size) / 10, breakModel); + BreakModel_Spawn(absmin, absmax, vecDir, g_dmg_iDamage * 2.5, gibCount, breakModel); else - NSLog("func_breakable (%s) does not have a propdata break model", funcbreakable_surftable[material]); + EntLog("func_breakable (%s) does not have a propdata break model", funcbreakable_surftable[material]); if (sndBreak != "") StartSoundDef(sndBreak, CHAN_BODY, true); else - NSLog("func_breakable (%s) does not have a surfaceproperty for break", funcbreakable_surftable[material]); + EntLog("func_breakable (%s) does not have a surfaceproperty for break", funcbreakable_surftable[material]); Disappear(); SetTakedamage(DAMAGE_NO); diff --git a/src/gs-entbase/server/func_guntarget.qc b/src/gs-entbase/server/func_guntarget.qc index abe7b6f0..1716676e 100644 --- a/src/gs-entbase/server/func_guntarget.qc +++ b/src/gs-entbase/server/func_guntarget.qc @@ -148,7 +148,7 @@ func_guntarget::Move(void) node = (path_corner)find(world, ::targetname, target); if (!node) { - NSEntWarning("node %s for %s not found!", target, targetname); + EntWarning("node %s for %s not found!", target, targetname); return; } @@ -172,7 +172,7 @@ func_guntarget::NextPath(void) { path_corner node; - NSLog("^2func_guntarget::^3NextPath^7: Talking to current target %s... ", target); + EntLog("Talking to current target %s... ", target); node = (path_corner)find(world, ::targetname, target); if (!node) { diff --git a/src/gs-entbase/server/func_plat.qc b/src/gs-entbase/server/func_plat.qc index ab066ea8..2b643755 100644 --- a/src/gs-entbase/server/func_plat.qc +++ b/src/gs-entbase/server/func_plat.qc @@ -62,6 +62,7 @@ public: virtual void Save(float); virtual void Restore(string,string); virtual void Trigger(entity, triggermode_t); + virtual void Input(entity, string, string); virtual void Respawn(void); virtual void SpawnKey(string,string); virtual void Spawned(void); @@ -234,6 +235,21 @@ func_plat::Respawn(void) } } +void +func_plat::Input(entity entityActivator, string inputName, string dataField) +{ + switch (inputName) { + case "GoUp": + MoveToPosition(GetMoverPosition1(), m_flSpeed); + break; + case "GoDown": + MoveToPosition(GetMoverPosition2(), m_flSpeed); + break; + default: + super::Input(entityActivator, inputName, dataField); + } +} + void func_plat::Trigger(entity act, triggermode_t state) { diff --git a/src/gs-entbase/server/func_pushable.qc b/src/gs-entbase/server/func_pushable.qc index 7fac27fa..ded28148 100644 --- a/src/gs-entbase/server/func_pushable.qc +++ b/src/gs-entbase/server/func_pushable.qc @@ -180,7 +180,7 @@ func_pushable::Respawn(void) if (!m_eCollBox) { m_eCollBox = spawn(); m_eCollBox.classname = "func_pushable_bbox"; - m_eCollBox.solid = SOLID_BBOX; + m_eCollBox.solid = SOLID_TRIGGER; m_eCollBox.owner = this; setsize(m_eCollBox, -(size/2) * 0.9f, (size/2) * 0.9f); setorigin(m_eCollBox, WorldSpaceCenter()); @@ -229,7 +229,7 @@ func_pushable::customphysics(void) if (modelindex == 0) { m_eCollBox.solid = SOLID_NOT; } else { - m_eCollBox.solid = SOLID_BBOX; + m_eCollBox.solid = SOLID_TRIGGER; } wasMoving = m_bIsMoving; diff --git a/src/gs-entbase/server/func_trackchange.qc b/src/gs-entbase/server/func_trackchange.qc index 1e03f919..78904f6e 100644 --- a/src/gs-entbase/server/func_trackchange.qc +++ b/src/gs-entbase/server/func_trackchange.qc @@ -142,10 +142,10 @@ func_trackchange::MoverStartsMoving(void) ourTrain.SetVelocity(GetVelocity()); ourTrain.SetAngularVelocity(GetAngularVelocity()); ourTrain.ScheduleThink(ClearVelocity, 100.0f); - print(sprintf("Changing %s to have no target\n", m_strTrainName)); - print(sprintf("%v %v\n", GetVelocity(), GetAngularVelocity())); + EntLog("Changing %s to have no target.", m_strTrainName); + EntLog("Velocity: %v; Angular Velocity: %v", GetVelocity(), GetAngularVelocity()); } else { - print(sprintf("No train to go with trackchange %s\n", targetname)); + EntLog("No train to go with trackchange %S", targetname); } } @@ -159,13 +159,13 @@ func_trackchange::MoverFinishesMoving(void) ourTrain.ClearVelocity(); if (GetMoverState() == MOVER_POS1) { - print(sprintf("Changing %s from %s to %s\n", m_strTrainName, m_strBottomTrack, m_strTopTrack)); + EntLog("Changing %S from %S to %S", m_strTrainName, m_strBottomTrack, m_strTopTrack); ourTrain.target = m_strTopTrack; } else { - print(sprintf("Changing %s from %s to %s\n", m_strTrainName, m_strBottomTrack, m_strBottomTrack)); + EntLog("Changing %S from %S to %S", m_strTrainName, m_strBottomTrack, m_strBottomTrack); ourTrain.target = m_strBottomTrack; } } else { - print(sprintf("No train to go with trackchange %s\n", targetname)); + EntLog("No train to go with trackchange %S", targetname); } } \ No newline at end of file diff --git a/src/gs-entbase/server/func_tracktrain.qc b/src/gs-entbase/server/func_tracktrain.qc index 21848215..58317c1d 100644 --- a/src/gs-entbase/server/func_tracktrain.qc +++ b/src/gs-entbase/server/func_tracktrain.qc @@ -110,6 +110,7 @@ public: nonvirtual vector GetTrainPivotPoint(bool); nonvirtual void RenderDebugInfo(void); + nonvirtual bool ControlCheck(entity); /* overrides */ virtual void Blocked(entity); @@ -304,14 +305,14 @@ func_tracktrain::RenderDebugInfo(void) /* line to the next node forward (green) */ if (eNode) { - eNode = eNode.GetPathTargetEntity(); + eNode = (path_track)eNode.GetPathTargetEntity(); if (eNode) { R_BeginPolygon("", 0, 0); R_PolygonVertex(oldNode.GetOrigin() + [0,0, m_flHeight], [0,1], [0,0.75,0], 1.0); R_PolygonVertex(eNode.GetOrigin() + [0,0, m_flHeight], [1,1], [0,0.75,0], 1.0); R_EndPolygon(); oldNode = eNode; - eNode = eNode.GetPathTargetEntity(); + eNode = (path_track)eNode.GetPathTargetEntity(); if (eNode) { R_BeginPolygon("", 0, 0); @@ -336,7 +337,7 @@ func_tracktrain::RenderDebugInfo(void) oldNode = eNode; if (eNode) { - eNode = eNode.GetSelfTargetEntity(); + eNode = (path_track)eNode.GetSelfTargetEntity(); if (eNode) { /* line to the next node forward (green) */ @@ -346,7 +347,7 @@ func_tracktrain::RenderDebugInfo(void) R_EndPolygon(); oldNode = eNode; - eNode = eNode.GetSelfTargetEntity(); + eNode = (path_track)eNode.GetSelfTargetEntity(); if (eNode) { R_BeginPolygon("", 0, 0); @@ -674,13 +675,13 @@ func_tracktrain::PathMoveBack(void) flTravelTime = (vlen(vecVelocity) / travelSpeed); if (flTravelTime <= 0.0) { - NSVehicle_Log("^1func_tracktrain::^3PathMoveBack^7: Distance short, teleporting next."); + NSVehicle_Log("^Distance short, teleporting next."); ScheduleThink(_PathArrivedBack, 0.0f); SetVelocity([1,1,1]); return; } - NSVehicle_Log("^1func_tracktrain::^3PathMoveBack^7: Changing velocity from '%v' to '%v'", GetVelocity(), vecVelocity); + NSVehicle_Log("Changing velocity from '%v' to '%v'", GetVelocity(), vecVelocity); SetVelocity(vecVelocity * (1 / flTravelTime)); _SoundMove(); @@ -873,8 +874,6 @@ func_tracktrain::PathClear(void) void func_tracktrain::Trigger(entity act, triggermode_t state) { - breakpoint(); - switch (state) { case TRIG_ON: PathMoveForward(); @@ -898,7 +897,7 @@ func_tracktrain::_AfterSpawn(void) path_track nodeAhead; /* get the first target */ - targetNode = GetTrackNodeForward(); + targetNode = (path_track)GetTrackNodeForward(); /* unpossible */ if (!targetNode || HasTriggerTarget() == false) { @@ -914,7 +913,7 @@ func_tracktrain::_AfterSpawn(void) /* face the train towards the next target. while it may be tempting to use GetPathTargetEntity() here, that node may be disabled. so look manually. */ - nodeAhead = find(world, ::targetname, targetNode.target); + nodeAhead = (path_track)find(world, ::targetname, targetNode.target); /* node found. */ if (nodeAhead) { diff --git a/src/gs-entbase/server/func_train.qc b/src/gs-entbase/server/func_train.qc index fcb8af26..c6db9c23 100644 --- a/src/gs-entbase/server/func_train.qc +++ b/src/gs-entbase/server/func_train.qc @@ -203,7 +203,7 @@ void func_train::SoundMove(void) { if (m_strMoveSnd) { - Sound_Play(this, CHAN_VOICE, m_strMoveSnd); + StartSoundDef(m_strMoveSnd, CHAN_VOICE, true); } } @@ -211,7 +211,7 @@ void func_train::SoundStop(void) { if (m_strStopSnd) { - Sound_Play(this, CHAN_BODY, m_strStopSnd); + StartSoundDef(m_strStopSnd, CHAN_BODY, true); } if (m_strMoveSnd) { @@ -248,7 +248,7 @@ func_train::PathMove(void) } SoundMove(); - NSLog("Travelling at %f up/s", m_flSpeed); + EntLog("Travelling at %f up/s", m_flSpeed); SetVelocity(vecVelocity * (1 / flTravelTime)); ScheduleThink(PathNext, flTravelTime); @@ -266,9 +266,9 @@ func_train::PathDone(void) } if (HasTargetname()) { - NSLog("func_train (id %d, name %S): Touched base with path_corner %S", num_for_edict(this), targetname, target); + EntLog("func_train (id %d, name %S): Touched base with path_corner %S", num_for_edict(this), targetname, target); } else { - NSLog("func_train (id %d): Touched base with path_corner %S", num_for_edict(this), target); + EntLog("func_train (id %d): Touched base with path_corner %S", num_for_edict(this), target); } /* fire the path_corners' target */ @@ -290,7 +290,7 @@ func_train::PathNext(void) /* a little more serious, but we don't want to break the map. */ if (eNode == __NULL__) { - print(sprintf("func_tracktrain (id %d) target %S does not exist.\n", num_for_edict(this), target)); + NSError("func_tracktrain (id %d) target %S does not exist.", num_for_edict(this), target); return; } diff --git a/src/gs-entbase/server/game_counter.qc b/src/gs-entbase/server/game_counter.qc index a324658d..68e29b23 100644 --- a/src/gs-entbase/server/game_counter.qc +++ b/src/gs-entbase/server/game_counter.qc @@ -123,7 +123,7 @@ game_counter::Respawn(void) void game_counter::SetCount(int value) { - NSLog("%s's count set to %i", targetname, value); + EntLog("%s's count set to %i", targetname, value); m_iCounted = value; } @@ -139,13 +139,13 @@ game_counter::Trigger(entity act, triggermode_t state) if (GetMaster(act) == FALSE) return; - NSLog("%s's incremented by 1", targetname); + EntLog("%s's incremented by 1", targetname); m_iCounted++; if (m_iCounted < m_iMaxCount) return; - NSLog("%s's triggering %s", targetname, target); + EntLog("%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); diff --git a/src/gs-entbase/server/game_counter_set.qc b/src/gs-entbase/server/game_counter_set.qc index 94bbf956..c325b5c9 100644 --- a/src/gs-entbase/server/game_counter_set.qc +++ b/src/gs-entbase/server/game_counter_set.qc @@ -101,7 +101,7 @@ game_counter_set::Trigger(entity act, triggermode_t state) if (GetMaster(act) == FALSE) return; - NSLog("%s's manipulating %s to be %i", targetname, target, m_iCount); + EntLog("%s's manipulating %s to be %i", targetname, target, m_iCount); /* apply the value to all the relevant game_counter entities */ for (entity f = world; (f = find(f, ::targetname, target));) { diff --git a/src/gs-entbase/server/game_player_equip.qc b/src/gs-entbase/server/game_player_equip.qc index 3d75c285..2123f1e3 100644 --- a/src/gs-entbase/server/game_player_equip.qc +++ b/src/gs-entbase/server/game_player_equip.qc @@ -139,8 +139,7 @@ game_player_equip::SpawnUnit(string cname, vector org) unit.nextthink = time; unit.real_owner = this; setorigin(unit, org); - NSLog("^2game_player_equip::^3Trigger^7: Spawning %s", - cname); + EntLog("Spawning %s", cname); } void @@ -150,7 +149,7 @@ game_player_equip::Trigger(entity act, triggermode_t state) string cname; if (!(act.flags & FL_CLIENT)) { - print("^1game_player_equip^7::^1Trigger: Activator not a client!\n"); + EntError("Activator %S not a client!", act.classname); return; } diff --git a/src/gs-entbase/server/game_player_team.qc b/src/gs-entbase/server/game_player_team.qc index 4688699a..3a4eaa9f 100644 --- a/src/gs-entbase/server/game_player_team.qc +++ b/src/gs-entbase/server/game_player_team.qc @@ -58,7 +58,7 @@ game_player_team::Trigger(entity entityActivator, triggermode_t state) toRead = (game_team_master)GetTargetEntity(); if (!toRead) { - NSEntWarning("Unable to find game_team_master named %S", GetTriggerTarget()); + EntWarning("Unable to find game_team_master named %S", GetTriggerTarget()); return; } diff --git a/src/gs-entbase/server/game_team_set.qc b/src/gs-entbase/server/game_team_set.qc index 470ec4fa..e12a5681 100644 --- a/src/gs-entbase/server/game_team_set.qc +++ b/src/gs-entbase/server/game_team_set.qc @@ -55,7 +55,7 @@ game_team_set::Trigger(entity activatorEntity, triggermode_t state) toChange = (game_team_master)GetTargetEntity(); if (!toChange) { - NSEntWarning("Unable to find game_team_master named %S", GetTriggerTarget()); + EntWarning("Unable to find game_team_master named %S", GetTriggerTarget()); return; } diff --git a/src/gs-entbase/server/logic_auto.qc b/src/gs-entbase/server/logic_auto.qc index ca0ca6ec..07d1db42 100644 --- a/src/gs-entbase/server/logic_auto.qc +++ b/src/gs-entbase/server/logic_auto.qc @@ -234,7 +234,7 @@ logic_auto::Processing(void) UseOutput(this, m_strOnBackgroundMap); if (HasSpawnFlags(LOGICAUTO_USEONCE)) { - NSLog("^2logic_auto::^3Processing ^7: %s triggerer removed self", target); + EntLog("%S triggerer removed self", target); Destroy(); } } diff --git a/src/gs-entbase/server/logic_case.qc b/src/gs-entbase/server/logic_case.qc index b6da27c3..3c570df0 100644 --- a/src/gs-entbase/server/logic_case.qc +++ b/src/gs-entbase/server/logic_case.qc @@ -491,13 +491,13 @@ logic_case::Input(entity activatorEntity, string inputName, string dataField) void logic_case::PickRandom(entity activatorEntity) { - NSEntWarning("Not implemented."); + EntWarning("Not implemented."); } void logic_case::PickRandomShuffle(entity activatorEntity) { - NSEntWarning("Not implemented."); + EntWarning("Not implemented."); } void diff --git a/src/gs-entbase/server/logic_timer.qc b/src/gs-entbase/server/logic_timer.qc index a6ff41a9..21942c2a 100644 --- a/src/gs-entbase/server/logic_timer.qc +++ b/src/gs-entbase/server/logic_timer.qc @@ -243,13 +243,13 @@ logic_timer::Input(entity activatorEntity, string inputName, string dataField) if (nextthink <= 0.0) nextthink += stof(dataField); else - NSEntWarning("AddToTimer when inactive!"); + EntWarning("AddToTimer when inactive!"); break; case "SubtractFromTimer": if (nextthink <= 0.0) nextthink -= stof(dataField); else - NSEntWarning("SubtractFromTimer when inactive!"); + EntWarning("SubtractFromTimer when inactive!"); break; default: diff --git a/src/gs-entbase/server/math_counter.qc b/src/gs-entbase/server/math_counter.qc new file mode 100644 index 00000000..84c9300b --- /dev/null +++ b/src/gs-entbase/server/math_counter.qc @@ -0,0 +1,11 @@ +class +math_counter:NSPointTrigger +{ + void math_counter(void); +}; + +void +math_counter::math_counter(void) +{ + +} \ No newline at end of file diff --git a/src/gs-entbase/server/monstermaker.qc b/src/gs-entbase/server/monstermaker.qc index 4e54b0b4..a14746d9 100644 --- a/src/gs-entbase/server/monstermaker.qc +++ b/src/gs-entbase/server/monstermaker.qc @@ -168,35 +168,13 @@ monstermaker::TurnOff(void) void monstermaker::TurnOn(void) { - ScheduleThink(Spawner, m_flDelay); + ScheduleThink(Spawner, 0.0f); m_iValue = 1; } void monstermaker::Spawner(void) { - static void monstermaker_spawnunit(void) { - /* these will get overwritten by the monster spawnfunction */ - vector neworg = self.origin; - vector newang = self.angles; - string tname = self.netname; - - /* prevent us from being deleted by callfunction() */ - self.spawnflags |= MSF_MULTIPLAYER; - - /* become the classname assigned */ - NSMonster t = (NSMonster)self; - callfunction(self.classname); - - /* apply the saved values back */ - t.origin = t.m_oldOrigin = neworg; - t.angles = t.m_oldAngle = newang; - t.targetname = tname; - - /* spawn anew */ - t.Respawn(); - } - int c = 0; /* look and count the buggers that are still around */ @@ -222,32 +200,33 @@ monstermaker::Spawner(void) return; } - if (isfunction(strcat("spawnfunc_", m_strMonster))) { - entity unit = spawn(); - unit.classname = strcat("spawnfunc_", m_strMonster); - unit.netname = m_strChildName; - unit.think = monstermaker_spawnunit; - unit.nextthink = time + 0.1f; - unit.real_owner = this; - NSLog("^2monstermaker::^3Trigger^7: Spawning %s", m_strMonster); - setorigin(unit, origin); - unit.angles = angles; - m_iMonsterSpawned++; + NSEntity unit = Entity_CreateClass(m_strMonster); - if (target) { - UseTargets(this, TRIG_TOGGLE, 0.0f); - } - - /* inherit the monsterclip flag */ - if (HasSpawnFlags(MMF_MONSTERCLIP)) { - unit.spawnflags |= MSF_MONSTERCLIP; - } - } else { - NSLog("^1monstermaker::^3Trigger^7: cannot call spawnfunction for %s", m_strMonster); + if (!unit) { + EntError("Cannot call spawnfunction for %s", m_strMonster); Destroy(); return; } + unit.real_owner = this; + EntLog("Spawning %s", m_strMonster); + unit.SetOrigin(GetOrigin()); + unit.SetAngles(GetAngles()); + unit.m_oldOrigin = GetOrigin(); + unit.m_oldAngle = GetAngles(); + unit.targetname = m_strChildName; + + m_iMonsterSpawned++; + + if (target) { + UseTargets(this, TRIG_TOGGLE, 0.0f); + } + + /* inherit the monsterclip flag */ + if (HasSpawnFlags(MMF_MONSTERCLIP)) { + unit.spawnflags |= MSF_MONSTERCLIP; + } + /* shut off for good when we've spawned all we ever wanted */ if ((m_iTotalMonsters > 0) && m_iMonsterSpawned >= m_iTotalMonsters) { ReleaseThink(); diff --git a/src/gs-entbase/server/multi_manager.qc b/src/gs-entbase/server/multi_manager.qc index 2c7e7c8f..4d894636 100644 --- a/src/gs-entbase/server/multi_manager.qc +++ b/src/gs-entbase/server/multi_manager.qc @@ -294,8 +294,8 @@ multi_manager::Trigger(entity act, triggermode_t state) entity eFind = find(world, ::targetname, wow.target); - NSLog("^2%s::^3Trigger^7: %s (%s)", - this.classname, wow.target, eFind.classname); + EntLog("Triggering %S (%S)", + wow.target, eFind.classname); wow.m_iValue = TRUE; UseTargets(wow.m_eActivator, TRIG_TOGGLE, 0.0f); diff --git a/src/gs-entbase/server/multisource.qc b/src/gs-entbase/server/multisource.qc index e427f0ad..d71c815a 100644 --- a/src/gs-entbase/server/multisource.qc +++ b/src/gs-entbase/server/multisource.qc @@ -57,12 +57,12 @@ void multisource::Trigger(entity act, triggermode_t unused) { if (QueryTargets() == FALSE) { - NSLog("[^1MULTISOURCE^7] %s is inactive.", targetname); + EntLog("[^1MULTISOURCE^7] %s is inactive.", targetname); m_iValue = FALSE; return; } - NSLog("[^1MULTISOURCE^7] %s is now active.", targetname); + EntLog("[^1MULTISOURCE^7] %s is now active.", targetname); m_iValue = TRUE; UseTargets(act, TRIG_TOGGLE, m_flDelay); } diff --git a/src/gs-entbase/server/path_corner.qc b/src/gs-entbase/server/path_corner.qc index b911b0cc..27a760aa 100644 --- a/src/gs-entbase/server/path_corner.qc +++ b/src/gs-entbase/server/path_corner.qc @@ -228,7 +228,7 @@ void path_corner::PathPassTrigger(entity activatingEntity, triggermode_t triggerMode) { if (HasSpawnFlags(PC_FIREONCE) && m_iFired) { - NSLog("path_corner (%s) can only fire its targets once", targetname); + EntLog("tried to fire more than once"); return; } @@ -240,9 +240,7 @@ path_corner::PathPassTrigger(entity activatingEntity, triggermode_t triggerMode) for (entity f = world; (f = find(f, ::targetname, m_strMessage));) { NSTrigger trigger = (NSTrigger)f; - NSLog("^2%s::^3PathPassTrigger^7:" \ - "Triggering %s `%s` from %s", \ - classname, f.classname, \ + EntLog("Triggering %s `%s` from %s", f.classname, \ trigger.targetname, activatingEntity.classname); if (trigger.Trigger != __NULL__) { diff --git a/src/gs-entbase/server/path_track.qc b/src/gs-entbase/server/path_track.qc index 2e5e7c88..cdbda5d6 100644 --- a/src/gs-entbase/server/path_track.qc +++ b/src/gs-entbase/server/path_track.qc @@ -270,10 +270,7 @@ path_track::PathEndTrigger(entity activatingEntity, triggermode_t triggerMode) for (entity f = world; (f = find(f, ::targetname, m_strEndTrigger));) { NSTrigger trigger = (NSTrigger)f; - NSLog("^2%s::^3PathEndTrigger^7:" \ - "Triggering %s `%s` from %s", \ - classname, f.classname, \ - trigger.targetname, activatingEntity.classname); + EntLog("Triggering %S %S from %S", f.classname, trigger.targetname, activatingEntity.classname); if (trigger.Trigger != __NULL__) { trigger.Trigger(activatingEntity, triggerMode); diff --git a/src/gs-entbase/server/phys_convert.qc b/src/gs-entbase/server/phys_convert.qc index f38b6c6f..7761a781 100644 --- a/src/gs-entbase/server/phys_convert.qc +++ b/src/gs-entbase/server/phys_convert.qc @@ -149,7 +149,7 @@ phys_convert::ConvertTarget(entity activatorEnt) NSPhysicsEntity new; if (!targetEnt) { - NSEntWarning("Cannot find target to convert."); + EntWarning("Cannot find target to convert."); return; } diff --git a/src/gs-entbase/server/prop_door_rotating.qc b/src/gs-entbase/server/prop_door_rotating.qc index 63b46a43..b7145569 100644 --- a/src/gs-entbase/server/prop_door_rotating.qc +++ b/src/gs-entbase/server/prop_door_rotating.qc @@ -119,7 +119,7 @@ prop_door_rotating::Turn(vector vecDest, void(void) vFunc) float flTravelLength, flTravelTime; if (!m_flSpeed) { - NSLog("^1prop_door_rotating::^3RotToDest^7: No speed defined for %s!", targetname); + EntError("No speed defined for %s!", targetname); prop_door_rotating::Respawn(); return; } diff --git a/src/gs-entbase/server/random_speaker.qc b/src/gs-entbase/server/random_speaker.qc index 9bdabf39..97cbbf3c 100644 --- a/src/gs-entbase/server/random_speaker.qc +++ b/src/gs-entbase/server/random_speaker.qc @@ -173,19 +173,13 @@ random_speaker::Enable(void) r += (m_flMinPos * (m_flRandPercent / 100)) * random(); ScheduleThink(PlaySample, r); - - NSLog("^2random_speaker::^3Disable^7: " \ - "%s playing %s in %d\n", \ - targetname, m_strSample, r); + EntLog("%s playing %s in %d\n", targetname, m_strSample, r); } void random_speaker::Disable(void) { - NSLog("^2random_speaker::^3Disable^7: " \ - "Disabled %s playing %s\n", \ - targetname, m_strSample); - + EntLog("Disabled %s playing %s\n", targetname, m_strSample); m_iValue = 0; ReleaseThink(); } diff --git a/src/gs-entbase/server/scripted_sentence.qc b/src/gs-entbase/server/scripted_sentence.qc index a3a11ada..4fce40e4 100644 --- a/src/gs-entbase/server/scripted_sentence.qc +++ b/src/gs-entbase/server/scripted_sentence.qc @@ -28,6 +28,14 @@ world. It'll enable mouth flapping and all sorts of other cool effects. - "pitch" : Desired sound pitch. May be overridden in the titles.txt entry. - "delay" : Delay before it'll be triggered? UNUSED RIGHT NOW. - "wait" : Delay before it can be triggered again? UNUSED RIGHT NOW. +- "listener" : The name of the entity we'll look at when speaking. Can be "player". + +# INPUTS +- "BeginSentence" : Starts the sentence. + +# OUTPUTS +- "OnBeginSentence" : Fired when the sentence starts. +- "OnEndSentence" : Fired when the sentence ends. # TRIVIA This entity was introduced in Half-Life (1998). @@ -39,18 +47,26 @@ public: void scripted_sentence(void); /* overrides */ + virtual void Spawned(void); virtual void Save(float); virtual void Restore(string,string); virtual void SpawnKey(string,string); virtual void Trigger(entity, triggermode_t); + virtual void Input(entity, string, string); + + nonvirtual void SentenceEnded(void); private: string m_strSpeaker; string m_strSentence; + int m_iSentenceID; float m_flDelay; float m_flWait; float m_flPitch; float m_flDuration; + string m_strListener; + string m_strOnBeginSentence; + string m_strOnEndSentence; }; void @@ -62,6 +78,23 @@ scripted_sentence::scripted_sentence(void) m_flWait = 0.0f; m_flPitch = 0.0f; m_flDuration = 0.0f; + m_strListener = __NULL__; + m_strOnBeginSentence = __NULL__; + m_strOnEndSentence = __NULL__; + m_iSentenceID = 0i; +} + +void +scripted_sentence::Spawned(void) +{ + super::Spawned(); + + m_iSentenceID = Sentences_GetID(m_strSentence); + + if (m_strOnBeginSentence) + m_strOnBeginSentence = CreateOutput(m_strOnBeginSentence); + if (m_strOnEndSentence) + m_strOnEndSentence = CreateOutput(m_strOnEndSentence); } void @@ -74,6 +107,10 @@ scripted_sentence::Save(float handle) SaveFloat(handle, "m_flWait", m_flWait); SaveFloat(handle, "m_flPitch", m_flPitch); SaveFloat(handle, "m_flDuration", m_flDuration); + SaveString(handle, "m_strListener", m_strListener); + SaveString(handle, "m_strOnBeginSentence", m_strOnBeginSentence); + SaveString(handle, "m_strOnEndSentence", m_strOnEndSentence); + SaveInt(handle, "m_iSentenceID", m_iSentenceID); } void @@ -98,35 +135,74 @@ scripted_sentence::Restore(string strKey, string strValue) case "m_flDuration": m_flDuration = ReadFloat(strValue); break; + case "m_strListener": + m_strListener = ReadString(strValue); + break; + case "m_strOnBeginSentence": + m_strOnBeginSentence = ReadString(strValue); + break; + case "m_strOnEndSentence": + m_strOnEndSentence = ReadString(strValue); + break; + case "m_iSentenceID": + m_iSentenceID = ReadInt(strValue); + break; default: super::Restore(strKey, strValue); } } void -scripted_sentence::SpawnKey(string strKey, string strValue) +scripted_sentence::SpawnKey(string keyName, string setValue) { - switch (strKey) { + switch (keyName) { case "entity": - m_strSpeaker = strValue; + m_strSpeaker = setValue; break; case "sentence": - m_strSentence = strtoupper(strValue); + m_strSentence = strtoupper(setValue); break; case "pitch": - m_flPitch = stof(strValue); + m_flPitch = ReadFloat(setValue); break; case "duration": - m_flDuration = stof(strValue); + m_flDuration = ReadFloat(setValue); break; case "wait": - m_flWait = stof(strValue); + m_flWait = ReadFloat(setValue); + break; + case "listener": + m_strListener = ReadString(setValue); + break; + case "OnBeginSentence": + m_strOnBeginSentence = ReadString(setValue); + break; + case "OnEndSentence": + m_strOnEndSentence = ReadString(setValue); break; default: - super::SpawnKey(strKey, strValue); + super::SpawnKey(keyName, setValue); } } +void +scripted_sentence::Input(entity entityActivator, string inputName, string dataField) +{ + switch (inputName) { + case "BeginSentence": + Trigger(entityActivator, TRIG_TOGGLE); + break; + default: + super::Input(entityActivator, inputName, dataField); + } +} + +void +scripted_sentence::SentenceEnded(void) +{ + UseOutput(this, m_strOnEndSentence); +} + void scripted_sentence::Trigger(entity act, triggermode_t unused) { @@ -150,19 +226,32 @@ scripted_sentence::Trigger(entity act, triggermode_t unused) } if (!spe) { - print(sprintf("^1scripted_sentence::^3Trigger^7: Couldn't find %s!\n", m_strSpeaker)); + NSError("Couldn't find %s!\n", m_strSpeaker); return; } - NSLog("^2scripted_sentence::^3Trigger^7: %s on %s", m_strSentence, m_strSpeaker); + EntLog("%s on %s", m_strSentence, m_strSpeaker); NSTalkMonster npc = (NSTalkMonster)spe; WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_SENTENCE); WriteEntity(MSG_MULTICAST, npc); - WriteInt(MSG_MULTICAST, Sentences_GetID(m_strSentence)); + WriteInt(MSG_MULTICAST, m_iSentenceID); msg_entity = npc; multicast(npc.origin, MULTICAST_PVS); npc.m_flNextSentence = time + m_flDuration; UseTargets(act, TRIG_TOGGLE, m_flDelay); + + /* I/O */ + /* Uncertain: Are we triggering the output on behalf of someone maybe? */ + UseOutput(this, m_strOnBeginSentence); + ScheduleThink(SentenceEnded, m_flDuration); + + if (m_strListener) { + if (m_strListener == "player") { + npc.m_eLookAt = find(world, ::classname, "player"); + } else { + npc.m_eLookAt = find(world, ::targetname, m_strListener); + } + } } diff --git a/src/gs-entbase/server/stubs.qc b/src/gs-entbase/server/stubs.qc index 59e57ba1..21779ee1 100644 --- a/src/gs-entbase/server/stubs.qc +++ b/src/gs-entbase/server/stubs.qc @@ -78,8 +78,8 @@ This entity was introduced in Quake (1996). */ CLASSEXPORT(info_target, info_notnull) -CLASSEXPORT(env_sound, info_notnull) -CLASSEXPORT(env_sun, info_notnull) +CLASSEXPORT(env_sound, info_null) +CLASSEXPORT(env_sun, info_null) CLASSEXPORT(info_intermission, info_notnull) CLASSEXPORT(prop_static, info_null) diff --git a/src/gs-entbase/server/target_cdaudio.qc b/src/gs-entbase/server/target_cdaudio.qc index 95c889bf..38cc97bd 100644 --- a/src/gs-entbase/server/target_cdaudio.qc +++ b/src/gs-entbase/server/target_cdaudio.qc @@ -110,9 +110,7 @@ target_cdaudio::Touch(entity eToucher) return; } - NSLog("^2target_cdaudio::^3Trigger^7: CD Track %i requested", - m_iCDTrack); - + EntLog(" CD Track %i requested", m_iCDTrack); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_MUSICTRACK); WriteByte(MSG_MULTICAST, m_iCDTrack); diff --git a/src/gs-entbase/server/trigger_auto.qc b/src/gs-entbase/server/trigger_auto.qc index 41d76f49..5f24f02b 100644 --- a/src/gs-entbase/server/trigger_auto.qc +++ b/src/gs-entbase/server/trigger_auto.qc @@ -114,8 +114,9 @@ trigger_auto::Respawn(void) /* deliberately add a bit more time in case we're first in the ent-lump also we'll only do this in multiplayer games. SP games will call trigger_auto_trigger() for when one player has fully joined */ - if (cvar("sv_playerslots") > 1) + if (cvar("sv_playerslots") > 1) { ScheduleThink(Processing, 0.25f); + } } void @@ -130,7 +131,7 @@ trigger_auto::Processing(void) //print(sprintf("%S %d %f %f\n", target, m_iTriggerState, m_flDelay, time)); if (HasSpawnFlags(1)) { - NSLog("^2trigger_auto::^3Processing^7: %s triggerer removed self", target); + EntLog("Trigger instructed to destroy itself."); Destroy(); } } diff --git a/src/gs-entbase/server/trigger_autosave.qc b/src/gs-entbase/server/trigger_autosave.qc index 953dedfe..ee6191c2 100644 --- a/src/gs-entbase/server/trigger_autosave.qc +++ b/src/gs-entbase/server/trigger_autosave.qc @@ -99,8 +99,7 @@ trigger_autosave::Touch(entity eToucher) msg_entity = this; multicast(origin, MULTICAST_ALL); - NSLog("^2trigger_autosave::^3Touch^7: %s called autosave", - eToucher.netname); + EntLog("%S called autosave", eToucher.netname); localcmd("save autosave\n"); SetSolid(SOLID_NOT); diff --git a/src/gs-entbase/server/trigger_cdaudio.qc b/src/gs-entbase/server/trigger_cdaudio.qc index f42021c6..1b87548d 100644 --- a/src/gs-entbase/server/trigger_cdaudio.qc +++ b/src/gs-entbase/server/trigger_cdaudio.qc @@ -94,8 +94,7 @@ trigger_cdaudio::Trigger(entity act, triggermode_t unused) return; } - NSLog("^2trigger_cdaudio::^3Trigger^7: CD Track %i requested", - m_iCDTrack); + EntLog("CD Track %i requested", m_iCDTrack); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_MUSICTRACK); diff --git a/src/gs-entbase/server/trigger_changelevel.qc b/src/gs-entbase/server/trigger_changelevel.qc index dded661f..025835a8 100644 --- a/src/gs-entbase/server/trigger_changelevel.qc +++ b/src/gs-entbase/server/trigger_changelevel.qc @@ -94,10 +94,16 @@ to define a shared point and a transition area for entities respectively. - TRIGGER_ONLY (2) : Can't activate through touching, only via triggers. # NOTES -When a Landmark is specified, you will have to position two info_landmark +When a `landmark` is specified, you will have to position two info_landmark entities across your two levels with the same name. They'll mark a translation point for the coordinates in your levels. +If you have set a landmark, you might also want to restrict the area in which entities get carried across to the next level. This is accomplished by placing a trigger_transition volume with the same name as the specified `landmark`. + +If you do not make use of the trigger_transition entity, it will carry over all of the entities that are in the same PVS (room and attached hallways) of the info_landmark. + +The PVS-culling method can prove difficult to work with. Developers have been spotted using 'killtarget' on entities before level transitions take place to manually filter through them (Half-Life's c1a0e - c1a0c). + # TRIVIA This entity was introduced in Quake (1996). */ @@ -250,10 +256,8 @@ trigger_changelevel::Change(void) /* standard level change */ if (!m_strLandmark) { - NSLog("^2trigger_changelevel::^3Change^7: Change to `%s`", - m_strMap); + EntLog("Change to %S", m_strMap); parm_string = m_strChangeTarget; - trigger_transition_pvsfallback(this); changelevel(m_strMap); return; } @@ -286,13 +290,13 @@ trigger_changelevel::Change(void) info_landmark lm = (info_landmark)e; /* found it */ if (lm.targetname == m_strLandmark) { - NSLog("^2trigger_changelevel::^3Change^7: Found landmark for %s", m_strLandmark); + EntLog("Found landmark for %S", m_strLandmark); g_landmarkpos = m_activator.origin - lm.origin; if (transitionHelper) { transitionHelper.SaveTransition(__NULL__, false); } else { - trigger_transition_pvsfallback(this); + trigger_transition_pvsfallback(lm); } changelevel(m_strMap, m_strLandmark); @@ -361,7 +365,7 @@ Landmark_GetSpot(void) /* return something useful at least */ entity ips = find(world, ::classname, "info_player_start"); - print(sprintf("^1ERROR^7: Landmark_GetSpot: Cannot find startspot '%s'!\n",startspot)); + NSError("Cannot find startspot %S!\n", startspot); return ips.origin; } diff --git a/src/gs-entbase/server/trigger_changetarget.qc b/src/gs-entbase/server/trigger_changetarget.qc index 969320ec..3fc7867a 100644 --- a/src/gs-entbase/server/trigger_changetarget.qc +++ b/src/gs-entbase/server/trigger_changetarget.qc @@ -86,8 +86,7 @@ trigger_changetarget::Trigger(entity act, triggermode_t state) for (f = __NULL__; (f = (NSEntity)find(f, ::targetname, target));) { - NSLog("^2trigger_changetarget::^3Trigger^7: " \ - "Changing %s (%s) target from '%s' to '%s'\n", \ + EntLog("Changing %s (%s) target from '%s' to '%s'\n", \ target, f.classname, f.target, target); /* now change the target */ diff --git a/src/gs-entbase/server/trigger_counter.qc b/src/gs-entbase/server/trigger_counter.qc index e3aa2d42..bc996f88 100644 --- a/src/gs-entbase/server/trigger_counter.qc +++ b/src/gs-entbase/server/trigger_counter.qc @@ -116,9 +116,7 @@ trigger_counter::Trigger(entity act, triggermode_t state) m_iCounted++; - NSLog("^2trigger_counter::^3Trigger^7: " \ - "Incremented '%s' by 1 (%i/%i)\n", \ - targetname, m_iCounted, m_iMaxCount); + EntLog("Incremented '%s' by 1 (%i/%i)\n", targetname, m_iCounted, m_iMaxCount); if (m_iCounted < m_iMaxCount) return; diff --git a/src/gs-entbase/server/trigger_hurt.qc b/src/gs-entbase/server/trigger_hurt.qc index 485513d1..882020a0 100644 --- a/src/gs-entbase/server/trigger_hurt.qc +++ b/src/gs-entbase/server/trigger_hurt.qc @@ -266,11 +266,9 @@ trigger_hurt::Touch(entity eToucher) type |= DMG_CHEMICAL; } + EntLog("Hurting %S (%d) with %i.", eToucher.classname, num_for_edict(eToucher), m_iDamage); Damage_Apply(eToucher, this, m_iDamage, 0, type); - NSLog("^2trigger_hurt::^3Touch^7: Hurting '%s' with %i", - eToucher.netname, m_iDamage); - /* shut it down if used once */ if (HasSpawnFlags(SF_HURT_ONCE)) { Trigger(eToucher, TRIG_OFF); diff --git a/src/gs-entbase/server/trigger_look.qc b/src/gs-entbase/server/trigger_look.qc index 87197c46..b004d070 100644 --- a/src/gs-entbase/server/trigger_look.qc +++ b/src/gs-entbase/server/trigger_look.qc @@ -169,7 +169,7 @@ trigger_look::Touch(entity eToucher) /* find the looktarget */ lt = find(world, ::targetname, m_strLookTarget); if (!lt) { - NSLog("^1trigger_look:Touch^7: Invalid m_strLookTarget %s!", m_strLookTarget); + EntLog("^1trigger_look:Touch^7: Invalid m_strLookTarget %s!", m_strLookTarget); Destroy(); return; } diff --git a/src/gs-entbase/server/trigger_once.qc b/src/gs-entbase/server/trigger_once.qc index 61c78793..6f1aaa4b 100644 --- a/src/gs-entbase/server/trigger_once.qc +++ b/src/gs-entbase/server/trigger_once.qc @@ -187,11 +187,11 @@ trigger_once::Touch(entity eToucher) m_iValue = 1; if (!target && !m_strKillTarget) { - NSLog("^2trigger_once::^3Touch^7: %S is triggering OnStartTouch", eToucher.classname); + EntLog("%S is triggering OnStartTouch", eToucher.classname); UseOutput(eToucher, m_strOnStartTouch); return; } - NSLog("^2trigger_once::^3Touch^7: %S is triggering %S", eToucher.classname, target); + EntLog("%S is triggering %S", eToucher.classname, target); UseTargets(eToucher, TRIG_TOGGLE, m_flDelay); } diff --git a/src/gs-entbase/server/trigger_relay.qc b/src/gs-entbase/server/trigger_relay.qc index 43a7a609..d522a2c5 100644 --- a/src/gs-entbase/server/trigger_relay.qc +++ b/src/gs-entbase/server/trigger_relay.qc @@ -116,7 +116,7 @@ void trigger_relay::Trigger(entity act, triggermode_t state) { if (m_iEnabled == FALSE) { - NSLog("trigger_relay (%s) has already been triggered", targetname); + EntLog("trigger_relay (%s) has already been triggered", targetname); return; } @@ -125,6 +125,6 @@ trigger_relay::Trigger(entity act, triggermode_t state) } m_iValue = TRUE; - NSLog("trigger_relay (%s) will trigger %s with state %d", targetname, target, m_iTriggerState); + EntLog("trigger_relay (%s) will trigger %s with state %d", targetname, target, m_iTriggerState); UseTargets(act, m_iTriggerState, m_flDelay); } diff --git a/src/gs-entbase/server/trigger_teleport.qc b/src/gs-entbase/server/trigger_teleport.qc index b8e76550..4371d88d 100644 --- a/src/gs-entbase/server/trigger_teleport.qc +++ b/src/gs-entbase/server/trigger_teleport.qc @@ -253,11 +253,9 @@ trigger_teleport::Touch(entity eToucher) Sound_Play(eTarget, CHAN_VOICE, m_sndTeleportExit); } - NSLog("^2trigger_teleport::^3Touch^7: Teleported '%s' to `%v`", - eToucher.netname, endpos); + EntLog("Teleported %S to %v", eToucher.netname, endpos); } else { - print(sprintf("^2trigger_teleport::^3Touch^7: Failed to teleport '%s'\n", - eToucher.netname)); + EntWarning("Failed to teleport %S", eToucher.netname); } } } diff --git a/src/gs-entbase/server/trigger_transition.qc b/src/gs-entbase/server/trigger_transition.qc index 9eca24e6..a20dad89 100644 --- a/src/gs-entbase/server/trigger_transition.qc +++ b/src/gs-entbase/server/trigger_transition.qc @@ -25,11 +25,6 @@ All entities touching this volume will carry across to the next level. # NOTES In order for this entity to work, one has to assign a working info_landmark entity to a trigger_changelevel, and give this entity the same targetname as said landmark. -In GoldSrc games, it appears that every point-entity that's part of the current PVS (mostly the 'room' and attached path-ways you're currently in) carries over to the next level - if a trigger_transition is not defined. -This is probably not what you want to ever do, especially in large outdoor maps where the 'room' is the entire map. - -You can also have more than one trigger_transition with the same name, so if any entity is in any of them they will move with the player across the desired level. - # TRIVIA This entity was introduced in Half-Life (1998). */ @@ -72,17 +67,25 @@ trigger_transition::SaveTransition(entity pvsTest, bool usePVS) /* loop through all entities */ for (NSEntity a = __NULL__; (a = (NSEntity)findfloat(a, ::identity, 1));) { bool replicateEntity = false; + bool continueInNextMap = false; + + /* no classname? never allow */ + if not (a.classname) { + continue; + } + //print(sprintf("TRANSITION: %i %S %S\n", i, a.classname, a.m_strGlobalName)); - /* if we're using the PVS, don't use the transition trigger as reference */ - if (usePVS == true && !a.m_strGlobalName) { - if (checkpvs(a.origin, pvsTest) == true) { + /* if we're using the PVS, use the info_landmark as a reference */ + if (usePVS == true) { + if (checkpvs(pvsTest.origin, a) == true) { replicateEntity = true; /* these checks are somewhat safe assumptions. */ if (a.classname == "player") { replicateEntity = false; } + if (a.classname == "info_landmark") { replicateEntity = false; } @@ -90,23 +93,31 @@ trigger_transition::SaveTransition(entity pvsTest, bool usePVS) /* to get rid of the 'out of model slots' error */ if (a.model == "" && solid != SOLID_NOT) { replicateEntity = false; - } - - /* one thing is verified in GoldSrc: no brushes carry over. */ - if (a.m_bIsBrush == true) { - continue; + continueInNextMap = false; } } } else if (WithinBounds(a) == true) { replicateEntity = true; } + /* only carry brushes with a global name */ + if (a.m_bIsBrush == true) { + replicateEntity = false; + continueInNextMap = false; + } + + /* global name = always find target in next map */ + if (a.m_strGlobalName) { + continueInNextMap = true; + replicateEntity = false; + } + if (replicateEntity == true) { fputs(transFile, sprintf("ENTITY \"%i\" %S\n", i, a.classname)); fputs(transFile, "{\n"); a.Save(transFile); fputs(transFile, "}\n"); - } else if (a.m_strGlobalName) { + } else if (continueInNextMap == true) { fputs(transFile, sprintf("CONTINUE \"%i\" %S\n", i, a.m_strGlobalName)); fputs(transFile, "{\n"); a.Save(transFile); @@ -129,11 +140,14 @@ trigger_transition::FindCarrierEntity(string globalName) return a; } } - return __NULL__; + + return (__NULL__); } vector Landmark_GetPosition(void); + + void trigger_transition::LoadTransition(void) { @@ -144,10 +158,10 @@ trigger_transition::LoadTransition(void) filestream transFile = fopen("trans.dat", FILE_READ); if (transFile < 0) { - error("this should never happen."); + NSError("Called to transition, but trans.dat does not exist."); } - print(sprintf("Found transition file. Will transition over entities.\n")); + NSLog("Found transition file. Will transition over entities."); while ((lineFeed = fgets(transFile))) { int c = tokenize(lineFeed); @@ -156,8 +170,17 @@ trigger_transition::LoadTransition(void) if (argv(0) == "{") { continue; } else if (argv(0) == "}") { - carrierEntity.TransitionComplete(); - carrierEntity = __NULL__; + + if (carrierEntity.solid == 0 && carrierEntity.movetype == 0) { + carrierEntity.Destroy(); + carrierEntity = __NULL__; + } + + if (carrierEntity) { + carrierEntity.TransitionComplete(); + carrierEntity.SendFlags = -1; + carrierEntity = __NULL__; + } continue; } @@ -166,16 +189,20 @@ trigger_transition::LoadTransition(void) carrierEntity = FindCarrierEntity(argv(2)); isNew = false; } else if (argv(0) == "ENTITY") { - carrierEntity = EntityDef_CreateClassname(argv(2)); + string desiredClass = argv(2); + if (desiredClass == "corpse") { + carrierEntity = __NULL__; + continue; + } + + carrierEntity = Entity_CreateClass(desiredClass); isNew = true; } } else if (c == 2) { /* key value pairs */ if (carrierEntity) { switch (argv(0)) { case "model": - if (isNew) { - carrierEntity.Restore(argv(0), argv(1)); - } + carrierEntity.model = argv(1); case "modelindex": break; #if 0 diff --git a/src/gs-entbase/shared/ambient_generic.qc b/src/gs-entbase/shared/ambient_generic.qc index 21c886f4..d2e8eea1 100644 --- a/src/gs-entbase/shared/ambient_generic.qc +++ b/src/gs-entbase/shared/ambient_generic.qc @@ -273,7 +273,7 @@ ambient_generic::Respawn(void) void ambient_generic::UseNormal(entity act, triggermode_t state) { - SndLog( "^2%s::^3UseNormal^7: %S Volume: %f; Radius: %d; Pitch: %f", classname, m_strActivePath, m_flVolume, m_flRadius, m_flPitch); + SndEntLog("Sample: %S Volume: %f; Radius: %d; Pitch: %f", m_strActivePath, m_flVolume, m_flRadius, m_flPitch); if (substring(m_strActivePath, 0, 1) == "!") { string seq = Sentences_GetSamples(m_strActivePath); @@ -300,11 +300,11 @@ void ambient_generic::UseLoop(entity act, triggermode_t state) { if (m_bToggle == true) { - SndLog( "^2%s::^3UseLoop^7: %s stops %S", classname, target, m_strActivePath); + SndEntLog( "%s stops %S", target, m_strActivePath); m_strActivePath = "common/null.wav"; } else { m_strActivePath = m_strSpawnPath; - SndLog( "^2%s::^3UseLoop^7: %s plays %S", classname, target, m_strActivePath); + SndEntLog( "%s plays %S", target, m_strActivePath); } m_bToggle = !m_bToggle; @@ -421,7 +421,7 @@ ambient_generic::ReceiveEntity(float isnew, float flChanged) if (flChanged & AMBIENT_ENABLED) m_bLoops = readbyte(); - SndLog( "^2%s::^3ReceiveEntity^7: received: %S Volume: %f; Radius: %d; Pitch: %d, Org: %v", classname, m_strActivePath, m_flVolume, m_flRadius, m_flPitch, origin); + SndEntLog("Received: %S Volume: %d%%; Radius: %d units; Pitch: %d, Org: %v", m_strActivePath, m_flVolume * 100, cvar("s_nominaldistance") / m_flRadius, m_flPitch, origin); if (m_bLoops == true) { if (flChanged & AMBIENT_MODERN) { diff --git a/src/gs-entbase/shared/decals.qc b/src/gs-entbase/shared/decals.qc index 1779667b..ab55f82f 100644 --- a/src/gs-entbase/shared/decals.qc +++ b/src/gs-entbase/shared/decals.qc @@ -157,7 +157,8 @@ decal::Place(vector org, string dname) /* we never hit any wall. */ if (g_tracedDecal.fraction == 1.0f) { - print(sprintf("^1infodecal tracing failed at %v\n", org)); + NSWarning("Placing of decal %S failed at %v", dname, org); + if (classname != "tempdecal") remove(this); return; diff --git a/src/gs-entbase/shared/env_glow.qc b/src/gs-entbase/shared/env_glow.qc index cd25bea2..1395d12e 100644 --- a/src/gs-entbase/shared/env_glow.qc +++ b/src/gs-entbase/shared/env_glow.qc @@ -92,7 +92,7 @@ void env_glow::Respawn(void) { if (!model && !m_strMaterial) { - NSEntWarning("no model specified"); + EntWarning("no model specified"); Destroy(); return; } @@ -209,7 +209,7 @@ env_glow::RendererRestarted(void) model = modelnameforindex(modelindex); m_strMaterial = spriteframe(model, 0, 0.0f); m_vecSize = drawgetimagesize(m_strMaterial) / 2; - //NSEntWarning("%S %d %S %v", model, modelindex, m_strMaterial, m_vecSize); + //EntWarning("%S %d %S %v", model, modelindex, m_strMaterial, m_vecSize); } } diff --git a/src/gs-entbase/shared/env_muzzleflash.qc b/src/gs-entbase/shared/env_muzzleflash.qc index 85e3c2d5..ea41181f 100644 --- a/src/gs-entbase/shared/env_muzzleflash.qc +++ b/src/gs-entbase/shared/env_muzzleflash.qc @@ -156,7 +156,7 @@ env_muzzleflash::Trigger(entity theActivator, triggermode_t triggerState) targetEnt = (NSEntity)find(world, ::targetname, m_parent); if (!targetEnt) { - NSEntWarning("Entity specified but not found."); + EntWarning("Entity specified but not found."); return; } } @@ -190,6 +190,10 @@ env_muzzleflash::predraw(void) addentity(this); alpha -= frametime * 16.0f; + if (m_eOwner.alpha == 0.0f) { + alpha = 0.0f; + } + if (alpha <= 0.0) { Destroy(); } diff --git a/src/gs-entbase/shared/func_vehicle.qc b/src/gs-entbase/shared/func_vehicle.qc index f3123f12..bf32caea 100644 --- a/src/gs-entbase/shared/func_vehicle.qc +++ b/src/gs-entbase/shared/func_vehicle.qc @@ -687,9 +687,9 @@ func_vehicle::Realign(void) vector end_pos; first = (NSEntity)first; second = (NSEntity)second; - NSLog("func_vehicle angles were: %v\n", angles); + EntLog("func_vehicle angles were: %v\n", angles); angles = vectoangles(first.origin - second.origin); - NSLog("func_vehicle angles is now: %v\n", angles); + EntLog("func_vehicle angles is now: %v\n", angles); end_pos = first.origin; end_pos[2] = m_oldOrigin[2] + 64; diff --git a/src/gs-entbase/shared/phys_rope.qc b/src/gs-entbase/shared/phys_rope.qc index e3a0b6db..fec2d8f4 100644 --- a/src/gs-entbase/shared/phys_rope.qc +++ b/src/gs-entbase/shared/phys_rope.qc @@ -201,7 +201,7 @@ phys_rope::EvaluateEntity(void) entity eFind = find(world, ::targetname, target); if (!eFind) { - print(sprintf("phys_rope: Unable to find target %S\n", target)); + EntError("phys_rope: Unable to find target %S\n", target); return; } diff --git a/src/gs-entbase/shared/point_spotlight.qc b/src/gs-entbase/shared/point_spotlight.qc index 34a11cb9..b6d0b233 100644 --- a/src/gs-entbase/shared/point_spotlight.qc +++ b/src/gs-entbase/shared/point_spotlight.qc @@ -104,8 +104,8 @@ point_spotlight::BeamViewDelta(vector cameraAngle) upDelta = (v * v_up); forwardDelta = (v * v_forward); - //NSLog("forwardDelta: %f\n", forwardDelta); - //NSLog("upDelta: %f (%f)\n", upDelta, 1.0 - upDelta); + //EntLog("forwardDelta: %f\n", forwardDelta); + //EntLog("upDelta: %f (%f)\n", upDelta, 1.0 - upDelta); if (forwardDelta < 0.0) return upDelta * (1.0 - forwardDelta); @@ -135,7 +135,7 @@ point_spotlight::predraw(void) vector vecAngle = g_view.GetCameraAngle(); float coneAlpha = BeamViewDelta(vecAngle); - //NSLog("coneAlpha: %f\n", coneAlpha); + //EntLog("coneAlpha: %f\n", coneAlpha); /* beam */ if (coneAlpha > 0.0) { diff --git a/src/gs-entbase/shared/prop_rope.qc b/src/gs-entbase/shared/prop_rope.qc index 75a0fff1..0dc3bde4 100644 --- a/src/gs-entbase/shared/prop_rope.qc +++ b/src/gs-entbase/shared/prop_rope.qc @@ -211,7 +211,7 @@ prop_rope::EvaluateEntity(void) entity eFind = find(world, ::targetname, target); if (!eFind) { - print(sprintf("prop_rope: Unable to find target %S\n", target)); + EntError("Unable to find rope target %S", target); return; } diff --git a/src/gs-entbase/shared/trigger_camera.qc b/src/gs-entbase/shared/trigger_camera.qc index 7eaac291..1f941900 100644 --- a/src/gs-entbase/shared/trigger_camera.qc +++ b/src/gs-entbase/shared/trigger_camera.qc @@ -70,13 +70,14 @@ private: string m_strMoveTo; entity m_eLooker_net; float m_flSpeed; + float m_flInitialSpeed; #endif }; void trigger_camera::trigger_camera(void) { - m_flWait = 4.0f; + m_flWait = 0.0f; m_eLooker = __NULL__; #ifndef CLIENT m_strAimAt = __NULL__; @@ -155,6 +156,9 @@ trigger_camera::SpawnKey(string strKey, string strValue) case "wait": m_flWait = ReadFloat(strValue); break; + case "speed": + m_flSpeed = ReadFloat(strValue); + break; default: super::SpawnKey(strKey, strValue); } @@ -200,7 +204,7 @@ trigger_camera::Restore(string strKey, string strValue) m_strMoveTo = ReadString(strValue); break; case "m_flSpeed": - m_flSpeed = ReadFloat(strValue); + m_flInitialSpeed = ReadFloat(strValue); break; default: super::Restore(strKey, strValue); @@ -239,15 +243,18 @@ trigger_camera::SendEntity(entity ePEnt, float flFlags) void trigger_camera::EvaluateEntity(void) { - entity t; + NSEntity aimingAt; if (!m_eLooker) return; - t = find(world, ::targetname, m_strAimAt); + aimingAt = (NSEntity)find(world, ::targetname, m_strAimAt); - if (t) { - angles = vectoangles(t.origin - origin); + if (aimingAt) { + TurnToPos(aimingAt.GetOrigin()); + } else { + //NSEntity targetNode = (NSEntity)find(world, ::targetname, target); + //TurnToPos(targetNode.GetOrigin()); } if (ATTR_CHANGED(origin)) { @@ -272,70 +279,87 @@ trigger_camera::EvaluateEntity(void) void trigger_camera::GoToTarget(void) { - float flTravelTime; - vector vecVelocity; + float travelTime; + vector camVelocity; + path_corner targetNode; - path_corner eNode; - eNode = (path_corner)find(world, ::targetname, target); + targetNode = (path_corner)find(world, ::targetname, target); - if (!eNode) { + if (!targetNode) { + EntError("Cannot find target %S", target); return; } - vecVelocity = (eNode.origin - origin); - flTravelTime = (vlen(vecVelocity) / eNode.m_flSpeed); + camVelocity = (targetNode.GetOrigin() - GetOrigin()); - NSLog("trigger_camera (%s): Moving to path_corner %S within %f secs", targetname, target, flTravelTime); + if (targetNode.m_flSpeed) { + m_flSpeed = targetNode.m_flSpeed; + } - if (!flTravelTime) { - NSEntWarning("distance too short, going to next"); + travelTime = (vlen(camVelocity) / m_flSpeed); + + EntLog("Moving to path_corner %S at %d within %f secs (%v)", target, m_flSpeed, travelTime, camVelocity); + + if (!travelTime) { + EntWarning("Distance too short, going to next."); NextPath(); return; } - SetVelocity(vecVelocity * (1 / flTravelTime)); - ScheduleThink(NextPath, flTravelTime); + if (!m_strAimAt) { + vector vecAngleDiff = targetNode.GetOrigin() - GetOrigin(); + vector vecAngleDest = vectoangles(vecAngleDiff); + vecAngleDiff = Math_AngleDiff(vecAngleDest, angles); + SetAngularVelocity(vecAngleDiff * (1 / travelTime)); + } + + SetVelocity(camVelocity * (1 / travelTime)); + ScheduleThink(NextPath, travelTime); } void trigger_camera::NextPath(void) { - path_corner eNode; + path_corner nextNode; if (target == "") { return; } - print(sprintf("Looking for target %S\n", target)); - eNode = (path_corner)find(world, ::targetname, target); + nextNode = (path_corner)find(world, ::targetname, target); - if (!eNode) { + if (!nextNode) { + NSError("Node %S suddenly missing from map!", target); return; } - NSLog("trigger_camera (%s): Touched base with path_corner %S", targetname, target); + EntLog("Arrived at target node %S.", target); /* fire the path_corners' target */ - eNode.Trigger(this, TRIG_TOGGLE); + nextNode.PathPassTrigger(this, TRIG_TOGGLE); + + if (target != m_strMoveTo) + m_strAimAt = __NULL__; + + SetOrigin(nextNode.origin - (mins + maxs) * 0.5); + SetTriggerTarget(nextNode.target); - SetOrigin(eNode.origin - (mins + maxs) * 0.5); - SetTriggerTarget(eNode.target); ClearVelocity(); /* warp next frame */ - if (eNode.HasSpawnFlags(PC_TELEPORT)) { - NSLog("^1trigger_camera::^3NextPath^7: Node %s wants %s to teleport\n", eNode.targetname, targetname); + if (nextNode.HasSpawnFlags(PC_TELEPORT)) { + EntLog("Node %S wants %S to teleport.", nextNode.targetname, targetname); ScheduleThink(NextPath, 0.0f); return; } /* stop until triggered again */ - if (eNode.HasSpawnFlags(PC_WAIT)) { + if (nextNode.HasSpawnFlags(PC_WAIT)) { return; } - if (eNode.m_flWait > 0) { - ScheduleThink(GoToTarget, eNode.m_flWait); + if (nextNode.m_flWait > 0) { + ScheduleThink(GoToTarget, nextNode.m_flWait); } else { GoToTarget(); } @@ -350,7 +374,7 @@ trigger_camera::Trigger(entity act, triggermode_t state) act = find(world, ::classname, "player"); } - NSLog("trigger_camera for %s %S is now %S\n", act.classname, act.netname, targetname); + EntLog("Controlling camera of %S", act.netname); /* kill the other cams the player may be attached to */ for (trigger_camera cam = __NULL__; (cam = (trigger_camera)find(cam, ::classname, "trigger_camera"));) { @@ -367,15 +391,20 @@ trigger_camera::Trigger(entity act, triggermode_t state) m_eLooker = act; m_eLooker.view2 = this; - NSLog("Triggering it on %s\n", act.netname); + m_flSpeed = m_flInitialSpeed; + + if (!m_flSpeed) { + m_flSpeed = 100.0f; + } + + /* Reset to the spawn values */ + SetMovetype(MOVETYPE_PUSH); + SetSolid(SOLID_NOT); SetOrigin(GetSpawnOrigin()); - ClearVelocity(); - ReleaseThink(); SetTriggerTarget(m_strMoveTo); NextPath(); GoToTarget(); SetSendFlags(0xFFFFFF); - ScheduleThink(DeactivateCamera, m_flWait); pvsflags = PVSF_IGNOREPVS; } @@ -383,7 +412,7 @@ trigger_camera::Trigger(entity act, triggermode_t state) void trigger_camera::DeactivateCamera(void) { - NSLog("Turning it off on %s\n", m_eLooker.netname); + EntLog("Turning it off on %S", m_eLooker.netname); m_eLooker.view2 = __NULL__; m_eLooker = __NULL__; SetSendFlags(-1); diff --git a/src/gs-entbase/shared/worldspawn.qc b/src/gs-entbase/shared/worldspawn.qc index ed6f9728..96cbb711 100644 --- a/src/gs-entbase/shared/worldspawn.qc +++ b/src/gs-entbase/shared/worldspawn.qc @@ -97,9 +97,9 @@ worldspawn::worldspawn(void) m_strAmbientSound = ""; m_strBGMTrack = ""; - print("--------- Map Initialization ---------\n"); - print(sprintf("Map: %s\n", mapname)); - print("----------- Game Map Init ------------\n"); + InitPrint("Map Initialization"); + NSLog("Map: %s", mapname); + InitPrint("Game Map Init"); lightstyle(0, "m"); lightstyle(1, "mmnmmommommnonmmonqnmmo"); @@ -125,7 +125,7 @@ worldspawn::worldspawn(void) if (autocvar_sv_levelexec) readcmd(sprintf("exec maps/%s.cfg\n", mapname)); - print("Spawning entities\n"); + InitStart(); } void @@ -202,6 +202,11 @@ worldspawn::SpawnKey(string strKey, string strValue) m_flHDRIrisFadeDown = ReadFloat(strValue); m_bHDREnabled = true; break; + /* empty, ignore */ + case "wad": + case "MaxRange": + case "sounds": + break; default: super::SpawnKey(strKey, strValue); break; diff --git a/src/menu-fn/entry.qc b/src/menu-fn/entry.qc index 31a87120..f752dec8 100644 --- a/src/menu-fn/entry.qc +++ b/src/menu-fn/entry.qc @@ -54,12 +54,12 @@ Menu_GammaHack(void) { if (cvar("brightness") != cvar("vid_brightness")) { localcmd("seta brightness 0\n"); - print("^1Menu_RendererRestarted^7: Brightness hack.\n"); + NSLog("Old config brightness. Applying brightness hack."); } if (cvar("gamma") != cvar("vid_gamma")) { localcmd("seta gamma 1\n"); - print("^1Menu_RendererRestarted^7: Gamma hack.\n"); + NSLog("Old config gamma. Applying gamma hack."); } } @@ -75,7 +75,7 @@ Menu_HasStartupVideos(void) void Menu_PlayStartupVideos(void) { - print("playing startup videos\n"); + NSLog("Playing startup videos.\n"); //localcmd("playvideo av:media/sierra.avi av:media/valve.avi\n"); } @@ -94,9 +94,9 @@ m_init(void) string menuMap; - print("--------- Initializing Menu ----------\n"); - print("Built: " __DATE__ " " __TIME__"\n"); - print("QCC: " __QCCVER__ "\n"); + NSLog("--------- Initializing Menu ----------"); + NSLog("Built: %s %s", __DATE__, __TIME__); + NSLog("QCC: %s", __QCCVER__); /* things that should really be default. platform_default.cfg is supposed to set * them the first time - however FTE doesn't do that when switching manifests diff --git a/src/menu-fn/layout_script.qc b/src/menu-fn/layout_script.qc index 7d0a4b3f..b64a07e0 100644 --- a/src/menu-fn/layout_script.qc +++ b/src/menu-fn/layout_script.qc @@ -87,7 +87,7 @@ Layout_FromFile_Create(CPageTab target, string cvar, string descr, string type, //new = spawn(CTextBox); //break; default: - warning(sprintf("Unknown widget type %S for cvar %S, ignoring", type, cvar)); + NSWarning("Unknown widget type %S for cvar %S, ignoring.", type, cvar); } if (!new) diff --git a/src/platform/gamelibrary.qc b/src/platform/gamelibrary.qc index 922555f4..3d382a03 100644 --- a/src/platform/gamelibrary.qc +++ b/src/platform/gamelibrary.qc @@ -468,8 +468,11 @@ GameLibrary_InitCustom(void) games = (gameinfo_t *)memrealloc(games, sizeof(gameinfo_t), old_count, (gameinfo_count + packageinfo_count)); /* The things we do for frequent flyer mileage. */ - if (!games) - error(sprintf("Attempting to allocate mod data for %i entries failed\n", gameinfo_count)); + if (!games) { + NSError("Attempting to allocate mod data for %i entries failed.", gameinfo_count); + crash(); + return; + } /* now loop through all the mods we found and load in the metadata */ for (id = 1; id < gameinfo_count; id++) { @@ -533,12 +536,12 @@ GameLibrary_InitCustom(void) /* we may have some mods, but we're not running any of them. Fatal */ if (gameinfo_current == -1) { - print("^1FATAL ERROR: NO LIBLIST.GAM FOR CURRENT MOD FOUND!\n"); + NSError("No definition for current game found. Fatal."); crash(); return; } - print(sprintf("GameLibrary initialized (%i entries).\n", gameinfo_count)); + NSLog("...GameLibrary initialized (%i entries).", gameinfo_count); } #endif @@ -583,7 +586,7 @@ static void GameLibrary_EndInstall(void) { int gid = g_iModInstallCache; - print(sprintf("Installation ended for %S!\n", g_strModInstallCache)); + NSLog("Installation ended for %S.", g_strModInstallCache); localcmd(sprintf("game %s\n", g_strModInstallCache)); localcmd("stopmusic\nsnd_restart\nwait\nvid_reload\n"); @@ -662,14 +665,13 @@ GameLibrary_InstallStart(int gameid) for (int i = 0; i < count; i++) { int pkgid = GameLibrary_IDForPackageName(argv(i)); localcmd(sprintf("pkg add %s\n", argv(i))); - print(sprintf("Marking package %s for install.\n", - argv(i))); + NSLog("Marking package %s for install.", argv(i)); } g_iModInstallCache = gameid; g_strModInstallCache = games[gameid].gamedir; localcmd("pkg apply\n"); - print("Starting installation of custom game packages\n"); + NSLog("Starting installation of custom game packages."); } void @@ -678,15 +680,12 @@ GameLibrary_Install(int gameID) string st; if (gameID >= gameinfo_count || gameID < 0i) { - print(sprintf("GameLibrary_Install: Invalid game id %i!\n", gameID)); + NSError("Invalid game id %i!\n", gameID); return; } st = getpackagemanagerinfo(games[gameID].pkgid, GPMI_INSTALLED); - print(st); - print("\n"); - if (st != "enabled") { GameLibrary_InstallStart(gameID); return; @@ -701,7 +700,7 @@ void GameLibrary_Activate(int gameID) { if (gameID >= gameinfo_count || gameID < 0i) { - print(sprintf("GameLibrary_Activate: Invalid game id %i!\n", gameID)); + NSError("Invalid game id %i.", gameID); return; } @@ -757,7 +756,7 @@ __variant GameLibrary_GetGameInfo(int gameID, gameInfo_t infoType) { if (gameID >= gameinfo_count || gameID < 0i) { - print(sprintf("GameLibrary_GetGameInfo: Invalid game id %i!\n", gameID)); + NSError("Invalid game id %i.", gameID); return __NULL__; } @@ -836,5 +835,5 @@ GameLibrary_DebugList(void) print(sprintf("%i %s (%s)\n", i, games[i].game, games[i].gamedir)); } - print(sprintf("\t%i game(s) loaded\n", gameinfo_count)); + print(sprintf("\t%i game(s) loaded.", gameinfo_count)); } diff --git a/src/platform/maplibrary.qc b/src/platform/maplibrary.qc index dd201fd0..a9b2c92a 100644 --- a/src/platform/maplibrary.qc +++ b/src/platform/maplibrary.qc @@ -170,7 +170,7 @@ MapLibrary_Init(void) } search_end(mapsearch); - print(sprintf("MapLibrary initialized (%i entries).\n", g_mapLibrary_count)); + NSLog("...MapLibrary initialized (%i entries).", g_mapLibrary_count); } int @@ -183,7 +183,7 @@ __variant MapLibrary_GetInfo(int mapID, mapType_t infoType) { if (mapID >= g_mapLibrary_count || mapID < 0i) { - print(sprintf("MapLibrary_GetInfo: Invalid map id %i!\n", mapID)); + NSError("Invalid map id %i", mapID); return __NULL__; } diff --git a/src/platform/master.qc b/src/platform/master.qc index 4d2468a3..466d09da 100644 --- a/src/platform/master.qc +++ b/src/platform/master.qc @@ -37,7 +37,8 @@ Master_Resolve(void) dprint("...\n"); if (!out) { - dprint("Failed to resolve address.\n"); + NSError("Failed to resolve master server address."); + return __NULL__; } return out; @@ -51,6 +52,7 @@ Master_GetTotalServers(void) if (a) { NSLog("Master reports a total of %i servers.", a); } + return gethostcachevalue(SLIST_HOSTCACHETOTALCOUNT); } @@ -95,7 +97,8 @@ Master_RecountServers(void) void Master_RefreshCache(void) { - dprint("Refreshing host cache...\n"); + NSLog("Refreshing host cache..."); + resethostcachemasks(); sethostcachemaskstring(0, gethostcacheindexforkey("gamedir"), cvar_string("game"), SLIST_TEST_EQUAL); sethostcachesort(gethostcacheindexforkey("ping"), FALSE); @@ -112,7 +115,7 @@ Master_RefreshCache(void) void Master_UpdateCache(void) { - dprint("Updating host cache...\n"); + NSLog("Updating host cache..."); resethostcachemasks(); sethostcachemaskstring(0, gethostcacheindexforkey("gamedir"), cvar_string("game"), SLIST_TEST_EQUAL); sethostcachesort(gethostcacheindexforkey("ping"), FALSE); diff --git a/src/server/NSGameRules.qc b/src/server/NSGameRules.qc index 972ce4b3..2a0b792f 100644 --- a/src/server/NSGameRules.qc +++ b/src/server/NSGameRules.qc @@ -374,10 +374,8 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type g_dmg_iFlags = type; g_dmg_iWeapon = w; - NSLog("Damage: %s damages %s with %d damage", c.classname, t.classname, dmg); - NSLog("\tHit-body: %d", g_dmg_iHitBody); - NSLog("\tFlags: %i", g_dmg_iFlags); - NSLog("\tWeapon: %i", g_dmg_iWeapon); + NSLog("%S does %d dmg to %S (body: %d, flags: %i, weapon: %i)", + c.classname, dmg, t.classname, g_dmg_iHitBody, g_dmg_iFlags, g_dmg_iWeapon); /* friendly fire penalty */ if (isFriendlyFire) { @@ -553,19 +551,25 @@ NSGameRules::PlayerRequestRespawn(NSClientPlayer bp) void NSGameRules::ChatMessageAll(NSClient cl, string strMessage) { + float edictNum = num_for_edict(cl) - 1; + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_CHAT); - WriteByte(MSG_MULTICAST, num_for_edict(cl) - 1); + WriteByte(MSG_MULTICAST, edictNum); WriteByte(MSG_MULTICAST, cl.team); WriteString(MSG_MULTICAST, strMessage); multicast([0,0,0], MULTICAST_ALL_R); - localcmd(sprintf("echo [ALL] %s: %s\n", cl.netname, strMessage)); + /* TODO: don't print on listen games */ + print(Util_ChatFormat(edictNum, 0, strMessage)); + print("\n"); } void NSGameRules::ChatMessageTeam(NSClient cl, string strMessage) { + float edictNum = num_for_edict(cl) - 1; + /* their finger probably slipped */ if (IsTeamplay() == false) { ChatMessageAll(cl, strMessage); @@ -580,7 +584,7 @@ NSGameRules::ChatMessageTeam(NSClient cl, string strMessage) WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_CHAT_TEAM); - WriteByte(MSG_MULTICAST, num_for_edict(cl) - 1); + WriteByte(MSG_MULTICAST, edictNum); WriteByte(MSG_MULTICAST, cl.team); WriteString(MSG_MULTICAST, strMessage); @@ -588,7 +592,8 @@ NSGameRules::ChatMessageTeam(NSClient cl, string strMessage) multicast([0,0,0], MULTICAST_ONE_R); } - localcmd(sprintf("echo [TEAM] %s: %s\n", cl.netname, strMessage)); + print(Util_ChatFormat(edictNum, cl.team, strMessage)); + print("\n"); } string diff --git a/src/server/defs.h b/src/server/defs.h index b2765cc1..6f3e2789 100644 --- a/src/server/defs.h +++ b/src/server/defs.h @@ -154,3 +154,4 @@ void main(void) NSEntity EntityDef_SpawnClassname(string className); NSEntity EntityDef_CreateClassname(string className); +NSEntity Entity_CreateClass(string className); diff --git a/src/server/entityDef.qc b/src/server/entityDef.qc index ec20c429..56d5204d 100644 --- a/src/server/entityDef.qc +++ b/src/server/entityDef.qc @@ -125,13 +125,15 @@ EntityDef_ReadFile(string filePath) /* bounds check */ if (g_entDefCount >= ENTITYDEF_MAX) { - error(sprintf("EntityDef_ReadFile: reached limit of %d defs\n", ENTITYDEF_MAX)); + NSError("Reached limit of %d defs.", ENTITYDEF_MAX); + error("Crash."); } /* open file */ defFile = fopen(filePath, FILE_READ); if (defFile < 0) { - error(sprintf("EntityDef_ReadFile: unable to read %S\n", filePath)); + NSError("Unable to read %S\n", filePath); + error("Crash."); } /* line by line */ @@ -248,6 +250,8 @@ EntityDef_Init(void) { searchhandle pm; + InitStart(); + g_entDefInclude = ""; pm = search_begin("def/*.def", TRUE, TRUE); @@ -284,6 +288,8 @@ EntityDef_Init(void) } } #endif + + InitEnd(); } static bool @@ -331,6 +337,8 @@ EntityDef_CheckCondition(int id, string keyWord, float tweakCondition, string ke tmp1 = stof(keyValue); tmp2 = stof(value); + print(sprintf("%d & %d\n", tmp1, tmp2)); + if (key == keyWord && tmp2 & tmp1) return true; break; @@ -498,7 +506,6 @@ EntityDef_SpawnClassname(string className) } } - NSLog("^1Failed spawning eDef %S", className); return __NULL__; } @@ -507,9 +514,17 @@ EntityDef_CreateClassname(string className) { entity oldSelf = self; NSEntity new = spawn(NSEntity); + NSEntity test; self = new; - EntityDef_SpawnClassname(className); + test = EntityDef_SpawnClassname(className); self = oldSelf; + + /* Failure */ + if (test == __NULL__) { + new.Destroy(); + return __NULL__; + } + return new; } @@ -564,4 +579,27 @@ EntityDef_HasSpawnClass(string className) } return false; +} + +static void +CallSpawnfuncByName(entity target, string className) +{ + entity oldSelf = self; + string spawnClass = strcat("spawnfunc_", className); + self = target; + callfunction(spawnClass); + self = oldSelf; +} + +NSEntity +Entity_CreateClass(string className) +{ + NSEntity newEntity = EntityDef_CreateClassname(className); + + if (!newEntity) { + newEntity = spawn(NSEntity); + CallSpawnfuncByName(newEntity, className); + } + + return newEntity; } \ No newline at end of file diff --git a/src/server/entry.qc b/src/server/entry.qc index 081334a6..721952ee 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -89,6 +89,8 @@ ClientDisconnect(void) /* this will hide/remove the player from other clients */ player pl = (player)self; pl.Disappear(); + pl.classname = ""; + pl.flags = 0; } /** Called by the `kill` console command. @@ -147,6 +149,12 @@ PutClientInServer(void) /* handle transitions */ if (whichpack("data/trans.dat")) { + + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + NSEntity levelEnt = (NSEntity)a; + levelEnt.TransitionComplete(); + } + trigger_transition::LoadTransition(); } @@ -232,7 +240,7 @@ The `self` global does not refer to anything. void SetNewParms(void) { - print("--------- Setting New Level Parameters ----------\n"); + InitPrint("Setting New Level Parameters"); if (g_ents_initialized) g_grMode.LevelNewParms(); @@ -248,7 +256,7 @@ allocated for every client. void SetChangeParms(void) { - print("--------- Setting Level-Change Parameters ----------\n"); + InitPrint("Setting Level-Change Parameters"); if (g_ents_initialized) g_grMode.LevelChangeParms((NSClientPlayer)self); @@ -358,9 +366,9 @@ So avoid calling spawn() related functions here. */ void init(float prevprogs) { - print("--------- Initializing Server Game ----------\n"); - print("Built: " __DATE__ " " __TIME__"\n"); - print("QCC: " __QCCVER__ "\n"); + InitPrint("Initializing Server Game"); + NSLog("Built: %s %s", __DATE__, __TIME__); + NSLog("QCC: %s", __QCCVER__); Plugin_Init(); @@ -369,7 +377,6 @@ init(float prevprogs) PropData_Init(); SurfData_Init(); DecalGroups_Init(); - Skill_Init(); /* DO NOT EVER CHANGE THESE. */ cvar_set("r_meshpitch", "1"); @@ -391,7 +398,9 @@ init_respawn(void) endspawn++; } - print(sprintf("...%i entities spawned (%i inhibited)\n", g_ent_spawned, g_ent_spawned - endspawn)); + NSLog("...%i entities spawned (%i inhibited)", g_ent_spawned, g_ent_spawned - endspawn); + + InitEnd(); remove(self); } @@ -464,7 +473,7 @@ initents(void) g_ents_initialized = TRUE; /* engine hacks for dedicated servers */ - cvar_set("s_nominaldistance", "1024"); + cvar_set("s_nominaldistance", "1536"); /* other engine hacks */ cvar_set("sv_nqplayerphysics", "0"); @@ -518,7 +527,11 @@ ConsoleCmd(string cmd) tokenize(cmd); switch (argv(0)) { case "addBot": - Bot_AddBot_f(strtolower(argv(1))); + string botProfile = strtolower(argv(1)); + float teamValue = stof(argv(2)); + float spawnDelay = stof(argv(3)); + string newName = argv(4); + Bot_AddBot_f(botProfile, teamValue, spawnDelay, newName); break; case "killAllBots": Bot_KillAllBots(); @@ -597,6 +610,12 @@ ConsoleCmd(string cmd) if (finder) setorigin(pl, finder.origin); break; + case "renetworkEntities": + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + NSEntity ent = (NSEntity)a; + ent.SendFlags = -1; + } + break; case "respawnEntities": for (entity a = world; (a = findfloat(a, ::identity, 1));) { NSEntity ent = (NSEntity)a; @@ -658,7 +677,7 @@ SV_PerformLoad(float fh, float entcount, float playerslots) NSEntity loadent = __NULL__; int num_loaded = 0i; - print("--------- Loading Existing Save ----------\n"); + InitPrint("Loading Existing Save"); g_isloading = true; #if 0 @@ -695,7 +714,7 @@ SV_PerformLoad(float fh, float entcount, float playerslots) #ifndef REEDICT n = stof(argv(1)); e = edict_num(n); - print(sprintf("Creating %s (edict %d)\n", cname, n)); + NSLog("Creating %s (edict %d)", cname, n); #else entity e = spawn(); #endif @@ -719,7 +738,7 @@ SV_PerformLoad(float fh, float entcount, float playerslots) loadent = (NSEntity)e; self = eold; } else { - print(sprintf("Could not spawn %s\n", cname)); + NSError("Could not spawn %s", cname); remove(e); self = eold; continue; @@ -729,7 +748,7 @@ SV_PerformLoad(float fh, float entcount, float playerslots) if (loadent) { loadent.RestoreComplete(); num_loaded++; - print(sprintf("completed %s (edict %d)\n\n", loadent.classname, n)); + NSLog("completed %s (edict %d)", loadent.classname, n); loadent = __NULL__; } } else { @@ -744,7 +763,7 @@ SV_PerformLoad(float fh, float entcount, float playerslots) } } - print(sprintf("loaded %i entities\n", num_loaded)); + NSLog("...loaded %i entities", num_loaded); g_isloading = false; } @@ -759,7 +778,7 @@ SV_PerformSave(float fh, float entcount, float playerslots) int num_saved = 0i; entity e; - print("--------- Performing Save ----------\n"); + InitPrint("Performing Save"); for (i = 0; i < entcount; i++) { NSEntity willsave; @@ -782,7 +801,7 @@ SV_PerformSave(float fh, float entcount, float playerslots) num_saved++; } fclose(fh); - print(sprintf("saved %i entities\n", num_saved)); + NSLog("saved %i entities", num_saved); } /** Called by the engine to check with us if a spawn function exists. @@ -793,17 +812,20 @@ to remove in case we won't initialize it. void CheckSpawn(void() spawnfunc) { - if (MapTweak_EntitySpawn(self)) - return; - if (EntityDef_SpawnClassname(self.classname)) - return; + string desiredClass = self.classname; - if (spawnfunc) { + if (MapTweak_EntitySpawn(self)) { + self._mapspawned = true; + self.classname = desiredClass; + } else if (EntityDef_SpawnClassname(desiredClass)) { + self._mapspawned = true; + } else if (spawnfunc) { spawnfunc(); + self.classname = desiredClass; self._mapspawned = true; g_ent_spawned++; } else { - print(sprintf("^1Cannot find entity class ^7%s\n", self.classname)); + NSError("Unable to spawn %s", desiredClass); remove(self); } @@ -816,4 +838,4 @@ CheckSpawn(void() spawnfunc) g_ent_spawned--; } } -} +} \ No newline at end of file diff --git a/src/server/mapcycle.qc b/src/server/mapcycle.qc index 90124b7b..08a4945b 100644 --- a/src/server/mapcycle.qc +++ b/src/server/mapcycle.qc @@ -28,7 +28,7 @@ Mapcycle_Load(string filename) fs_mapcycle = fopen(filename, FILE_READ); if (fs_mapcycle < 0) { - print(strcat("^1could not load ", filename, "\n")); + NSError("Missing file %s", filename); return; } @@ -57,7 +57,7 @@ Mapcycle_Load(string filename) /* the current map in the list will decide the nextmap */ localcmd(sprintf("alias nextmap m%i\n", map_next)); - print(sprintf("mapcycle initialized with %i entries.\n", mapcount)); + NSLog("...MapCycle initialized with %i entries.", mapcount); } void @@ -69,14 +69,15 @@ Mapcycle_Init(void) if (g_grMode.IsMultiplayer() == false) return; - print("--------- Initializing MapCycle ----------\n"); + InitStart(); /* in case some server admin wants a map to continously loop */ if (cycleFile == "") { - print("mapcycle disabled via cvar. skipping\n"); + NSLog("MapCycle disabled via cvar. Skipping."); localcmd("alias nextmap map_restart 0\n"); return; } Mapcycle_Load(cycleFile); + InitEnd(); } diff --git a/src/server/maptweaks.qc b/src/server/maptweaks.qc index 498fed72..06d09c60 100644 --- a/src/server/maptweaks.qc +++ b/src/server/maptweaks.qc @@ -47,6 +47,8 @@ MapTweaks_Init(void) string newCvar, newInfo, newItem; int atTweak = 0i; + InitStart(); + tweakFile = fopen("scripts/maptweaks.txt", FILE_READ); g_mapTweakCount = 0; newCvar = newInfo = newItem = ""; @@ -60,6 +62,8 @@ MapTweaks_Init(void) } } } else { + NSError("Missing file scripts/maptweaks.txt"); + InitEnd(); return; } @@ -97,6 +101,7 @@ MapTweaks_Init(void) } fclose(tweakFile); + InitEnd(); } static bool diff --git a/src/server/nodes.qc b/src/server/nodes.qc index b9bf488f..f434dc7c 100644 --- a/src/server/nodes.qc +++ b/src/server/nodes.qc @@ -164,7 +164,7 @@ Nodes_InsertNodeForClassname(string classn) void Nodes_BuildFromEnts(void) { - print("rebuilding node tree..."); + NSLog("Rebuilding node tree..."); /* run through the ents and rebuild the tree */ Nodes_InsertNodeForClassname("info_node"); @@ -179,13 +179,13 @@ Nodes_BuildFromEnts(void) if (g_iNodes == 0) Nodes_InsertNodeForClassname("info_player_deathmatch"); - print(sprintf("%i possible nodes found in %s\n", g_iNodes, mapname)); + NSLog("%i possible nodes found in %s", g_iNodes, mapname); if (g_iNodes) { - print(sprintf("saving nodes nodes for %s\n", mapname)); + NSLog("saving nodes nodes for %s", mapname); Nodes_Save(sprintf("%s.way", mapname)); } else { - print(sprintf("no node data found for %s\n", mapname)); + NSLog("no node data found for %s", mapname); } } @@ -193,14 +193,14 @@ Nodes_BuildFromEnts(void) void Nodes_Init(void) { - print("--------- Initializing Nodes Subsystem ----------\n"); + InitStart(); g_nodes_present = FALSE; /* skip if present. TODO: check if they're out of date? */ if (whichpack(sprintf("data/%s.way", mapname))) { g_nodes_present = TRUE; #ifdef NODE_DEBUG - print(sprintf("loading existing nodes for %s\n", mapname)); + NSLog("loading existing nodes for %s", mapname); Nodes_Load(sprintf("%s.way", mapname)); #endif } else { @@ -216,7 +216,7 @@ Nodes_Init(void) g_iNodes = 0; #endif - print("Nodes subsystem initialized.\n"); + InitEnd(); } #ifdef NODE_DEBUG @@ -231,13 +231,16 @@ SV_AddDebugPolygons(void) { Way_DrawDebugInfo(); - if (!g_iNodes) { - return; - } - if (cvar("developer") != 1) return; +#if 1 + for (entity s = world; (s = find(s, ::classname, "func_tracktrain"));) { + func_tracktrain train = (func_tracktrain)s; + train.RenderDebugInfo(); + } +#endif + makevectors(self.v_angle); /* draw the rectangles */ @@ -251,6 +254,22 @@ SV_AddDebugPolygons(void) R_EndPolygon(); } + for (entity s = world; (s = find(s, ::classname, "path_track"));) { + vector pos = s.origin; + pos[2] += 32; + R_BeginPolygon("textures/dev/path_track", 0, 0); + R_PolygonVertex(pos + v_right * 24 - v_up * 24, [1,1], [1,1,1], 1.0f); + R_PolygonVertex(pos - v_right * 24 - v_up * 24, [0,1], [1,1,1], 1.0f); + R_PolygonVertex(pos - v_right * 24 + v_up * 24, [0,0], [1,1,1], 1.0f); + R_PolygonVertex(pos + v_right * 24 + v_up * 24, [1,0], [1,1,1], 1.0f); + R_EndPolygon(); + + R_BeginPolygon("", 0, 0); + R_PolygonVertex(s.origin, [0,1], [1,1,1], NODE_LINE_ALPHA); + R_PolygonVertex(pos, [1,1], [1,1,1], NODE_LINE_ALPHA); + R_EndPolygon(); + } + for (entity s = world; (s = find(s, ::classname, "scripted_sequence"));) { vector pos = s.origin; pos[2] += 32; @@ -267,45 +286,5 @@ SV_AddDebugPolygons(void) R_PolygonVertex(pos, [1,1], [1,1,1], NODE_LINE_ALPHA); R_EndPolygon(); } - - /* draw the radius */ - R_BeginPolygon("", 0, 0); - for (int i = 0; i < g_iNodes; i++) { - node_t *w = g_pNodes + i; - vector org = w->origin; - - for (float j = 0; j < (2 * M_PI); j += (2 * M_PI) / 4) { - R_PolygonVertex( - org + [sin(j),cos(j)]*w->radius, - [1,1], - [0,0.25,0], - 1.0f - ); - } - R_EndPolygon(); - } - - /* draw the lines */ - R_BeginPolygon("", 1, 0); - for (int i = 0; i < g_iNodes; i++) { - node_t *w = g_pNodes+i; - vector org = w->origin; - vector rgb = [1,1,1]; - - for (int j = 0; j < w->nb_count; j++) { - int k = w->nb[j].node; - - /* check for invalids */ - if (k < 0 || k >= g_iNodes) { - break; - } - - node_t *w2 = &g_pNodes[k]; - - R_PolygonVertex(org, [0,1], [1,1,1], NODE_LINE_ALPHA); - R_PolygonVertex(w2->origin, [1,1], [1,1,1], NODE_LINE_ALPHA); - R_EndPolygon(); - } - } } #endif diff --git a/src/server/plugins.qc b/src/server/plugins.qc index c6de6de3..6b7e2437 100644 --- a/src/server/plugins.qc +++ b/src/server/plugins.qc @@ -31,18 +31,20 @@ Plugin_Init(void) int i; if (autocvar_sv_plugins) { - print("--------- Initializing Plugins ----------\n"); g_plugins_enabled = 1; } else { g_plugins_enabled = 0; return; } + InitStart(); + pdb = fopen("plugins.txt", FILE_READ); if (pdb < 0) { - print("^1no plugins.txt found.\n"); + NSWarning("No plugins.txt found. Plugins disabled.\n"); g_plugins_enabled = 0; + InitEnd(); return; } @@ -85,7 +87,8 @@ Plugin_Init(void) } } - print(sprintf("initialized %i plugins.\n", g_plugincount)); + NSLog("...initialized %i plugins.", g_plugincount); + InitEnd(); } /* diff --git a/src/server/skill.qc b/src/server/skill.qc index 8f05d784..643c7f99 100644 --- a/src/server/skill.qc +++ b/src/server/skill.qc @@ -27,8 +27,13 @@ This will almost always result in them using default values, or (worst case) 0. void Skill_Init(void) { + string mapSkillFile = sprintf("maps/%s_skl.cfg", serverkey("mapname")); + Skill_ParseConfig("cfg/skill_manifest.cfg"); - Skill_ParseConfig(sprintf("maps/%s_skl.cfg", mapname)); + + if (FileExists(mapSkillFile)) { + Skill_ParseConfig(mapSkillFile); + } } /* @@ -68,7 +73,7 @@ Skill_ParseConfig(string fileName) filestream configFile = fopen(fileName, FILE_READ); if (configFile < 0) { - print(sprintf("^1Warning: Unable to exec %S for parsing.\n", fileName)); + NSWarning("Unable to exec %S for parsing.", fileName); return (false); } diff --git a/src/server/way.h b/src/server/way.h index d7394cab..e14a3108 100644 --- a/src/server/way.h +++ b/src/server/way.h @@ -23,4 +23,5 @@ #define LF_WALK 0x00000010i #define LF_AIM 0x00000020i #define LF_USER 0x00000040i +#define LF_HAZARDOUS 0x00000080i #define LF_DESTINATION 0x80000000i diff --git a/src/shared/NSBrushTrigger.qc b/src/shared/NSBrushTrigger.qc index 867a72eb..8adc83d7 100644 --- a/src/shared/NSBrushTrigger.qc +++ b/src/shared/NSBrushTrigger.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSClient.h b/src/shared/NSClient.h index 34f68100..4e594095 100644 --- a/src/shared/NSClient.h +++ b/src/shared/NSClient.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -62,19 +62,20 @@ public: virtual float predraw(void); #endif + /** Get the string value of an InfoKey. */ + nonvirtual string GetInfoKey(string); + /** Floating point based version of GetInfoKey(). */ + nonvirtual float GetInfoKeyFloat(string); + #ifdef SERVER /** Server: This is where the input* variables arrive after sending them out from the client (see ClientInputFrame). This is also where we will instruct the server to run physics on the client. */ virtual void ServerInputFrame(void); - /** Set the value of an InfoKey. */ + /** Server: Set the value of an InfoKey. */ nonvirtual void SetInfoKey(string, string); - /** Get the string value of an InfoKey. */ - nonvirtual string GetInfoKey(string); - /** Floating point based version of SetInfoKey(). */ + /** Server: Floating point based version of SetInfoKey(). */ nonvirtual void SetInfoKeyFloat(string, float); - /** Floating point based version of GetInfoKey(). */ - nonvirtual float GetInfoKeyFloat(string); /* overrides */ virtual void Save(float); diff --git a/src/shared/NSClient.qc b/src/shared/NSClient.qc index 9b6de012..1198fd5d 100644 --- a/src/shared/NSClient.qc +++ b/src/shared/NSClient.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -69,25 +69,38 @@ NSClient::SetInfoKey(string strKey, string strValue) forceinfokey(this, strKey, strValue); } -string -NSClient::GetInfoKey(string strKey) -{ - return infokey(this, strKey); -} - void NSClient::SetInfoKeyFloat(string strKey, float floatValue) { forceinfokey(this, strKey, ftos(floatValue)); } +#endif + +string +NSClient::GetInfoKey(string strKey) +{ +#ifdef SERVER + return infokey(this, strKey); +#endif + +#ifdef CLIENT + return getplayerkeyvalue(entnum-1, strKey); +#endif +} + float NSClient::GetInfoKeyFloat(string strKey) { +#ifdef SERVER return infokeyf(this, strKey); +#endif + +#ifdef CLIENT + return getplayerkeyfloat(entnum-1, strKey); +#endif } -#endif void NSClient::SharedInputFrame(void) diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index 598b12b5..48b83d64 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSClientSpectator.qc b/src/shared/NSClientSpectator.qc index c50e0a62..f88ed487 100644 --- a/src/shared/NSClientSpectator.qc +++ b/src/shared/NSClientSpectator.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSDebris.qc b/src/shared/NSDebris.qc index 7373adf9..d63af324 100644 --- a/src/shared/NSDebris.qc +++ b/src/shared/NSDebris.qc @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2023-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + #ifdef CLIENT void NSDebris::NSDebris(void) @@ -17,4 +33,4 @@ NSDebris::SetImpactDecal(string impactDecal) { m_strImpactDecal = impactDecal; } -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSEntity.h b/src/shared/NSEntity.h index d61a1a52..d8ed2b30 100644 --- a/src/shared/NSEntity.h +++ b/src/shared/NSEntity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -147,6 +147,9 @@ public: /** Unsets any any angle related values within the entity. */ nonvirtual void ClearAngles(void); + + /** Forces the entity to re-network updates to all clients. */ + nonvirtual void ForceNetworkUpdate(void); #endif /* sets */ @@ -202,6 +205,11 @@ public: /** Remove one or more special flags from the entity. */ nonvirtual void RemoveFlags(float); + /** Turns to the specified angle. */ + nonvirtual void TurnTo(float); + /** Turns towards the specified position. */ + nonvirtual void TurnToPos(vector); + /** Overrides the Think function of the entity. Only use it when you want to retain a think timer that's already been set for the entity. */ nonvirtual void SetThink(void()); @@ -399,4 +407,4 @@ NSEntity_SpawnClass(string className, vector spawnOrigin, vector spawnAngles) setorigin(output, spawnOrigin); self = oldSelf; return output; -} \ No newline at end of file +} diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index adfe9253..4b0f5179 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -39,7 +39,7 @@ void NSEntity::Spawned( void ) { #ifdef SERVER m_oldstrTarget = target; - if ( m_oldModel ) { + if ( m_oldModel && m_oldModel != "" ) { precache_model( GetSpawnModel() ); } @@ -332,7 +332,11 @@ void NSEntity::RestoreAngles( void ) { } void NSEntity::ClearAngles( void ) { - angles =[0, 0, 0]; + angles = [0, 0, 0]; +} + +void NSEntity::ForceNetworkUpdate( void ) { + SendFlags = -1; } #endif @@ -532,6 +536,14 @@ void NSEntity::RemoveFlags( float fl ) { flags &= ~fl; } +void NSEntity::TurnTo( float targetAngle ) { + angles[1] = targetAngle; +} + +void NSEntity::TurnToPos( vector targetPos ) { + angles = vectoangles(targetPos - WorldSpaceCenter()); +} + void NSEntity::SetThink( void ( void ) func ) { think = func; } @@ -546,7 +558,7 @@ void NSEntity::SetNextThink( float fl ) { if ( flTime >= 0 ) nextthink = flTime; else - NSLog( "%s sets bogus nextthink value %f\n", classname, flTime ); + EntError( "%s sets bogus nextthink value %f\n", classname, flTime ); } void NSEntity::ScheduleThink( void ( void ) func, float fl ) { @@ -676,13 +688,11 @@ void NSEntity::ClearVelocity( void ) { #ifdef SERVER void NSEntity::Respawn( void ) { - NSTrigger::Respawn(); - + super::Respawn(); SetSolid( m_oldSolid ); SetAngles( GetSpawnAngles() ); SetOrigin( GetSpawnOrigin() ); SetModel( GetSpawnModel() ); - SetTriggerTarget( m_oldstrTarget ); /* FIXME: Move into NSTrigger::Respawn */ } void NSEntity::Save( float handle ) { @@ -690,6 +700,7 @@ void NSEntity::Save( float handle ) { SaveFloat( handle, "pvsflags", pvsflags ); SaveFloat( handle, "_mapspawned", _mapspawned ); SaveFloat( handle, "scale", scale ); + SaveFloat( handle, "friction", friction ); SaveVector( handle, "m_vecMins", m_vecMins ); SaveVector( handle, "m_vecMaxs", m_vecMaxs ); SaveVector( handle, "m_oldOrigin", m_oldOrigin ); @@ -714,6 +725,9 @@ void NSEntity::Restore( string strKey, string strValue ) { case "scale": scale = ReadFloat( strValue ); break; + case "friction": + friction = ReadFloat( strValue ); + break; case "m_vecMins": m_vecMins = ReadVector( strValue ); break; @@ -857,6 +871,9 @@ void NSEntity::SpawnKey( string strKey, string strValue ) { case "solid": solid = ReadFloat( strValue ); break; + case "friction": + friction = ReadFloat( strValue ); + break; #ifdef SERVER case "health": health = ReadFloat( strValue ); @@ -875,6 +892,8 @@ void NSEntity::SpawnKey( string strKey, string strValue ) { break; #endif + case "_minlight": + break; default: super::SpawnKey( strKey, strValue ); break; @@ -888,6 +907,10 @@ void NSEntity::Destroy( void ) { removed = 1; /* mark this as cleanly removed */ OnRemoveEntity(); customphysics = __NULL__; + modelindex = 0; + solid = 0; + movetype = 0; + classname = 0; ScheduleThink(Util_Destroy, 0.0f ); } @@ -960,13 +983,13 @@ bool NSEntity::StartSound( string strSample, float channel, float flags, bool br #endif } - SndLog( "^2%s::^3StartSound^7: %s (chan: %d bcast: %d) (%v)", classname, strSample, channel, broadcast, origin ); + SndEntLog( "%s (chan: %d bcast: %d) (%v)", strSample, channel, broadcast, origin ); return ( true ); } bool NSEntity::StartSoundDef( string strSample, float channel, bool broadcast ) { - SndLog( "^2%s::^3StartSoundDef^7: %s (chan: %d bcast: %d)", classname, strSample, channel, broadcast ); + SndEntLog( "%s (chan: %d bcast: %d)", strSample, channel, broadcast ); Sound_Play( this, channel, strSample ); return ( true ); } @@ -1108,4 +1131,4 @@ NSEntity::GetNearbySpot(void) return testPos; return g_vec_null; -} \ No newline at end of file +} diff --git a/src/shared/NSIO.h b/src/shared/NSIO.h index 87e5b6f6..65ef6bd7 100644 --- a/src/shared/NSIO.h +++ b/src/shared/NSIO.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -137,3 +137,47 @@ public: }; .bool _mapspawned; + +void +_NSEntLog(string className, string functionName, float edictNum, string warnMessage) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^7%s (%d)^7: %s\n", time, className, edictNum, warnMessage)); + else + print(sprintf("^7%s (%d)^7: %s\n", className, edictNum, warnMessage)); +} + +void +_NSEntWarning(string className, string functionName, float edictNum, string warnMessage) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^3%s (%d)^7: %s\n", time, functionName, edictNum, warnMessage)); + else + print(sprintf("^3%s (%d)^7: %s\n", functionName, edictNum, warnMessage)); +} + +void +_NSEntError(string className, string functionName, float edictNum, string warnMessage) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^1%s (id: %d)^7: %s\n", time, functionName, edictNum, warnMessage)); + else + print(sprintf("^1%s (id: %d)^7: %s\n", functionName, edictNum, warnMessage)); +} +/** Logs an entity class specific log message, with detailed info. + The console variable `entity_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define EntLog(...) if (autocvar_g_developer) _NSEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) + +/** Logs an entity class specific warning message, with detailed info. + The console variable `entity_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define EntWarning(...) _NSEntWarning(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) + +/** Logs an entity class specific error message, with detailed info. + The console variable `entity_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define EntError(...) _NSEntError(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index 6a264523..9cdfe66b 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -204,7 +204,7 @@ NSIO::CreateOutput(string outmsg) NSLog("Input: %s", new_minion.m_strInput); NSLog("Data Message: %s", new_minion.m_strData); NSLog("Delay: %f", new_minion.m_flDelay); - NSLog("Uses: %i\n", new_minion.m_iCount); + NSLog("Uses: %i", new_minion.m_iCount); } /* return the name that'll act as the trigger for all outputs */ @@ -251,12 +251,13 @@ NSIO::Input(entity eAct, string strInput, string strData) UseOutput(eAct, m_strOnUser4); break; default: - if (strData != "") - NSLog("^2%s::^3Input^7: Receives input %s from %s with data %s\n", - this.classname, strInput, eAct.classname, strData); - else - NSLog("^2%s::^3Input^7: Receives input %s from %s\n", - this.classname, strInput, eAct.classname); + if (strData != "") { + EntWarning("Receives unknown input %S from %d with data %S", + strInput, num_for_edict(eAct), strData); + } else { + EntWarning("Receives unknown input %S from %d", + strInput, num_for_edict(eAct)); + } } } @@ -737,8 +738,10 @@ NSIO::SpawnKey(string strKey, string strValue) break; #endif default: - NSLog("^3%s^7::SpawnKey:: Unknown key '%s' with value '%s'", +#ifdef SERVER + EntWarning("%s has unknown key %S with value %S", classname, strKey, strValue); +#endif break; } } @@ -753,4 +756,4 @@ float NSIO::GetTime(void) { return (movetype == MOVETYPE_PUSH) ? ltime : time; -} \ No newline at end of file +} diff --git a/src/shared/NSItem.qc b/src/shared/NSItem.qc index 6c0e9b9b..11f065d7 100644 --- a/src/shared/NSItem.qc +++ b/src/shared/NSItem.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSMonster.h b/src/shared/NSMonster.h index 84f1c64c..598f3917 100644 --- a/src/shared/NSMonster.h +++ b/src/shared/NSMonster.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,12 +16,14 @@ var bool autocvar_ai_debugLogic = false; void -_NSMonster_Log(string msg) +_NSMonster_Log(string className, string functionName, float edictNum, string warnMessage) { - if (autocvar_ai_debugLogic == true) - print(sprintf("%f %s\n", time, msg)); + if (autocvar_g_developerTimestamps) + printf("^9%f ^5%s (%d) ^7: %s\n", time, functionName, edictNum, warnMessage); + else + printf("^5%s (%d) ^7: %s\n", functionName, edictNum, warnMessage); } -#define NSMonster_Log(...) _NSMonster_Log(sprintf(__VA_ARGS__)) +#define NSMonsterLog(...) if (autocvar_ai_debugLogic == true) _NSMonster_Log(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) /** Bitfield enumeration for NSMonster its SendFlags field. diff --git a/src/shared/NSMonster.qc b/src/shared/NSMonster.qc index e87ecb95..2fe32020 100644 --- a/src/shared/NSMonster.qc +++ b/src/shared/NSMonster.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -604,7 +604,7 @@ NSMonster::AlertNearby(void) if (vlen(origin - w.origin) > 512) continue; - //NSMonster_Log("Alert! %s get %s", w.classname, m_eEnemy.classname); + //NSMonsterLog("Alert! %s get %s", w.classname, m_eEnemy.classname); NSMonster f = (NSMonster)w; /* we shouldn't override this when they already got a target */ @@ -663,6 +663,10 @@ NSMonster_TraceAgainsTarget(NSMonster monster, NSEntity target) void NSMonster::SeeThink(void) { + if (HasSpawnFlags(MSF_PRISONER) == true) { + return; + } + if (m_eLookAt) { vector vecDelta; makevectors( angles ); @@ -675,7 +679,7 @@ NSMonster::SeeThink(void) makevectors(v_angle); vector tmp = vectoangles(v_forward); subblendfrac = tmp[0] / 90; - bonecontrol1 = m_flHeadYaw; /* head turning */ + bonecontrol1 = Math_Lerp(bonecontrol1, m_flHeadYaw, frametime * 15.0f); /* head turning */ } } @@ -983,7 +987,7 @@ NSMonster::AttackRanged(void) } static void AttackRanged_RangedSpecial(void) { - NSMonster_Log("AttackRanged_RangedSpecial: %S", m_defRanged2); + NSMonsterLog("AttackRanged_RangedSpecial: %S", m_defRanged2); NSProjectile_SpawnDef(m_defRanged2, this); } @@ -1001,7 +1005,7 @@ NSMonster::AttackRanged(void) if (_m_flReloadTracker > m_flReloadCount) { throwAnyway = true; _m_bShouldThrow = true; - NSMonster_Log("throwAnyway: true!"); + NSMonsterLog("throwAnyway: true!"); } /* special always first if possible */ @@ -1027,14 +1031,14 @@ NSMonster::AttackRanged(void) /* out of ammo, cannot reload */ if (m_flReserveAmmo == 0) { - //NSMonster_Log("Out of ammo!"); + //NSMonsterLog("Out of ammo!"); return 0; } /* do we not have unlimited ammo? */ if (m_flReserveAmmo != -1) { m_flReserveAmmo -= m_flReloadCount; - NSMonster_Log("Reserve ammo: %d", m_flReserveAmmo); + NSMonsterLog("Reserve ammo: %d", m_flReserveAmmo); /* oh no, we're below 0 in terms of ammo. */ if (m_flReserveAmmo < 0) { @@ -1043,7 +1047,7 @@ NSMonster::AttackRanged(void) } } - NSMonster_Log("Starting at %d bullets", startAmmo); + NSMonsterLog("Starting at %d bullets", startAmmo); _m_flReloadTracker = startAmmo; AnimPlay(actReload); StartSoundDef(m_sndReload, CHAN_WEAPON, true); @@ -1051,11 +1055,11 @@ NSMonster::AttackRanged(void) if (m_flReloadDelay) { m_flAttackThink = time + m_flReloadDelay; - NSMonster_Log("Reloading, delay %f seconds", m_flReloadDelay); + NSMonsterLog("Reloading, delay %f seconds", m_flReloadDelay); } else { float actDuration = frameduration(modelindex, actReload); m_flAttackThink = time + actDuration; - NSMonster_Log("Reloading, act delays it by %f seconds", actDuration); + NSMonsterLog("Reloading, act delays it by %f seconds", actDuration); } return 1; @@ -1068,10 +1072,10 @@ NSMonster::AttackRanged(void) if (m_defRanged1) if (EntityDef_HasSpawnClass(m_defRanged1)) { NSProjectile_SpawnDef(m_defRanged1, this); - NSMonster_Log("Firing ranged def %S", m_defRanged1); + NSMonsterLog("Firing ranged def %S", m_defRanged1); } else { TraceAttack_FireBullets(1, GetEyePos(), rangedDmg, [0.01,0.01] * m_flAttackAccuracy, 0); - NSMonster_Log("Firing traceline def with %d", rangedDmg); + NSMonsterLog("Firing traceline def with %d", rangedDmg); } StartSoundDef(m_sndRangedAttack, CHAN_WEAPON, true); @@ -1086,11 +1090,11 @@ NSMonster::AttackRanged(void) if (rangedDly) { m_flAttackThink = time + rangedDly + burstTime; - NSMonster_Log("Primary ranged attack, delay %f seconds (burst %d)", rangedDly, burstTime); + NSMonsterLog("Primary ranged attack, delay %f seconds (burst %d)", rangedDly, burstTime); } else { float actAttackTime = frameduration(modelindex, actRanged); m_flAttackThink = time + actAttackTime + burstTime; - NSMonster_Log("Primary ranged attack, act delays it by %f seconds (burst %f)", actAttackTime, burstTime); + NSMonsterLog("Primary ranged attack, act delays it by %f seconds (burst %f)", actAttackTime, burstTime); } return 1; @@ -1173,7 +1177,7 @@ NSMonster::FreeState(void) NSEntity findKT = (NSEntity)find(world, ::targetname, m_strSequenceKillTarget); if (findKT) { - NSMonster_Log("^2%s::^3FreeState^7: Killing %S", classname, m_strSequenceKillTarget); + NSMonsterLog("Killing %S", m_strSequenceKillTarget); findKT.Destroy(); } else { error("Could not remove scripted killtarget!\n"); @@ -1207,7 +1211,8 @@ NSMonster::FreeState(void) if (m_iSequenceRemove) { Hide(); } - NSMonster_Log("^2%s::^3FreeState^7: (%i, %S)", classname, m_iSequenceRemove, to_trigger); + + NSMonsterLog("Sequence over (hidden: %i, triggering: %S)", m_iSequenceRemove, to_trigger); } void @@ -1215,7 +1220,7 @@ NSMonster::FreeStateMoved(void) { vector new_origin; new_origin = gettaginfo(this, 1); - NSMonster_Log("^2%s::^3FreeStateMoved^7: moved to %v", classname, new_origin); + NSMonsterLog("Moved to %v", new_origin); SetOrigin(new_origin); DropToFloor(); FreeState(); @@ -1227,7 +1232,7 @@ NSMonster::FreeStateDead(void) vector new_origin; new_origin = gettaginfo(this, 1); - NSMonster_Log("^2%s::^3FreeStateMoved^7: moved to %v", classname, new_origin); + NSMonsterLog("Moved to %v", new_origin); SetOrigin(new_origin); DropToFloor(); @@ -1251,14 +1256,14 @@ NSMonster::RouteEnded(void) m_iSequenceState = SEQUENCESTATE_ENDING; think = (m_iSequenceFlags & SSFL_NOSCRIPTMOVE) ? FreeState : FreeStateMoved; nextthink = time + duration; - NSMonster_Log("^2%s::^3RouteEnded^7: %s overriding anim for %f seconds (modelindex %d, frame %d)", \ - classname, this.targetname, duration, modelindex, m_flSequenceEnd); + NSMonsterLog("%s overriding anim for %f seconds (modelindex %d, frame %d)", \ + this.targetname, duration, modelindex, m_flSequenceEnd); } else { /* we still need to trigger targets */ think = (m_iSequenceFlags & SSFL_NOSCRIPTMOVE) ? FreeState : FreeStateMoved; nextthink = time; - NSMonster_Log("^2%s::^3RouteEnded^7: %s has no anim, finished sequence", \ - classname, this.targetname); + NSMonsterLog("%s has no anim, finished sequence", \ + this.targetname); } } @@ -2279,7 +2284,7 @@ NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) return; if (autocvar_ai_debugAlerts) - NSMonster_Log("AI alert from %v with radius %f and alliance %i", pos, radius, alliance); + NSLog("AI alert from %v with radius %f and alliance %i", pos, radius, alliance); for (entity w = world; (w = nextent(w));) { if (w.takedamage == DAMAGE_NO) @@ -2293,7 +2298,7 @@ NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) /* only target monsters */ if (!(w.flags & FL_MONSTER)) { if (autocvar_ai_debugAlerts) - NSMonster_Log("\t%S is not a monster", w.classname); + NSLog("\t%S is not a monster", w.classname); continue; } @@ -2302,26 +2307,26 @@ NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) /* they already got a target of some kind */ if (f.m_eEnemy) { if (autocvar_ai_debugAlerts) - NSMonster_Log("\t%S already has a target", w.classname); + NSLog("\t%S already has a target", w.classname); continue; } /* if they're our friend... ignore*/ if (f.IsFriend(alliance)) { if (autocvar_ai_debugAlerts) - NSMonster_Log("\t%S is friend of alliance %i", w.classname, alliance); + NSLog("\t%S is friend of alliance %i", w.classname, alliance); continue; } /* if the monster is dead... ignore */ if (f.health <= 0) { if (autocvar_ai_debugAlerts) - NSMonster_Log("\t%S is dead, cannot be alerted", w.classname); + NSLog("\t%S is dead, cannot be alerted", w.classname); continue; } if (autocvar_ai_debugAlerts) - NSMonster_Log("\twe're alerting %S to go to %v", w.classname, pos); + NSLog("\twe're alerting %S to go to %v", w.classname, pos); /* we've heard a noise. investigate the location */ f.RouteClear(); diff --git a/src/shared/NSMoverEntity.qc b/src/shared/NSMoverEntity.qc index a5d2b0cc..24b78d05 100644 --- a/src/shared/NSMoverEntity.qc +++ b/src/shared/NSMoverEntity.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2023-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -203,6 +203,9 @@ NSMoverEntity::GetMoverRotation2(void) void NSMoverEntity::MoveToPosition(vector vecDest, float flSpeed) { + if (vecDest == origin) + return; + MoveAndRotateToPosition(vecDest, GetAngles(), flSpeed); } @@ -240,7 +243,7 @@ NSMoverEntity::MoveAndRotateToPosition(vector vecDest, vector vecAngle, float fl /* abort if no speed is defined whatsoever */ if (!flSpeed) { - NSEntWarning("NSMoverEntity::MoveToPosition: No speed defined!"); + EntWarning("NSMoverEntity::MoveToPosition: No speed defined!"); return; } @@ -261,7 +264,6 @@ NSMoverEntity::MoveAndRotateToPosition(vector vecDest, vector vecAngle, float fl /* if we're already there, don't bother and trigger it right now. */ if (fTravelTime <= 0.0) { - if (m_moverState == MOVER_1TO2) { MoverStartsMoving(); _ArrivedAtRotPosition2(); @@ -379,4 +381,4 @@ NSMoverEntity::MoverStartsMoving(void) void NSMoverEntity::MoverFinishesMoving(void) { -} \ No newline at end of file +} diff --git a/src/shared/NSNavAI.h b/src/shared/NSNavAI.h index 787b3ff8..a9db8e30 100644 --- a/src/shared/NSNavAI.h +++ b/src/shared/NSNavAI.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSNavAI.qc b/src/shared/NSNavAI.qc index 72d747ee..1b17656d 100644 --- a/src/shared/NSNavAI.qc +++ b/src/shared/NSNavAI.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -97,8 +97,7 @@ NSNavAI::CheckRoute_Path(void) /* close enough...? */ if (flDist < 80) { - NSNavAI_Log("^2%s::^3CheckRoute_Path^7: " \ - "reached path node %s", classname, m_pathTarget); + NSNavAI_Log("Reached path node %S", m_pathTarget); m_pathTarget = m_pathEntity.target; m_pathEntity = (NSEntity)m_pathEntity.GetTargetEntity(); @@ -127,12 +126,10 @@ NSNavAI::CheckRoute(void) /* HACK: for followers */ if (m_eFollowing) { RouteToPosition(m_eFollowing.origin); - NSNavAI_Log("^2%s::^3CheckRoute^7: " \ - "Giving up current route to follower, re-calculating", classname); + NSNavAI_Log("Giving up current route to follower, re-calculating"); } else { RouteToPosition(m_vecLastNode); - NSNavAI_Log("^2%s::^3CheckRoute^7: " \ - "Giving up current route, re-calculating", classname); + NSNavAI_Log("Giving up current route, re-calculating."); } } _m_flRouteGiveUp = time + 2.0f; @@ -156,8 +153,7 @@ NSNavAI::CheckRoute(void) flDist = floor(vlen(evenpos - origin)); if (flDist < flNodeRadius) { - NSNavAI_Log("^2%s::^3CheckRoute^7: " \ - "%s reached node", classname, targetname); + NSNavAI_Log("%S reached node", targetname); m_iCurNode--; velocity = [0,0,0]; /* clamp friction */ @@ -168,8 +164,7 @@ NSNavAI::CheckRoute(void) /* can we walk directly to our target destination? */ if (trace_fraction == 1.0) { - NSNavAI_Log("^2%s::^3CheckRoute^7: Walking directly to last node at '%v'", \ - classname, m_vecLastNode); + NSNavAI_Log("Walking directly to last node at '%v'", m_vecLastNode); m_iCurNode = -1; } } @@ -188,8 +183,7 @@ NSNavAI::CheckRoute(void) if (!trace_startsolid && trace_fraction == 1.0f) { evenpos = vecNextNode; m_iCurNode = iNextNode; - NSNavAI_Log("^2%s::^3CheckRoute^7: skipping to next node %i at '%v'", \ - classname, iNextNode, vecNextNode); + NSNavAI_Log("Skipping to next node %i at '%v'", iNextNode, vecNextNode); return; } } @@ -199,7 +193,7 @@ NSNavAI::CheckRoute(void) if (m_iCurNode < -1) { RouteClear(); RouteEnded(); - NSNavAI_Log("^2%s::^3CheckRoute^7: %s reached end", classname, targetname); + NSNavAI_Log("%S reached end", targetname); } /* crouch attempt */ @@ -304,12 +298,10 @@ NSNavAI::RouteToPositionDenyFlags(vector destination, int denylinkflags) /* can we walk directly to our target destination? */ if (trace_fraction == 1.0) { - NSNavAI_Log("^2%s::^3RouteToPosition^7: " \ - "Walking directly to last node", p.classname); + NSNavAI_Log("Walking directly to last node"); p.m_iCurNode = -1; } else { - NSNavAI_Log("^2%s::^3RouteToPosition^7: " \ - "Path obstructed, calculating route", p.classname); + NSNavAI_Log("Path obstructed, calculating route"); /* run through all nodes, mark the closest direct path possible */ for (int i = 0; i < p.m_iNodes; i++) { @@ -354,7 +346,7 @@ NSNavAI::ChasePath(string startPath) m_pathTarget = startPath; m_pathEntity = (NSEntity)find(world, ::targetname, m_pathTarget); - NSNavAI_Log("Actor %S chase Path set to %S\n", netname, m_pathEntity.targetname); + NSNavAI_Log("Actor %S chase Path set to %S", netname, m_pathEntity.targetname); } void diff --git a/src/shared/NSPhysicsConstraint.qc b/src/shared/NSPhysicsConstraint.qc index 93fee309..faa27a53 100644 --- a/src/shared/NSPhysicsConstraint.qc +++ b/src/shared/NSPhysicsConstraint.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2023-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -328,7 +328,7 @@ NSPhysicsConstraint::Ballsocket(entity firstEnt, entity secondEnt, vector pos1, new.velocity = pos2; new.WakeTargets(); - print(sprintf("Created ballsocket between %s and %s\n", firstEnt.classname, secondEnt.classname)); + EntLog("Created ballsocket between %S and %S.", firstEnt.classname, secondEnt.classname); return new; } @@ -336,7 +336,7 @@ NSPhysicsConstraint NSPhysicsConstraint::Weld(entity firstEnt, entity secondEnt, float bone1, float bone2, float forceLimit, bool noCollide, bool deleteEnt1OnBreak) { if (firstEnt == secondEnt) { - print("^1Cannot weld the entity with itself!\n"); + EntError("Cannot weld the entity with itself!"); return __NULL__; } @@ -346,7 +346,7 @@ NSPhysicsConstraint::Weld(entity firstEnt, entity secondEnt, float bone1, float new.SetEntity2(secondEnt); new.WakeTargets(); - print(sprintf("Created weld between %s and %s\n", firstEnt.classname, secondEnt.classname)); + EntLog("Created weld between %S and %S.", firstEnt.classname, secondEnt.classname); return new; } @@ -361,7 +361,7 @@ NSPhysicsConstraint::Rope(entity firstEnt, entity secondEnt, vector pos1, vector new.velocity = pos2; new.WakeTargets(); - print(sprintf("Created rope between %s and %s\n", firstEnt.classname, secondEnt.classname)); + EntLog("Created rope between %S and %S", firstEnt.classname, secondEnt.classname); return new; } diff --git a/src/shared/NSPhysicsEntity.qc b/src/shared/NSPhysicsEntity.qc index c9f1fb65..ed5d5aab 100644 --- a/src/shared/NSPhysicsEntity.qc +++ b/src/shared/NSPhysicsEntity.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -502,7 +502,6 @@ NSPhysicsEntity::_TouchThink(void) if (NSPhysicsEntity_Contents(origin) & CONTENTBIT_WATER) { makevectors([0,0,0]); velocity[2] += m_flBuoyancyRatio; - print(sprintf("in water... applying %v\n", v_up * (GetMass() * m_flBuoyancyRatio))); } #endif @@ -688,7 +687,7 @@ NSPhysicsEntity::SpawnKey(string strKey, string strValue) vector NSPhysicsEntity::AlignAngles(vector from, vector to) { - NSEntWarning("Not implemented"); + EntWarning("Not implemented"); return angles; } @@ -762,7 +761,7 @@ NSPhysicsEntity::ApplyTorqueCenter(vector vecTorque) void NSPhysicsEntity::EnableDrag(bool setEnabled) { - NSEntWarning("Not implemented"); + EntWarning("Not implemented"); } void @@ -775,7 +774,7 @@ NSPhysicsEntity::EnableGravity(bool setEnabled) void NSPhysicsEntity::EnableMotion(bool setEnabled) { - NSEntWarning("Not implemented"); + EntWarning("Not implemented"); } float @@ -904,7 +903,7 @@ NSPhysicsEntity::IsPenetrating(void) void NSPhysicsEntity::SetAngleDragCoefficient(float setValue) { - NSEntWarning("Not implemented"); + EntWarning("Not implemented"); } void @@ -923,7 +922,7 @@ NSPhysicsEntity::SetDamping(float linearDamp, float angleDamp) void NSPhysicsEntity::SetDragCoefficient(float dragValue) { - NSEntWarning("Not implemented"); + EntWarning("Not implemented"); } void @@ -993,4 +992,4 @@ NSPhysicsEntity::Sleep(void) SetSolid(SOLID_BBOX); } m_iEnabled = FALSE; -} \ No newline at end of file +} diff --git a/src/shared/NSPointTrigger.qc b/src/shared/NSPointTrigger.qc index 784f9033..5d78a471 100644 --- a/src/shared/NSPointTrigger.qc +++ b/src/shared/NSPointTrigger.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSPortal.h b/src/shared/NSPortal.h index d1c52a05..dd7dabce 100644 --- a/src/shared/NSPortal.h +++ b/src/shared/NSPortal.h @@ -28,7 +28,9 @@ typedef enumflags PORTALFL_CHANGED_TARG_ORIGIN_Z, PORTALFL_CHANGED_TARG_ANGLES_X, PORTALFL_CHANGED_TARG_ANGLES_Y, - PORTALFL_CHANGED_TARG_ANGLES_Z + PORTALFL_CHANGED_TARG_ANGLES_Z, + PORTALFL_CHANGED_ENABLED, + PORTALFL_CHANGED_MODELINDEX } nsportal_changed_t; class @@ -50,28 +52,40 @@ NSPortal:NSEntity virtual void EvaluateEntity(void); virtual float SendEntity(entity, float); + virtual void PortalWasClosed(void); + virtual void PortalWasOpened(void); + /** Sets the NSPortal ID. Only used to link portals together via PortalAutoLink. */ nonvirtual void SetPortalID(int); /** Will link this portal to another NSPortal. */ - nonvirtual bool PortalLinkTo(NSPortal); + nonvirtual bool PortalLinkTo(NSPortal, bool); /** Will link this portal to the youngest other NSPortal. */ - nonvirtual void PortalAutoLink(void); + nonvirtual void PortalAutoLink(bool); + /** Closes the portal, will not remove it from world. */ + nonvirtual void PortalClose(void); + /** Sets the model to use for the portal. */ + nonvirtual void SetPortalModel(string); #endif #ifdef CLIENT virtual void ReceiveEntity(float, float); + virtual float predraw(void); #endif private: NSPortal m_ePortalTarget; NSPortal m_ePortalTarget_net; - PREDICTED_VECTOR(m_vecTargetPos) - PREDICTED_VECTOR(m_vecTargetAngle) + NETWORKED_VECTOR(m_vecTargetPos) + NETWORKED_VECTOR(m_vecTargetAngle) + NETWORKED_BOOL(m_bEnabled) + NETWORKED_FLOAT(m_flPortalModel) vector m_vecPortalPos; vector m_vecPortalN; vector m_vecPortalS; vector m_vecPortalT; + bool m_bWasEnabled; + /** Will transport an entity from its position to the exit position. */ nonvirtual void TransportEntity(NSEntity); @@ -80,6 +94,7 @@ private: vector m_vecTargetN; vector m_vecTargetS; vector m_vecTargetT; + float m_flSize; #endif #ifdef SERVER @@ -98,7 +113,8 @@ private: } #endif -#define SOLID_PORTAL 21 +#define SOLID_PORTAL 21 -.float portalnum; -.float impulse; //used as the radius for the solid_portal csg subtraction \ No newline at end of file +.float portalnum; +.float impulse; //used as the radius for the solid_portal csg subtraction +.bool isPortal; \ No newline at end of file diff --git a/src/shared/NSPortal.qc b/src/shared/NSPortal.qc index c7ee4c62..1eff1d74 100644 --- a/src/shared/NSPortal.qc +++ b/src/shared/NSPortal.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2024 Vera Visions LLC. * Copyright (c) 2014 David Walton * * Permission to use, copy, modify, and distribute this software for any @@ -30,6 +30,8 @@ NSPortal::NSPortal(void) m_vecPortalS = g_vec_null; m_vecPortalT = g_vec_null; m_brushNum = -1; + m_bEnabled = false; + isPortal = true; #ifdef CLIENT m_vecTargetPos = g_vec_null; @@ -47,10 +49,14 @@ NSPortal::NSPortal(void) /* unique portal IDs */ { float numPortals = 0; - for (NSPortal e = __NULL__; (e = (NSPortal)find(e, ::classname, "NSPortal"));) { + for (NSPortal e = __NULL__; (e = (NSPortal)findfloat(e, ::isPortal, true));) { e.portalnum = numPortals++; } } + + /* default fallback */ + precache_model("models/b_portal.bsp"); + SetPortalModel("models/b_portal.bsp"); #endif } @@ -104,7 +110,7 @@ NSPortal::Restore(string strKey, string strValue) } void -NSPortal::PortalAutoLink(void) +NSPortal::PortalAutoLink(bool openPortal) { /* this just links against the youngest portal of the same ID at this time */ NSPortal youngestPortal, oldestPortal; @@ -113,7 +119,7 @@ NSPortal::PortalAutoLink(void) float oldestTime = 0.0f; /* delete any portal with the same id */ - for (NSPortal e = __NULL__; (e = (NSPortal)find(e, ::classname, "NSPortal"));) { + for (NSPortal e = __NULL__; (e = (NSPortal)findfloat(e, ::isPortal, true));) { if (e == this) continue; @@ -132,24 +138,43 @@ NSPortal::PortalAutoLink(void) /* remove the first portal from the world */ if (youngestPortal != oldestPortal) { - oldestPortal.Destroy(); + oldestPortal.PortalClose(); } - PortalLinkTo(youngestPortal); + PortalLinkTo(youngestPortal, openPortal); +} + +void +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_ePortalTarget = __NULL__; + m_ePortalTarget._PortalUpdated(); + } + + /* now kill our own reference */ + m_ePortalTarget = __NULL__; + m_bEnabled = false; + _PortalUpdated(); } bool -NSPortal::PortalLinkTo(NSPortal target) +NSPortal::PortalLinkTo(NSPortal target, bool openPortal) { m_ePortalTarget = target; - skin = m_ePortalTarget ? 0 : 1; - SendFlags |= 1; + + m_bEnabled = openPortal; + + SendFlags = -1; _PortalUpdated(); if (m_ePortalTarget) { m_ePortalTarget.m_ePortalTarget = this; - m_ePortalTarget.skin = skin; - m_ePortalTarget.SendFlags |= 1; + m_ePortalTarget.m_bEnabled = openPortal; + m_ePortalTarget.SendFlags = -1; m_ePortalTarget._PortalUpdated(); } @@ -161,6 +186,22 @@ NSPortal::SetPortalID(int value) { m_iPortalValue = value; } + +void +NSPortal::SetPortalModel(string modelPath) +{ + m_flPortalModel = getmodelindex(modelPath); +} + +void +NSPortal::PortalWasOpened(void) +{ +} + +void +NSPortal::PortalWasClosed(void) +{ +} #endif void @@ -179,9 +220,29 @@ NSPortal::_PortalUpdated(void) /* expand the size of the object along the plane, and set up a portal region. */ movetype = MOVETYPE_NONE; - solid = skin ? SOLID_BSP : SOLID_PORTAL; - precache_model("models/b_portal.bsp"); - setmodel(this, "models/b_portal.bsp"); + + if (m_bEnabled == true) { + solid = SOLID_PORTAL; + setmodel(this, modelnameforindex(m_flPortalModel)); + if (m_bWasEnabled == false) { + m_bWasEnabled = true; +#ifdef SERVER + PortalWasOpened(); +#endif +#ifdef CLIENT + m_flSize = 0.0f; +#endif + } + } else { + if (m_bWasEnabled == true) { + m_bWasEnabled = false; +#ifdef SERVER + PortalWasClosed(); +#endif + } + solid = SOLID_BSP; + //modelindex = 0; + } /* determine size of major axis */ float portalSize = max(size[0], size[1], size[2]); @@ -374,6 +435,8 @@ NSPortal::EvaluateEntity(void) EVALUATE_VECTOR(m_vecTargetAngle, 0, PORTALFL_CHANGED_TARG_ANGLES_X) EVALUATE_VECTOR(m_vecTargetAngle, 1, PORTALFL_CHANGED_TARG_ANGLES_Y) EVALUATE_VECTOR(m_vecTargetAngle, 2, PORTALFL_CHANGED_TARG_ANGLES_Z) + EVALUATE_FIELD(m_bEnabled, PORTALFL_CHANGED_ENABLED) + EVALUATE_FIELD(m_flPortalModel, PORTALFL_CHANGED_MODELINDEX) } float @@ -399,6 +462,9 @@ NSPortal::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(m_vecTargetAngle[2], PORTALFL_CHANGED_TARG_ANGLES_Z) } + SENDENTITY_BYTE(m_bEnabled, PORTALFL_CHANGED_ENABLED) + SENDENTITY_FLOAT(m_flPortalModel, PORTALFL_CHANGED_MODELINDEX) + return (true); } #endif @@ -427,13 +493,15 @@ NSPortal::ReceiveEntity(float flNew, float flChanged) READENTITY_FLOAT(m_vecTargetAngle[1], PORTALFL_CHANGED_TARG_ANGLES_Y) READENTITY_FLOAT(m_vecTargetAngle[2], PORTALFL_CHANGED_TARG_ANGLES_Z) + READENTITY_BYTE(m_bEnabled, PORTALFL_CHANGED_ENABLED) + READENTITY_FLOAT(m_flPortalModel, PORTALFL_CHANGED_MODELINDEX) + if (m_ePortalTarget) { if (m_ePortalTarget.m_ePortalTarget) m_ePortalTarget.m_ePortalTarget.m_ePortalTarget = __NULL__; m_ePortalTarget. m_ePortalTarget = this; } else { - skin = 1; makevectors(angles); m_vecTargetPos = origin; m_vecTargetN = v_forward; @@ -443,6 +511,21 @@ NSPortal::ReceiveEntity(float flNew, float flChanged) _PortalUpdated(); drawmask = MASK_ENGINE; - predraw = 0; +// predraw = 0; } -#endif \ No newline at end of file + +float +NSPortal::predraw(void) +{ + scale = m_flSize; + + addentity(this); + + m_flSize += frametime * 10.0f; + + if (m_flSize > 1.0) + m_flSize = 1.0f; + + return PREDRAW_NEXT; +} +#endif diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index 3bccc97d..cc61d965 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -171,4 +171,4 @@ public: NSProjectile NSProjectile_SpawnDef(string entityDef, NSEntity theOwner); NSProjectile NSProjectile_SpawnDefAtPosition(string entityDef, NSEntity theOwner, vector vecOrigin, vector vecAngles); NSProjectile NSProjectile_SpawnDefAttachment(string entityDef, NSEntity theOwner, int attachmentID); -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index 745d3b4c..6bb217bd 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -190,7 +190,7 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "explode_light_color": m_vecExplodeLightColor = ReadVector(strValue); break; - case "explode_light_radus": + case "explode_light_radius": m_fExplodelLightRadius = ReadFloat(strValue); break; case "explode_light_fadetime": @@ -976,4 +976,4 @@ NSProjectile_SpawnDefAttachment(string entityDef, NSEntity theOwner, int attachm rocket.Launch(attachmentPos, theOwner.GetAngles(), 0.0f, 0.0f, 0.0f); return rocket; } -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index 7e6987ba..7704d292 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -985,11 +985,10 @@ NSRenderableEntity::HandleAnimEvent(float flTimeStamp, int iCode, string strData case 1003: /* trigger SSQC entity with specific targetname */ for (entity f = world; (f = find(f, ::targetname, strData));) { NSEntity trigger = (NSEntity)f; + if (trigger.Trigger != __NULL__) { trigger.Trigger(this, TRIG_TOGGLE); - NSLog("^2%s^7::^3ModelEvent^7: " \ - "Calling trigger '%s'\n", - classname, strData); + EntLog("Calling trigger '%s'", strData); } } break; @@ -1017,9 +1016,9 @@ NSRenderableEntity::HandleAnimEvent(float flTimeStamp, int iCode, string strData } //print(sprintf("Received: %f %i %S\n", flTimeStamp, iCode, strData)); - NSLog("SSQC model event: %f %i %S", flTimeStamp, iCode, strData); + EntWarning("Unknown server model event: %f %i %S", flTimeStamp, iCode, strData); #else - NSLog("CSQC model event: %f %i %S", flTimeStamp, iCode, strData); + EntWarning("Unknown client model event: %f %i %S", flTimeStamp, iCode, strData); #endif } } @@ -1110,6 +1109,9 @@ NSRenderableEntity::Input(entity eAct, string strInput, string strData) case "Alpha": SetRenderAmt(stof(strData) / 255); break; + case "Skin": + SetSkin(stof(strData)); + break; case "DisableShadow": effects |= EF_NOSHADOW; break; @@ -1119,7 +1121,7 @@ NSRenderableEntity::Input(entity eAct, string strInput, string strData) case "SetAnimation": float animFrame = frameforname(modelindex, strcat("@", strData)); SetFrame(animFrame); - print(sprintf("SetAnimation: %S (%d) on %S\n",strData, animFrame, model)); + //print(sprintf("SetAnimation: %S (%d) on %S\n",strData, animFrame, model)); break; case "SetBodyInGroup": int argC = tokenize(strData); @@ -1206,4 +1208,4 @@ NSRenderableEntity::SpawnKey(string strKey, string strValue) super::SpawnKey(strKey, strValue); break; } -} \ No newline at end of file +} diff --git a/src/shared/NSSpraylogo.qc b/src/shared/NSSpraylogo.qc index 75a9fb4e..f81a0a41 100644 --- a/src/shared/NSSpraylogo.qc +++ b/src/shared/NSSpraylogo.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/NSSquadMonster.qc b/src/shared/NSSquadMonster.qc index 3a8594f2..d4267b5d 100644 --- a/src/shared/NSSquadMonster.qc +++ b/src/shared/NSSquadMonster.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2023-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -185,7 +185,7 @@ NSSquadMonster::AddToSquad(NSSquadMonster addMember) m_eSquadLeader = this; startMember = this; m_inSquad = true; - NSMonster_Log("%s (%d) became squad leader\n", classname, num_for_edict(this)); + NSMonsterLog("%s (%d) became squad leader\n", classname, num_for_edict(this)); //SetBody(GetBody() | m_iSquadLeaderBody); /* apply the squad leader body */ @@ -211,7 +211,7 @@ NSSquadMonster::AddToSquad(NSSquadMonster addMember) addMember.m_eSquadLeader = startMember; addMember.m_inSquad = true; addMember.HasJoinedSquad(); - NSMonster_Log("%s (%d) added to squad, member %i\n", classname, num_for_edict(this), i); + NSMonsterLog("%s (%d) added to squad, member %i\n", classname, num_for_edict(this), i); return; } } @@ -315,4 +315,4 @@ NSSquadMonster::GetFarthestSquadMember(void) return farthestMember; } -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSSurfacePropEntity.h b/src/shared/NSSurfacePropEntity.h index 2660d013..0f858d21 100644 --- a/src/shared/NSSurfacePropEntity.h +++ b/src/shared/NSSurfacePropEntity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -124,6 +124,16 @@ public: /** Returns how many seconds have passed since we died. Will return -1 if not applicable. */ nonvirtual float TimeSinceDeath(void); + /** Called when a different entity gets damaged by this entity. */ + virtual void DamageFeedback(NSSurfacePropEntity, NSSurfacePropEntity, int); + + /** Sets which function to call upon taking pain. */ + nonvirtual void SetPainCallback(void(void)); + /** Sets which function to call upon taking death. */ + nonvirtual void SetDeathCallback(void(void)); + /** Returns whether this entity reacts to damage being inflicted. */ + nonvirtual bool CanBeDamaged(void); + /** Sets the colour of the blood of this entity. */ nonvirtual void SetBloodColor(vector); /** Returns the blood color of this entity. */ @@ -179,4 +189,4 @@ private: #ifdef CLIENT void NSSurfacePropEntity_ReadEntity(bool); -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSSurfacePropEntity.qc b/src/shared/NSSurfacePropEntity.qc index 2f2c851a..e69bf17f 100644 --- a/src/shared/NSSurfacePropEntity.qc +++ b/src/shared/NSSurfacePropEntity.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,16 +37,17 @@ NSSurfacePropEntity::NSSurfacePropEntity(void) vector NSSurfacePropEntity::GetEyePos(void) { - if (HasFlags(FL_FAKESPEC)) - return origin; + if (HasFlags(FL_FAKESPEC)) { + return (origin); + } - return origin + view_ofs; + return (origin + view_ofs); } vector NSSurfacePropEntity::GetViewAngle(void) { - return v_angle; + return (v_angle); } void @@ -82,7 +83,7 @@ NSSurfacePropEntity::SetBloodColor(vector newColor) vector NSSurfacePropEntity::GetBloodColor(void) { - return m_vecBloodColor; + return (m_vecBloodColor); } bool @@ -100,7 +101,7 @@ NSSurfacePropEntity::SetCanBleed(bool bleedValue) bool NSSurfacePropEntity::CanBleed(void) { - return iBleeds; + return (iBleeds); } void @@ -129,17 +130,17 @@ NSSurfacePropEntity::SetMaxHealth(float new_health) float NSSurfacePropEntity::GetHealth(void) { - return health; + return (health); } float NSSurfacePropEntity::GetMaxHealth(void) { - return max_health; + return (max_health); } float NSSurfacePropEntity::GetSpawnHealth(void) { - return m_oldHealth; + return (m_oldHealth); } void @@ -150,7 +151,7 @@ NSSurfacePropEntity::SetArmor(float new_armor) float NSSurfacePropEntity::GetArmor(void) { - return armor; + return (armor); } bool @@ -264,96 +265,97 @@ NSSurfacePropEntity::Save(float handle) } void -NSSurfacePropEntity::Restore(string strKey, string strValue) +NSSurfacePropEntity::Restore(string keyName, string savedValue) { - switch (strKey) { + switch (keyName) { case "m_flBurnNext": - m_flBurnNext = ReadFloat(strValue); + m_flBurnNext = ReadFloat(savedValue); break; case "armor": - armor = ReadFloat(strValue); + armor = ReadFloat(savedValue); break; case "health": - health = ReadFloat(strValue); + health = ReadFloat(savedValue); break; case "m_eBurner": - m_eBurner = edict_num(ReadFloat(strValue)); + m_eBurner = edict_num(ReadFloat(savedValue)); break; case "m_iBurnWeapon": - m_iBurnWeapon = ReadInt(strValue); + m_iBurnWeapon = ReadInt(savedValue); break; case "m_flBurnTime": - m_flBurnTime = ReadFloat(strValue); + m_flBurnTime = ReadFloat(savedValue); break; case "m_flBurnDmgTime": - m_flBurnDmgTime = ReadFloat(strValue); + m_flBurnDmgTime = ReadFloat(savedValue); break; case "m_strOnBreak": - m_strOnBreak = ReadString(strValue); + m_strOnBreak = ReadString(savedValue); break; case "m_oldHealth": - m_oldHealth = ReadFloat(strValue); + m_oldHealth = ReadFloat(savedValue); break; case "m_vecBloodColor": - m_vecBloodColor = ReadVector(strValue); + m_vecBloodColor = ReadVector(savedValue); break; case "m_iMaterial": - m_iMaterial = ReadInt(strValue); + m_iMaterial = ReadInt(savedValue); break; case "m_iPropData": - m_iPropData = ReadInt(strValue); + m_iPropData = ReadInt(savedValue); break; case "m_flDeathTime": - m_flDeathTime = ReadFloat(strValue); + m_flDeathTime = ReadFloat(savedValue); break; default: - super::Restore(strKey, strValue); + super::Restore(keyName, savedValue); } } void -NSSurfacePropEntity::Input(entity eAct, string strInput, string strData) +NSSurfacePropEntity::Input(entity entityActivator, string inputName, string dataField) { - switch (strInput) { + switch (inputName) { case "Ignite": - Ignite(eAct, 5000, 0); + Ignite(entityActivator, 5000, 0); break; case "IgniteLifetime": - Ignite(eAct, stof(strData), 0); + float lifeTime = stof(dataField); + Ignite(entityActivator, lifeTime, 0); break; case "Extinguish": Extinguish(); break; default: - super::Input(eAct, strInput, strData); + super::Input(entityActivator, inputName, dataField); } } void -NSSurfacePropEntity::SpawnKey(string strKey, string strValue) +NSSurfacePropEntity::SpawnKey(string keyName, string setValue) { - switch (strKey) { + switch (keyName) { case "health": - max_health = health = ReadFloat(strValue); + max_health = health = ReadFloat(setValue); m_oldHealth = health; break; case "propdata": - m_strPropData = ReadString(strValue); + m_strPropData = ReadString(setValue); break; case "surfdata": case "materialdata": - m_strSurfData = ReadString(strValue); + m_strSurfData = ReadString(setValue); break; /* entityDef */ case "blood_color": - m_vecBloodColor = ReadVector(strValue); + m_vecBloodColor = ReadVector(setValue); break; /* Input/Output system */ case "OnBreak": - m_strOnBreak = PrepareOutput(m_strOnBreak, ReadString(strValue)); + m_strOnBreak = PrepareOutput(m_strOnBreak, ReadString(setValue)); break; default: - super::SpawnKey(strKey, strValue); + super::SpawnKey(keyName, setValue); break; } } @@ -361,7 +363,13 @@ NSSurfacePropEntity::SpawnKey(string strKey, string strValue) void NSSurfacePropEntity::Pain(void) { - + /* implemented in sub-class */ +} + +void +NSSurfacePropEntity::DamageFeedback(NSSurfacePropEntity theVictim, NSSurfacePropEntity theInflictor, int desiredDamage) +{ + /* implemented in sub-class */ } void @@ -371,8 +379,9 @@ NSSurfacePropEntity::Death(void) UseOutput(g_dmg_eAttacker, m_strOnBreak); - if (HasPropData() == false) + if (HasPropData() == false) { return; + } if (GetPropData(PROPINFO_SKIN) != 0) { SetSkin(GetPropData(PROPINFO_SKIN)); @@ -406,6 +415,7 @@ NSSurfacePropEntity::SetSurfaceData(string type) m_strSurfData = type; _SurfaceDataFinish(); } + void NSSurfacePropEntity::SetPropData(string type) { @@ -423,6 +433,7 @@ NSSurfacePropEntity::_SurfaceDataFinish(void) else m_iMaterial = -1; } + void NSSurfacePropEntity::_PropDataFinish(void) { @@ -438,9 +449,27 @@ float NSSurfacePropEntity::TimeSinceDeath(void) { if (IsAlive()) - return -1; + return (-1); - return time - m_flDeathTime; + return (time - m_flDeathTime); +} + +void +NSSurfacePropEntity::SetPainCallback(void(void) painFunc) +{ + Pain = painFunc; +} + +void +NSSurfacePropEntity::SetDeathCallback(void(void) deathFunc) +{ + Death = deathFunc; +} + +bool +NSSurfacePropEntity::CanBeDamaged(void) +{ + return (takedamage == DAMAGE_NO) ? false : true; } void @@ -602,10 +631,13 @@ NSSurfacePropEntity::ReceiveEntity(float flNew, float flChanged) if (scale == 0.0) scale = 1.0f; - if (flChanged & SRFENT_CHANGED_SIZE) + if (flChanged & SRFENT_CHANGED_SIZE) { setsize(this, mins * scale, maxs * scale); - if (flChanged & SRFENT_CHANGED_BODY) + } + + if (flChanged & SRFENT_CHANGED_BODY) { setcustomskin(this, "", sprintf("geomset 0 %i\ngeomset 1 %i\n", m_iBody, m_iBody)); + } } void @@ -626,20 +658,27 @@ NSSurfacePropEntity::RenderFire(void) float NSSurfacePropEntity::predraw(void) { - RenderFire(); - return super::predraw(); + float returnValue = super::predraw(); + + if (returnValue) { + RenderFire(); + } + + return returnValue; } void -NSSurfacePropEntity_ReadEntity(bool new) +NSSurfacePropEntity_ReadEntity(bool isNew) { - float fl; - NSSurfacePropEntity rend = (NSSurfacePropEntity)self; - if (new) { + float networkFlags; + NSSurfacePropEntity rendEnt = (NSSurfacePropEntity)self; + + if (isNew) { spawnfunc_NSSurfacePropEntity(); } - fl = readfloat(); - rend.ReceiveEntity(new, fl); + + networkFlags = readfloat(); + rendEnt.ReceiveEntity(isNew, networkFlags); } #endif @@ -653,4 +692,4 @@ NSSurfacePropEntity::SetModel(string newModel) m_iPropData = PropData_ForModel(model); } #endif -} \ No newline at end of file +} diff --git a/src/shared/NSTalkMonster.qc b/src/shared/NSTalkMonster.qc index 937031d9..c7919c2e 100644 --- a/src/shared/NSTalkMonster.qc +++ b/src/shared/NSTalkMonster.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -288,6 +288,8 @@ NSTalkMonster::Sentence(string sentence) WriteInt(MSG_MULTICAST, Sentences_GetID(seq)); msg_entity = this; multicast(origin, MULTICAST_PVS); + + SndEntLog("Attempting to say %S", seq); } void @@ -576,7 +578,7 @@ NSTalkMonster::FollowPlayer(void) /* Give up after 1024 units */ if (flPlayerDist > m_flMaxFollowDistance) { m_eFollowing = world; - NSMonster_Log("Maximum follow distance reached. Will stop following."); + NSMonsterLog("Maximum follow distance reached. Will stop following."); } else if (flPlayerDist >= m_flFollowDistance) { /* we only allow speed changes every second, avoid jitter */ if (m_flFollowSpeedChanged < time) { @@ -958,7 +960,7 @@ NSTalkMonster::ProcessWordQue(void) SentenceSample(m_pSentenceQue[m_iSentencePos].m_strSnd); - NSMonster_Log("^2NSEntity::^3ProcessWordQue^7: Speaking %s", m_pSentenceQue[m_iSentencePos].m_strSnd); + NSMonsterLog("Speaking sentence sample %S", m_pSentenceQue[m_iSentencePos].m_strSnd); m_iSentencePos++; if (m_iSentencePos == m_iSentenceCount) { @@ -1008,6 +1010,9 @@ NSTalkMonster::Sentence(string msg) m_pSentenceQue[i].m_flPitch = 100; } m_flSentenceTime = time; + + + SndEntLog("Saying %S", msg); } float @@ -1146,15 +1151,14 @@ NSTalkMonster_ParseSentence(void) ent = findfloat(world, entnum, e); if (ent) { - if (ent.classname != "speaker" && ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic") - NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d not a NSTalkMonster!", e); - else { + if (ent.classname != "speaker" && ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic") { + NSError("Entity %d not a NSTalkMonster!", e); + } else { targ = (NSTalkMonster)ent; targ.Sentence(sentence); - NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d saying %s", e, sentence); } } else { - NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d not in PVS", e); + NSError("Entity %d not in PVS", e); } } #endif diff --git a/src/shared/NSTimer.qc b/src/shared/NSTimer.qc index 4049b1b8..19511710 100644 --- a/src/shared/NSTimer.qc +++ b/src/shared/NSTimer.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Vera Visions LLC. + * Copyright (c) 2022-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -180,4 +180,4 @@ NSTimer::Restore(string strKey, string strValue) break; } } -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSTrigger.h b/src/shared/NSTrigger.h index b1cb7058..6fbc2309 100644 --- a/src/shared/NSTrigger.h +++ b/src/shared/NSTrigger.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -92,6 +92,7 @@ public: /* overrides */ virtual void Save(float); virtual void Restore(string,string); + virtual void Respawn(void); virtual void Input(entity,string,string); /* Called to check if the target entity can touch trigger itself. */ @@ -169,4 +170,4 @@ private: #ifdef CLIENT float team; #endif -}; \ No newline at end of file +}; diff --git a/src/shared/NSTrigger.qc b/src/shared/NSTrigger.qc index 054f1596..b9f970aa 100644 --- a/src/shared/NSTrigger.qc +++ b/src/shared/NSTrigger.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,6 +37,12 @@ NSTrigger::NSTrigger(void) } #ifdef SERVER +void +NSTrigger::Respawn(void) +{ + super::Respawn(); + SetTriggerTarget( m_oldstrTarget ); +} bool NSTrigger::CanBeTriggeredBy(entity testEnt) @@ -78,34 +84,27 @@ NSTrigger::CanBeTriggeredBy(entity testEnt) void NSTrigger::Trigger(entity act, triggermode_t state) { - NSLog("^2%s::^3Trigger^7: Triggered by %s with no consequence", - classname, act.classname); + EntWarning("Triggered by %S with no consequence", act.classname); } void -NSTrigger::UseTargets(entity act, int state, float fDelay) +NSTrigger::UseTargets(entity act, int state, float triggerDelay) { static void Entities_UseTargets_Think(void) { NSTrigger::UseTargets(self.owner, self.health, 0.0f); remove(self); } - if not (target) + if (!m_strKillTarget && !target) return; - if not (m_strKillTarget) - if not (target) - return; - - if (fDelay > 0.0f) { - NSLog("^2%s::^3UseTargets^7: Triggering `%s`", - classname, target); - + if (triggerDelay > 0.0f) { + EntLog("Scheduling trigger of %S in %f seconds.", target, triggerDelay); NSTrigger eTimer = spawn(NSTrigger); eTimer.owner = act; eTimer.think = Entities_UseTargets_Think; eTimer.target = target; - eTimer.nextthink = time + fDelay; + eTimer.nextthink = time + triggerDelay; eTimer.health = state; /* ugly */ } else { if (m_strMessage) { @@ -115,10 +114,9 @@ NSTrigger::UseTargets(entity act, int state, float fDelay) for (entity f = world; (f = find(f, ::targetname, target));) { NSTrigger trigger = (NSTrigger)f; - NSLog("^2%s::^3UseTargets^7:" \ - "Triggering %s `%s` from %s", \ - classname, f.classname, \ - trigger.targetname, act.classname); + EntLog("Triggering %s %S, activator %S (%d)", \ + f.classname, trigger.targetname, \ + act.classname, num_for_edict(act)); if (trigger.Trigger != __NULL__) { trigger.Trigger(act, state); @@ -127,8 +125,8 @@ NSTrigger::UseTargets(entity act, int state, float fDelay) if (m_strKillTarget && m_strKillTarget != "") { NSEntity eKill = (NSEntity)find(world, ::targetname, m_strKillTarget); - NSLog("^2%s::^3UseTargets^7: Killing `%s`", - classname, m_strKillTarget); + EntLog("Killtargeting %S", m_strKillTarget); + if (eKill) { eKill.Destroy(); } @@ -175,18 +173,20 @@ NSTrigger::GetMaster(entity queryingEntity) /* we couldn't find it, so let's not even bother going further */ if (!t) { - NSLog("^2%s::^3GetMaster^7: Invalid master (%s), return success", - classname, m_strMaster); + /*NSLog("^2%s::^3GetMaster^7: Invalid master (%s), return success", + classname, m_strMaster);*/ return (1); } +/* if (t.GetValue(queryingEntity) == 1) NSLog("^2%s::^3GetMaster^7: %s learns %s ^2POSITIVE", classname, targetname, m_strMaster); else NSLog("^2%s::^3GetMaster^7: %s learns %s ^1NEGATIVE", classname, targetname, m_strMaster); - +*/ + return t.GetValue(queryingEntity); } diff --git a/src/shared/NSVehicle.h b/src/shared/NSVehicle.h index f7d7a1a0..2347f599 100644 --- a/src/shared/NSVehicle.h +++ b/src/shared/NSVehicle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,12 +16,14 @@ var bool autocvar_vehicle_developer = false; void -_NSVehicle_Log(string msg) +_NSVehicle_Log(string className, string functionName, float edictNum, string warnMessage) { - if (autocvar_vehicle_developer == true) - print(sprintf("%f %s\n", time, msg)); + if (autocvar_g_developerTimestamps) + printf("^9%f ^2%s (%d) ^7: %s\n", time, functionName, edictNum, warnMessage); + else + printf("^2%s (%d) ^7: %s\n", functionName, edictNum, warnMessage); } -#define NSVehicle_Log(...) _NSVehicle_Log(sprintf(__VA_ARGS__)) +#define NSVehicle_Log(...) if (autocvar_vehicle_developer == true) _NSVehicle_Log(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) /** This entity class represents vehicles that are predicted across the network. */ class NSVehicle:NSSurfacePropEntity diff --git a/src/shared/NSVehicle.qc b/src/shared/NSVehicle.qc index 63cac0a3..72879bfa 100644 --- a/src/shared/NSVehicle.qc +++ b/src/shared/NSVehicle.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -446,6 +446,7 @@ NSVehicle::PlayerEnter(NSClientPlayer pl) m_eDriverLast = m_eDriver; pl.vehicle = this; pl.flags |= FL_INVEHICLE; + EntLog("Player %S entered this vehicle.", pl.GetInfoKey("name")); } void @@ -454,6 +455,8 @@ NSVehicle::PlayerLeave(NSClientPlayer pl) if (!pl) return; + EntLog("Player %S exits this vehicle.", pl.GetInfoKey("name")); + owner = __NULL__; pl.flags &= ~FL_INVEHICLE; pl.velocity = g_vec_null; diff --git a/src/shared/cloader.h b/src/shared/cloader.h index e53b54fd..23436711 100644 --- a/src/shared/cloader.h +++ b/src/shared/cloader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2023-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -13,43 +13,43 @@ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/*! @file cloader.h - @brief Constants macro loader - -Scripters and level designers are able to define parameters through the use -of name-based lookups, so they can change them later in one convenient place. - -In the game directory, they are defined within `scripts/constants.txt`. -An example file looks like this: - -``` -// weapon constants -WEAPON_NONE 0 -WEAPON_KNIFE 1 -WEAPON_POTATO 2 -``` - -Within [EntityDefs](Documentation/EntityDef.md) files, you will then be able to set a given key to the value -of one of the defined constants by prefixing the name with a `$` symbol. -That would look something like this: - -``` -"weapon" "$WEAPON_POTATO" -``` - -The same applies to data read within level files and most routines related to parsing key/value pairs, so it is not limited to usage within EntityDef. -*/ - -/** Called upon game init internally to populate our look-up table. -*/ -void Constants_Init(void); - -/** Look up a name and retrieve its value. - -@param constName Name of the constant to look up. -@param returnValue The value to return if constName is not defined. -@return The value of the named constant. Will return returnValue if it does not exist. */ -string Constants_LookUp(string constName, string returnValue); - -var hashtable g_hashConstants; \ No newline at end of file + +/*! @file cloader.h + @brief Constants macro loader + +Scripters and level designers are able to define parameters through the use +of name-based lookups, so they can change them later in one convenient place. + +In the game directory, they are defined within `scripts/constants.txt`. +An example file looks like this: + +``` +// weapon constants +WEAPON_NONE 0 +WEAPON_KNIFE 1 +WEAPON_POTATO 2 +``` + +Within [EntityDefs](Documentation/EntityDef.md) files, you will then be able to set a given key to the value +of one of the defined constants by prefixing the name with a `$` symbol. +That would look something like this: + +``` +"weapon" "$WEAPON_POTATO" +``` + +The same applies to data read within level files and most routines related to parsing key/value pairs, so it is not limited to usage within EntityDef. +*/ + +/** Called upon game init internally to populate our look-up table. +*/ +void Constants_Init(void); + +/** Look up a name and retrieve its value. + +@param constName Name of the constant to look up. +@param returnValue The value to return if constName is not defined. +@return The value of the named constant. Will return returnValue if it does not exist. */ +string Constants_LookUp(string constName, string returnValue); + +var hashtable g_hashConstants; diff --git a/src/shared/cloader.qc b/src/shared/cloader.qc index 93be55d3..dbdc0643 100644 --- a/src/shared/cloader.qc +++ b/src/shared/cloader.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2023-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -13,59 +13,65 @@ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef MAX_CONSTANTS_ID +#define MAX_CONSTANTS_ID 128 +#endif + +string g_constIndex[MAX_CONSTANTS_ID]; + +void +Constants_Init(void) +{ + filestream constFile; + string tempString; + int arguments = 0i; + int indexCount = 0i; -#ifndef MAX_CONSTANTS_ID -#define MAX_CONSTANTS_ID 128 -#endif + InitStart(); + + if (!g_hashConstants) { + g_hashConstants = hash_createtab(2, HASH_ADD); + } + + constFile = fopen("scripts/constants.txt", FILE_READ); + + if (constFile < 0) { + NSError("Missing file scripts/constants.txt"); + InitEnd(); + return; + } + + while ((tempString = fgets(constFile))) { + arguments = (int)tokenize_console(tempString); + + if (arguments != 2) { + continue; + } + + /* sanity bounds check */ + if (indexCount == MAX_CONSTANTS_ID) { + NSError("Hit maximum number of %d constants.", MAX_CONSTANTS_ID); + InitEnd(); + return; + } + + g_constIndex[indexCount] = argv(1); + hash_add(g_hashConstants, argv(0), indexCount); + indexCount++; + } -string g_constIndex[MAX_CONSTANTS_ID]; - -void -Constants_Init(void) -{ - filestream constFile; - string tempString; - int arguments = 0i; - int indexCount = 0i; - - if (!g_hashConstants) { - g_hashConstants = hash_createtab(2, HASH_ADD); - } - - constFile = fopen("scripts/constants.txt", FILE_READ); - - if (constFile < 0) { - print("Unable to load scripts/constants.txt"); - return; - } - - while ((tempString = fgets(constFile))) { - arguments = (int)tokenize_console(tempString); - - if (arguments != 2) { - continue; - } - - /* sanity bounds check */ - if (indexCount == MAX_CONSTANTS_ID) { - print("Constants_Init: Hit maximum number of constants.\n"); - return; - } - - g_constIndex[indexCount] = argv(1); - hash_add(g_hashConstants, argv(0), indexCount); - indexCount++; - } -} - -string -Constants_LookUp(string constName, string returnValue) -{ - int constIndex = -1i; - - /* only if we're prefixed */ - if (substring(constName, 0, 1) == "$") - constIndex = hash_get(g_hashConstants, substring(constName, 1, -1), -1i); - - return (constIndex == -1i) ? returnValue : g_constIndex[constIndex]; -} \ No newline at end of file + InitEnd(); +} + +string +Constants_LookUp(string constName, string returnValue) +{ + int constIndex = -1i; + + /* only if we're prefixed */ + if (substring(constName, 0, 1) == "$") + constIndex = hash_get(g_hashConstants, substring(constName, 1, -1), -1i); + + return (constIndex == -1i) ? returnValue : g_constIndex[constIndex]; +} diff --git a/src/shared/colors.h b/src/shared/colors.h index d8298ff9..a29fa1c3 100644 --- a/src/shared/colors.h +++ b/src/shared/colors.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/damage.h b/src/shared/damage.h index 5118fa72..68829b07 100644 --- a/src/shared/damage.h +++ b/src/shared/damage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/decalgroups.h b/src/shared/decalgroups.h index d90bda3f..5eff9d0e 100644 --- a/src/shared/decalgroups.h +++ b/src/shared/decalgroups.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Vera Visions LLC. + * Copyright (c) 2022-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -48,4 +48,4 @@ int DecalGroups_NumForName(string group); #ifdef CLIENT void DecalGroups_Precache(void); void DecalGroups_Receive(void); -#endif \ No newline at end of file +#endif diff --git a/src/shared/decalgroups.qc b/src/shared/decalgroups.qc index 236ab60c..95385ff8 100644 --- a/src/shared/decalgroups.qc +++ b/src/shared/decalgroups.qc @@ -1,4 +1,18 @@ -/* Copyright (c) 2022, Vera Visions, L.L.C. All rights reserved. */ +/* + * Copyright (c) 2022-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ #ifdef CLIENT typedef struct @@ -100,8 +114,8 @@ DecalGroups_Init(void) filestream fh; string line; + InitStart(); g_decalgroup_count = 0i; - print("--------- Initializing Decal Groups ----------\n"); /* create the hash-table if it doesn't exist */ if (!g_hashdecalgroup) { @@ -110,7 +124,8 @@ DecalGroups_Init(void) fh = fopen("scripts/decals.txt", FILE_READ); if (fh < 0) { - print("^1[DECALS] Can't find scripts/decals.txt\n"); + NSError("Missing file scripts/decals.txt"); + InitEnd(); return; } @@ -148,7 +163,8 @@ DecalGroups_Init(void) #endif #endif - print(sprintf("decal groups initialized with %i entries.\n", g_decalgroup_count)); + NSLog("...decal groups initialized with %i entries.", g_decalgroup_count); + InitEnd(); } #ifdef CLIENT diff --git a/src/shared/defs.h b/src/shared/defs.h index f7e5bd4c..01d3cc7f 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -139,8 +139,6 @@ string __fullspawndata; #define CLASSEXPORT(a,b) void a(void) { if (!isfunction(#b)) { self.classname = strcat("spawnfunc_", #b); } else { self.classname = #b; } callfunction(self.classname); } -#define printf(x, ...) print(sprintf(x, ...)) - const vector VEC_HULL_MIN = [-16,-16,-36]; const vector VEC_HULL_MAX = [16,16,36]; const vector VEC_CHULL_MIN = [-16,-16,-18]; @@ -204,27 +202,30 @@ crossprint(string m) #endif } +#if 0 __wrap string precache_model(string m) { if not (m) { breakpoint(); + return ""; + } + + if (m == "") { + breakpoint(); + return ""; } -#ifdef CLIENT - NSLog("^3Client precaching model ^7%s", m); -#else - NSLog("^3Server precaching model ^7%s", m); -#endif return prior(m); } +#endif __wrap string precache_sound(string sample) { if (sample != "") /* not empty */ if not(whichpack(strcat("sound/", sample))) { /* not present on disk */ - print(strcat("^1sfx sample ", sample, " does not exist!\n")); + NSError("SFX sample %S does not exist.", sample); return "misc/missing.wav"; } @@ -514,4 +515,4 @@ FileExists(string filePath) return false; return true; -} \ No newline at end of file +} diff --git a/src/shared/entities.h b/src/shared/entities.h index 6aad2556..b2e766a0 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -104,7 +104,7 @@ Entity_SelectRandom(string className) /* immediately exit out if we've got none */ if (max < 1i) { - print(sprintf("^1Error: %s is not present on this map.\n", className)); + NSError("%S is not present on this map.", className); return __NULL__; } diff --git a/src/shared/events.h b/src/shared/events.h index bbc6345d..443f5146 100644 --- a/src/shared/events.h +++ b/src/shared/events.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/global.h b/src/shared/global.h index e7d6d2a6..5b10fa2d 100644 --- a/src/shared/global.h +++ b/src/shared/global.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,11 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +var bool autocvar_g_developer = false; +var bool autocvar_g_developerTimestamps = false; + +#define printf(...) print(sprintf(__VA_ARGS__)) + #ifdef DOXYGEN /** Doxygen doesn't know what enumflags (aka bitfields) are, used as e.g. */ #define enumflags enum @@ -22,8 +27,28 @@ void _NSLog(string msg) { - if (cvar("g_developer") == 1) - print(sprintf("%f %s\n", time, msg)); + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^7%s\n", time, msg)); + else + print(sprintf("^7%s\n", msg)); +} + +void +_NSError(string functionName, string msg) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^1%s^7: %s\n", time, functionName, msg)); + else + print(sprintf("^1%s^7: %s\n", functionName, msg)); +} + +void +_NSWarning(string functionName, string msg) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^3%s^7: %s\n", time, functionName, msg)); + else + print(sprintf("^3%s^7: %s\n", functionName, msg)); } void @@ -37,27 +62,31 @@ _NSAssert(bool condition, string function, string descr) } } -void -_NSEntWarning(string className, vector classOrg, string warnMessage) -{ - print(sprintf("^1Class %s at %v: %s\n", className, classOrg, warnMessage)); -} - -/** Logs an error type message, with timestamp. +/** Logs an message, with timestamp. The console variable `g_developer` has to be `1` for them to be visible. @param description(...) contains a formatted string containing a description. */ -#define NSLog(...) _NSLog(sprintf(__VA_ARGS__)) +#define NSLog(...) if (autocvar_g_developer) _NSLog(sprintf(__VA_ARGS__)) + +/** Logs an error message, with timestamp. + The console variable `g_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define NSError(...) _NSError(__FUNC__, sprintf(__VA_ARGS__)) + +/** Logs a warning message, with timestamp. + The console variable `g_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define NSWarning(...) _NSWarning(__FUNC__, sprintf(__VA_ARGS__)) /** Generates an assertion, if a given condition is false. + The console variable `g_developer` has to be `1` for them to be visible. @param condition is the expression to be evaluated. @param description(...) contains a formatted string containing an error description. */ -#define NSAssert(condition, ...) _NSAssert(condition, __FUNC__, sprintf(__VA_ARGS__)) - - -#define NSEntWarning(...) _NSEntWarning(classname, origin, sprintf(__VA_ARGS__)) +#define NSAssert(condition, ...) if (autocvar_g_developer) _NSAssert(condition, __FUNC__, sprintf(__VA_ARGS__)) typedef enumflags { @@ -69,4 +98,60 @@ typedef enumflags SEARCH_NAMESORT /**< Sort the results alphabetically (slower) */ } searchFlags_t; -const vector g_vec_null = [0.0f, 0.0f, 0.0f]; \ No newline at end of file +const vector g_vec_null = [0.0f, 0.0f, 0.0f]; + +/* the console needs some attention too. */ +var float g_initTime; + +void +InitPrint(string functionName) +{ + int chars = 51i; + int charsLeft; + int charExtra; + string sideLeft = ""; + string sideRight = ""; + + if (functionName == __NULL__) { + NSLog("---------------------------------------------------"); + return; + } + + /* word and padding */ + chars = chars - (int)strlen(functionName) - 2i; + charsLeft = chars / 2i; + charExtra = chars % 2i; + + for (int i = 0i; i < charsLeft; i++) + sideLeft = strcat(sideLeft,"-"); + + for (int i = 0i; i < (charsLeft + charExtra); i++) { + sideRight = strcat(sideRight,"-"); + } + + NSLog( "%s %s %s", sideLeft, functionName, sideRight); +} + +void +_InitStart(string functionName) +{ + if (g_initTime != 0) + error("Called InitStart() without InitEnd()ing the previous one!"); + + InitPrint(functionName); + g_initTime = gettime(1); +} + +#define InitStart() _InitStart(__FUNC__) + + +void +_InitEnd(void) +{ + float endTime = gettime(1); + NSLog("loaded in %.1f seconds", (endTime - g_initTime)); + NSLog("---------------------------------------------------"); + g_initTime = 0; +} + +#define InitEnd() _InitEnd() diff --git a/src/shared/materials.h b/src/shared/materials.h index 82adb481..52c09d04 100644 --- a/src/shared/materials.h +++ b/src/shared/materials.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -36,179 +36,179 @@ var bool g_materialsAreLegacy; /* FIXME: world.... sigh, we should box this into a worldspawn class */ .string materials_file; -// Impact types -typedef enum -{ - IMPACT_MELEE, - IMPACT_EXPLOSION, - IMPACT_DEFAULT, - IMPACT_ALIEN, - IMPACT_COMPUTER, - IMPACT_CONCRETE, - IMPACT_DIRT, - IMPACT_FLESH, - IMPACT_FOLIAGE, - IMPACT_GLASS, - IMPACT_GRATE, - IMPACT_METAL, - IMPACT_SAND, - IMPACT_SLOSH, - IMPACT_SNOW, - IMPACT_TILE, - IMPACT_VENT, - IMPACT_WOOD -} impactType_t; - -typedef enum -{ - GSMATERIAL_GLASS, - GSMATERIAL_WOOD, - GSMATERIAL_METAL, - GSMATERIAL_FLESH, - GSMATERIAL_CINDER, - GSMATERIAL_TILE, - GSMATERIAL_COMPUTER, - GSMATERIAL_GLASS_UNBREAKABLE, - GSMATERIAL_ROCK, - GSMATERIAL_NONE -} materialType_t; - - -/* q3 bsp base flags */ -#define SURF_NODAMAGE 0x1i // never give falling damage -#define SURF_SLICK 0x2i // effects game physics -#define SURF_SKY 0x4i // lighting from environment map -#define SURF_LADDER 0x8i // climb this surface -#define SURF_NOIMPACT 0x10i // don't make missile explosions -#define SURF_NOMARKS 0x20i // don't leave missile marks -#define SURF_Q3FLESH 0x40i // make flesh sounds and effects -#define SURF_NODRAW 0x80i // don't generate a drawsurface at all -#define SURF_HINT 0x100i // make a primary bsp splitter -#define SURF_SKIP 0x200i // completely ignore, allowing non-closed brushes -#define SURF_NOLIGHTMAP 0x400i // surface doesn't need a lightmap -#define SURF_POINTLIGHT 0x800i // generate lighting info at vertexes -#define SURF_METALSTEPS 0x1000i // clanking footsteps -#define SURF_NOSTEPS 0x2000i // no footstep sounds -#define SURF_NONSOLID 0x4000i // don't collide against curves with this set -#define SURF_LIGHTFILTER 0x8000i // act as a light filter during q3map -light -#define SURF_ALPHASHADOW 0x10000i // do per-pixel light shadow casting in q3map -#define SURF_NODLIGHT 0x20000i // don't dlight even if solid (solid lava, skies) -#define SURF_DUST 0x40000i // leave a dust trail when walking on this surface - -/* behaviour surfaceflags */ -#define SURF_LEAKSTEAM 0x00080000i /* when shot, the material emits steam */ -#define SURF_LEAKWATER 0x00100000i /* when shot, the material emits water */ -#define SURF_RESERVED1 0x00200000i -#define SURF_RESERVED2 0x00400000i -#define SURF_RESERVED3 0x00800000i -#define SURF_RESERVED4 0x01000000i -#define SURF_RESERVED5 0x02000000i -#define SURF_RESERVED6 0x04000000i -#define SURF_PENETRATE 0x08000000i - -/* old TW material surfaceflags (need to be masked) */ -#define SURF_MASK 0x0FFFFFFFi -#define SURF_ALIEN 0x10000000i -#define SURF_BLOODYFLESH 0x20000000i -#define SURF_FOLIAGE 0x30000000i -#define SURF_COMPUTER 0x40000000i -#define SURF_DIRT 0x50000000i -#define SURF_VENT 0x60000000i -#define SURF_GRATE 0x70000000i -#define SURF_METAL 0x80000000i -#define SURF_GLASS 0x90000000i -#define SURF_SAND 0xA0000000i -#define SURF_SLOSH 0xB0000000i -#define SURF_SNOW 0xC0000000i -#define SURF_TILE 0xD0000000i -#define SURF_WOOD 0xE0000000i -#define SURF_CONCRETE 0xF0000000i - -const int CONTENTBIT_NONE = 0x00000000i; - -const int CONTENTBIT_SOLID = 0x00000001i -; /* SOLID_BSP */ -const int CONTENTBIT_UNUSED1 = 0x00000002i -; -const int CONTENTBIT_UNUSED2 = 0x00000004i -; -const int CONTENTBIT_LAVA = 0x00000008i; - /* surfaceParm lava */ - -const int CONTENTBIT_SLIME = 0x00000010i; - /* surfaceParm slime */ -const int CONTENTBIT_WATER = 0x00000020i; - /* surfaceParm water */ -const int CONTENTBIT_UNUSED3 = 0x00000040i -; -const int CONTENTBIT_GRENADECLIP = 0x00000080i -; /* surfaceParm grenadeclip */ - -const int CONTENTBIT_UNUSED4 = 0x00000100i; -const int CONTENTBIT_UNUSED5 = 0x00000200i; -const int CONTENTBIT_UNUSED6 = 0x00000400i -; -const int CONTENTBIT_UNUSED7 = 0x00000800i -; - -const int CONTENTBIT_UNUSED8 = 0x00001000i; -const int CONTENTBIT_UNUSED9 = 0x00002000i; -const int CONTENTBIT_FTELADDER = 0x00004000i; /* surfaceparm climb */ -const int CONTENTBIT_VEHICLECLIP = 0x00008000i; - -const int CONTENTBIT_PLAYERCLIP = 0x00010000i; - /* surfaceParm playerclip */ -const int CONTENTBIT_MONSTERCLIP = 0x00020000i; - /* surfaceParm monsterclip */ -const int CONTENTBIT_PROJECTILE = 0x00040000i; -const int CONTENTBIT_UNUSED12 = 0x00080000i; - -const int CONTENTBIT_CLUSTERPORTAL = 0x00100000i; -const int CONTENTBIT_DONOTENTER = 0x00200000i; -const int CONTENTBIT_BOTCLIP = 0x00400000i -; /* surfaceParm botclip */ -const int CONTENTBIT_MOVER = 0x00800000i -; - -const int CONTENTBIT_UNUSED13 = 0x01000000i -; -const int CONTENTBIT_BODY = 0x02000000i; /* SOLID_BBOX/SLIDEBOX */ -const int CONTENTBIT_CORPSE = 0x04000000i; /* SOLID_CORPSE */ -const int CONTENTBIT_UNUSED14 = 0x08000000i; - -const int CONTENTBIT_UNUSED15 = 0x10000000i; -const int CONTENTBIT_Q2LADDER = 0x20000000i; /* Q2BSP climbables */ -const int CONTENTBIT_UNUSED16 = 0x40000000i; -const int CONTENTBIT_SKY = 0x80000000i; /* Q1BSP only! */ +// Impact types +typedef enum +{ + IMPACT_MELEE, + IMPACT_EXPLOSION, + IMPACT_DEFAULT, + IMPACT_ALIEN, + IMPACT_COMPUTER, + IMPACT_CONCRETE, + IMPACT_DIRT, + IMPACT_FLESH, + IMPACT_FOLIAGE, + IMPACT_GLASS, + IMPACT_GRATE, + IMPACT_METAL, + IMPACT_SAND, + IMPACT_SLOSH, + IMPACT_SNOW, + IMPACT_TILE, + IMPACT_VENT, + IMPACT_WOOD +} impactType_t; + +typedef enum +{ + GSMATERIAL_GLASS, + GSMATERIAL_WOOD, + GSMATERIAL_METAL, + GSMATERIAL_FLESH, + GSMATERIAL_CINDER, + GSMATERIAL_TILE, + GSMATERIAL_COMPUTER, + GSMATERIAL_GLASS_UNBREAKABLE, + GSMATERIAL_ROCK, + GSMATERIAL_NONE +} materialType_t; + + +/* q3 bsp base flags */ +#define SURF_NODAMAGE 0x1i // never give falling damage +#define SURF_SLICK 0x2i // effects game physics +#define SURF_SKY 0x4i // lighting from environment map +#define SURF_LADDER 0x8i // climb this surface +#define SURF_NOIMPACT 0x10i // don't make missile explosions +#define SURF_NOMARKS 0x20i // don't leave missile marks +#define SURF_Q3FLESH 0x40i // make flesh sounds and effects +#define SURF_NODRAW 0x80i // don't generate a drawsurface at all +#define SURF_HINT 0x100i // make a primary bsp splitter +#define SURF_SKIP 0x200i // completely ignore, allowing non-closed brushes +#define SURF_NOLIGHTMAP 0x400i // surface doesn't need a lightmap +#define SURF_POINTLIGHT 0x800i // generate lighting info at vertexes +#define SURF_METALSTEPS 0x1000i // clanking footsteps +#define SURF_NOSTEPS 0x2000i // no footstep sounds +#define SURF_NONSOLID 0x4000i // don't collide against curves with this set +#define SURF_LIGHTFILTER 0x8000i // act as a light filter during q3map -light +#define SURF_ALPHASHADOW 0x10000i // do per-pixel light shadow casting in q3map +#define SURF_NODLIGHT 0x20000i // don't dlight even if solid (solid lava, skies) +#define SURF_DUST 0x40000i // leave a dust trail when walking on this surface + +/* behaviour surfaceflags */ +#define SURF_LEAKSTEAM 0x00080000i /* when shot, the material emits steam */ +#define SURF_LEAKWATER 0x00100000i /* when shot, the material emits water */ +#define SURF_RESERVED1 0x00200000i +#define SURF_RESERVED2 0x00400000i +#define SURF_RESERVED3 0x00800000i +#define SURF_RESERVED4 0x01000000i +#define SURF_RESERVED5 0x02000000i +#define SURF_RESERVED6 0x04000000i +#define SURF_PENETRATE 0x08000000i + +/* old TW material surfaceflags (need to be masked) */ +#define SURF_MASK 0x0FFFFFFFi +#define SURF_ALIEN 0x10000000i +#define SURF_BLOODYFLESH 0x20000000i +#define SURF_FOLIAGE 0x30000000i +#define SURF_COMPUTER 0x40000000i +#define SURF_DIRT 0x50000000i +#define SURF_VENT 0x60000000i +#define SURF_GRATE 0x70000000i +#define SURF_METAL 0x80000000i +#define SURF_GLASS 0x90000000i +#define SURF_SAND 0xA0000000i +#define SURF_SLOSH 0xB0000000i +#define SURF_SNOW 0xC0000000i +#define SURF_TILE 0xD0000000i +#define SURF_WOOD 0xE0000000i +#define SURF_CONCRETE 0xF0000000i + +const int CONTENTBIT_NONE = 0x00000000i; + +const int CONTENTBIT_SOLID = 0x00000001i +; /* SOLID_BSP */ +const int CONTENTBIT_UNUSED1 = 0x00000002i +; +const int CONTENTBIT_UNUSED2 = 0x00000004i +; +const int CONTENTBIT_LAVA = 0x00000008i; + /* surfaceParm lava */ + +const int CONTENTBIT_SLIME = 0x00000010i; + /* surfaceParm slime */ +const int CONTENTBIT_WATER = 0x00000020i; + /* surfaceParm water */ +const int CONTENTBIT_UNUSED3 = 0x00000040i +; +const int CONTENTBIT_GRENADECLIP = 0x00000080i +; /* surfaceParm grenadeclip */ + +const int CONTENTBIT_UNUSED4 = 0x00000100i; +const int CONTENTBIT_UNUSED5 = 0x00000200i; +const int CONTENTBIT_UNUSED6 = 0x00000400i +; +const int CONTENTBIT_UNUSED7 = 0x00000800i +; + +const int CONTENTBIT_UNUSED8 = 0x00001000i; +const int CONTENTBIT_UNUSED9 = 0x00002000i; +const int CONTENTBIT_FTELADDER = 0x00004000i; /* surfaceparm climb */ +const int CONTENTBIT_VEHICLECLIP = 0x00008000i; + +const int CONTENTBIT_PLAYERCLIP = 0x00010000i; + /* surfaceParm playerclip */ +const int CONTENTBIT_MONSTERCLIP = 0x00020000i; + /* surfaceParm monsterclip */ +const int CONTENTBIT_PROJECTILE = 0x00040000i; +const int CONTENTBIT_UNUSED12 = 0x00080000i; + +const int CONTENTBIT_CLUSTERPORTAL = 0x00100000i; +const int CONTENTBIT_DONOTENTER = 0x00200000i; +const int CONTENTBIT_BOTCLIP = 0x00400000i +; /* surfaceParm botclip */ +const int CONTENTBIT_MOVER = 0x00800000i +; + +const int CONTENTBIT_UNUSED13 = 0x01000000i +; +const int CONTENTBIT_BODY = 0x02000000i; /* SOLID_BBOX/SLIDEBOX */ +const int CONTENTBIT_CORPSE = 0x04000000i; /* SOLID_CORPSE */ +const int CONTENTBIT_UNUSED14 = 0x08000000i; + +const int CONTENTBIT_UNUSED15 = 0x10000000i; +const int CONTENTBIT_Q2LADDER = 0x20000000i; /* Q2BSP climbables */ +const int CONTENTBIT_UNUSED16 = 0x40000000i; +const int CONTENTBIT_SKY = 0x80000000i; /* Q1BSP only! */ /* a bit content group */ const int CONTENTBITS_MONSTER = CONTENTBIT_SOLID|CONTENTBIT_BODY|CONTENTBIT_MONSTERCLIP|CONTENTBIT_BOTCLIP; - -/* this is used for material-lookups using the external materials.txt file - * method used in Half-Life. In that environment we have to strip any - * prefixes and limit our material-name to 12 chars for everything to be - * identified correctly */ -string -Materials_FixName(string old_name) -{ - string tex_name = old_name; - - /* strip the first 2 chars when they're frame/random indicators */ - if (str2chr(tex_name, 0) == '-') - tex_name = substring(tex_name, 2, -1); - else if (str2chr(tex_name, 0) == '+') - tex_name = substring(tex_name, 2, -1); - - /* also not allowed */ - if (str2chr(tex_name, 0) == '~') - tex_name = substring(tex_name, 1, -1); - else if (str2chr(tex_name, 0) == '{') - tex_name = substring(tex_name, 1, -1); - - /* limit to 12 chars! */ - tex_name = substring(tex_name, 0, 12); - - NSLog("%s > %s", old_name, tex_name); - - return tex_name; -} \ No newline at end of file + +/* this is used for material-lookups using the external materials.txt file + * method used in Half-Life. In that environment we have to strip any + * prefixes and limit our material-name to 12 chars for everything to be + * identified correctly */ +string +Materials_FixName(string old_name) +{ + string tex_name = old_name; + + /* strip the first 2 chars when they're frame/random indicators */ + if (str2chr(tex_name, 0) == '-') + tex_name = substring(tex_name, 2, -1); + else if (str2chr(tex_name, 0) == '+') + tex_name = substring(tex_name, 2, -1); + + /* also not allowed */ + if (str2chr(tex_name, 0) == '~') + tex_name = substring(tex_name, 1, -1); + else if (str2chr(tex_name, 0) == '{') + tex_name = substring(tex_name, 1, -1); + + /* limit to 12 chars! */ + tex_name = substring(tex_name, 0, 12); + + //NSLog("%s > %s", old_name, tex_name); + + return tex_name; +} diff --git a/src/shared/materials.qc b/src/shared/materials.qc index 82b4daa1..feb8c3c1 100644 --- a/src/shared/materials.qc +++ b/src/shared/materials.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -42,7 +42,7 @@ Materials_LoadFromText(string filename) fclose(fileMaterial); } else { - dprint(strcat("^1Failed to load ", filename,"!\n")); + NSError("Missing file %s", filename); } #endif } @@ -178,7 +178,7 @@ Materials_LoadFromLegacyText(string filename) } fclose(fileMaterial); } else { - dprint(strcat("^1Failed to load ", filename,"!\n")); + NSError("Missing file %s", filename); } } @@ -186,7 +186,7 @@ Materials_LoadFromLegacyText(string filename) void Materials_Init(void) { - print("--------- Initializing Material Data ----------\n"); + InitStart(); g_mat_total = 0i; g_hashMaterials = __NULL__; @@ -206,6 +206,9 @@ Materials_Init(void) /* we're dealing with legacy materials */ if (g_materialsAreLegacy) { + string wastesName = sprintf("maps/%s.mat", mapname); + string svenName = sprintf("maps/%s_materials.txt", mapname); + /* prepare the mapper */ Materials_Mapper_Init(); @@ -225,10 +228,12 @@ Materials_Init(void) search_end(pm); /* the way TW did it back in '03 */ - Materials_LoadFromLegacyText(sprintf("maps/%s.mat", mapname)); + if (FileExists(wastesName)) + Materials_LoadFromLegacyText(wastesName); /* Trinity-Renderer does it this way */ - Materials_LoadFromLegacyText(sprintf("maps/%s_materials.txt", mapname)); + if (FileExists(svenName)) + Materials_LoadFromLegacyText(svenName); /* no longer needed! */ Materials_Mapper_Shutdown(); @@ -250,5 +255,6 @@ Materials_Init(void) search_end(mdlsearch); } - print(sprintf("material data initialized with %i entries.\n", g_mat_total)); + NSLog("material data initialized with %i entries.", g_mat_total); + InitEnd(); } diff --git a/src/shared/math.h b/src/shared/math.h index f2ee41f3..9dea56cf 100644 --- a/src/shared/math.h +++ b/src/shared/math.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/math.qc b/src/shared/math.qc index 75bfb5d7..0b301b4d 100644 --- a/src/shared/math.qc +++ b/src/shared/math.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/motd.h b/src/shared/motd.h index a00adb3d..4959ecaa 100644 --- a/src/shared/motd.h +++ b/src/shared/motd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,4 +37,4 @@ void MOTD_Init(void); string MOTD_GetTextBody(void); /** Returns how many individual lines are present in the message of the day. */ int MOTD_GetLineCount(void); -#endif \ No newline at end of file +#endif diff --git a/src/shared/motd.qc b/src/shared/motd.qc index 2e661f77..a28859bc 100644 --- a/src/shared/motd.qc +++ b/src/shared/motd.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Vera Visions LLC. + * Copyright (c) 2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,7 +22,9 @@ static int g_motd_lines; void MOTD_Init(void) { + InitStart(); #ifdef SERVER + /* wipe the slate clean */ for (int i = 0; i < MOTD_LINES; i++) { localcmd(sprintf("serverinfo motdline%i \"\"\n", i)); @@ -44,6 +46,7 @@ MOTD_Init(void) g_motd_lines = motdLines; #endif + InitEnd(); } #ifdef SERVER @@ -99,4 +102,4 @@ MOTD_GetLineCount(void) { return g_motd_lines; } -#endif \ No newline at end of file +#endif diff --git a/src/shared/platform.h b/src/shared/platform.h index 249ef136..137a68ca 100644 --- a/src/shared/platform.h +++ b/src/shared/platform.h @@ -82,7 +82,7 @@ Platform_FileInGamedir(string fileName, string gameDir) fileSearch = search_begin(fileName, SEARCH_FULLPACKAGE, TRUE); fileCount = search_getsize(fileSearch); - print(sprintf("looking for %S in %S\n", fileName, gameDir)); + NSLog("Looking for %S in %S", fileName, gameDir); /* doesn't exist */ if (fileCount <= 0) @@ -94,11 +94,13 @@ Platform_FileInGamedir(string fileName, string gameDir) fileDir = substring(fullPath, 0, strlen(gameDir)); /* only need to check same-ness */ if (fileDir == gameDir) { - print("found it\n"); + NSLog("Found %S in %S", fileName, gameDir); return true; } } + NSError("Did not find %S in %S", fileName, gameDir); + /* file exists but is in a different gamedir */ return false; } diff --git a/src/shared/player_pmove.qc b/src/shared/player_pmove.qc index c76cab46..bca52194 100644 --- a/src/shared/player_pmove.qc +++ b/src/shared/player_pmove.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/pmove.qc b/src/shared/pmove.qc index f5eae09d..cf8a0f3f 100644 --- a/src/shared/pmove.qc +++ b/src/shared/pmove.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/shared/pmove_custom.qc b/src/shared/pmove_custom.qc index 40c80c7d..b654ef69 100644 --- a/src/shared/pmove_custom.qc +++ b/src/shared/pmove_custom.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -785,4 +785,4 @@ PMoveCustom_RunCrouchPhysics(entity target) target.view_ofs = PHY_VIEWPOS; } PMoveCustom_RunPlayerPhysics(target); -} \ No newline at end of file +} diff --git a/src/shared/propdata.qc b/src/shared/propdata.qc index cce8c152..d4a5b049 100644 --- a/src/shared/propdata.qc +++ b/src/shared/propdata.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -276,6 +276,9 @@ PropData_ForModel(string modelname) string line; int index; + if (!g_propdata_count) + return -1; + if (!modelname) return -1; @@ -309,7 +312,7 @@ PropData_ForModel(string modelname) g_propdata = (propdata_t *)memrealloc(g_propdata, sizeof(propdata_t), index, g_propdata_count); #else if (g_propdata_count >= PROPDATA_MAX) { - printf(sprintf("PropData_ForModel: Reached PROPDATA_MAX (%d)\n", PROPDATA_MAX)); + NSError("PropData_ForModel: Reached PROPDATA_MAX (%d)", PROPDATA_MAX); return -1i; } #endif @@ -323,7 +326,7 @@ PropData_ForModel(string modelname) if (fh < 0) { g_propdata_count--; - NSLog("Can't find propdata for model %s", modelname); + NSWarning("No PropData for model %S", modelname); return -1; } @@ -398,10 +401,7 @@ PropData_ForModel(string modelname) } fclose(fh); - dprint("^1[PROPDATA] No type found for "); - dprint(modelname); - dprint("\n"); - + NSError("No type found for %s", modelname); return -1; } @@ -418,7 +418,7 @@ PropData_Load(string type) index = (int)hash_get(g_hashpropdata, type, -1); if (index < 0) { - crossprint(sprintf("^1 PropData_Load: type %s is not defined\n", type)); + NSError("PropData type %S is not defined.", type); return -1; } else { return index; @@ -541,11 +541,7 @@ PropData_Init(void) string line; int index; -#ifdef SERVER - print("--------- Initializing PropDefs (SERVER) ----------\n"); -#else - print("--------- Initializing PropDefs (CLIENT) ----------\n"); -#endif + InitStart(); /* remove old data */ PropData_Shutdown(); @@ -561,7 +557,8 @@ PropData_Init(void) /* Defaults go here */ fh = fopen("scripts/propdata.txt", FILE_READ); if (fh < 0) { - print("^1[PROPDATA] Can't find propdata.txt\n"); + NSWarning("Missing file scripts/propdata.txt"); + InitEnd(); return; } @@ -578,8 +575,8 @@ PropData_Init(void) /* alocate our stuff */ g_propdata = (propdata_t *)memalloc(sizeof(propdata_t) * PROPDATA_MAX); g_breakmodel = (breakmodel_t *)memalloc(sizeof(breakmodel_t) * PROPDATA_MAX); - print(sprintf("allocated %d bytes for prop data.\n", sizeof(propdata_t) * PROPDATA_MAX)); - print(sprintf("allocated %d bytes for breakmodels.\n", sizeof(breakmodel_t) * PROPDATA_MAX)); + NSLog("...allocated %d bytes for prop data.", sizeof(propdata_t) * PROPDATA_MAX); + NSLog("...allocated %d bytes for breakmodels.", sizeof(breakmodel_t) * PROPDATA_MAX); #endif fseek(fh, 0); @@ -607,7 +604,6 @@ PropData_Init(void) } precache_model(mname); - NSLog("precaching break model: %S", mname); /* gotta tokenize our inputs again */ x = tokenize(g_breakmodel[i].data); @@ -619,7 +615,7 @@ PropData_Init(void) } g_breakmodel_end = g_breakmodel_count; - print("PropData initialized.\n"); + InitEnd(); } /* we can only tokenize one thing at a time, so we save the type for the current @@ -717,8 +713,8 @@ BreakModel_SpawnID(vector smins, vector smaxs, vector dir, float speed, int coun impactDecal = value; break; default: - print(sprintf("^1BreakModel_Spawn: Unrecognized model attribute %S with value %S\n", - key, value)); + NSError("Unrecognized model attribute %S with value %S", + key, value); } } @@ -801,11 +797,11 @@ BreakModel_Receive(void) /* sanity check */ if (index >= g_breakmodel_count) { - print(sprintf("^1Unable to spawn breakmodel of id %i. Not cached on client. (Client knows of %i)\n", index, g_breakmodel_count)); + NSError("Unable to spawn breakmodel of id %i. Not cached on client. (Client knows of %i)", index, g_breakmodel_count); return; } - //print(sprintf("i: %i max: %i name: %S\n", index, g_breakmodel_count, g_breakmodel[index].name)); + NSLog("BreakModel: i: %i max: %i name: %S", index, g_breakmodel_count, g_breakmodel[index].name); BreakModel_SpawnID(smins, smaxs, dir, speed, count, index); } @@ -846,11 +842,14 @@ void BreakModel_Spawn(vector smins, vector smaxs, vector dir, float speed, int count, string type) { int index; + vector pvsPosition; index = (int)hash_get(g_hashbreakmodel, type, -1); if (index == -1) return; + pvsPosition = (smins + ( 0.5 * ( smaxs - smins ))); + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_BREAKMODEL); WriteByte(MSG_MULTICAST, index); @@ -865,7 +864,7 @@ BreakModel_Spawn(vector smins, vector smaxs, vector dir, float speed, int count, WriteCoord(MSG_MULTICAST, dir[2]); WriteFloat(MSG_MULTICAST, speed); WriteByte(MSG_MULTICAST, count); - multicast((smins - smaxs), MULTICAST_PVS); + multicast(pvsPosition, MULTICAST_PVS); } void @@ -895,4 +894,4 @@ BreakModel_Entity(NSSurfacePropEntity target, vector dir, float speed) WriteByte(MSG_MULTICAST, count); multicast(pos, MULTICAST_PVS); } -#endif \ No newline at end of file +#endif diff --git a/src/shared/sentences.qc b/src/shared/sentences.qc index 171e649c..dfee853e 100644 --- a/src/shared/sentences.qc +++ b/src/shared/sentences.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -53,14 +53,15 @@ Sentences_Init(void) string temp; int c, i; - print("--------- Initializing SentencesDef (CLIENT) ----------\n"); + InitStart(); Sentences_Shutdown(); fs_sentences = fopen("sound/sentences.txt", FILE_READ); if (fs_sentences < 0) { - print("^1could not load sound/sentences.txt\n"); + NSError("Missing file sound/sentences.txt"); + InitEnd(); return; } @@ -91,7 +92,7 @@ Sentences_Init(void) g_sentences_count); #else if (g_sentences_count + 1 >= SENTENCES_LIMIT) { - print("^1reached limit of max sentences!\n"); + NSError("Reached limit of %d SentenceDefs.", SENTENCES_LIMIT); return; } @@ -118,7 +119,8 @@ Sentences_Init(void) } fclose(fs_sentences); - print(sprintf("SentencesDef initialized with %i entries.\n", g_sentences_count)); + NSLog("...SentencesDef initialized with %i entries.", g_sentences_count); + InitEnd(); } string @@ -151,7 +153,7 @@ Sentences_GetSamples(string msg) if (i != -1i) return g_sentences[i].m_strSamples; else { - print(sprintf("^1ERROR: Cannot find sentence %S\n", msg)); + NSError("Can't find sentence %S", msg); return ""; } } @@ -171,7 +173,7 @@ Sentences_Init(void) string temp; int c; - print("--------- Initializing SentencesDef (SERVER) ----------\n"); + InitStart(); if (g_sentences_count > 0) { g_sentences_count = 0; @@ -185,7 +187,8 @@ Sentences_Init(void) fs_sentences = fopen("sound/sentences.txt", FILE_READ); if (fs_sentences < 0) { - print("^1could not load sound/sentences.txt\n"); + NSError("Missing file sound/sentences.txt"); + InitEnd(); return; } @@ -216,7 +219,8 @@ Sentences_Init(void) g_sentences_count); #else if (g_sentences_count + 1 >= SENTENCES_LIMIT) { - print("^1reached limit of max sentences!\n"); + NSError("Reached limit of max sentences!"); + InitEnd(); return; } @@ -228,7 +232,8 @@ Sentences_Init(void) } fclose(fs_sentences); - print(sprintf("SentencesDef initialized with %i entries.\n", g_sentences_count)); + NSLog("SentencesDef initialized with %i entries.", g_sentences_count); + InitEnd(); } string @@ -264,12 +269,12 @@ Sentences_GetSamples(string word) /* if we've got one, choose a random sample of them */ if (gc) { r = floor(random(0, gc)); - NSLog("^3Sentences_GetSamples^7: Choosing %s%i", word, r); + SndLog("Choosing %s%i", word, r); return sprintf("%s%i", word, r); } /* we've somehow messed up catastrophically */ - print(sprintf("^1ERROR: Invalid sentence keyword %s\n", word)); + NSError("Invalid sentence keyword %s", word); return (""); } @@ -279,11 +284,11 @@ Sentences_GetID(string sentence) int i = (int)hash_get(g_hashsentences, sentence, -1i); if (i != -1i) { - print(sprintf("^2SUCCESS: Found sentence %S\n", sentence)); + SndLog("Found sentence %S", sentence); return i; } else { - print(sprintf("^1ERROR: Cannot find sentence %S\n", sentence)); + NSError("Can't find sentence %S", sentence); return 0; } } -#endif \ No newline at end of file +#endif diff --git a/src/shared/sound.h b/src/shared/sound.h index b5719da8..2d9f843d 100644 --- a/src/shared/sound.h +++ b/src/shared/sound.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,12 +30,34 @@ var bool autocvar_s_developer = false; void -_Sound_Log(string msg) +_SndLog(string functionName, string msg) { - if (autocvar_s_developer == true) - print(sprintf("%f %s\n", time, msg)); + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^xF50%s^7: %s\n", time, functionName, msg)); + else + print(sprintf("^xF50%s^7: %s\n", functionName, msg)); } -#define SndLog(...) _Sound_Log(sprintf(__VA_ARGS__)) + +/** Logs an sound system specific log message. + The console variable `s_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define SndLog(...) if (autocvar_s_developer) _SndLog(__FUNC__, sprintf(__VA_ARGS__)) + +void +_SndEntLog(string className, string functionName, float edictNum, string warnMessage) +{ + if (autocvar_g_developerTimestamps) + print(sprintf("^9%f ^xF50%s (id: %d)^7: %s\n", time, functionName, edictNum, warnMessage)); + else + print(sprintf("^xF50%s (id: %d)^7: %s\n", functionName, edictNum, warnMessage)); +} + +/** Logs an sound specific entity class log message. + The console variable `s_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define SndEntLog(...) if (autocvar_s_developer) _SndEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) /** Global hash table for name > soundDef id lookup. */ var hashtable g_hashsounds; @@ -112,4 +134,4 @@ void Sound_Speak(entity targetEntity, string sentencesEntry); /** Stops sounds on a given channel, on a target entity. */ void Sound_Stop(entity target, int chan); -void Sound_DebugList(); \ No newline at end of file +void Sound_DebugList(); diff --git a/src/shared/sound.qc b/src/shared/sound.qc index 18316592..5c219b72 100644 --- a/src/shared/sound.qc +++ b/src/shared/sound.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -49,26 +49,21 @@ void SoundSource_Init(void); void Sound_Init(void) { -#ifdef SERVER - print("--------- Initializing SoundDef (SERVER) ----------\n"); -#else - print("--------- Initializing SoundDef (CLIENT) ----------\n"); -#endif + InitStart(); /* make sure it's all reset */ Sound_Shutdown(); #ifndef SOUNDSHADER_DYNAMIC g_sounds = (snd_t *)memalloc(sizeof(snd_t) * SOUNDSHADER_MAX); - print(sprintf("allocated %d bytes for soundDef\n", sizeof(snd_t) * SOUNDSHADER_MAX)); + NSLog("...allocated %d bytes for SoundDef", sizeof(snd_t) * SOUNDSHADER_MAX); #endif /* Source Engine conventions */ SoundSource_Init(); precache_sound("common/null.wav"); - - print("SoundDef initialized.\n"); + InitEnd(); } static void @@ -407,7 +402,6 @@ Sound_Precache(string shader) cache = (int)hash_get(g_hashsounds, shader, -1); if (cache >= 0) { - SndLog("^1Sound_Precache: def %s already precached", shader); return cache; } } @@ -418,7 +412,7 @@ Sound_Precache(string shader) g_sounds = (snd_t *)memrealloc(g_sounds, sizeof(snd_t), index, g_sounds_count); #else if (g_sounds_count >= SOUNDSHADER_MAX) { - error(sprintf("Sound_Precache: Reached SOUNDSHADER_MAX (%d)\n", SOUNDSHADER_MAX)); + NSError("Reached SOUNDSHADER_MAX (%d)", SOUNDSHADER_MAX); return -1; } #endif @@ -454,11 +448,8 @@ Sound_Precache(string shader) fclose(fh); } - print("^1no SoundDef found for "); - print(shader); - print("\n"); + NSError("No SoundDef %S found.", shader); g_sounds_count--; - search_end(sh); return -1; } @@ -477,7 +468,7 @@ Sound_Distance(entity target, string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - crossprint(sprintf("^1Sound_Distance: def %s is not precached\n", shader)); + NSError("SoundDef %S is not precached", shader); return; } @@ -510,10 +501,6 @@ Sound_Distance(entity target, string shader) } #endif -#ifdef DEVELOPER - print(sprintf("Sound_Distance: %s\n", argv(r))); -#endif - sound( target, 5, @@ -540,7 +527,7 @@ Sound_DistancePos(vector pos, string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - SndLog("^1Sound_DistancePos: def %s is not precached (SERVER)\n", shader); + NSError("SoundDef %S is not precached", shader); return; } @@ -573,7 +560,7 @@ Sound_DistancePos(vector pos, string shader) } #endif - SndLog(sprintf("Sound_DistancePos: %s\n", argv(r))); + SndLog("Playing %S", argv(r)); pointsound_proper(pos, argv(r), volume, ATTN_NONE, pitch); } @@ -600,7 +587,7 @@ Sound_Play(entity target, int chan, string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - SndLog("^1Sound_Play: def %s is not precached\n", shader); + NSError("SoundDef %S is not precached", shader); return; } @@ -661,9 +648,7 @@ Sound_Play(entity target, int chan, string shader) } #endif -#ifdef DEVELOPER - print(sprintf("Sound_Play: %s\n", argv(r))); -#endif + SndLog("Playing %S", argv(r)); #ifdef SERVER if (g_sounds[sample].shakes > 0.0) { @@ -688,7 +673,7 @@ Sound_Play(entity target, int chan, string shader) pointparticles(g_sounds[sample].pointparticle, target.origin, [0,0,0], 1); #else if (g_sounds[sample].pointparticle) - print(sprintf("SoundDef %S is attempting to spawn a particle on the server side.\n", shader)); + NSWarning("SoundDef %S is attempting to spawn a particle on the server side.", shader); #endif sound( @@ -723,7 +708,7 @@ Sound_PlayAt(vector pos, string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - SndLog("^1Sound_PlayAt: def %s is not precached\n", shader); + NSError("SoundDef %S is not precached", shader); return; } @@ -779,7 +764,7 @@ Sound_PlayLocal(string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - SndLog("^1Sound_PlayLocal: def %s is not precached\n", shader); + NSError("SoundDef %S is not precached", shader); return; } @@ -865,7 +850,7 @@ Sound_Speak(entity target, string shader) sample = (int)hash_get(g_hashsounds, shader, -1); if (sample < 0) { - SndLog("^1Sound_Speak: def %s is not precached (SERVER)\n", shader); + NSError("SoundDef %S is not precached", shader); return; } @@ -956,4 +941,4 @@ Sound_DebugList(void) } print(sprintf("\t%i total soundDef loaded\n", g_sounds_count)); -} \ No newline at end of file +} diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index 6897fd21..b5600b54 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -175,7 +175,7 @@ SurfData_Load(string type) index = (int)hash_get(g_hashsurfdata, type, -1); if (index < 0) { - crossprint(sprintf("^1 SurfData_Load: type %s is not defined\n", type)); + NSError("SurfData %S is not defined.", type); return -1; } else { return index; @@ -207,7 +207,7 @@ SurfData_CountLine(string line) default: /* new definition starts */ if (c == 1 && braced == 0) { - t_name = strtolower(line); + t_name = strtolower(argv(0)); if (t_name) g_surfdata_count++; @@ -312,7 +312,7 @@ SurfData_Init(void) string line; int index; - print("--------- Initializing Surface Data ----------\n"); + InitStart(); /* remove old data */ SurfData_Shutdown(); @@ -328,7 +328,7 @@ SurfData_Init(void) /* it's OK for one to not exist... */ if (fh < 0) { - print("^1[SURFDATA] Can't find surfaceproperties.txt\n"); + NSError("missing scripts/surfaceproperties.txt!"); return; } @@ -339,7 +339,7 @@ SurfData_Init(void) /* we did not find 'default' as the first entry. */ if (g_spDefaultSet == false) { - error("^1no 'default' defined at the top of scripts/surfaceproperties.txt"); + NSError("no 'default' defined at the top of scripts/surfaceproperties.txt!"); return; } @@ -394,7 +394,8 @@ SurfData_Init(void) Sound_Precache(g_surfdata[i].m_sndBreak); } - print(sprintf("surface data initialized with %i entries.\n", g_surfdata_count)); + NSLog("...SurfData initialized with %i entries.", g_surfdata_count); + InitEnd(); } static string g_curSurfData; @@ -474,11 +475,6 @@ SurfData_Impact_Parse(void) string impactfx = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_FX_BULLETIMPACT); float impactid = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_FX_BULLETIMPACTID); - NSLog("SurfData_Impact_Parse:"); - NSLog("\tent: %S texture: %S", surfnum.classname, tex_name); - NSLog("\tplaying impact sfx %S at %v", impactsfx, impactorg); - NSLog("\temitting impact fx %S at %v", impactfx, impactorg); - Sound_PlayAt(impactorg, impactsfx); pointparticles( impactid, impactorg, impactang, 1 ); } @@ -520,7 +516,6 @@ SurfData_Impact(entity e, vector org, vector ang) if (trace_surfacename != "") { string n = strcat(dirname(e.model), "/", trace_surfacename); int texdata = SurfData_TexToSurfData(n); - NSLog("SurfData_Impact: %S %i\n", n, texdata); SurfData_ImpactID_Net(texdata, org, ang); } else SurfData_Impact_SurfaceParm(e, org, ang); @@ -549,4 +544,4 @@ SurfData_ImpactOfNamedType(string materialName, vector worldPosition, vector imp { int index = (int)hash_get(g_hashsurfdata, materialName, -1); SurfData_ImpactOfType(index, worldPosition, impactNormal); -} \ No newline at end of file +} diff --git a/src/shared/util.h b/src/shared/util.h index c89f6f01..568ad24f 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -1,2 +1,19 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + void Util_ChangeClass(entity, string); -string Util_ExtensionFromString(string inputString); \ No newline at end of file +string Util_ExtensionFromString(string inputString); +string Util_ChatFormat(float playerNum, float teamNum, string chatMessage); \ No newline at end of file diff --git a/src/shared/util.qc b/src/shared/util.qc index c91e4a78..bc606b9e 100644 --- a/src/shared/util.qc +++ b/src/shared/util.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -76,4 +76,24 @@ Util_ExtensionFromString(string inputString) { int modelNameLength = strlen(inputString); return substring(inputString, modelNameLength - 3, modelNameLength); +} + +string +Util_ChatFormat(float playerNum, float teamNum, string chatMessage) +{ + vector teamColor = stov(serverkey(sprintf("teamcolor_%d", teamNum))); + string teamColorString = sprintf("^x%x%x%x", teamColor[0] * 15,teamColor[1] * 15,teamColor[2] * 15); + string teamName = serverkey(sprintf("team_%d", teamNum)); + +#ifdef CLIENT + string playerName = getplayerkeyvalue(playerNum, "name"); +#else + string playerName = infokey(edict_num(playerNum+1), "name"); +#endif + + if (teamNum == 0) { + return sprintf("%s^7: %s", playerName, chatMessage); + } else { + return sprintf("%s %s(%s)^7: %s", playerName, teamColorString, teamName, chatMessage); + } } \ No newline at end of file diff --git a/src/shared/weapons.qc b/src/shared/weapons.qc index 4d5f24d5..f0181daa 100644 --- a/src/shared/weapons.qc +++ b/src/shared/weapons.qc @@ -96,4 +96,4 @@ void Weapon_DropCurrentWeapon(NSClientPlayer pl) {} int Weapon_GetCount() {} int Weapon_GetBitID(int) {} int Weapons_IsEmpty(NSClientPlayer, int) {} -#endif \ No newline at end of file +#endif