Making certain entities invisible to certain players

Post Python examples to help other users.
User avatar
iPlayer
Developer
Posts: 522
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Making certain entities invisible to certain players

Postby iPlayer » Sat Sep 17, 2016 10:34 am

... or you could even make certain entities be transmitted only to one player.

Syntax: Select all

from entities import CheckTransmitInfo
from entities.entity import Entity
from entities.helpers import index_from_edict
from entities.hooks import EntityCondition, EntityPreHook
from memory import make_object
from players.entity import Player


def transmit_filter(entity, player):
if player.name != "iPlayer":
return True

if entity.classname != "prop_physics_multiplayer":
return True

return False


# You can define your own entity_condition function that should return
# True for entities whose SetTransmit method we want to hook
entity_condition = EntityCondition.equals_entity_classname(
"prop_physics_multiplayer")


@EntityPreHook(entity_condition, 'set_transmit')
def pre_set_transmit(args):
entity = make_object(Entity, args[0])
edict = make_object(CheckTransmitInfo, args[1]).client
player = Player(index_from_edict(edict))

# We always transmit the player to himself. If we don't, bad things happen.
if player.index == entity.index:
return None

return None if transmit_filter(entity, player) else False


Things to change:

Syntax: Select all

def transmit_filter(entity, player):
if player.name != "iPlayer":
return True

if entity.classname != "prop_physics_multiplayer":
return True

return False

This filter receives two arguments: entity for transmission and the player to transmit this entity to. If transmission should happen, filter must return True, otherwise False.

Syntax: Select all

entity_condition = EntityCondition.equals_entity_classname(
"prop_physics_multiplayer")

Basically, entity_condition is a function that receives an Entity instance and returns True if that's the entity we want to set the hook on. Different entity classes have different SetTransmit methods, so if we set the hook on CBaseCombatCharacter::SetTransmit, transmitting of the CSprite won't get hooked.

If you want to hook player transmission (e.g. make certain players invisible to some other players), you can go with

Syntax: Select all

entity_condition = EntityCondition.is_player


Reference for the first argument SetTransmit receives:
https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/iservernetworkable.h#L37

This example has been written after I found the snippet of SM code provided by Bristwex

Syntax: Select all

SDKHook(entity, SDKHook_SetTransmit, Hook_SetTransmit); 

public Action:Hook_SetTransmit(entity, client)
{
if (<entity and client checks>)
{
return Plugin_Continue;
}
return Plugin_Handled;
}
Last edited by iPlayer on Fri May 05, 2017 3:02 pm, edited 3 times in total.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 522
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Making certain entities invisible to certain players

Postby iPlayer » Sat Sep 17, 2016 10:54 am

L'In20Cible wrote:https://github.com/Source-Python-Dev-Team/Source.Python/search?utf8=%E2%9C%93&q=set_transmit
https://github.com/Source-Python-Dev-Te ... p.cpp#L513


Thanks, completely missed that. Updated my previous post.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 522
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Making certain entities invisible to certain players

Postby iPlayer » Fri May 05, 2017 3:05 pm

Updated the first post. Added the following check to the hook:

Syntax: Select all

# We always transmit the player to himself. If we don't, bad things happen.
if player.index == entity.index:
return None


In all games "bad things" is player not being able to see themselves moving, i.e. they will be stuck on their screen. Apparently on CS:GO (and only on Windows SRCDS) the server will just disconnect the player with the following error:

Code: Select all

Host_Error: CL_ReadPreserveEnt: u.m_nNewEntity == MAX_EDICTS


To avoid further problems, I decided to enforce this check into this example. There's really no reason not to transmit the player to himself.

Thanks to EmilioK for narrowing down the issue.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

Hail, Companion. [...] Hands to yourself, sneak thief. Image

Return to “Code examples / Cookbook”

Who is online

Users browsing this forum: No registered users and 1 guest