From 0b75388ace3555d1723e8a11bddd4540d966c371 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Tue, 8 Sep 2020 03:36:49 +0200 Subject: [PATCH] game_player_equip: Initial implementation. --- src/gs-entbase/server.src | 1 + src/gs-entbase/server/game_player_equip.cpp | 134 ++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 src/gs-entbase/server/game_player_equip.cpp diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index 3928324d..08837bd1 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -28,6 +28,7 @@ server/env_render.cpp server/env_shake.cpp server/env_message.cpp server/game_text.cpp +server/game_player_equip.cpp server/path_corner.cpp server/path_track.cpp server/func_recharge.cpp diff --git a/src/gs-entbase/server/game_player_equip.cpp b/src/gs-entbase/server/game_player_equip.cpp new file mode 100644 index 00000000..b2316d77 --- /dev/null +++ b/src/gs-entbase/server/game_player_equip.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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. + */ + +/*QUAKED game_player_equip (1 0 0) (-8 -8 -8) (8 8 8) GPEFL_TRIGGERONLY +"targetname" Name +"master" Team Master + +Entity that emits items when triggered, or upon player spawn (MP-only). + +When the flag GPEFL_TRIGGERONLY is set, the entity has to be triggered +in order to 'give' the activator the item. Otherwise it'll automatically +'give' every client its noted items upon spawning. +However, this only applies to Multiplayer games. In Singleplayer, the entity +will only work with GPEFL_TRIGGERONLY being set. + +Notes: +I say 'give' very loosely because the entity spawns the item in physical pickup +form above the player. As you can imagine, it's kind of wasteful but this is the +expected behaviour. Some modifications might depend on that... + +I still need to implement the Team Master functionality. + +Trivia: +This entity was introduced in Half-Life (1998). +*/ + +enumflags +{ + GPEFL_TRIGGERONLY +}; + +class game_player_equip:CBaseTrigger +{ + string m_strBuffer; + + void(void) game_player_equip; + + virtual void(string, vector) SpawnUnit; + virtual void(entity, int) Trigger; +}; + +void +game_player_equip::SpawnUnit(string cname, vector org) +{ + static void game_player_equip_spawnunit(void) { + /* these might get overwritten by the spawnfunction */ + vector neworg = self.origin; + + /* become the classname assigned */ + CBaseEntity t = (CBaseEntity)self; + callfunction(self.classname); + + /* apply the saved values back */ + t.origin = t.m_oldOrigin = neworg; + + /* spawn anew */ + t.Respawn(); + } + + entity unit = spawn(); + unit.classname = cname; + unit.think = game_player_equip_spawnunit; + unit.nextthink = time; + unit.real_owner = this; + setorigin(unit, org); + dprint(sprintf("^2game_player_equip::^3Trigger^7: Spawning %s\n", + cname)); +} + +void +game_player_equip::Trigger(entity act, int state) +{ + int total, i, count, x; + string cname; + + if (!(act.flags & FL_CLIENT)) { + print("^1game_player_equip^7::^1Trigger: Activator not a client!\n"); + return; + } + + /* loop through all catalogued entries */ + total = tokenizebyseparator(m_strBuffer, " "); + + for (i = 0; i < total; i+=2) { + cname = argv(i); + count = stoi(argv(i+1)); + + for (x = 0; x < count; x++) { + if (isfunction(strcat("spawnfunc_", cname))) { + cname = strcat("spawnfunc_", cname); + game_player_equip::SpawnUnit(cname, act.origin); + } else if (isfunction(cname)) { + game_player_equip::SpawnUnit(cname, act.origin); + } + } + } +} + +void +game_player_equip::game_player_equip(void) +{ + /* like multi_manager, we save non-field infos in the spawndata */ + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { + case "{": + case "}": + case "classname": + case "origin": + case "targetname": + case "spawnflags": + case "angle": + case "angles": + continue; + break; + default: + m_strBuffer = sprintf("%s%s %s ", m_strBuffer, argv(i), argv(i+1)); + } + } + + CBaseTrigger::CBaseTrigger(); +}