Example #1
0
        /*
         * ================
         * CG_AddExplosion
         * ================
         */
        static void CG_AddExplosion(localEntity_t *ex)
        {
            refEntity_t *ent;

            ent = &ex->refEntity;

            // add the entity
            trap_R_AddRefEntityToScene(ent);

            // add the dlight
            if (ex->light)
            {
                float light;

                light = (float)(cg.time - ex->startTime) / (ex->endTime - ex->startTime);
                if (light < 0.5)
                {
                    light = 1.0;
                }
                else
                {
                    light = 1.0 - (light - 0.5) * 2;
                }
                light = ex->light * light;
                trap_R_AddLightToScene(ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2]);
            }
        }
Example #2
0
        /*
         * ================
         * CG_ReflectVelocity
         * ================
         */
        void CG_ReflectVelocity(localEntity_t *le, trace_t *trace)
        {
            vec3_t velocity;
            float  dot;
            int    hitTime;

            // reflect the velocity on the trace plane
            hitTime = cg.time - cg.frametime + cg.frametime * trace->fraction;
            BG_EvaluateTrajectoryDelta(&le->pos, hitTime, velocity);
            dot = DotProduct(velocity, trace->plane.normal);
            VectorMA(velocity, -2 * dot, trace->plane.normal, le->pos.trDelta);

            VectorScale(le->pos.trDelta, le->bounceFactor, le->pos.trDelta);

            VectorCopy(trace->endpos, le->pos.trBase);
            le->pos.trTime = cg.time;


            // check for stop, making sure that even on low FPS systems it doesn't bobble
            if (trace->allsolid ||
                (trace->plane.normal[2] > 0 &&
                 (le->pos.trDelta[2] < 40 || le->pos.trDelta[2] < -cg.frametime * le->pos.trDelta[2])))
            {
                le->pos.trType = TR_STATIONARY;
            }
            else
            {
            }
        }
Example #3
0
        /*
         * =================
         * CG_AddFallScaleFade
         *
         * This is just an optimized CG_AddMoveScaleFade
         * For blood mists that drift down, fade out, and are
         * removed if the view passes through them.
         * There are often 100+ of these, so it needs to be simple.
         * =================
         */
        static void CG_AddFallScaleFade(localEntity_t *le)
        {
            refEntity_t *re;
            float        c;
            vec3_t       delta;
            float        len;

            re = &le->refEntity;

            // fade time
            c = (le->endTime - cg.time) * le->lifeRate;

            re->shaderRGBA[3] = 0xff * c * le->color[3];

            re->origin[2] = le->pos.trBase[2] - (1.0 - c) * le->pos.trDelta[2];

            re->radius = le->radius * (1.0 - c) + 16;

            // if the view would be "inside" the sprite, kill the sprite
            // so it doesn't add too much overdraw
            VectorSubtract(re->origin, cg.refdef.vieworg, delta);
            len = VectorLength(delta);
            if (len < le->radius)
            {
                CG_FreeLocalEntity(le);
                return;
            }

            trap_R_AddRefEntityToScene(re);
        }
Example #4
0
        /*
         * ================
         * CG_FragmentBounceSound
         * ================
         */
        void CG_FragmentBounceSound(localEntity_t *le, trace_t *trace)
        {
            if (le->leBounceSoundType == LEBS_BLOOD)
            {
                // half the gibs will make splat sounds
                if (rand() & 1)
                {
                    int         r = rand() & 3;
                    sfxHandle_t s;

                    if (r == 0)
                    {
                        s = cgs.media.gibBounce1Sound;
                    }
                    else if (r == 1)
                    {
                        s = cgs.media.gibBounce2Sound;
                    }
                    else
                    {
                        s = cgs.media.gibBounce3Sound;
                    }
                    trap_S_StartSound(trace->endpos, ENTITYNUM_WORLD, CHAN_AUTO, s);
                }
            }
            else if (le->leBounceSoundType == LEBS_BRASS)
            {
            }

            // don't allow a fragment to make multiple bounce sounds,
            // or it gets too noisy as they settle
            le->leBounceSoundType = LEBS_NONE;
        }
Example #5
0
        /*
         * ====================================================================================
         *
         * FRAGMENT PROCESSING
         *
         * A fragment localentity interacts with the environment in some way (hitting walls),
         * or generates more localentities along a trail.
         *
         * ====================================================================================
         */

        /*
         * ================
         * CG_BloodTrail
         *
         * Leave expanding blood puffs behind gibs
         * ================
         */
        void CG_BloodTrail(localEntity_t *le)
        {
            int            t;
            int            t2;
            int            step;
            vec3_t         newOrigin;
            localEntity_t *blood;

            step = 150;
            t    = step * ((cg.time - cg.frametime + step) / step);
            t2   = step * (cg.time / step);

            for ( ; t <= t2; t += step)
            {
                BG_EvaluateTrajectory(&le->pos, t, newOrigin);

                blood = CG_SmokePuff(newOrigin, vec3_origin,
                                     20,                                // radius
                                     1, 1, 1, 1,                        // color
                                     2000,                              // trailTime
                                     t,                                 // startTime
                                     0,                                 // fadeInTime
                                     0,                                 // flags
                                     cgs.media.bloodTrailShader);
                // use the optimized version
                blood->leType = LE_FALL_SCALE_FADE;
                // drop a total of 40 units over its lifetime
                blood->pos.trDelta[2] = 40;
            }
        }
Example #6
0
        localEntity_t *cg_freeLocalEntities;                    // single linked list

        /*
         * ===================
         * CG_InitLocalEntities
         *
         * This is called at startup and for tournement restarts
         * ===================
         */
        void    CG_InitLocalEntities(void)
        {
            int i;

            memset(cg_localEntities, 0, sizeof(cg_localEntities));
            cg_activeLocalEntities.next = &cg_activeLocalEntities;
            cg_activeLocalEntities.prev = &cg_activeLocalEntities;
            cg_freeLocalEntities        = cg_localEntities;
            for (i = 0; i < MAX_LOCAL_ENTITIES - 1; i++)
            {
                cg_localEntities[i].next = &cg_localEntities[i + 1];
            }
        }
Example #7
0
        /*
         * ==================
         * CG_FreeLocalEntity
         * ==================
         */
        void CG_FreeLocalEntity(localEntity_t *le)
        {
            if (!le->prev)
            {
                CG_Error("CG_FreeLocalEntity: not active");
            }

            // remove from the doubly linked active list
            le->prev->next = le->next;
            le->next->prev = le->prev;

            // the free list is only singly linked
            le->next             = cg_freeLocalEntities;
            cg_freeLocalEntities = le;
        }
Example #8
0
        /*
         * =====================================================================
         *
         * TRIVIAL LOCAL ENTITIES
         *
         * These only do simple scaling or modulation before passing to the renderer
         * =====================================================================
         */

        /*
         * ====================
         * CG_AddFadeRGB
         * ====================
         */
        void CG_AddFadeRGB(localEntity_t *le)
        {
            refEntity_t *re;
            float        c;

            re = &le->refEntity;

            c  = (le->endTime - cg.time) * le->lifeRate;
            c *= 0xff;

            re->shaderRGBA[0] = le->color[0] * c;
            re->shaderRGBA[1] = le->color[1] * c;
            re->shaderRGBA[2] = le->color[2] * c;
            re->shaderRGBA[3] = le->color[3] * c;

            trap_R_AddRefEntityToScene(re);
        }
Example #9
0
        /*
         * ================
         * CG_AddSpriteExplosion
         * ================
         */
        static void CG_AddSpriteExplosion(localEntity_t *le)
        {
            refEntity_t re;
            float       c;

            re = le->refEntity;

            c = (le->endTime - cg.time) / ( float )(le->endTime - le->startTime);
            if (c > 1)
            {
                c = 1.0;                        // can happen during connection problems
            }

            re.shaderRGBA[0] = 0xff;
            re.shaderRGBA[1] = 0xff;
            re.shaderRGBA[2] = 0xff;
            re.shaderRGBA[3] = 0xff * c * 0.33;

            re.reType = RT_SPRITE;
            re.radius = 42 * (1.0 - c) + 30;

            trap_R_AddRefEntityToScene(&re);

            // add the dlight
            if (le->light)
            {
                float light;

                light = (float)(cg.time - le->startTime) / (le->endTime - le->startTime);
                if (light < 0.5)
                {
                    light = 1.0;
                }
                else
                {
                    light = 1.0 - (light - 0.5) * 2;
                }
                light = le->light * light;
                trap_R_AddLightToScene(re.origin, light, le->lightColor[0], le->lightColor[1], le->lightColor[2]);
            }
        }
Example #10
0
        /*
         * ==================
         * CG_AddMoveScaleFade
         * ==================
         */
        static void CG_AddMoveScaleFade(localEntity_t *le)
        {
            refEntity_t *re;
            float        c;
            vec3_t       delta;
            float        len;

            re = &le->refEntity;

            if (le->fadeInTime > le->startTime && cg.time < le->fadeInTime)
            {
                // fade / grow time
                c = 1.0 - (float)(le->fadeInTime - cg.time) / (le->fadeInTime - le->startTime);
            }
            else
            {
                // fade / grow time
                c = (le->endTime - cg.time) * le->lifeRate;
            }

            re->shaderRGBA[3] = 0xff * c * le->color[3];

            if (!(le->leFlags & LEF_PUFF_DONT_SCALE))
            {
                re->radius = le->radius * (1.0 - c) + 8;
            }

            BG_EvaluateTrajectory(&le->pos, cg.time, re->origin);

            // if the view would be "inside" the sprite, kill the sprite
            // so it doesn't add too much overdraw
            VectorSubtract(re->origin, cg.refdef.vieworg, delta);
            len = VectorLength(delta);
            if (len < le->radius)
            {
                CG_FreeLocalEntity(le);
                return;
            }

            trap_R_AddRefEntityToScene(re);
        }
Example #11
0
        /*
         * ================
         * CG_FragmentBounceMark
         * ================
         */
        void CG_FragmentBounceMark(localEntity_t *le, trace_t *trace)
        {
            int radius;

            if (le->leMarkType == LEMT_BLOOD)
            {
                radius = 16 + (rand() & 31);
                CG_ImpactMark(cgs.media.bloodMarkShader, trace->endpos, trace->plane.normal, random() * 360,
                              1, 1, 1, 1, true, radius, false);
            }
            else if (le->leMarkType == LEMT_BURN)
            {
                radius = 8 + (rand() & 15);
                CG_ImpactMark(cgs.media.burnMarkShader, trace->endpos, trace->plane.normal, random() * 360,
                              1, 1, 1, 1, true, radius, false);
            }


            // don't allow a fragment to make multiple marks, or they
            // pile up while settling
            le->leMarkType = LEMT_NONE;
        }
Example #12
0
        /*
         * ===================
         * CG_AllocLocalEntity
         *
         * Will allways succeed, even if it requires freeing an old active entity
         * ===================
         */
        localEntity_t *CG_AllocLocalEntity(void)
        {
            localEntity_t *le;

            if (!cg_freeLocalEntities)
            {
                // no free entities, so free the one at the end of the chain
                // remove the oldest active entity
                CG_FreeLocalEntity(cg_activeLocalEntities.prev);
            }

            le = cg_freeLocalEntities;
            cg_freeLocalEntities = cg_freeLocalEntities->next;

            memset(le, 0, sizeof(*le));

            // link into the active list
            le->next = cg_activeLocalEntities.next;
            le->prev = &cg_activeLocalEntities;
            cg_activeLocalEntities.next->prev = le;
            cg_activeLocalEntities.next       = le;
            return(le);
        }
Example #13
0
        /*
         * ===================
         * CG_AddScorePlum
         * ===================
         */
                #define NUMBER_SIZE    8

        void CG_AddScorePlum(localEntity_t *le)
        {
            refEntity_t *re;
            vec3_t       origin, delta, dir, vec, up = { 0, 0, 1 };
            float        c, len;
            int          i, score, digits[10], numdigits, negative;
Example #14
0
        /*
         * ================
         * CG_AddFragment
         * ================
         */
        void CG_AddFragment(localEntity_t *le)
        {
            vec3_t  newOrigin;
            trace_t trace;

            if (le->pos.trType == TR_STATIONARY)
            {
                // sink into the ground if near the removal time
                int   t;
                float oldZ;

                t = le->endTime - cg.time;
                if (t < SINK_TIME)
                {
                    // we must use an explicit lighting origin, otherwise the
                    // lighting would be lost as soon as the origin went
                    // into the ground
                    VectorCopy(le->refEntity.origin, le->refEntity.lightingOrigin);
                    le->refEntity.renderfx |= RF_LIGHTING_ORIGIN;
                    oldZ = le->refEntity.origin[2];
                    le->refEntity.origin[2] -= 16 * (1.0 - (float)t / SINK_TIME);
                    trap_R_AddRefEntityToScene(&le->refEntity);
                    le->refEntity.origin[2] = oldZ;
                }
                else
                {
                    trap_R_AddRefEntityToScene(&le->refEntity);
                }

                return;
            }

            // calculate new position
            BG_EvaluateTrajectory(&le->pos, cg.time, newOrigin);

            // trace a line from previous position to new position
            CG_Trace(&trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID);
            if (trace.fraction == 1.0)
            {
                // still in free fall
                VectorCopy(newOrigin, le->refEntity.origin);

                if (le->leFlags & LEF_TUMBLE)
                {
                    vec3_t angles;

                    BG_EvaluateTrajectory(&le->angles, cg.time, angles);
                    AnglesToAxis(angles, le->refEntity.axis);
                }

                trap_R_AddRefEntityToScene(&le->refEntity);

                // add a blood trail
                if (le->leBounceSoundType == LEBS_BLOOD)
                {
                    CG_BloodTrail(le);
                }

                return;
            }

            // if it is in a nodrop zone, remove it
            // this keeps gibs from waiting at the bottom of pits of death
            // and floating levels
            if (trap_CM_PointContents(trace.endpos, 0) & CONTENTS_NODROP)
            {
                CG_FreeLocalEntity(le);
                return;
            }

            // leave a mark
            CG_FragmentBounceMark(le, &trace);

            // do a bouncy sound
            CG_FragmentBounceSound(le, &trace);

            // reflect the velocity on the trace plane
            CG_ReflectVelocity(le, &trace);

            trap_R_AddRefEntityToScene(&le->refEntity);
        }