Annotation of quake2/rogue/dm_ball.c, revision 1.1

1.1     ! root        1: // dm_ball.c
        !             2: // pmack
        !             3: // june 98
        !             4: 
        !             5: #include "g_local.h"
        !             6: 
        !             7: // defines
        !             8: 
        !             9: #define DBALL_GOAL_TEAM1       0x0001
        !            10: #define DBALL_GOAL_TEAM2       0x0002
        !            11: 
        !            12: // globals
        !            13: 
        !            14: edict_t *dball_ball_entity = NULL;
        !            15: int            dball_ball_startpt_count;
        !            16: int            dball_team1_goalscore;
        !            17: int            dball_team2_goalscore;
        !            18: 
        !            19: cvar_t *dball_team1_skin;
        !            20: cvar_t *dball_team2_skin;
        !            21: cvar_t *goallimit;
        !            22: 
        !            23: // prototypes
        !            24: 
        !            25: extern void EndDMLevel (void);
        !            26: extern void ClientUserinfoChanged (edict_t *ent, char *userinfo);
        !            27: extern void    SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles);
        !            28: extern float PlayersRangeFromSpot (edict_t *spot);
        !            29: 
        !            30: void DBall_BallDie (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
        !            31: void DBall_BallRespawn (edict_t *self);
        !            32: 
        !            33: // **************************
        !            34: // Game rules
        !            35: // **************************
        !            36: 
        !            37: int DBall_CheckDMRules (void)
        !            38: {
        !            39:        if(goallimit && goallimit->value)
        !            40:        {
        !            41:                if(dball_team1_goalscore >= goallimit->value)
        !            42:                        gi.bprintf (PRINT_HIGH, "Team 1 Wins.\n");
        !            43:                else if(dball_team2_goalscore >= goallimit->value)
        !            44:                        gi.bprintf (PRINT_HIGH, "Team 2 Wins.\n");
        !            45:                else
        !            46:                        return 0;
        !            47: 
        !            48:                EndDMLevel ();
        !            49:                return 1;
        !            50:        }
        !            51: 
        !            52:        return 0;
        !            53: }
        !            54: 
        !            55: //==================
        !            56: //==================
        !            57: void DBall_ClientBegin (edict_t *ent)
        !            58: {
        !            59:        int                     team1, team2, unassigned;
        !            60:        edict_t         *other;
        !            61:        char            *p;
        !            62:        static char     value[512];
        !            63:        int                     j;
        !            64: 
        !            65:        team1 = 0;
        !            66:        team2 = 0;
        !            67:        unassigned = 0;
        !            68: 
        !            69:        for (j = 1; j <= game.maxclients; j++)
        !            70:        {
        !            71:                other = &g_edicts[j];
        !            72:                if (!other->inuse)
        !            73:                        continue;
        !            74:                if (!other->client)
        !            75:                        continue;
        !            76:                if (other == ent)       // don't count the new player
        !            77:                        continue;
        !            78:                
        !            79:                strcpy(value, Info_ValueForKey (other->client->pers.userinfo, "skin"));
        !            80:                p = strchr(value, '/');
        !            81:                if (p)
        !            82:                {
        !            83:                        if(!strcmp(dball_team1_skin->string, value))
        !            84:                                team1++;
        !            85:                        else if(!strcmp(dball_team2_skin->string, value))
        !            86:                                team2++;
        !            87:                        else
        !            88:                                unassigned++;
        !            89:                }
        !            90:                else
        !            91:                        unassigned++;
        !            92:        }
        !            93: 
        !            94:        if(team1 > team2)
        !            95:        {
        !            96:                gi.dprintf("assigned to team 2\n");
        !            97:                Info_SetValueForKey(ent->client->pers.userinfo, "skin", dball_team2_skin->string);
        !            98:        }
        !            99:        else
        !           100:        {
        !           101:                gi.dprintf("assigned to team 1\n");
        !           102:                Info_SetValueForKey(ent->client->pers.userinfo, "skin", dball_team1_skin->string);
        !           103:        }
        !           104:        
        !           105:        ClientUserinfoChanged(ent, ent->client->pers.userinfo);
        !           106: 
        !           107:        if(unassigned)
        !           108:                gi.dprintf("%d unassigned players present!\n", unassigned);
        !           109: }
        !           110: 
        !           111: //==================
        !           112: //==================
        !           113: void DBall_SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles)
        !           114: {
        !           115:        edict_t *bestspot;
        !           116:        float   bestdistance, bestplayerdistance;
        !           117:        edict_t *spot;
        !           118:        char    *spottype;
        !           119:        char    skin[512];
        !           120: 
        !           121:        strcpy(skin, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
        !           122:        if(!strcmp(dball_team1_skin->string, skin))
        !           123:                spottype = "dm_dball_team1_start";
        !           124:        else if(!strcmp(dball_team2_skin->string, skin))
        !           125:                spottype = "dm_dball_team2_start";
        !           126:        else
        !           127:                spottype = "info_player_deathmatch";
        !           128: 
        !           129:        spot = NULL;
        !           130:        bestspot = NULL;
        !           131:        bestdistance = 0;
        !           132:        while ((spot = G_Find (spot, FOFS(classname), spottype)) != NULL)
        !           133:        {
        !           134:                bestplayerdistance = PlayersRangeFromSpot (spot);
        !           135: 
        !           136:                if (bestplayerdistance > bestdistance)
        !           137:                {
        !           138:                        bestspot = spot;
        !           139:                        bestdistance = bestplayerdistance;
        !           140:                }
        !           141:        }
        !           142: 
        !           143:        if (bestspot)
        !           144:        {
        !           145:                VectorCopy (bestspot->s.origin, origin);
        !           146:                origin[2] += 9;
        !           147:                VectorCopy (bestspot->s.angles, angles);
        !           148:                return;
        !           149:        }
        !           150: 
        !           151:        // if we didn't find an appropriate spawnpoint, just
        !           152:        // call the standard one.
        !           153:        SelectSpawnPoint(ent, origin, angles);
        !           154: }
        !           155: 
        !           156: //==================
        !           157: //==================
        !           158: void DBall_GameInit (void)
        !           159: {
        !           160:        // we don't want a minimum speed for friction to take effect.
        !           161:        // this will allow any knockback to move stuff.
        !           162:        sv_stopspeed->value = 0;
        !           163:        dball_team1_goalscore = 0;
        !           164:        dball_team2_goalscore = 0;
        !           165: 
        !           166:        dmflags->value = (int)dmflags->value | DF_NO_MINES | DF_NO_NUKES | DF_NO_STACK_DOUBLE | 
        !           167:                                                DF_NO_FRIENDLY_FIRE | DF_SKINTEAMS;
        !           168:        
        !           169:        dball_team1_skin = gi.cvar ("dball_team1_skin", "male/ctf_r", 0);
        !           170:        dball_team2_skin = gi.cvar ("dball_team2_skin", "male/ctf_b", 0);
        !           171:        goallimit = gi.cvar ("goallimit", "0", 0);
        !           172: }
        !           173: 
        !           174: //==================
        !           175: //==================
        !           176: void DBall_PostInitSetup (void)
        !           177: {
        !           178:        edict_t         *e;
        !           179: 
        !           180:        e=NULL;
        !           181:        // turn teleporter destinations nonsolid.
        !           182:        while(e = G_Find (e, FOFS(classname), "misc_teleporter_dest"))
        !           183:        {
        !           184:                e->solid = SOLID_NOT;
        !           185:                gi.linkentity (e);
        !           186:        }
        !           187: 
        !           188:        // count the ball start points
        !           189:        dball_ball_startpt_count = 0;
        !           190:        e=NULL;
        !           191:        while(e = G_Find (e, FOFS(classname), "dm_dball_ball_start"))
        !           192:        {
        !           193:                dball_ball_startpt_count++;
        !           194:        }
        !           195: 
        !           196:        if(dball_ball_startpt_count == 0)
        !           197:                gi.dprintf("No Deathball start points!\n");
        !           198: }
        !           199: 
        !           200: //==================
        !           201: // DBall_ChangeDamage - half damage between players. full if it involves
        !           202: //             the ball entity
        !           203: //==================
        !           204: int DBall_ChangeDamage (edict_t *targ, edict_t *attacker, int damage, int mod)
        !           205: {
        !           206:        // cut player -> ball damage to 1
        !           207:        if (targ == dball_ball_entity)
        !           208:                return 1;
        !           209: 
        !           210:        // damage player -> player is halved
        !           211:        if (attacker != dball_ball_entity)
        !           212:                return damage / 2;
        !           213: 
        !           214:        return damage;
        !           215: }
        !           216: 
        !           217: //==================
        !           218: //==================
        !           219: int DBall_ChangeKnockback (edict_t *targ, edict_t *attacker, int knockback, int mod)
        !           220: {
        !           221:        if(targ != dball_ball_entity)
        !           222:                return knockback;
        !           223:        
        !           224:        if(knockback < 1)
        !           225:        {
        !           226:                // FIXME - these don't account for quad/double
        !           227:                if(mod == MOD_ROCKET)           // rocket
        !           228:                        knockback = 70;
        !           229:                else if(mod == MOD_BFG_EFFECT)  // bfg
        !           230:                        knockback = 90;
        !           231:                else
        !           232:                        gi.dprintf ("zero knockback, mod %d\n", mod);
        !           233:        }
        !           234:        else
        !           235:        {
        !           236:                // FIXME - change this to an array?
        !           237:                switch(mod)
        !           238:                {
        !           239:                        case MOD_BLASTER:
        !           240:                                knockback *= 3;
        !           241:                                break;
        !           242:                        case MOD_SHOTGUN:
        !           243:                                knockback = (knockback * 3) / 8;
        !           244:                                break;
        !           245:                        case MOD_SSHOTGUN:
        !           246:                                knockback = knockback / 3;
        !           247:                                break;
        !           248:                        case MOD_MACHINEGUN:
        !           249:                                knockback = (knockback * 3) / 2;
        !           250:                                break;
        !           251:                        case MOD_HYPERBLASTER:
        !           252:                                knockback *= 4;
        !           253:                                break;
        !           254:                        case MOD_GRENADE:
        !           255:                        case MOD_HANDGRENADE:
        !           256:                        case MOD_PROX:
        !           257:                        case MOD_G_SPLASH:
        !           258:                        case MOD_HG_SPLASH:
        !           259:                        case MOD_HELD_GRENADE:
        !           260:                        case MOD_TRACKER:
        !           261:                        case MOD_DISINTEGRATOR:
        !           262:                                knockback /= 2;
        !           263:                                break;
        !           264:                        case MOD_R_SPLASH:
        !           265:                                knockback = (knockback * 3) / 2;
        !           266:                                break;
        !           267:                        case MOD_RAILGUN:
        !           268:                        case MOD_HEATBEAM:
        !           269:                                knockback /= 3;
        !           270:                                break;
        !           271:                }
        !           272:        }
        !           273: 
        !           274: //     gi.dprintf("mod: %d    knockback: %d\n", mod, knockback);
        !           275:        return knockback;
        !           276: }
        !           277: 
        !           278: // **************************
        !           279: // Goals
        !           280: // **************************
        !           281: 
        !           282: void DBall_GoalTouch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
        !           283: {
        !           284:        int             team_score;
        !           285:        int             scorechange;
        !           286:        int             j;
        !           287:        char    value[512];
        !           288:        char    *p;
        !           289:        edict_t *ent;
        !           290: 
        !           291:        if(other != dball_ball_entity)
        !           292:                return;
        !           293: 
        !           294:        self->health = self->max_health;
        !           295: 
        !           296:        // determine which team scored, and bump the team score
        !           297:        if(self->spawnflags & DBALL_GOAL_TEAM1)
        !           298:        {
        !           299:                dball_team1_goalscore += self->wait;            
        !           300:                team_score = 1;
        !           301:        }
        !           302:        else
        !           303:        {
        !           304:                dball_team2_goalscore += self->wait;            
        !           305:                team_score = 2;
        !           306:        }
        !           307: 
        !           308:        // bump the score for everyone on the correct team.
        !           309:        for (j = 1; j <= game.maxclients; j++)
        !           310:        {
        !           311:                ent = &g_edicts[j];
        !           312:                if (!ent->inuse)
        !           313:                        continue;
        !           314:                if (!ent->client)
        !           315:                        continue;
        !           316:                
        !           317:                if (ent == other->enemy)
        !           318:                        scorechange = self->wait + 5;
        !           319:                else
        !           320:                        scorechange = self->wait;
        !           321: 
        !           322:                strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
        !           323:                p = strchr(value, '/');
        !           324:                if (p)
        !           325:                {
        !           326:                        if(!strcmp(dball_team1_skin->string, value))
        !           327:                        {
        !           328:                                if(team_score == 1)
        !           329:                                        ent->client->resp.score += scorechange;
        !           330:                                else if(other->enemy == ent)
        !           331:                                        ent->client->resp.score -= scorechange;
        !           332:                        }
        !           333:                        else if(!strcmp(dball_team2_skin->string, value))
        !           334:                        {
        !           335:                                if(team_score == 2)
        !           336:                                        ent->client->resp.score += scorechange;
        !           337:                                else if(other->enemy == ent)
        !           338:                                        ent->client->resp.score -= scorechange;
        !           339:                        }
        !           340:                        else
        !           341:                                gi.dprintf("unassigned player!!!!\n");
        !           342:                }
        !           343:        }
        !           344: 
        !           345:        if(other->enemy)
        !           346:                gi.dprintf("score for team %d by %s\n", team_score, other->enemy->client->pers.netname);
        !           347:        else
        !           348:                gi.dprintf("score for team %d by someone\n", team_score);
        !           349: 
        !           350:        DBall_BallDie (other, other->enemy, other->enemy, 0, vec3_origin);
        !           351: 
        !           352:        G_UseTargets (self, other);
        !           353: }
        !           354: 
        !           355: // **************************
        !           356: // Ball
        !           357: // **************************
        !           358: 
        !           359: edict_t *PickBallStart (edict_t *ent)
        !           360: {
        !           361:        int             which, current;
        !           362:        edict_t *e;
        !           363: 
        !           364:        which = ceil(random() * dball_ball_startpt_count);
        !           365:        e = NULL;
        !           366:        current = 0;
        !           367: 
        !           368:        while(e = G_Find (e, FOFS(classname), "dm_dball_ball_start"))
        !           369:        {
        !           370:                current++;
        !           371:                if(current == which)
        !           372:                        return e;
        !           373:        }
        !           374: 
        !           375:        if(current == 0)
        !           376:                gi.dprintf("No ball start points found!\n");
        !           377: 
        !           378:        return G_Find(NULL, FOFS(classname), "dm_dball_ball_start");
        !           379: }
        !           380: 
        !           381: //==================
        !           382: // DBall_BallTouch - if the ball hit another player, hurt them
        !           383: //==================
        !           384: void DBall_BallTouch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
        !           385: {
        !           386:        vec3_t  dir;
        !           387:        float   dot;
        !           388:        float   speed;
        !           389: 
        !           390:        if(other->takedamage == DAMAGE_NO)
        !           391:                return;
        !           392: 
        !           393:        // hit a player
        !           394:        if(other->client) 
        !           395:        {
        !           396:                if(ent->velocity[0] || ent->velocity[1] || ent->velocity[2])
        !           397:                {
        !           398:                        speed = VectorLength(ent->velocity);
        !           399: 
        !           400:                        VectorSubtract(ent->s.origin, other->s.origin, dir);
        !           401:                        dot = DotProduct(dir, ent->velocity);
        !           402: 
        !           403:                        if(dot > 0.7)
        !           404:                        {
        !           405:                                T_Damage (other, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 
        !           406:                                                speed/10, speed/10, 0, MOD_DBALL_CRUSH);
        !           407:                        }
        !           408:                }
        !           409:        }
        !           410: }
        !           411: 
        !           412: //==================
        !           413: // DBall_BallPain
        !           414: //==================
        !           415: void DBall_BallPain (edict_t *self, edict_t *other, float kick, int damage)
        !           416: {
        !           417:        self->enemy = other;
        !           418:        self->health = self->max_health;
        !           419: //     if(other->classname)
        !           420: //             gi.dprintf("hurt by %s -- %d\n", other->classname, self->health);
        !           421: }
        !           422: 
        !           423: void DBall_BallDie (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
        !           424: {
        !           425:        // do the splash effect
        !           426:        gi.WriteByte (svc_temp_entity);
        !           427:        gi.WriteByte (TE_DBALL_GOAL);
        !           428:        gi.WritePosition (self->s.origin);
        !           429:        gi.multicast (self->s.origin, MULTICAST_PVS);
        !           430: 
        !           431:        VectorClear(self->s.angles);
        !           432:        VectorClear(self->velocity);
        !           433:        VectorClear(self->avelocity);
        !           434: 
        !           435:        // make it invisible and desolid until respawn time
        !           436:        self->solid = SOLID_NOT;
        !           437: //     self->s.modelindex = 0;
        !           438:        self->think = DBall_BallRespawn;
        !           439:        self->nextthink = level.time + 2;
        !           440:        gi.linkentity(self);
        !           441: 
        !           442: }
        !           443: 
        !           444: void DBall_BallRespawn (edict_t *self)
        !           445: {
        !           446:        edict_t         *start;
        !           447: 
        !           448:        // do the splash effect
        !           449:        gi.WriteByte (svc_temp_entity);
        !           450:        gi.WriteByte (TE_DBALL_GOAL);
        !           451:        gi.WritePosition (self->s.origin);
        !           452:        gi.multicast (self->s.origin, MULTICAST_PVS);
        !           453: 
        !           454:        // move the ball and stop it
        !           455:        start = PickBallStart(self);
        !           456:        if(start)
        !           457:        {
        !           458:                VectorCopy(start->s.origin, self->s.origin);
        !           459:                VectorCopy(start->s.origin, self->s.old_origin);
        !           460:        }
        !           461: 
        !           462:        VectorClear(self->s.angles);
        !           463:        VectorClear(self->velocity);
        !           464:        VectorClear(self->avelocity);
        !           465:        
        !           466:        self->solid = SOLID_BBOX;
        !           467:        self->s.modelindex = gi.modelindex ("models/objects/dball/tris.md2");
        !           468:        self->s.event = EV_PLAYER_TELEPORT;
        !           469:        self->groundentity = NULL;
        !           470: 
        !           471:        // kill anything at the destination
        !           472:        KillBox (self);
        !           473: 
        !           474:        gi.linkentity (self);
        !           475: }
        !           476: 
        !           477: // ************************
        !           478: // SPEED CHANGES
        !           479: // ************************
        !           480: 
        !           481: #define DBALL_SPEED_ONEWAY             1
        !           482: 
        !           483: void DBall_SpeedTouch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
        !           484: {
        !           485:        float   dot;
        !           486:        vec3_t  vel;
        !           487: 
        !           488:        if(other != dball_ball_entity)
        !           489:                return;
        !           490: 
        !           491:        if(self->timestamp >= level.time)
        !           492:                return;
        !           493: 
        !           494:        if(VectorLength(other->velocity) < 1)
        !           495:                return;
        !           496: 
        !           497:        if(self->spawnflags & DBALL_SPEED_ONEWAY)
        !           498:        {
        !           499:                VectorCopy (other->velocity, vel);
        !           500:                VectorNormalize (vel);
        !           501:                dot = DotProduct (vel, self->movedir);
        !           502:                if(dot < 0.8)
        !           503:                        return;
        !           504:        }
        !           505: 
        !           506:        self->timestamp = level.time + self->delay;
        !           507:        VectorScale (other->velocity, self->speed, other->velocity);
        !           508: }
        !           509: 
        !           510: // ************************
        !           511: // SPAWN FUNCTIONS
        !           512: // ************************
        !           513: 
        !           514: /*QUAKED dm_dball_ball (1 .5 .5) (-48 -48 -48) (48 48 48)
        !           515: Deathball Ball
        !           516: */
        !           517: void SP_dm_dball_ball (edict_t *self)
        !           518: {
        !           519:        if(!(deathmatch->value))
        !           520:        {
        !           521:                G_FreeEdict(self);      
        !           522:                return;
        !           523:        }
        !           524: 
        !           525:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           526:        {
        !           527:                G_FreeEdict(self);      
        !           528:                return;
        !           529:        }
        !           530: 
        !           531:        dball_ball_entity = self;
        !           532: //     VectorCopy (self->s.origin, dball_ball_startpt);
        !           533: 
        !           534:        self->s.modelindex = gi.modelindex ("models/objects/dball/tris.md2");
        !           535:        VectorSet (self->mins, -32, -32, -32);
        !           536:        VectorSet (self->maxs, 32, 32, 32);
        !           537:        self->solid = SOLID_BBOX;
        !           538:        self->movetype = MOVETYPE_NEWTOSS;
        !           539:        self->clipmask = MASK_MONSTERSOLID;
        !           540: 
        !           541:        self->takedamage = DAMAGE_YES;
        !           542:        self->mass = 50;
        !           543:        self->health = 50000;
        !           544:        self->max_health = 50000;
        !           545:        self->pain = DBall_BallPain;
        !           546:        self->die = DBall_BallDie;
        !           547:        self->touch = DBall_BallTouch;
        !           548: 
        !           549:        gi.linkentity (self);
        !           550: }
        !           551: 
        !           552: /*QUAKED dm_dball_team1_start (1 .5 .5) (-16 -16 -24) (16 16 32)
        !           553: Deathball team 1 start point
        !           554: */
        !           555: void SP_dm_dball_team1_start (edict_t *self)
        !           556: {
        !           557:        if (!deathmatch->value)
        !           558:        {
        !           559:                G_FreeEdict (self);
        !           560:                return;
        !           561:        }
        !           562:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           563:        {
        !           564:                G_FreeEdict(self);      
        !           565:                return;
        !           566:        }
        !           567: }
        !           568: 
        !           569: /*QUAKED dm_dball_team2_start (1 .5 .5) (-16 -16 -24) (16 16 32)
        !           570: Deathball team 2 start point
        !           571: */
        !           572: void SP_dm_dball_team2_start (edict_t *self)
        !           573: {
        !           574:        if (!deathmatch->value)
        !           575:        {
        !           576:                G_FreeEdict (self);
        !           577:                return;
        !           578:        }
        !           579:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           580:        {
        !           581:                G_FreeEdict(self);      
        !           582:                return;
        !           583:        }
        !           584: }
        !           585: 
        !           586: /*QUAKED dm_dball_ball_start (1 .5 .5) (-48 -48 -48) (48 48 48)
        !           587: Deathball ball start point
        !           588: */
        !           589: void SP_dm_dball_ball_start (edict_t *self)
        !           590: {
        !           591:        if (!deathmatch->value)
        !           592:        {
        !           593:                G_FreeEdict (self);
        !           594:                return;
        !           595:        }
        !           596:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           597:        {
        !           598:                G_FreeEdict(self);      
        !           599:                return;
        !           600:        }
        !           601: }
        !           602: 
        !           603: /*QUAKED dm_dball_speed_change (1 .5 .5) ? ONEWAY
        !           604: Deathball ball speed changing field.
        !           605: 
        !           606: speed: multiplier for speed (.5 = half, 2 = double, etc) (default = double)
        !           607: angle: used with ONEWAY so speed change is only one way.
        !           608: delay: time between speed changes (default: 0.2 sec)
        !           609: */
        !           610: void SP_dm_dball_speed_change (edict_t *self)
        !           611: {
        !           612:        if (!deathmatch->value)
        !           613:        {
        !           614:                G_FreeEdict (self);
        !           615:                return;
        !           616:        }
        !           617:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           618:        {
        !           619:                G_FreeEdict(self);      
        !           620:                return;
        !           621:        }
        !           622: 
        !           623:        if(!self->speed)
        !           624:                self->speed = 2;
        !           625: 
        !           626:        if(!self->delay)
        !           627:                self->delay = 0.2;
        !           628: 
        !           629:        self->touch = DBall_SpeedTouch;
        !           630:        self->solid = SOLID_TRIGGER;
        !           631:        self->movetype = MOVETYPE_NONE;
        !           632:        self->svflags |= SVF_NOCLIENT;
        !           633: 
        !           634:        if (!VectorCompare(self->s.angles, vec3_origin))
        !           635:                G_SetMovedir (self->s.angles, self->movedir);
        !           636:        else
        !           637:                VectorSet (self->movedir, 1, 0, 0);
        !           638: 
        !           639:        gi.setmodel (self, self->model);
        !           640:        gi.linkentity (self);
        !           641: }
        !           642: 
        !           643: /*QUAKED dm_dball_goal (1 .5 .5) ? TEAM1 TEAM2
        !           644: Deathball goal
        !           645: 
        !           646: Team1/Team2 - beneficiary of this goal. when the ball enters this goal, the beneficiary team will score.
        !           647: 
        !           648: "wait": score to be given for this goal (default 10) player gets score+5.
        !           649: */
        !           650: void SP_dm_dball_goal (edict_t *self)
        !           651: {
        !           652:        if(!(deathmatch->value))
        !           653:        {
        !           654:                G_FreeEdict(self);      
        !           655:                return;
        !           656:        }
        !           657: 
        !           658:        if(gamerules && (gamerules->value != RDM_DEATHBALL))
        !           659:        {
        !           660:                G_FreeEdict(self);      
        !           661:                return;
        !           662:        }
        !           663: 
        !           664:        if(!self->wait)
        !           665:                self->wait = 10;
        !           666: 
        !           667:        self->touch = DBall_GoalTouch;
        !           668:        self->solid = SOLID_TRIGGER;
        !           669:        self->movetype = MOVETYPE_NONE;
        !           670:        self->svflags |= SVF_NOCLIENT;
        !           671: 
        !           672:        if (!VectorCompare(self->s.angles, vec3_origin))
        !           673:                G_SetMovedir (self->s.angles, self->movedir);
        !           674: 
        !           675:        gi.setmodel (self, self->model);
        !           676:        gi.linkentity (self);
        !           677: 
        !           678: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.