def tdeath_touch(*qwp_extra): if qc.other == qc.self.owner: return # frag anyone who teleports in on top of an invincible player if qc.other.classname == 'player': if qc.other.invincible_finished > qc.time: qc.self.classname = 'teledeath2' if qc.self.owner.classname != 'player': # other monsters explode themselves combat.T_Damage(qc.self.owner, qc.self, qc.self, 50000) return if qc.other.health: combat.T_Damage(qc.other, qc.self, qc.self, 50000)
def T_MissileTouch(*qwp_extra): if qc.other == qc.self.owner: return # don't explode on owner if qc.self.cnt: return qc.self.cnt = 1 if engine.pointcontents(qc.self.origin) == defs.CONTENT_SKY: qc.self.remove() return damg = 100 + random.random() * 20 if qc.other.health: combat.T_Damage(qc.other, qc.self, qc.self.owner, damg) # don't do radius damage to the other, because all the damage # was done in the impact combat.T_RadiusDamage(qc.self, qc.self.owner, 120, qc.other) # sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); qc.self.origin -= 8 * qc.self.velocity.normalize() qc.WriteByte(defs.MSG_MULTICAST, defs.SVC_TEMPENTITY) qc.WriteByte(defs.MSG_MULTICAST, defs.TE_EXPLOSION) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.x) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.y) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.z) engine.multicast(qc.self.origin, defs.MULTICAST_PHS) qc.self.remove()
def Grapple_Track(*qwp_extra): # Release dead targets if qc.self.enemy.classname == 'player' and qc.self.enemy.health <= 0: qc.self.owner.on_hook = defs.FALSE qc.self.owner.attack_finished = qc.time + 0.75 # drop the hook if owner is dead or has released the button if not qc.self.owner.on_hook or qc.self.owner.health <= 0: Reset_Grapple(qc.self) return # bring the pAiN! if qc.self.enemy.classname == 'player': # 4.1, if we can't see our enemy, unlock if not combat.CanDamage(qc.self.enemy, qc.self.owner): Reset_Grapple(qc.self) return # move the hook along with the player. It's invisible, but # we need this to make the sound come from the right spot qc.setorigin(qc.self, qc.self.enemy.origin) qc.self.sound(defs.CHAN_WEAPON, 'blob/land1.wav', 1, defs.ATTN_NORM) combat.T_Damage(qc.self.enemy, qc.self, qc.self.owner, 1) qc.makevectors(qc.self.v_angle) weapons.SpawnBlood(qc.self.enemy.origin, 1) # If the hook is not attached to the player, constantly copy # copy the target's velocity. Velocity copying DOES NOT work properly # for a hooked client. if qc.self.enemy.classname != 'player': qc.self.velocity = qc.self.enemy.velocity qc.self.nextthink = qc.time + 0.1
def superspike_touch(*qwp_extra): if qc.other == qc.self.owner: return if qc.self.cnt: return if qc.other.solid == defs.SOLID_TRIGGER: return # trigger field, do nothing qc.self.cnt = 1 if engine.pointcontents(qc.self.origin) == defs.CONTENT_SKY: qc.self.remove() return # hit something that bleeds if qc.other.takedamage: spawn_touchblood(18) combat.T_Damage(qc.other, qc.self, qc.self.owner, 18) else: qc.WriteByte(defs.MSG_MULTICAST, defs.SVC_TEMPENTITY) qc.WriteByte(defs.MSG_MULTICAST, defs.TE_SUPERSPIKE) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.x) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.y) qc.WriteCoord(defs.MSG_MULTICAST, qc.self.origin.z) engine.multicast(qc.self.origin, defs.MULTICAST_PHS) qc.self.remove()
def hurt_touch(*qwp_extra): if qc.other.takedamage: qc.self.solid = defs.SOLID_NOT combat.T_Damage(qc.other, qc.self, qc.self, qc.self.dmg) qc.self.think = hurt_on qc.self.nextthink = qc.time + 1 return
def PlayerPostThink(*qwp_extra): mspeed = 0 aspeed = 0 r = 0 # dprint ("post think\n"); if qc.self.view_ofs == Vector(0, 0, 0): return # intermission or finale if qc.self.deadflag: return # check to see if player landed and play landing sound if (qc.self.jump_flag < -300) and (qc.self.flags & defs.FL_ONGROUND): if qc.self.watertype == defs.CONTENT_WATER: qc.self.sound(defs.CHAN_BODY, 'player/h2ojump.wav', 1, defs.ATTN_NORM) elif qc.self.jump_flag < -650: qc.self.deathtype = 'falling' combat.T_Damage(qc.self, qc.world, qc.world, 5) qc.self.sound(defs.CHAN_VOICE, 'player/land2.wav', 1, defs.ATTN_NORM) else: qc.self.sound(defs.CHAN_VOICE, 'player/land.wav', 1, defs.ATTN_NORM) qc.self.jump_flag = qc.self.velocity.z CheckPowerups() weapons.W_WeaponFrame()
def Laser_Touch(*qwp_extra): org = Vector(0, 0, 0) if qc.other == qc.self.owner: return # don't explode on owner if engine.pointcontents(qc.self.origin) == defs.CONTENT_SKY: qc.self.remove() return qc.self.sound(defs.CHAN_WEAPON, 'enforcer/enfstop.wav', 1, defs.ATTN_STATIC) org = qc.self.origin - 8 * qc.self.velocity.normalize() if qc.other.health: weapons.SpawnBlood(org, 15) qc.other.deathtype = 'laser' combat.T_Damage(qc.other, qc.self, qc.self.owner, 15) else: qc.WriteByte(defs.MSG_MULTICAST, defs.SVC_TEMPENTITY) qc.WriteByte(defs.MSG_MULTICAST, defs.TE_GUNSHOT) qc.WriteByte(defs.MSG_MULTICAST, 5) qc.WriteCoord(defs.MSG_MULTICAST, org.x) qc.WriteCoord(defs.MSG_MULTICAST, org.y) qc.WriteCoord(defs.MSG_MULTICAST, org.z) engine.multicast(org, defs.MULTICAST_PVS) qc.self.remove()
def LightningHit(from0, damage, *qwp_extra): qc.WriteByte(defs.MSG_MULTICAST, defs.SVC_TEMPENTITY) qc.WriteByte(defs.MSG_MULTICAST, defs.TE_LIGHTNINGBLOOD) qc.WriteCoord(defs.MSG_MULTICAST, qc.trace_endpos.x) qc.WriteCoord(defs.MSG_MULTICAST, qc.trace_endpos.y) qc.WriteCoord(defs.MSG_MULTICAST, qc.trace_endpos.z) engine.multicast(qc.trace_endpos, defs.MULTICAST_PVS) combat.T_Damage(qc.trace_ent, from0, from0, damage)
def door_blocked(*qwp_extra): combat.T_Damage(qc.other, qc.self, qc.self, qc.self.dmg) # if a door has a negative wait, it would never come back if blocked, # so let it just squash the object to death real fast if qc.self.wait >= 0: if qc.self.state == defs.STATE_DOWN: door_go_up() else: door_go_down()
def TeamDeathPenalty(targ, attacker, *qwp_extra): # Don't kill anyone if teamplay is negative. if defs.teamplay < 0: return if (defs.teamplay & TEAM_DEATH_PENALTY ) and attacker != targ and attacker.steam == targ.steam: # We should kill the attacker. combat.T_Damage(attacker, attacker, attacker, 1000) # Add a frag to offset the self-kill penalty. attacker.frags += 1
def plat_crush(*qwp_extra): # dprint ("plat_crush\n"); qc.other.deathtype = 'squish' combat.T_Damage(qc.other, qc.self, qc.self, 1) if qc.self.state == defs.STATE_UP: plat_go_down() elif qc.self.state == defs.STATE_DOWN: plat_go_up() else: qc.objerror('plat_crush: bad self.state\012')
def tdeath_touch(*qwp_extra): other2 = engine.world if qc.other == qc.self.owner: return # frag anyone who teleports in on top of an invincible player if qc.other.classname == 'player': if qc.other.invincible_finished > qc.time and qc.self.owner.invincible_finished > qc.time: qc.self.classname = 'teledeath3' qc.other.invincible_finished = 0 qc.self.owner.invincible_finished = 0 combat.T_Damage(qc.other, qc.self, qc.self, 50000) other2 = qc.self.owner qc.self.owner = qc.other combat.T_Damage(other2, qc.self, qc.self, 50000) if qc.other.invincible_finished > qc.time: qc.self.classname = 'teledeath2' combat.T_Damage(qc.self.owner, qc.self, qc.self, 50000) return if qc.other.health: combat.T_Damage(qc.other, qc.self, qc.self, 50000)
def TeamHealthDam(targ, inflictor, attacker, damage, *qwp_extra): if defs.teamplay < 0 or defs.gamestart: return defs.TRUE if attacker.steam == targ.steam and attacker != targ: # Attacker and target are on the same team. if defs.teamplay & TEAM_ATTACKER_DAMAGE: # Damage applied to teammate. combat.T_Damage(attacker, inflictor, attacker, damage) if defs.teamplay & TEAM_HEALTH_PROTECT: # Health is protected return defs.FALSE return defs.TRUE
def W_FireAxe(*qwp_extra): qc.makevectors(qc.self.v_angle) source = qc.self.origin + Vector(0, 0, 16) qc.traceline(source, source + qc.v_forward * 64, defs.FALSE, qc.self) if qc.trace_fraction == 1.0: return org = qc.trace_endpos - qc.v_forward * 4 if qc.trace_ent.takedamage: qc.trace_ent.axhitme = 1 SpawnBlood(org, 20) combat.T_Damage(qc.trace_ent, qc.self, qc.self, 20) else: # hit wall qc.self.sound(defs.CHAN_WEAPON, 'player/axhit2.wav', 1, defs.ATTN_NORM) qc.WriteByte(defs.MSG_MULTICAST, defs.SVC_TEMPENTITY) qc.WriteByte(defs.MSG_MULTICAST, defs.TE_GUNSHOT) qc.WriteByte(defs.MSG_MULTICAST, 3) qc.WriteCoord(defs.MSG_MULTICAST, org.x) qc.WriteCoord(defs.MSG_MULTICAST, org.y) qc.WriteCoord(defs.MSG_MULTICAST, org.z) engine.multicast(org, defs.MULTICAST_PVS)
def changelevel_touch(*qwp_extra): global nextmap pos = engine.world if qc.other.classname != 'player': return # if "noexit" is set, blow up the player trying to leave # ZOID, 12-13-96, noexit isn't supported in QW. Overload samelevel # if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) if (engine.cvar('samelevel') == 2) or ((engine.cvar('samelevel') == 3) and (qc.mapname != 'start')): combat.T_Damage(qc.other, qc.self, qc.self, 50000) return engine.bprint(defs.PRINT_HIGH, qc.other.netname) engine.bprint(defs.PRINT_HIGH, ' exited the level\012') nextmap = qc.self.map subs.SUB_UseTargets() qc.self.touch = subs.SUB_Null # we can't move people right now, because touch functions are called # in the middle of C movement code, so set a think time to do it qc.self.think = execute_changelevel qc.self.nextthink = qc.time + 0.1
def train_blocked(*qwp_extra): if qc.time < qc.self.attack_finished: return qc.self.attack_finished = qc.time + 0.5 qc.other.deathtype = 'squish' combat.T_Damage(qc.other, qc.self, qc.self, qc.self.dmg)
def Anchor_Grapple(*qwp_extra): if qc.other == qc.self.owner: return # DO NOT allow the grapple to hook to any projectiles, no matter WHAT! # if you create new types of projectiles, make sure you use one of the # classnames below or write code to exclude your new classname so # grapples will not stick to them. if qc.other.classname == 'missile' or qc.other.classname == 'grenade' or qc.other.classname == 'spike' or qc.other.classname == 'hook': return # Don't stick the the sky. if engine.pointcontents(qc.self.origin) == defs.CONTENT_SKY: Reset_Grapple(qc.self) return if qc.other.classname == 'player': # glance off of teammates if qc.other.steam == qc.self.owner.steam: return qc.self.sound(defs.CHAN_WEAPON, 'player/axhit1.wav', 1, defs.ATTN_NORM) combat.T_Damage(qc.other, qc.self, qc.self.owner, 10) # make hook invisible since we will be pulling directly # towards the player the hook hit. Quakeworld makes it # too quirky to try to match hook's velocity with that of # the client that it hit. qc.self.setmodel(None) elif qc.other.classname != 'player': qc.self.sound(defs.CHAN_WEAPON, 'player/axhit2.wav', 1, defs.ATTN_NORM) # One point of damage inflicted upon impact. Subsequent # damage will only be done to PLAYERS... this way secret # doors and triggers will only be damaged once. if qc.other.takedamage: combat.T_Damage(qc.other, qc.self, qc.self.owner, 1) qc.self.velocity = Vector(0, 0, 0) qc.self.avelocity = Vector(0, 0, 0) # conveniently clears the sound channel of the CHAIN1 sound, # which is a looping sample and would continue to play. Tink1 is # the least offensive choice, ass NULL.WAV loops and clogs the # channel with silence qc.self.owner.sound(defs.CHAN_NO_PHS_ADD + defs.CHAN_WEAPON, 'weapons/tink1.wav', 1, defs.ATTN_NORM) if not qc.self.owner.button0: Reset_Grapple(qc.self) return if qc.self.owner.flags & defs.FL_ONGROUND: qc.self.owner.flags -= defs.FL_ONGROUND qc.self.owner.on_hook = defs.TRUE qc.self.owner.sound(defs.CHAN_WEAPON, 'weapons/chain2.wav', 1, defs.ATTN_NORM) # CHAIN2 is a looping sample. Use LEFTY as a flag so that client.qc # will know to only play the tink sound ONCE to clear the weapons # sound channel. (Lefty is a leftover from AI.QC, so I reused it to # avoid adding a field) qc.self.owner.lefty = defs.TRUE qc.self.enemy = qc.other # remember this guy! qc.self.think = Grapple_Track qc.self.nextthink = qc.time qc.self.solid = defs.SOLID_NOT qc.self.touch = subs.SUB_Null
def TeamCheckLock(*qwp_extra): n = 0 s = None t = None pteam = 0 # Don't do anything if teamplay is negative if defs.teamplay < 0: return if defs.gamestart: s = qc.self.infokey('bottomcolor') pteam = qc.stof(s) if pteam != 0: qc.self.stuffcmd('setinfo bottomcolor 0\012') qc.self.steam = -1 return if qc.self.player_flag & defs.TEAM_STUFF_COLOR: qc.self.player_flag -= defs.TEAM_STUFF_COLOR s = str(qc.self.steam) qc.self.stuffcmd('setinfo bottomcolor ') qc.self.stuffcmd(s) qc.self.stuffcmd('\012') s = qc.self.infokey('topcolor') n = qc.stof(s) if CrossDressCheck(n, qc.self.steam): s = str(qc.self.steam) qc.self.stuffcmd('setinfo topcolor ') qc.self.stuffcmd(s) qc.self.stuffcmd('\012') s = GetShortTeamColor(qc.self.steam) qc.self.stuffcmd('setinfo team ') qc.self.stuffcmd(s) qc.self.stuffcmd('\012') if defs.teamplay & TEAM_CAPTURE_FLAG: qc.self.stuffcmd('setinfo skin ') qc.self.stuffcmd(qc.self.ctfskin) qc.self.stuffcmd('\012') qc.self.lastteamset = qc.time return s = qc.self.infokey('bottomcolor') pteam = qc.stof(s) # Check to see if the player has changed skins if qc.self.steam > 0 and qc.time - qc.self.lastteamset > 2: if defs.teamplay & TEAM_CAPTURE_FLAG: if qc.self.infokey('skin') != qc.self.ctfskin: qc.self.stuffcmd('setinfo skin ') qc.self.stuffcmd(qc.self.ctfskin) qc.self.stuffcmd('\012') qc.self.lastteamset = qc.time s = GetShortTeamColor(qc.self.steam) if qc.self.infokey('team') != s: qc.self.stuffcmd('setinfo team ') qc.self.stuffcmd(s) qc.self.stuffcmd('\012') qc.self.lastteamset = qc.time # check for crossdressing s = qc.self.infokey('topcolor') n = qc.stof(s) if CrossDressCheck(n, qc.self.steam): s = str(qc.self.steam) qc.self.stuffcmd('setinfo topcolor ') qc.self.stuffcmd(s) qc.self.stuffcmd('\012') return # Check to see if the player has changed colors if qc.time - qc.self.lastteamset > 2 and pteam != qc.self.steam: # Player has changed colors # If teams are static and we've been on some team already, # put us back on the team we were on. if (defs.teamplay & TEAM_STATIC_TEAMS) and (qc.self.steam >= 0): if TeamColorIsLegal(qc.self.steam): # changing teams sucks, kill him # if he has tried to change teams several # times, kick him off the server. if qc.self.suicide_count > 3: qc.self.sprint( defs.PRINT_HIGH, "You were told you can't change teams.\012Go play color games somewhere else.\012" ) qc.self.stuffcmd('disconnect\012') engine.bprint(defs.PRINT_MEDIUM, qc.self.netname) engine.bprint(defs.PRINT_MEDIUM, ' has bad color sense\012') # case base respawn qc.self.killed = 99 combat.T_Damage(qc.self, qc.self, qc.self, 1000) # Kill the player qc.self.killed = 2 # trying to change teams counts as a suicide qc.self.suicide_count += 1 qc.self.logfrag(qc.self) # he pays for it qc.self.sprint(defs.PRINT_HIGH, 'You cannot change teams.\012') qc.self.stuffcmd('setinfo bottomcolor ') s = str(qc.self.steam) qc.self.stuffcmd(s) qc.self.stuffcmd('\012') qc.self.lastteamset = qc.time return else: # If we're on an illegal team, force a change. qc.self.steam = -1 elif not (defs.teamplay & TEAM_LOCK_COLORS): return if qc.self.steam >= 0: # case base respawn qc.self.killed = 99 combat.T_Damage(qc.self, qc.self, qc.self, 1000) # Kill the player qc.self.killed = 0 qc.self.steam = pteam qc.self.frags = 0 # Zero out frags TeamAssign()
def WaterMove(*qwp_extra): # dprint (ftos(self.waterlevel)); if qc.self.movetype == defs.MOVETYPE_NOCLIP: return if qc.self.health < 0: return if qc.self.waterlevel != 3: if qc.self.air_finished < qc.time: qc.self.sound(defs.CHAN_VOICE, 'player/gasp2.wav', 1, defs.ATTN_NORM) elif qc.self.air_finished < qc.time + 9: qc.self.sound(defs.CHAN_VOICE, 'player/gasp1.wav', 1, defs.ATTN_NORM) qc.self.air_finished = qc.time + 12 qc.self.dmg = 2 elif qc.self.air_finished < qc.time: # drown! if qc.self.pain_finished < qc.time: qc.self.dmg += 2 if qc.self.dmg > 15: qc.self.dmg = 10 combat.T_Damage(qc.self, qc.world, qc.world, qc.self.dmg) qc.self.pain_finished = qc.time + 1 if not qc.self.waterlevel: if qc.self.flags & defs.FL_INWATER: # play leave water sound qc.self.sound(defs.CHAN_BODY, 'misc/outwater.wav', 1, defs.ATTN_NORM) qc.self.flags -= defs.FL_INWATER return if qc.self.watertype == defs.CONTENT_LAVA: # do damage if qc.self.dmgtime < qc.time: if qc.self.radsuit_finished > qc.time: qc.self.dmgtime = qc.time + 1 else: qc.self.dmgtime = qc.time + 0.2 combat.T_Damage(qc.self, qc.world, qc.world, 10 * qc.self.waterlevel) elif qc.self.watertype == defs.CONTENT_SLIME: # do damage if qc.self.dmgtime < qc.time and qc.self.radsuit_finished < qc.time: qc.self.dmgtime = qc.time + 1 combat.T_Damage(qc.self, qc.world, qc.world, 4 * qc.self.waterlevel) if not (qc.self.flags & defs.FL_INWATER): # player enter water sound if qc.self.watertype == defs.CONTENT_LAVA: qc.self.sound(defs.CHAN_BODY, 'player/inlava.wav', 1, defs.ATTN_NORM) if qc.self.watertype == defs.CONTENT_WATER: qc.self.sound(defs.CHAN_BODY, 'player/inh2o.wav', 1, defs.ATTN_NORM) if qc.self.watertype == defs.CONTENT_SLIME: qc.self.sound(defs.CHAN_BODY, 'player/slimbrn2.wav', 1, defs.ATTN_NORM) qc.self.flags += defs.FL_INWATER qc.self.dmgtime = 0
def secret_blocked(*qwp_extra): if qc.time < qc.self.attack_finished: return qc.self.attack_finished = qc.time + 0.5 combat.T_Damage(qc.other, qc.self, qc.self, qc.self.dmg)
def fire_touch(*qwp_extra): combat.T_Damage(qc.other, qc.self, qc.self, 20) qc.self.remove()
def ApplyMultiDamage(*qwp_extra): if not multi_ent: return combat.T_Damage(multi_ent, qc.self, qc.self, multi_damage)