|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.