def _on_drop_remove_weapon(stack_data): 'Remove weapons that are dropped. This is to stop weapon duplicating.' ## We could turn the weapon into a physics prop, however for some reason weapon models ## do not function as props with physics :s index = index_from_pointer(stack_data[1]) item = items.find_by_index(index) if item: item.on_dropped(player_inventories[index_from_pointer(stack_data[0])])
def pre_bump_weapon(pointers): pointer_player, pointer_weapon = pointers player = player_manager[index_from_pointer(pointer_player)] weapon_index = index_from_pointer(pointer_weapon) for callback in weapon_pickup_filters: if callback(player, weapon_index) is False: # Disallow pick-up return True # Allow pick-up return None
def pre_bump_weapon(pointers): pointer_player, pointer_weapon = pointers player = main_player_manager[index_from_pointer(pointer_player)] weapon_index = index_from_pointer(pointer_weapon) for callback in weapon_pickup_filters: if callback(player, weapon_index) is False: # Disallow pick-up return True # Allow pick-up return None
def _pre_on_take_damage(args): info = make_object(TakeDamageInfo, args[1]) entity = Entity(info.attacker) if info.attacker else None if entity is not None and entity.is_player(): attacker = wcgo.player.Player(entity.index) else: attacker = None victim = wcgo.player.Player(index_from_pointer(args[0])) eargs = { 'attacker': attacker, 'victim': victim, 'info': info, } # Adds the weapon argument dependent on scenario if attacker is not None and attacker.active_weapon != -1: eargs['weapon'] = Weapon(index_from_inthandle(attacker.active_weapon)) else: eargs['weapon'] = None if attacker is None or attacker.userid == victim.userid: victim.hero.execute_skills('player_pre_self_injury', player=victim, **eargs) return if not (attacker.steamid == 'BOT' and attacker.hero is None): attacker.hero.execute_skills('player_pre_attack', player=attacker, **eargs) if not (victim.steamid == 'BOT' and victim.hero is None): victim.hero.execute_skills('player_pre_victim', player=victim, **eargs)
def on_take_damage(args): protected_player = protected_player_manager[index_from_pointer(args[0])] if protected_player.dead: return info = make_object(TakeDamageInfo, args[1]) return protected_player._hurt(info)
def _pre_on_take_damage(args): """ Hooked to a function that is fired any time an entity takes damage. """ player_index = index_from_pointer(args[0]) info = make_object(TakeDamageInfo, args[1]) defender = Player(player_index) attacker = None if not info.attacker else Player(info.attacker) eargs = { 'attacker': attacker, 'defender': defender, 'info': info, 'weapon': Weapon( index_from_inthandle(attacker.active_weapon) ).class_name if attacker and attacker.active_weapon != -1 else '' } if not player_index == info.attacker: defender.hero.execute_skills('player_pre_defend', **eargs) ''' Added exception to check whether world caused damage. ''' if attacker: attacker.hero.execute_skills('player_pre_attack', **eargs)
def _pre_on_take_damage(args): """ Hooked to a function that is fired any time an entity takes damage. """ player_index = index_from_pointer(args[0]) info = make_object(TakeDamageInfo, args[1]) defender = Player(player_index) attacker = None if not info.attacker else Player(info.attacker) eargs = { 'attacker': attacker, 'defender': defender, 'info': info, 'weapon': Weapon(index_from_inthandle(attacker.active_weapon)).class_name if attacker and attacker.active_weapon != -1 else '' } if not player_index == info.attacker: defender.hero.execute_skills('player_pre_defend', **eargs) ''' Added exception to check whether world caused damage. ''' if attacker: attacker.hero.execute_skills('player_pre_attack', **eargs)
def _pre_damage_call_events(stack_data): take_damage_info = make_object(TakeDamageInfo, stack_data[1]) if not take_damage_info.attacker: return entity = Entity(take_damage_info.attacker) attacker = players[entity.index] if entity.is_player() else None victim = players[index_from_pointer(stack_data[0])] event_args = { 'attacker': attacker, 'victim': victim, 'take_damage_info': take_damage_info, } if attacker: if victim.team == attacker.team: attacker.hero.call_events('player_pre_teammate_attack', player=attacker, **event_args) victim.hero.call_events('player_pre_teammate_victim', player=victim, **event_args) return attacker.hero.call_events('player_pre_attack', player=attacker, **event_args) victim.hero.call_events('player_pre_victim', player=victim, **event_args) if victim.health <= take_damage_info.damage: attacker.hero.call_events('player_pre_death', player=victim, **event_args)
def pre_on_take_damage(stack_data): index = index_from_pointer(stack_data[0]) if index not in _blocks_by_solids: return block = _blocks_by_solids[index] info = make_object(TakeDamageInfo, stack_data[1]) if is_world_entity(info.attacker): return True attacker = rats[info.attacker] for block_ in block.neighbours(): if block_.type not in (BlockType.WORLD, BlockType.WORLD_IMMUNE): continue if not block_.flags & BlockFlags.DISCOVERED: continue if attacker.area_id != block_.area_id: continue block.break_start() break return True
def _pre_bump_weapon(args): """ Hooked to a function that is fired any time a weapon is requested to be picked up in game. """ player_index = index_from_pointer(args[0]) weapon_index = index_from_pointer(args[1]) weapon = Weapon(weapon_index) player = Player(player_index) eargs = {'weapon': weapon, 'player': player} if weapon.classname in player.restrictions: player.hero.execute_skills('weapon_pickup_fail', **eargs) return False else: player.hero.execute_skills('weapon_pickup', **eargs)
def _spend_skills_on_level_up(player, race, amount): """ Callback for the race_level_up event to handle menu sending, bot auto-upgrades and level up effects. """ if (race.level > sum(skill.max_level for skill in race.skills) or race.level > race.max_level): return spend_skills_menu.send(player.index) if player.steamid == 'BOT': while race.unused_points > 0: skill = find_upgradable_skill(race) if skill: skill.level_up(1) levelup_sound.origin = player.origin levelup_sound.play(player.index) pointer = player.give_named_item('env_smokestack', 0, None, False) entity = Entity(index_from_pointer(pointer)) for output in ('basespread 10', 'spreadspeed 60', 'initial 0', 'speed 105', 'rate 50', 'startsize 7', 'endsize 2', 'twist 0', 'jetlength 100', 'angles 0 0 0', 'rendermode 18', 'renderamt 100', 'rendercolor 255 255 3', 'SmokeMaterial effects/yellowflare.vmt'): entity.add_output(output) entity.turn_on() attach_entity_to_player(player, entity) entity.delay(0.5, entity.turn_off)
def _weapon_bump(args): """ Hooked to a function that is fired any time a weapon is requested to be picked up in game. """ player_index = index_from_pointer(args[0]) weapon_index = index_from_pointer(args[1]) weapon = WeaponEntity(weapon_index) player = Player(player_index) eargs = {'weapon': weapon, 'player': player} if weapon.classname in player.restrictions: player.hero.execute_skills('weapon_pickup_fail', **eargs) return False else: player.hero.execute_skills('weapon_pickup', **eargs)
def _pre_run_command_call_events(stack_data): player = players[index_from_pointer(stack_data[0])] usercmd = make_object(UserCmd, stack_data[1]) player.hero.call_events('player_pre_run_command', player=player, usercmd=usercmd)
def _pre_run_command_call_events(stack_data): player = player_dict[index_from_pointer(stack_data[0])] usercmd = make_object(UserCmd, stack_data[1]) if not player.dead or player.call_events_when_dead: player.call_events('player_pre_run_command', player=player, usercmd=usercmd)
def _on_buy_internal(args): """ Hooked to a function that is fired any time a weapon is purchased. (Stops bots from buying.) """ player_index = index_from_pointer(args[0]) player = Player(player_index) if player.playerinfo.is_fake_client() and len(player.restrictions) > 0: return 0
def _on_entity_use(stack): entity_index = index_from_pointer(stack[0]) player_index = make_object(InputData, stack[1]).activator.index flag = flag_manager.find(entity_index) other = flag_manager.find_by_carrier(player_index) if flag and not other: Delay(0.1, flag_manager.on_carrier_pickup, flag, Player(player_index))
def pre_on_take_damage(stack_data): rat = rats[index_from_pointer(stack_data[0])] info = make_object(TakeDamageInfo, stack_data[1]) if info.attacker == rat.player.index or is_world_entity(info.attacker): return attacker = rats[info.attacker] if rat.area_id != attacker.area_id: return True
def on_take_damage(args): dm_player_victim = player_manager[index_from_pointer(args[0])] if dm_player_victim.protected: return True info = make_object(TakeDamageInfo, args[1]) try: dm_player_attacker = player_manager[info.attacker] except KeyError: return if dm_player_attacker.protected: dm_player_attacker.cancel_protection_delay() dm_player_attacker.unprotect() return True
def level_up(player): player.client_command('play */source-python/wcs/levelup.mp3') pointer = player.give_named_item('env_smokestack', 0, None, False) entity = Entity(index_from_pointer(pointer)) for output in ('basespread 10', 'spreadspeed 60', 'initial 0', 'speed 105', 'rate 50', 'startsize 7', 'endsize 2', 'twist 0', 'jetlength 100', 'angles 0 0 0', 'rendermode 18', 'renderamt 100', 'rendercolor 255 255 3', 'SmokeMaterial effects/yellowflare.vmt'): entity.add_output(output) entity.call_input('TurnOn') entity.set_parent(player.pointer, -1) tick_delays.delay(2, entity.call_input, 'TurnOff') tick_delays.delay(2.1, entity.call_input, 'Kill')
def _on_level_change(hero): player = hero.owner spend_skills.send(player) pointer = player.give_named_item('env_smokestack') entity = Entity(index_from_pointer(pointer)) Model('effects/yellowflare.vmt') for output in ('basespread 10', 'spreadspeed 60', 'initial 0', 'speed 105', 'rate 50', 'startsize 7', 'endsize 2', 'twist 0', 'jetlength 100', 'angles 0 0 0', 'rendermode 18', 'renderamt 100', 'rendercolor 255 255 3', 'SmokeMaterial effects/yellowflare.vmt'): entity.add_output(output) entity.turn_on() entity.set_parent(player.pointer, -1) entity.delay(0.5, entity.turn_off, cancel_on_level_end=True)
def _on_level_change(hero): player = hero.owner spend_skills.send(player) pointer = player.give_named_item('env_smokestack', 0, None, False) entity = Entity(index_from_pointer(pointer)) Model('effects/yellowflare.vmt') for output in ('basespread 10', 'spreadspeed 60', 'initial 0', 'speed 105', 'rate 50', 'startsize 7', 'endsize 2', 'twist 0', 'jetlength 100', 'angles 0 0 0', 'rendermode 18', 'renderamt 100', 'rendercolor 255 255 3', 'SmokeMaterial effects/yellowflare.vmt'): entity.add_output(output) entity.turn_on() entity.set_parent(player.pointer, -1) entity.delay(0.5, entity.turn_off, cancel_on_level_end=True)
def pre_on_take_damage(stack): if _global_bypass: return info = make_object(TakeDamageInfo, stack[1]) attacker = info.attacker if 0 < attacker <= global_vars.max_clients: wcsattacker = Player.from_index(attacker) else: wcsattacker = None index = index_from_pointer(stack[0]) wcsvictim = Player.from_index(index) OnTakeDamage.manager.notify(wcsvictim, wcsattacker, info)
def get_view_entity(self): """Return the entity that the player is looking at.""" # Get the player's current trace data trace = self.get_trace_ray() # Did the trace hit? if not trace.did_hit(): return None # Get the entity that the trace hit pointer = Pointer(trace.get_entity().get_base_entity()) # Get the index of the entity the trace hit index = index_from_pointer(pointer, False) # Return a Entity instance of the hit entity if it has an index return Entity(index) if index else None
def _execute_pre_damage_skills(args): """Execute skills for pre attack and victim.""" take_damage_info = make_object(TakeDamageInfo, args[1]) if not take_damage_info.attacker: return attacker = g_players[take_damage_info.attacker] victim = g_players[index_from_pointer(args[0])] if victim.team == attacker.team: return event_args = { 'attacker': attacker, 'victim': victim, 'take_damage_info': take_damage_info, } event_args['player'] = attacker attacker.hero.execute_skills('pre_player_attack', event_args) event_args['player'] = victim victim.hero.execute_skills('pre_player_victim', event_args)
def _on_take_damage(args): """ Hooked to a function that is fired any time an entity takes damage. """ player_index = index_from_pointer(args[0]) info = make_object(TakeDamageInfo, args[1]) defender = Player(player_index) attacker = None if not info.attacker else Player(info.attacker) eargs = { 'attacker': attacker, 'defender': defender, 'info': info } if not player_index == info.attacker: defender.hero.execute_skills('player_pre_defend', **eargs) attacker.hero.execute_skills('player_pre_attack', **eargs)
def _on_use_add_weapon(stack_data): 'Add items to the inventory which do not have the <use> input.' ## If a <Item> cannot be accessed via the <use> input. We try to find it by ## hooking the player\'s <run_command> and firing a trace ray upon <PlayerButtons.USE> ## being pushed. usercmd = make_object(UserCmd, stack_data[1]) if not usercmd.buttons & PlayerButtons.USE: return player = player_inventories[index_from_pointer(stack_data[0])] trace = player.get_trace_ray() if not trace.did_hit() or trace.entity_index == 0: return item = items.find_by_index(trace.entity_index) if not item or item.entity.classname != 'prop_dynamic': return item.on_remove() item.on_pickup(player)
def level_up(player): """Display the level up effect on a player.""" pointer = player.give_named_item('env_smokestack', 0, None, False) entity = Entity(index_from_pointer(pointer)) entity.add_output('basespread 10') entity.add_output('spreadspeed 60') entity.add_output('initial 0') entity.add_output('speed 105') entity.add_output('rate 50') entity.add_output('startsize 7') entity.add_output('endsize 2') entity.add_output('twist 0') entity.add_output('jetlength 100') entity.add_output('angles 0 0 0') entity.add_output('rendermode 18') entity.add_output('renderamt 100') entity.add_output('rendercolor 255 255 3') entity.add_output('SmokeMaterial effects/yellowflare.vmt') entity.call_input('TurnOn') entity.set_parent(player.pointer, -1) tick_delays.delay(2, entity.call_input, 'TurnOff') tick_delays.delay(2.1, entity.call_input, 'Kill')
def pre_set_transmit(stack_data): """Hides 'point_worldtext' entities that are part of FloatingNumbers for everyone except the specified recipient. """ index = index_from_pointer(stack_data[0]) try: # Does this index belong to a FloatingNumber instance? floating_number = number_instances[index] except KeyError: # Nope, don't go further. return None info = CheckTransmitInfo._obj(stack_data[1]) # Strip the FL_EDICT_ALWAYS flag from the 'point_worldtext'. floating_number.state_flags = floating_number.state_flags ^ FL_EDICT_ALWAYS # Is this the recipient of the FloatingNumber entity? if floating_number.recipient == userid_from_edict(info.client): # Show the entity. return None else: # If not, hide the entity. return False
def pre_bump_weapon(args): player_index = index_from_pointer(args[0]) weapon = make_object(WeaponEntity, args[1]) player_restriction = get_player_restriction(player_index) if player_restriction.is_restricted(weapon.classname): return False
def _obj(cls, ptr): """Return an entity instance of the given pointer.""" return cls(index_from_pointer(ptr))
def _pre_bump_weapon(args): """Prevent the weapon bump if the weapon is restricted.""" player = EasyPlayer(index_from_pointer(args[0])) weapon = Weapon(index_from_pointer(args[1])) if weapon.classname in player.restrictions: return False
def _on_buy_internal(args): """Prevent the weapon buy if the weapon is restricted.""" player = EasyPlayer(index_from_pointer(args[0])) weapon = 'weapon_{}'.format(args[1]) if weapon in player.restrictions: return 0
def _setup_weapon(self, player): 'When the weapon is given, this sets up the ammo and clip.' self.entity = SPWeapon( index_from_pointer(player.give_named_item(self.classname))) self._setup_ammo() setattr(player, '{}_weapon'.format(self.slot), self)
def on_take_damage_alive_pre(stack_data): """Creates a FloatingNumber when a player takes damage.""" # Get the Player instance of the victim. player_v = player_instances[index_from_pointer(stack_data[0])] # Get the CTakeDamageInfo instance. info = TakeDamageInfo._obj(stack_data[1]) # Get the index of the entity that caused the damage. index_a = info.attacker # Did the player take damage from the world? if index_a == 0: # Are damage numbers disabled for world damage (world_damage set to 0)? if not world_damage.get_int(): return number_origin = player_v.get_number_origin() unique_data = [] for player in player_instances.values(): # There's no need for bots to see the FloatingNumber. if player.is_bot(): continue # Is the player not looking at the position where the # FloatingNumber is going to spawn? if not player.is_in_fov(target=number_origin): continue distance = number_origin.get_distance(player.origin) # Add this player's unique data to the list. unique_data.append({ 'angle': player.view_angle, 'size': 10 + distance * DISTANCE_MULTIPLIER, 'recipient': player.userid }) # Will no one be able to see this FloatingNumber? if not unique_data: # Don't bother spawning it. return FloatingNumber.world_damage( origin=number_origin, # Since `info.damage` is a float, convert it to an integer before # converting it to a string to get rid of the decimal part. number=str(int(info.damage)), color=WHITE, unique_data=unique_data ) # Or from a player? else: try: # Try to get the Player instance of the attacker. player_a = player_instances[index_a] except ValueError: # Damage was caused indirectly (grenade, projectile). try: # Try to get a Player instance again, but this time using the # the owner inthandle of the entity that caused the damage. player_a = player_instances.from_inthandle( Entity(info.inflictor).owner_handle) except (ValueError, OverflowError): # ValueError: not a player. # OverflowError: invalid owner inthandle (-1). return # Is the attacker a bot? if player_a.is_bot(): return # Self inflicted damage? if player_v is player_a: return number_origin = player_v.get_number_origin() velocity = None # Did the bullet go through another entity before hitting the player? if info.penetrated and wall_bangs.get_int(): # Let's check if that entity is the world. trace = GameTrace() engine_trace.clip_ray_to_entity( # Create a Ray() from the attacker's eyes to the hit position. Ray(player_a.eye_location, info.position), ContentMasks.ALL, Entity(WORLD_ENTITY_INDEX), trace ) # Is this an actual wall-bang (bullet went through world)? if trace.did_hit(): # Calculate the directional vector from the wall to the player. from_wall = trace.start_position - trace.end_position # Calculate the offset for the FloatingNumber's new origin. origin_offset = 10 + from_wall.length * 0.01 # Normalize it. # Vector(368.52, 40.71, -7.77) -> Vector(0.99, 0.10, -0.02) from_wall.normalize() # Change the origin of the FloatingNumber so it spawns in front # of the wall where the wall-bang took place. number_origin = trace.end_position + origin_offset * from_wall right, up = Vector(), Vector() from_wall.get_vector_vectors(right, up) velocity = from_wall * 25 + ( right * 35 * player_a.next_direction) # If the bullet went through something else (another player) # before hitting the wall, adjust how high the FloatingNumber # gets pushed. velocity.z = 75 * info.penetrated distance = number_origin.get_distance(player_a.origin) # TODO: Figure out a better way to allow other plugins to change the # color of the FloatingNumber. Or hardcode the colors to unused # DamageTypes (e.g. AIRBOAT = YELLOW, PHYSGUN = BLUE)? color = YELLOW if info.type == DamageTypes.AIRBOAT else WHITE FloatingNumber( origin=number_origin, number=str(int(info.damage)), # Change the color if it's a headshot. color=RED if player_v.last_hitgroup == 1 else color, angle=player_a.view_angle, # Increase the size depending on the distance. size=10 + distance * DISTANCE_MULTIPLIER, recipient=player_a.userid, velocity=velocity )
def pre_start_touch(stack_data): entity_index = index_from_pointer(stack_data[0]) other_index = index_from_pointer(stack_data[1]) _ecx_storage_start_touch_flags[ stack_data.registers.esp.address.address] = (entity_index, other_index)