Author: RisK <si.tenmis@bbrk>     Reply to Message
Date: 8/18/2002 11:50:23 PM
Subject: RE: Why do...

Rav, it supries me how naive you can be, still insisting the world is flat.

There is no performace hit and I do not know where you hide your ass when you are playing on servers (if you play at all), but this does indeed happen on regular basis.

Let me cast a light on this for you, wether you follow or not. The vanila server code is about 50.000 lines, the code needed to 'fix' this is less than ten lines. The CPU overhead is closer to none than any, same can be said about the few bytes added to the stack..... ach, like you would understand this




This took me about 40min to figure out, but then again I'm not very familar with MOD'ing and the q3 code, hopfully pice and my non existent html skills will get along.

Green is would remain unchanged, just for references.
Blue is new code.
Red is removed code.

In g_items.c (func LaunchItem) change:
        if (g_gametype.integer == GT_CTF && item->giType == IT_TEAM) {
                // Special case for CTF flags
#endif
                dropped->think = Team_DroppedFlagThink;
                dropped->nextthink = level.time + 30000;
                Team_CheckDroppedItem( dropped );
        } else { // auto-remove after 30 seconds

To:
        if (g_gametype.integer == GT_CTF && item->giType == IT_TEAM) {
                // Special case for CTF flags
#endif
                dropped->think = Team_DroppedFlagThink;
                dropped->nextthink = level.time + 30000;
                Team_CheckDroppedItem( dropped );
                dropped->takedamage = qtrue;
                dropped->health = 400;
        } else { // auto-remove after 30 seconds

In g_mover.c (func Blocked_Door) change:
        if ( !other->client) {
                // except CTF flags!!!!
                if( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM ) {
                        Team_DroppedFlagThink( other );
                        return;
                }
                G_TempEntity( other->s.origin, EV_ITEM_POP );
                G_FreeEntity( other );
                return;
        }

To:
        if ( !other->client && !( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM )) {
                G_TempEntity( other->s.origin, EV_ITEM_POP );
                G_FreeEntity( other );
                return;
        }

In g_combat.c (func G_Damage) change:
        if (!targ->takedamage) {
                return;
        }

        // the intermission has allready been qualified for, so don't
        // allow any extra scoring
 
To:
        if (!targ->takedamage) {
                return;
        }

        if ( g_gametype.integer == GT_CTF && targ->item->giType == IT_TEAM && ( mod == MOD_TRIGGER_HURT || mod == MOD_CRUSH ) ) {
                targ->health-=damage;
                if ( targ->health <= 0 ) {
                        Team_DroppedFlagThink( targ );
                }
                return;
        }
 
        // the intermission has allready been qualified for, so don't
        // allow any extra scoring
 

That is all, not 100% stress tested, but worked with very platform, door, crusher I tried it with without a flaw. Now I really hope you understand that this is not an issue about performance, complexity or anything like that, it is solely the reasons I stated before.

And here is a little bonus I added. This is probably not done the proper way, but it functions, a simple code that will return the flag is it gets stuck on instagib hurt zone (trigger_hurt).

In g_local.h change:
//
// g_trigger.c
//
void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace );
 

To:
//
// g_trigger.c
//
void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace );
void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace );
 
In g_trigger (func G_RunItem) change:
                return;
        }

        G_BounceItem( ent, &tr );
 
To:
                return;
        }

        
if ( g_gametype.integer == GT_CTF && ent->item->giType == IT_TEAM ) {
                int i,num;
                int touch[MAX_GENTITIES];
                vec3_t mins, maxs;
                gentity_t *hit;
                trace_t trace;
                static vec3_t range = { 40, 40, 52 };

                VectorSubtract( ent->r.currentOrigin, range, mins );
                VectorAdd( ent->r.currentOrigin, range, maxs );

                num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES );

                for ( i=0 ; i<num ; i++ ) {
                        hit = &g_entities[touch[i]];

                        if ( hit->touch == hurt_touch ) {
                                hit->touch (hit, ent, &trace);
                        }
                }
        }

        G_BounceItem( ent, &tr );


-RisK
_