⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameutil.java

📁 Jake2是一个Java 3D游戏引擎.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1997-2001 Id Software, Inc. *  * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. *  * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. *  * See the GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. *   */// Created on 01.11.2003 by RST.// $Id: GameUtil.java,v 1.15 2005/12/27 21:02:31 salomo Exp $package jake2.game;import jake2.Defines;import jake2.Globals;import jake2.client.M;import jake2.qcommon.Com;import jake2.util.Lib;import jake2.util.Math3D;public class GameUtil {    public static void checkClassname(edict_t ent) {        if (ent.classname == null) {            Com.Printf("edict with classname = null: " + ent.index);        }    }    /**      * Use the targets.     *      * The global "activator" should be set to the entity that initiated the     * firing.     *      * If self.delay is set, a DelayedUse entity will be created that will     * actually do the SUB_UseTargets after that many seconds have passed.     *      * Centerprints any self.message to the activator.     *      * Search for (string)targetname in all entities that match     * (string)self.target and call their .use function     */    public static void G_UseTargets(edict_t ent, edict_t activator) {        edict_t t;        checkClassname(ent);        // check for a delay        if (ent.delay != 0) {            // create a temp object to fire at a later time            t = G_Spawn();            t.classname = "DelayedUse";            t.nextthink = GameBase.level.time + ent.delay;            t.think = Think_Delay;            t.activator = activator;            if (activator == null)                GameBase.gi.dprintf("Think_Delay with no activator\n");            t.message = ent.message;            t.target = ent.target;            t.killtarget = ent.killtarget;            return;        }        // print the message        if ((ent.message != null)                && (activator.svflags & Defines.SVF_MONSTER) == 0) {            GameBase.gi.centerprintf(activator, "" + ent.message);            if (ent.noise_index != 0)                GameBase.gi.sound(activator, Defines.CHAN_AUTO,                        ent.noise_index, 1, Defines.ATTN_NORM, 0);            else                GameBase.gi.sound(activator, Defines.CHAN_AUTO, GameBase.gi                        .soundindex("misc/talk1.wav"), 1, Defines.ATTN_NORM, 0);        }        // kill killtargets        EdictIterator edit = null;        if (ent.killtarget != null) {            while ((edit = GameBase.G_Find(edit, GameBase.findByTarget,                    ent.killtarget)) != null) {                t = edit.o;                G_FreeEdict(t);                if (!ent.inuse) {                    GameBase.gi                            .dprintf("entity was removed while using killtargets\n");                    return;                }            }        }        // fire targets        if (ent.target != null) {            edit = null;            while ((edit = GameBase.G_Find(edit, GameBase.findByTarget,                    ent.target)) != null) {                t = edit.o;                // doors fire area portals in a specific way                if (Lib.Q_stricmp("func_areaportal", t.classname) == 0                        && (Lib.Q_stricmp("func_door", ent.classname) == 0 || Lib                                .Q_stricmp("func_door_rotating", ent.classname) == 0))                    continue;                if (t == ent) {                    GameBase.gi.dprintf("WARNING: Entity used itself.\n");                } else {                    if (t.use != null)                        t.use.use(t, ent, activator);                }                if (!ent.inuse) {                    GameBase.gi                            .dprintf("entity was removed while using targets\n");                    return;                }            }        }    }    public static void G_InitEdict(edict_t e, int i) {        e.inuse = true;        e.classname = "noclass";        e.gravity = 1.0f;        //e.s.number= e - g_edicts;        e.s = new entity_state_t(e);        e.s.number = i;        e.index = i;    }    /**     * Either finds a free edict, or allocates a new one. Try to avoid reusing     * an entity that was recently freed, because it can cause the client to     * think the entity morphed into something else instead of being removed and     * recreated, which can cause interpolated angles and bad trails.     */    public static edict_t G_Spawn() {        int i;        edict_t e = null;        for (i = (int) GameBase.maxclients.value + 1; i < GameBase.num_edicts; i++) {            e = GameBase.g_edicts[i];            // the first couple seconds of server time can involve a lot of            // freeing and allocating, so relax the replacement policy            if (!e.inuse                    && (e.freetime < 2 || GameBase.level.time - e.freetime > 0.5)) {                e = GameBase.g_edicts[i] = new edict_t(i);                G_InitEdict(e, i);                return e;            }        }        if (i == GameBase.game.maxentities)            GameBase.gi.error("ED_Alloc: no free edicts");        e = GameBase.g_edicts[i] = new edict_t(i);        GameBase.num_edicts++;        G_InitEdict(e, i);        return e;    }    /**     * Marks the edict as free     */    public static void G_FreeEdict(edict_t ed) {        GameBase.gi.unlinkentity(ed); // unlink from world        //if ((ed - g_edicts) <= (maxclients.value + BODY_QUEUE_SIZE))        if (ed.index <= (GameBase.maxclients.value + Defines.BODY_QUEUE_SIZE)) {            // gi.dprintf("tried to free special edict\n");            return;        }        GameBase.g_edicts[ed.index] = new edict_t(ed.index);        ed.classname = "freed";        ed.freetime = GameBase.level.time;        ed.inuse = false;    }    /**     * Call after linking a new trigger in during gameplay to force all entities     * it covers to immediately touch it.     */    public static void G_ClearEdict(edict_t ent) {        int i = ent.index;        GameBase.g_edicts[i] = new edict_t(i);    }    /**     * Kills all entities that would touch the proposed new positioning of ent.     * Ent should be unlinked before calling this!     */    public static boolean KillBox(edict_t ent) {        trace_t tr;        while (true) {            tr = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs,                    ent.s.origin, null, Defines.MASK_PLAYERSOLID);            if (tr.ent == null || tr.ent == GameBase.g_edicts[0])                break;            // nail it            GameCombat.T_Damage(tr.ent, ent, ent, Globals.vec3_origin, ent.s.origin,                    Globals.vec3_origin, 100000, 0,                    Defines.DAMAGE_NO_PROTECTION, Defines.MOD_TELEFRAG);            // if we didn't kill it, fail            if (tr.ent.solid != 0)                return false;        }        return true; // all clear    }    /**      * Returns true, if two edicts are on the same team.      */    public static boolean OnSameTeam(edict_t ent1, edict_t ent2) {        if (0 == ((int) (GameBase.dmflags.value) & (Defines.DF_MODELTEAMS | Defines.DF_SKINTEAMS)))            return false;        if (ClientTeam(ent1).equals(ClientTeam(ent2)))            return true;        return false;    }    /**      * Returns the team string of an entity      * with respect to rteam_by_model and team_by_skin.      */    static String ClientTeam(edict_t ent) {        String value;        if (ent.client == null)            return "";        value = Info.Info_ValueForKey(ent.client.pers.userinfo, "skin");        int p = value.indexOf("/");        if (p == -1)            return value;        if (((int) (GameBase.dmflags.value) & Defines.DF_MODELTEAMS) != 0) {            return value.substring(0, p);        }        return value.substring(p + 1, value.length());    }    static void ValidateSelectedItem(edict_t ent) {        gclient_t cl;        cl = ent.client;        if (cl.pers.inventory[cl.pers.selected_item] != 0)            return; // valid        GameItems.SelectNextItem(ent, -1);    }    /**     * Returns the range catagorization of an entity reletive to self 0 melee     * range, will become hostile even if back is turned 1 visibility and     * infront, or visibility and show hostile 2 infront and show hostile 3 only     * triggered by damage.     */    public static int range(edict_t self, edict_t other) {        float[] v = { 0, 0, 0 };        float len;        Math3D.VectorSubtract(self.s.origin, other.s.origin, v);        len = Math3D.VectorLength(v);        if (len < Defines.MELEE_DISTANCE)            return Defines.RANGE_MELEE;        if (len < 500)            return Defines.RANGE_NEAR;        if (len < 1000)            return Defines.RANGE_MID;        return Defines.RANGE_FAR;    }    static void AttackFinished(edict_t self, float time) {        self.monsterinfo.attack_finished = GameBase.level.time + time;    }    /**     * Returns true if the entity is in front (in sight) of self     */    public static boolean infront(edict_t self, edict_t other) {        float[] vec = { 0, 0, 0 };        float dot;        float[] forward = { 0, 0, 0 };        Math3D.AngleVectors(self.s.angles, forward, null, null);        Math3D.VectorSubtract(other.s.origin, self.s.origin, vec);        Math3D.VectorNormalize(vec);        dot = Math3D.DotProduct(vec, forward);        if (dot > 0.3)            return true;        return false;    }    /**     * Returns 1 if the entity is visible to self, even if not infront().     */    public static boolean visible(edict_t self, edict_t other) {        float[] spot1 = { 0, 0, 0 };        float[] spot2 = { 0, 0, 0 };        trace_t trace;        Math3D.VectorCopy(self.s.origin, spot1);        spot1[2] += self.viewheight;        Math3D.VectorCopy(other.s.origin, spot2);        spot2[2] += other.viewheight;        trace = GameBase.gi.trace(spot1, Globals.vec3_origin,                Globals.vec3_origin, spot2, self, Defines.MASK_OPAQUE);        if (trace.fraction == 1.0)            return true;        return false;    }    /**     * Finds a target.     *      * Self is currently not attacking anything, so try to find a target     * 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -