Annotation of quakeworld/progs/combat.qc, revision 1.1.1.1

1.1       root        1: 
                      2: void() T_MissileTouch;
                      3: void() info_player_start;
                      4: void(entity targ, entity attacker) ClientObituary;
                      5: void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage;
                      6: 
                      7: /*SERVER
                      8: void() monster_death_use;
                      9: */
                     10: 
                     11: //============================================================================
                     12: 
                     13: /*
                     14: ============
                     15: CanDamage
                     16: 
                     17: Returns true if the inflictor can directly damage the target.  Used for
                     18: explosions and melee attacks.
                     19: ============
                     20: */
                     21: float(entity targ, entity inflictor) CanDamage =
                     22: {
                     23: // bmodels need special checking because their origin is 0,0,0
                     24:        if (targ.movetype == MOVETYPE_PUSH)
                     25:        {
                     26:                traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
                     27:                if (trace_fraction == 1)
                     28:                        return TRUE;
                     29:                if (trace_ent == targ)
                     30:                        return TRUE;
                     31:                return FALSE;
                     32:        }
                     33:        
                     34:        traceline(inflictor.origin, targ.origin, TRUE, self);
                     35:        if (trace_fraction == 1)
                     36:                return TRUE;
                     37:        traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
                     38:        if (trace_fraction == 1)
                     39:                return TRUE;
                     40:        traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
                     41:        if (trace_fraction == 1)
                     42:                return TRUE;
                     43:        traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
                     44:        if (trace_fraction == 1)
                     45:                return TRUE;
                     46:        traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
                     47:        if (trace_fraction == 1)
                     48:                return TRUE;
                     49: 
                     50:        return FALSE;
                     51: };
                     52: 
                     53: 
                     54: /*
                     55: ============
                     56: Killed
                     57: ============
                     58: */
                     59: void(entity targ, entity attacker) Killed =
                     60: {
                     61:        local entity oself;
                     62: 
                     63:        oself = self;
                     64:        self = targ;
                     65:        
                     66:        if (self.health < -99)
                     67:                self.health = -99;              // don't let sbar look bad if a player
                     68: 
                     69:        if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
                     70:        {       // doors, triggers, etc
                     71:                self.th_die ();
                     72:                self = oself;
                     73:                return;
                     74:        }
                     75: 
                     76:        self.enemy = attacker;
                     77: 
                     78: // bump the monster counter
                     79:        if (self.flags & FL_MONSTER)
                     80:        {
                     81:                killed_monsters = killed_monsters + 1;
                     82:                WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
                     83:        }
                     84: 
                     85:        ClientObituary(self, attacker);
                     86:        
                     87:        self.takedamage = DAMAGE_NO;
                     88:        self.touch = SUB_Null;
                     89:        self.effects = 0;
                     90: 
                     91: /*SERVER
                     92:        monster_death_use();
                     93: */
                     94:        self.th_die ();
                     95:        
                     96:        self = oself;
                     97: };
                     98: 
                     99: 
                    100: /*
                    101: ============
                    102: T_Damage
                    103: 
                    104: The damage is coming from inflictor, but get mad at attacker
                    105: This should be the only function that ever reduces health.
                    106: ============
                    107: */
                    108: void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
                    109: {
                    110:        local   vector  dir;
                    111:        local   entity  oldself;
                    112:        local   float   save;
                    113:        local   float   take;
                    114:        local   string  s;
                    115:        local   string  attackerteam, targteam;
                    116: 
                    117: 
                    118:        if (!targ.takedamage)
                    119:                return;
                    120: 
                    121: // used by buttons and triggers to set activator for target firing
                    122:        damage_attacker = attacker;
                    123: 
                    124: 
                    125: // check for quad damage powerup on the attacker
                    126:        if (attacker.super_damage_finished > time && inflictor.classname != "door")
                    127:        if (deathmatch == 4)
                    128:                damage = damage * 8;
                    129:        else
                    130:                damage = damage * 4;
                    131: 
                    132: // save damage based on the target's armor level
                    133: 
                    134:        save = ceil(targ.armortype*damage);
                    135:        if (save >= targ.armorvalue)
                    136:        {
                    137:                save = targ.armorvalue;
                    138:                targ.armortype = 0;     // lost all armor
                    139:                targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
                    140:        }
                    141:        
                    142:        targ.armorvalue = targ.armorvalue - save;
                    143:        take = ceil(damage-save);
                    144: 
                    145: // add to the damage total for clients, which will be sent as a single
                    146: // message at the end of the frame
                    147: // FIXME: remove after combining shotgun blasts?
                    148:        if (targ.flags & FL_CLIENT)
                    149:        {
                    150:                targ.dmg_take = targ.dmg_take + take;
                    151:                targ.dmg_save = targ.dmg_save + save;
                    152:                targ.dmg_inflictor = inflictor;
                    153:        }
                    154: 
                    155:        damage_inflictor = inflictor;        
                    156: 
                    157: 
                    158: // figure momentum add
                    159:        if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
                    160:        {
                    161:                dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
                    162:                dir = normalize(dir);
                    163:                // Set kickback for smaller weapons
                    164: //Zoid -- use normal NQ kickback
                    165: //             // Read: only if it's not yourself doing the damage
                    166: //             if ( (damage < 60) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname != targ.netname)) 
                    167: //                     targ.velocity = targ.velocity + dir * damage * 11;
                    168: //             else                        
                    169:                // Otherwise, these rules apply to rockets and grenades                        
                    170:                // for blast velocity
                    171:                        targ.velocity = targ.velocity + dir * damage * 8;
                    172:                
                    173:                // Rocket Jump modifiers
                    174:                if ( (rj > 1) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname == targ.netname)) 
                    175:                        targ.velocity = targ.velocity + dir * damage * rj;
                    176: 
                    177:        }
                    178: 
                    179: 
                    180: 
                    181: // check for godmode or invincibility
                    182:        if (targ.flags & FL_GODMODE)
                    183:                return;
                    184:        if (targ.invincible_finished >= time)
                    185:        {
                    186:                if (self.invincible_sound < time)
                    187:                {
                    188:                        sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
                    189:                        self.invincible_sound = time + 2;
                    190:                }
                    191:                return;
                    192:        }
                    193: 
                    194: // team play damage avoidance
                    195: //ZOID 12-13-96: self.team doesn't work in QW.  Use keys
                    196:        attackerteam = infokey(attacker, "team");
                    197:        targteam = infokey(targ, "team");
                    198: 
                    199:        if ((teamplay == 1) && (targteam == attackerteam) &&
                    200:                (attacker.classname == "player") && (attackerteam != "") &&
                    201:                inflictor.classname !="door")
                    202:                return;
                    203: 
                    204:        if ((teamplay == 3) && (targteam == attackerteam) &&
                    205:                (attacker.classname == "player") && (attackerteam != "") &&
                    206:                (targ != attacker)&& inflictor.classname !="door")
                    207:                return;
                    208:                
                    209: // do the damage
                    210:        targ.health = targ.health - take;
                    211: 
                    212:        if (targ.health <= 0)
                    213:        {
                    214:                Killed (targ, attacker);
                    215:                return;
                    216:        }
                    217: 
                    218: // react to the damage
                    219:        oldself = self;
                    220:        self = targ;
                    221: 
                    222: /*SERVER
                    223:        if ( (self.flags & FL_MONSTER) && attacker != world)
                    224:        {
                    225:        // get mad unless of the same class (except for soldiers)
                    226:                if (self != attacker && attacker != self.enemy)
                    227:                {
                    228:                        if ( (self.classname != attacker.classname) 
                    229:                        || (self.classname == "monster_army" ) )
                    230:                        {
                    231:                                if (self.enemy.classname == "player")
                    232:                                        self.oldenemy = self.enemy;
                    233:                                self.enemy = attacker;
                    234:                                FoundTarget ();
                    235:                        }
                    236:                }
                    237:        }
                    238: */
                    239:        if (self.th_pain)
                    240:        {
                    241:                self.th_pain (attacker, take);
                    242:        }
                    243: 
                    244:        self = oldself;
                    245: };
                    246: 
                    247: /*
                    248: ============
                    249: T_RadiusDamage
                    250: ============
                    251: */
                    252: void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage =
                    253: {
                    254:        local   float   points;
                    255:        local   entity  head;
                    256:        local   vector  org;
                    257: 
                    258:        head = findradius(inflictor.origin, damage+40);
                    259:        
                    260:        while (head)
                    261:        {
                    262:                //bprint (PRINT_HIGH, head.classname);
                    263:                //bprint (PRINT_HIGH, " | ");
                    264:                //bprint (PRINT_HIGH, head.netname);
                    265:                //bprint (PRINT_HIGH, "\n");
                    266:        
                    267:                if (head != ignore)
                    268:                {
                    269:                        if (head.takedamage)
                    270:                        {
                    271:                                org = head.origin + (head.mins + head.maxs)*0.5;
                    272:                                points = 0.5*vlen (inflictor.origin - org);
                    273:                                if (points < 0)
                    274:                                        points = 0;
                    275:                                points = damage - points;
                    276:                                
                    277:                                if (head == attacker)
                    278:                                        points = points * 0.5;
                    279:                                if (points > 0)
                    280:                                {
                    281:                                        if (CanDamage (head, inflictor))
                    282:                                        {
                    283:                                                head.deathtype = dtype;
                    284:                                                T_Damage (head, inflictor, attacker, points);
                    285:                                        }
                    286:                                }
                    287:                        }
                    288:                }
                    289:                head = head.chain;
                    290:        }
                    291: };
                    292: 
                    293: /*
                    294: ============
                    295: T_BeamDamage
                    296: ============
                    297: */
                    298: void(entity attacker, float damage) T_BeamDamage =
                    299: {
                    300:        local   float   points;
                    301:        local   entity  head;
                    302:        
                    303:        head = findradius(attacker.origin, damage+40);
                    304:        
                    305:        while (head)
                    306:        {
                    307:                if (head.takedamage)
                    308:                {
                    309:                        points = 0.5*vlen (attacker.origin - head.origin);
                    310:                        if (points < 0)
                    311:                                points = 0;
                    312:                        points = damage - points;
                    313:                        if (head == attacker)
                    314:                                points = points * 0.5;
                    315:                        if (points > 0)
                    316:                        {
                    317:                                if (CanDamage (head, attacker))
                    318:                                        T_Damage (head, attacker, attacker, points);
                    319:                        }
                    320:                }
                    321:                head = head.chain;
                    322:        }
                    323: };
                    324: 

unix.superglobalmegacorp.com

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