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

📄 sv.java

📁 JAKE2用JAVA写的queck2的3D游戏开发引擎
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        if (ent.velocity[2] != 0 || ent.velocity[1] != 0                || ent.velocity[0] != 0) {            // apply friction            // let dead monsters who aren't completely onground slide            if ((wasonground)                    || 0 != (ent.flags & (Defines.FL_SWIM | Defines.FL_FLY)))                if (!(ent.health <= 0.0 && !M.M_CheckBottom(ent))) {                    vel = ent.velocity;                    speed = (float) Math                            .sqrt(vel[0] * vel[0] + vel[1] * vel[1]);                    if (speed != 0) {                        friction = Defines.sv_friction;                        control = speed < Defines.sv_stopspeed ? Defines.sv_stopspeed                                : speed;                        newspeed = speed - Defines.FRAMETIME * control                                * friction;                        if (newspeed < 0)                            newspeed = 0;                        newspeed /= speed;                        vel[0] *= newspeed;                        vel[1] *= newspeed;                    }                }            if ((ent.svflags & Defines.SVF_MONSTER) != 0)                mask = Defines.MASK_MONSTERSOLID;            else                mask = Defines.MASK_SOLID;            SV_FlyMove(ent, Defines.FRAMETIME, mask);            GameBase.gi.linkentity(ent);            GameBase.G_TouchTriggers(ent);            if (!ent.inuse)                return;            if (ent.groundentity != null)                if (!wasonground)                    if (hitsound)                        GameBase.gi.sound(ent, 0,                         		GameBase.gi.soundindex("world/land.wav"), 1, 1, 0);        }        // regular thinking        SV_RunThink(ent);    }    /**     * Called by monster program code. The move will be adjusted for slopes and     * stairs, but if the move isn't possible, no move is done, false is     * returned, and pr_global_struct.trace_normal is set to the normal of the     * blocking wall.     */        // FIXME: since we need to test end position contents here, can we avoid    // doing it again later in catagorize position?    public static boolean SV_movestep(edict_t ent, float[] move, boolean relink) {        float dz;        float[] oldorg = { 0, 0, 0 };        float[] neworg = { 0, 0, 0 };        float[] end = { 0, 0, 0 };        trace_t trace = null; // = new trace_t();        int i;        float stepsize;        float[] test = { 0, 0, 0 };        int contents;        //	   try the move        Math3D.VectorCopy(ent.s.origin, oldorg);        Math3D.VectorAdd(ent.s.origin, move, neworg);        //	   flying monsters don't step up        if ((ent.flags & (Defines.FL_SWIM | Defines.FL_FLY)) != 0) {            // try one move with vertical motion, then one without            for (i = 0; i < 2; i++) {                Math3D.VectorAdd(ent.s.origin, move, neworg);                if (i == 0 && ent.enemy != null) {                    if (ent.goalentity == null)                        ent.goalentity = ent.enemy;                    dz = ent.s.origin[2] - ent.goalentity.s.origin[2];                    if (ent.goalentity.client != null) {                        if (dz > 40)                            neworg[2] -= 8;                        if (!((ent.flags & Defines.FL_SWIM) != 0 && (ent.waterlevel < 2)))                            if (dz < 30)                                neworg[2] += 8;                    } else {                        if (dz > 8)                            neworg[2] -= 8;                        else if (dz > 0)                            neworg[2] -= dz;                        else if (dz < -8)                            neworg[2] += 8;                        else                            neworg[2] += dz;                    }                }                trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs,                        neworg, ent, Defines.MASK_MONSTERSOLID);                // fly monsters don't enter water voluntarily                if ((ent.flags & Defines.FL_FLY) != 0) {                    if (ent.waterlevel == 0) {                        test[0] = trace.endpos[0];                        test[1] = trace.endpos[1];                        test[2] = trace.endpos[2] + ent.mins[2] + 1;                        contents = GameBase.gi.pointcontents.pointcontents(test);                        if ((contents & Defines.MASK_WATER) != 0)                            return false;                    }                }                // swim monsters don't exit water voluntarily                if ((ent.flags & Defines.FL_SWIM) != 0) {                    if (ent.waterlevel < 2) {                        test[0] = trace.endpos[0];                        test[1] = trace.endpos[1];                        test[2] = trace.endpos[2] + ent.mins[2] + 1;                        contents = GameBase.gi.pointcontents.pointcontents(test);                        if ((contents & Defines.MASK_WATER) == 0)                            return false;                    }                }                if (trace.fraction == 1) {                    Math3D.VectorCopy(trace.endpos, ent.s.origin);                    if (relink) {                        GameBase.gi.linkentity(ent);                        GameBase.G_TouchTriggers(ent);                    }                    return true;                }                if (ent.enemy == null)                    break;            }            return false;        }        //	   push down from a step height above the wished position        if ((ent.monsterinfo.aiflags & Defines.AI_NOSTEP) == 0)            stepsize = GameBase.STEPSIZE;        else            stepsize = 1;        neworg[2] += stepsize;        Math3D.VectorCopy(neworg, end);        end[2] -= stepsize * 2;        trace = GameBase.gi.trace(neworg, ent.mins, ent.maxs, end, ent,                Defines.MASK_MONSTERSOLID);        if (trace.allsolid)            return false;        if (trace.startsolid) {            neworg[2] -= stepsize;            trace = GameBase.gi.trace(neworg, ent.mins, ent.maxs, end, ent,                    Defines.MASK_MONSTERSOLID);            if (trace.allsolid || trace.startsolid)                return false;        }        // don't go in to water        if (ent.waterlevel == 0) {            test[0] = trace.endpos[0];            test[1] = trace.endpos[1];            test[2] = trace.endpos[2] + ent.mins[2] + 1;            contents = GameBase.gi.pointcontents.pointcontents(test);            if ((contents & Defines.MASK_WATER) != 0)                return false;        }        if (trace.fraction == 1) {            // if monster had the ground pulled out, go ahead and fall            if ((ent.flags & Defines.FL_PARTIALGROUND) != 0) {                Math3D.VectorAdd(ent.s.origin, move, ent.s.origin);                if (relink) {                    GameBase.gi.linkentity(ent);                    GameBase.G_TouchTriggers(ent);                }                ent.groundentity = null;                return true;            }            return false; // walked off an edge        }        //	   check point traces down for dangling corners        Math3D.VectorCopy(trace.endpos, ent.s.origin);        if (!M.M_CheckBottom(ent)) {            if ((ent.flags & Defines.FL_PARTIALGROUND) != 0) {                // entity had floor mostly pulled out from underneath it                // and is trying to correct                if (relink) {                    GameBase.gi.linkentity(ent);                    GameBase.G_TouchTriggers(ent);                }                return true;            }            Math3D.VectorCopy(oldorg, ent.s.origin);            return false;        }        if ((ent.flags & Defines.FL_PARTIALGROUND) != 0) {            ent.flags &= ~Defines.FL_PARTIALGROUND;        }        ent.groundentity = trace.ent;        ent.groundentity_linkcount = trace.ent.linkcount;        //	   the move is ok        if (relink) {            GameBase.gi.linkentity(ent);            GameBase.G_TouchTriggers(ent);        }        return true;    }    /**      * Turns to the movement direction, and walks the current distance if facing     * it.     */    public static boolean SV_StepDirection(edict_t ent, float yaw, float dist) {        float[] move = { 0, 0, 0 };        float[] oldorigin = { 0, 0, 0 };        float delta;        ent.ideal_yaw = yaw;        M.M_ChangeYaw(ent);        yaw = (float) (yaw * Math.PI * 2 / 360);        move[0] = (float) Math.cos(yaw) * dist;        move[1] = (float) Math.sin(yaw) * dist;        move[2] = 0;        Math3D.VectorCopy(ent.s.origin, oldorigin);        if (SV_movestep(ent, move, false)) {            delta = ent.s.angles[Defines.YAW] - ent.ideal_yaw;            if (delta > 45 && delta < 315) { // not turned far enough, so don't                                             // take the step                Math3D.VectorCopy(oldorigin, ent.s.origin);            }            GameBase.gi.linkentity(ent);            GameBase.G_TouchTriggers(ent);            return true;        }        GameBase.gi.linkentity(ent);        GameBase.G_TouchTriggers(ent);        return false;    }    /**     * SV_FixCheckBottom     *      */    public static void SV_FixCheckBottom(edict_t ent) {        ent.flags |= Defines.FL_PARTIALGROUND;    }    public static void SV_NewChaseDir(edict_t actor, edict_t enemy, float dist) {        float deltax, deltay;        float d[] = { 0, 0, 0 };        float tdir, olddir, turnaround;        //FIXME: how did we get here with no enemy        if (enemy == null) {            Com.DPrintf("SV_NewChaseDir without enemy!\n");            return;        }        olddir = Math3D.anglemod((int) (actor.ideal_yaw / 45) * 45);        turnaround = Math3D.anglemod(olddir - 180);        deltax = enemy.s.origin[0] - actor.s.origin[0];        deltay = enemy.s.origin[1] - actor.s.origin[1];        if (deltax > 10)            d[1] = 0;        else if (deltax < -10)            d[1] = 180;        else            d[1] = DI_NODIR;        if (deltay < -10)            d[2] = 270;        else if (deltay > 10)            d[2] = 90;        else            d[2] = DI_NODIR;        //	   try direct route        if (d[1] != DI_NODIR && d[2] != DI_NODIR) {            if (d[1] == 0)                tdir = d[2] == 90 ? 45 : 315;            else                tdir = d[2] == 90 ? 135 : 215;            if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))                return;        }        //	   try other directions        if (((Lib.rand() & 3) & 1) != 0 || Math.abs(deltay) > Math.abs(deltax)) {            tdir = d[1];            d[1] = d[2];            d[2] = tdir;        }        if (d[1] != DI_NODIR && d[1] != turnaround                && SV_StepDirection(actor, d[1], dist))            return;        if (d[2] != DI_NODIR && d[2] != turnaround                && SV_StepDirection(actor, d[2], dist))            return;        /* there is no direct path to the player, so pick another direction */        if (olddir != DI_NODIR                && SV_StepDirection(actor, olddir, dist))            return;        if ((Lib.rand() & 1) != 0) /* randomly determine direction of search */{            for (tdir = 0; tdir <= 315; tdir += 45)                if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))                    return;        } else {            for (tdir = 315; tdir >= 0; tdir -= 45)                if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))                    return;        }        if (turnaround != DI_NODIR                && SV_StepDirection(actor, turnaround, dist))            return;        actor.ideal_yaw = olddir; // can't move        // if a bridge was pulled out from underneath a monster, it may not have        // a valid standing position at all        if (!M.M_CheckBottom(actor))            SV_FixCheckBottom(actor);    }    /**     * SV_CloseEnough - returns true if distance between 2 ents is smaller than     * given dist.       */    public static boolean SV_CloseEnough(edict_t ent, edict_t goal, float dist) {        int i;        for (i = 0; i < 3; i++) {            if (goal.absmin[i] > ent.absmax[i] + dist)                return false;            if (goal.absmax[i] < ent.absmin[i] - dist)                return false;        }        return true;    }	public static int DI_NODIR = -1;}

⌨️ 快捷键说明

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