Particle effects!

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

Postby iPlayer » Sat Dec 05, 2015 11:22 pm

I did.

Syntax: Select all

from entities.entity import Entity
from engines.precache import Generic as PrecacheGeneric
from events import Event
from mathlib import Vector
from stringtables.downloads import Downloadables


PARTICLE_FILE = "particles/my_particle_systems.pcf"


my_downloads = Downloadables()
my_downloads.add(PARTICLE_FILE)

PrecacheGeneric(PARTICLE_FILE)


@Event('bullet_impact')
def on_bullet_impact(game_event):
x, y, z = game_event.get_float('x'), game_event.get_float('y'), game_event.get_float('z')
entity = Entity.create('info_particle_system')
entity.set_key_value_bool('start_active', True)
entity.set_key_value_string('effect_name', "my_particle_system")
entity.spawn()
entity.teleport(Vector(x, y, z), None, None)
entity.activate()


Built-in particle systems work fine.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Postby L'In20Cible » Sat Dec 05, 2015 11:25 pm

Syntax: Select all

PrecacheGeneric(PARTICLE_FILE, preload=True)
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Sat Dec 05, 2015 11:26 pm

Also found a post at AlliedModders claiming that CS:S is something special in this case:

No any precache here, i cannot use my own particle systems by that code,
Just spawn is simple enough...

My friend uses 3 ddl's and a lot of code to use them at cs:s

he's vid:

https://www.youtube.com/watch?v=b0hZ1yAzXhA


Unfortunately, the guy and his friend don't want to publish the code.


L'In20Cible
Nvm. Tried that and didn't work.


I'd also like to quote this
No,precachemodel will not work at all,even cs:go.
PrecacheGeneric works at cs:go,but not at cs:s.


Any other ways to precaches available?
User avatar
Doldol
Senior Member
Posts: 200
Joined: Sat Jul 07, 2012 7:09 pm
Location: Belgium

Postby Doldol » Mon Dec 07, 2015 1:04 am

iPlayer wrote:Also found a post at AlliedModders claiming that CS:S is something special in this case:



Unfortunately, the guy and his friend don't want to publish the code.


So a sigscanned/virtual offset function? I don't see how the number of dll's loaded would change anything. You can't magically make the client do something it can't, unless he meant client-side dlls, in which case you're screwed if you want to use that on a public server.

BTW: That linked topic mentions PrecacheModel at the end, worth a shot?
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Mon Dec 07, 2015 6:04 am

No, I tried PrecacheModel and it didn't work either.

It only works when I put the following manifest in /custom/myparticles/particles_manifest.txt

Code: Select all

particles_manifest
{
    "file"        "particles/my_particle_systems.pcf"
    "file"        "particles/achievement.pcf"
    "file"        "particles/blood_impact.pcf"
    "file"        "particles/fire_01.pcf"
    "file"        "particles/burning_fx.pcf"
    "file"        "particles/water_impact.pcf"
    "file"        "!particles/muzzleflashes.pcf"
    "file"        "particles/error.pcf"
}


And then it works.


Client just don't look it up in download dir, I only looks at this manifest. And I feel like there must be a way to add a new entry to client's manifest. Unfortunately, manifest itself can't be downloaded to client.


Edit: There's a stringtable called ParticleEffectNames

Edit2: Tried

Syntax: Select all

string_tables.ParticleEffectNames.add_string("my_particle_system", "my_particle_system")

and

Syntax: Select all

string_tables.ParticleEffectNames.add_string("my_particle_system", "my_particle_system", is_server=False)


Didn't work.

And I'm sure it's possible to do from serverside, because the guy hosts public zombie-server.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Mon Dec 07, 2015 5:49 pm

There's also this CServerTools::ReloadParticleDefintions function, I guess it may end up sending something to client. But I'm unsure what kind of file the function requires (manifest?) and how to call it.
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Particle effects!

Postby Predz » Sat Sep 10, 2016 12:55 am

I have been revisiting this recently, and noticed the cause of the problem for having to reconnect. For some reason the client always downloads the required pcf files after the client actually precaches all of their materials/generic items. I was wondering whether it is possible to force the client to re-"precache" on their side? I understand this is probably beyond our capabilities due to this is manipulating the client's side, however if so then this maybe a work around. I am going to make a post in the valve csgo forums about this too, because surely it is meant to be that the downloads should happen before the precaching of data?

You can see below what I am trying to get at:

Code: Select all

Connected to 79.132.247.181:27019

Counter-Strike: Global Offensive
Map: workshop/145931981/glass_war_csgo
Players: 2 (0 bots) / 32 humans
Build: 6494
Server Number: 3

Missing map material: MAPS/GLASS_WAR/CONCRETEWALL01
Missing map material: MAPS/GLASS_WAR/CONCRETEWALL01
#######################################
Map workshop/145931981/glass_war_csgo missing stringtable dictionary, don't ship this way!!!
Run with -stringtables on the command line or convar
stringtable_alwaysrebuilddictionaries enabled to build the string table
#######################################
SignalXWriteOpportunity(3)

Particles: Missing 'particles/wcgo_test.pcf'
Attempted to precache unknown particle system "WC_GO"!

Downloading particles/wcgo_test.pcf.
Download finished!

Got pure server whitelist: sv_pure = 1.
Predz connected.

Attempting to create unknown particle system 'WC_GO'


My current test work fine as long as map change happens or they reconnect, because they obviously then recache the particles. But would really like to find a way to do this, for convenience to players :)
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Particle effects!

Postby Predz » Sat Sep 10, 2016 9:39 am

iPlayer have you tried to hook the CServerTools function? I am trying myself now, however cannot get hold of a CServerTools instance anymore. I believe we used to have access to it via the "server_tools" object.

The only reason I say hook, is because I am trying to identify what function is called upon the particles being precached. If so then maybe we can re-call it.

Edit: Virtual Offsets for this function are 19 (Linux) and 18 (Windows)
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Particle effects!

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

No, I didn't.

Since you're on it, what happens if you do
*/particles/my_particle_systems.pcf
everywhere instead of bare
particles/my_particle_systems.pcf
?
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Particle effects!

Postby Predz » Sat Sep 10, 2016 12:16 pm

I am going to test it like this however very unlikely to change anything from what I have know. I have the particle effects working currently, apart from when the player joins for the first time, on the current map. As soon as map change happens or they rejoin everything then works. Just trying to find a fix for this issue.

EDIT: Yep adding the relative path to the downloads just causes it to no longer be downloaded. So unfortunately changes nothing. :frown:
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Particle effects!

Postby L'In20Cible » Sat Sep 10, 2016 1:47 pm

I have an idea that may work, but I need your files/code for further testing.
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Particle effects!

Postby Predz » Sat Sep 10, 2016 2:16 pm

This is a bit messy at the moment, but shown below:

Syntax: Select all

from core import AutoUnload
from core import PLATFORM
from core import echo_console
from engines.precache import Generic
from entities.entity import Entity
from events.manager import event_manager
from events import Event
from players.entity import Player
from listeners import OnLevelInit
from listeners.tick import Delay
from stringtables import string_tables

import memory
from memory import Convention
from memory import DataType
from memory import Callback
from memory.hooks import PreHook
from memory.manager import CustomType
from memory.manager import manager
from messages import SayText2

# ======================================================================
# >> PARTICLE MANAGEMENT
# ======================================================================

for pcf in ('wcgo_test.pcf', ):
string_tables.ExtraParticleFilesTable.add_string(pcf)
Generic('particles/'+pcf, True, True)

class Particles(dict):

def __init__(self):
super(Particles, self).__init__()
self._refresh_table_instance()

def _refresh_table_instance(self):
self._table = string_tables.ParticleEffectNames

def server_spawn(self, event):
self._refresh_table_instance()
for item in self:
self[item] = self._table.add_string(item)

_particles = Particles()

event_manager.register_for_event(
'server_spawn', _particles.server_spawn)

for particle in ('WC_GO', ):
_particles[particle] = _particles._table.add_string(particle)

# ======================================================================
# >> CUSTOM TYPE FOR CPARTICLESYSTEMMGR
# ======================================================================

server = memory.find_binary('server', srv_check=False)

class CParticleSystemMgr(CustomType, metaclass=manager):

Init = manager.virtual_function(3, [])

particle_manager = memory.make_object(CParticleSystemMgr, server.find_pointer('g_pParticleSystemMgr', level=1))

@PreHook(particle_manager.Init)
def _init(args):
echo_console('1')

# ======================================================================
# >> MAKE PARTICLE
# ======================================================================

def make_particle(position, particle_name, lifetime):
particle = Entity.create('info_particle_system')
particle.effect_name = particle_name
particle.origin = position
particle.effect_index = _particles[particle_name]
particle.start_active = 1
particle.start()

return particle

@Event('player_jump')
def _player_jump(event):
player = Player.from_userid(event['userid'])
particle = make_particle(player.origin, 'WC_GO', 10)
particle.set_parent(player, -1)


For the pcf file I have it on dropbox as a friend made it: https://www.dropbox.com/s/jv7e0t4yrh6opi3/wcgo_test.pcf?dl=0
Manifest
Junior Member
Posts: 10
Joined: Thu Jun 18, 2015 7:24 pm

Re: Particle effects!

Postby Manifest » Sun Sep 11, 2016 8:14 pm

For the pcf file I have it on dropbox as a friend made it: https://www.dropbox.com/s/jv7e0t4yrh6op ... t.pcf?dl=0


I'd like to emphasize that this file was purely made for testing purposes, and is not a pretty particle effect in any way what so ever, and I hope we can somehow find a fix for this issue, as it will allow for some nice visuals in CS:GO in comparison to only using smokestacks, steam and temp entities.

I really do appreciate all the help that the forum has been providing in solving this case, big ups to you guys! :-)
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Particle effects!

Postby L'In20Cible » Sun Sep 11, 2016 11:49 pm

The best solution I came with:

Syntax: Select all

from core import PLATFORM
from listeners import OnClientFullyConnect
from memory import Convention
from memory import DataType
from memory import get_object_pointer
from memory import find_binary
from memory.hooks import PreHook
from players.entity import Player

clients = set()

def get_file_requested_function():
if PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x56\x8B\xF1\x57\x8B\x8E\x10\x02\x00\x00\x8B\x01\xFF'
else:
identifier = '_ZN11CGameClient13FileRequestedEPKcjb'

# CGameClient::FileRequested(CGameClient *this, const char *, unsigned int, bool)
address = find_binary('engine').find_address(identifier)
return address.make_function(Convention.THISCALL, (DataType.POINTER,
DataType.STRING, DataType.UINT, DataType.BOOL), DataType.VOID)

@PreHook(get_file_requested_function())
def pre_file_requested(stack_data):
if stack_data[1] != 'particles/wcgo_test.pcf':
return
clients.add(stack_data[0].address)

@OnClientFullyConnect
def on_client_fully_connect(player_index):
player = Player(player_index)
address = get_object_pointer(player.client).address
if address not in clients:
return
clients.remove(address)
player.client_command('retry')


Which is forcing the player to reconnect the first time they request the particles from the server.
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Particle effects!

Postby Predz » Mon Sep 12, 2016 8:58 am

Thanks!

I made a change to where you get the Client instance from but it works perfectly! :)

Syntax: Select all

clients = set()

def get_file_requested_function():
if PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x56\x8B\xF1\x57\x8B\x8E\x10\x02\x00\x00\x8B\x01\xFF'
else:
identifier = '_ZN11CGameClient13FileRequestedEPKcjb'

# CGameClient::FileRequested(CGameClient *this, const char *, unsigned int, bool)
address = find_binary('engine', srv_check=False).find_address(identifier)
return address.make_function(Convention.THISCALL, (DataType.POINTER,
DataType.STRING, DataType.UINT, DataType.BOOL), DataType.VOID)

@PreHook(get_file_requested_function())
def pre_file_requested(stack_data):
if stack_data[1] != 'particles/wcgo_test.pcf':
return
clients.add(stack_data[0].address)

@OnClientFullyConnect
def on_client_fully_connect(player_index):
player = Player(player_index)
address = player.base_client.address
if address not in clients:
return
clients.remove(address)
player.client_command('retry')
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Particle effects!

Postby L'In20Cible » Mon Sep 12, 2016 12:01 pm

I tested on windows, and it was called using the "client" address. You may want to test on both and add a platform check if needed otherwise your plugin will work on one, but not on the other.
Manifest
Junior Member
Posts: 10
Joined: Thu Jun 18, 2015 7:24 pm

Re: Particle effects!

Postby Manifest » Tue Sep 13, 2016 9:29 pm

Thank you very much for helping out on this topic and coming up with a solution, especially a big thank you to you L'In20Cible!
I cannot wait to try and fiddle around with this and create some particle effect of my own :-)

Once again big ups to all you guys on Source Python, you are really doing an amazing job, and I am looking forward to seeing this community develop even further :-)

Return to “Code examples / Cookbook”

Who is online

Users browsing this forum: No registered users and 24 guests