Page 1 of 1

Detonate a smoke grenade

Posted: Tue Mar 21, 2017 1:18 pm
by marcowmadeira
I'm writting a plugin to store players nades, so they can spawn a exact copy of it whenever they want, but i run into a problem, the smokes grenades and decoys doesn't detonate. I had the same problem for grenades but found the solution online, i simply had to call 'InitializeSpawnFromWorld' on that entity, but on smokes, that input doesn't exist.

Here is a snippet of what my code looks like:

Syntax: Select all

class SavedNade:
def __init__(self, entity):
self.classname = entity.classname
self.origin = entity.origin
self.angles = entity.angles
self.velocity = Vector(
entity.velocity.x,
entity.velocity.y,
entity.velocity.z
)
self.owner = entity.owner


def spawn(self):
entity = Entity.create(self.classname)
entity.spawn()

if 'hegrenade' in self.classname or 'molotov' in self.classname:
entity.call_input('InitializeSpawnFromWorld')

# Teleport entity
entity.teleport(self.origin, self.angles, self.velocity)

if 'smoke' in self.classname:
entity.gravity = 0.4
entity.friction = 0.2
entity.elasticity = 0.45

entity.delay(1.0, self.detonate, (entity.index,))


def detonate(self, entity_index):
entity = Entity(entity_index)
if entity.velocity.length > 0.1:
entity.delay(1.0, self.detonate, (entity.index,))
return

SayText2("detonate").send()


Is there any input i can call to make the smoke working as intended? Or even if there was a way to manually detonate it, that would work too.

Re: Detonate a smoke grenade

Posted: Fri Mar 24, 2017 1:27 am
by satoon101
I just added the detonate virtual function for CHEGrenadeProjectile and CMolotovProjectile, so it should be easier to detonate them by using that function directly. I, unfortunately, cannot find the virtual offset for CSmokeGrenadeProjectile, CSensorGrenadeProjectile, or CDecoyProjectile. I tried just using CBaseGrenade instead of having them individually, but it crashed my server when I logged onto it. My guess is that they have a different offset, but I am not sure how to find those anymore on CS:GO, since they removed the symbols from the Linux binaries.

InitializeSpawnFromWorld seems to only be an input for CHEGrenadeProjectile and CMolotovProjectile.

Re: Detonate a smoke grenade

Posted: Fri Mar 24, 2017 1:36 am
by marcowmadeira
They have their own detonation method based on this, is there a way to call that function?

Re: Detonate a smoke grenade

Posted: Sat Mar 25, 2017 5:42 am
by satoon101
I just found and added the dynamic functions for CSmokeGrenadeProjectile::Think_Detonate, CDecoyProjectile::Think_Detonate, and CSensorGrenadeProjectile::Think_Detonate. I also added the smokegrenade one to CS:S, as it has the same issue as CS:GO. I set the property to "detonate", but they might be a bit tricky to actually cause detonation. I noticed when having a pre-hook, each of them could fire more than once.

*Edit: I should note that the Linux signatures have not been tested, so they may be slightly wrong. Let us know if they aren't firing properly, as I don't currently have a way to test.

Re: Detonate a smoke grenade

Posted: Sat Mar 25, 2017 10:06 am
by Ayuto
If you want to make the Linux symbols visible again, you can use the attached IDA Python script and database. The database is basically a dump of all functions and their signatures I created with the last version of the server.so where symbols were still visible. The script reads this database, searches the signatures and renames the auto-generated functions. I quickly wrote this up after they removed the symbols and since then I have not tweaked the script that creates this database to generate a better database, but the results are still satisfying.

https://www.file-upload.net/download-12 ... b.rar.html

Re: Detonate a smoke grenade

Posted: Sat Mar 25, 2017 10:24 am
by marcowmadeira

Code: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
  File "../addons/source-python/packages/source-python/listeners/tick.py", line 76, in _tick
    self.pop(0).execute()
  File "../addons/source-python/packages/source-python/listeners/tick.py", line 170, in execute
    return self.callback(*self.args, **self.kwargs)
  File "../addons/source-python/packages/source-python/entities/_base.py", line 758, in _callback
    callback(*args, **kwargs)
  File "../addons/source-python/plugins/practicemod/practicemod.py", line 374, in detonate
    entity.detonate()
  File "../addons/source-python/packages/source-python/entities/_base.py", line 110, in __getattr__
    if hasattr(server_class, attr):
  File "../addons/source-python/packages/source-python/memory/manager.py", line 611, in __get__
    binary = find_binary(cls._binary, cls._srv_check)

OSError: Unable to find ../bin/server_srv.so


Its not working on linux.

Re: Detonate a smoke grenade

Posted: Sat Mar 25, 2017 2:07 pm
by satoon101
Oops, I forgot the srv_check in those files. The next build should fix that error.

Ayuto wrote:If you want to make the Linux symbols visible again, you can use the attached IDA Python script and database. The database is basically a dump of all functions and their signatures I created with the last version of the server.so where symbols were still visible. The script reads this database, searches the signatures and renames the auto-generated functions. I quickly wrote this up after they removed the symbols and since then I have not tweaked the script that creates this database to generate a better database, but the results are still satisfying.

https://www.file-upload.net/download-12 ... b.rar.html

Ah, cool, thank you! It was fairly easy to find the 3 that I needed, but this will definitely help in the future.

Re: Detonate a smoke grenade

Posted: Sat Mar 25, 2017 3:51 pm
by marcowmadeira
Still not working, now it just crashes the server.

http://puu.sh/uXZJQ/a2e4b90292.png

Re: Detonate a smoke grenade

Posted: Mon Mar 27, 2017 3:53 pm
by Ayuto
Please post the code to reproduce the crash (a copy and pasteable plugin) including the output of "sp info".

Re: Detonate a smoke grenade

Posted: Mon Mar 27, 2017 5:18 pm
by PhantomDancer
entity.set_property_int("m_nSmokeEffectTickBegin",entity.get_property_int("m_nLastThinkTick"))

Re: Detonate a smoke grenade

Posted: Mon Mar 27, 2017 7:42 pm
by PhantomDancer
just thought, if future people watch this thread, you can add delay functionality:

entity.delay(5.0, entity.set_property_int, (["m_nSmokeEffectTickBegin",entity.get_property_int("m_nLastThinkTick")]))

this will only create the visuals, if you also want to create the pop sound, follow the same mechanism with sthn of entity.emit_sound("BaseSmokeEffect.Sound")

Re: Detonate a smoke grenade

Posted: Mon Mar 27, 2017 11:20 pm
by satoon101
As a note, I did also add m_nSmokeEffectTickBegin to the entity data a few days ago, so you can just use:

Syntax: Select all

entity. smoke_effect_tick_begin = entity.get_property_int('m_nLastThinkTick')


I will probably add m_nLastThinkTick, as well, so in the future it would just be something like:

Syntax: Select all

entity. smoke_effect_tick_begin = entity.last_think_tick


But, please definitely show the code to reproduce the crash. I imagine that I don't have the Linux signature correct, but just to be sure, it would be nice to check the code you are using.

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 1:40 am
by marcowmadeira
Ayuto wrote:Please post the code to reproduce the crash (a copy and pasteable plugin) including the output of "sp info".

Here it is:

Code: Select all

from commands import CommandReturn
from commands.say import SayCommand
from entities.entity import Entity
from listeners import OnEntitySpawned
from listeners.tick import Delay
from mathlib import Vector
from messages import SayText2
from players.entity import Player

saved_nades = {}

@OnEntitySpawned
def on_entity_spawned(base_entity):
    if "projectile" in base_entity.classname:
        Delay(0.01, on_created_projectile, (base_entity,))


@SayCommand(['.ts', '.throwsmoke'])
def throw_smoke(command, index, teamonly):
    if index not in saved_nades or 'smokegrenade_projectile' not in saved_nades[index]:
        SayText2("You don't have a smoke grenade saved").send(index)
        return CommandReturn.BLOCK

    saved_nades[index]['smokegrenade_projectile'].spawn()

    return CommandReturn.BLOCK

def on_created_projectile(base_entity):
    entity = Entity(base_entity.index)
    if entity.owner is None:
        return

   
    player = Player(entity.owner.index)

    if player.index not in saved_nades:
        saved_nades[player.index] = {}
   
    saved_nades[player.index][base_entity.classname] = SavedNade(entity)


class SavedNade:
    def __init__(self, entity):
        self.classname = entity.classname
        self.origin = entity.origin
        self.angles = entity.angles
        self.velocity = Vector(
            entity.velocity.x,
            entity.velocity.y,
            entity.velocity.z
        )
        self.owner = entity.owner


    def spawn(self):
        entity = Entity.create(self.classname)

        entity.spawn()

        if 'hegrenade' in self.classname or 'molotov' in self.classname:
            entity.call_input('InitializeSpawnFromWorld')

        # Teleport entity
        entity.teleport(self.origin, self.angles, self.velocity)
       
        entity.set_property_int('m_nNextThinkTick', 1)

        if 'smoke' in self.classname or 'decoy' in self.classname:

            entity.gravity = 0.4
            entity.friction = 0.2
            entity.elasticity = 0.45

            entity.delay(1.0, self.detonate, (entity.index,))

    def detonate(self, entity_index):

        entity = Entity(entity_index)

        if entity.velocity.length > 0.1:
            entity.delay(1.0, self.detonate, (entity.index,))
            return


        # Temp fix
        # entity.smoke_effect_tick_begin = entity.get_property_int('m_nLastThinkTick')

        entity.detonate()

sp info

Date : 2017-03-28 01:35:22.179708
OS : Linux-4.4.0-38-generic-x86_64-with-debian-stretch-sid
Game : csgo
SP version : 563
Server plugins:
00: Source.Python, (C) 2012-2016, Source.Python Team.
01: Metamod:Source 1.10.6
SP plugins:
00: ts


PhantomDancer wrote:entity.set_property_int("m_nSmokeEffectTickBegin",entity.get_property_int("m_nLastThinkTick"))

That's a nice workaround, but it's not really the same as it doesn't show the "poping" smoke, it simply appears the whole smoke effect "out of nowhere"

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 5:38 am
by PhantomDancer
if you use the following, does that create your desired "poping" effect? :

Syntax: Select all

entity.set_property_bool("m_bDidSmokeEffect",True)

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 7:55 am
by marcowmadeira
PhantomDancer wrote:if you use the following, does that create your desired "poping" effect? :

Syntax: Select all

entity.set_property_bool("m_bDidSmokeEffect",True)

Doesn't seem to do anything, unfortunately.

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 10:06 am
by PhantomDancer
well, what exactly isnt working? does it still crash? the following code is working for me on windows.

Syntax: Select all

from commands import CommandReturn
from commands.say import SayCommand
from entities.entity import Entity
from listeners import OnEntitySpawned
from listeners.tick import Delay
from mathlib import Vector
from messages import SayText2
from players.entity import Player

saved_nades = {}

@OnEntitySpawned
def on_entity_spawned(base_entity):
if "projectile" in base_entity.classname:
Delay(0.01, on_created_projectile, (base_entity,))


@SayCommand(['.ts', '.throwsmoke'])
def throw_smoke(command, index, teamonly):
if index not in saved_nades or 'smokegrenade_projectile' not in saved_nades[index]:
SayText2("You don't have a smoke grenade saved").send(index)
return CommandReturn.BLOCK

saved_nades[index]['smokegrenade_projectile'].spawn()

return CommandReturn.BLOCK

def on_created_projectile(base_entity):
entity = Entity(base_entity.index)
if entity.owner is None:
return


player = Player(entity.owner.index)

if player.index not in saved_nades:
saved_nades[player.index] = {}

saved_nades[player.index][base_entity.classname] = SavedNade(entity)

class SavedNade:
def __init__(self, entity):
self.classname = entity.classname
self.origin = entity.origin
self.angles = entity.angles
self.velocity = Vector(
entity.velocity.x,
entity.velocity.y,
entity.velocity.z
)
self.owner = entity.owner


def spawn(self):
entity = Entity.create(self.classname)
entity.spawn()

if 'hegrenade' in self.classname or 'molotov' in self.classname:
entity.call_input('InitializeSpawnFromWorld')

# Teleport entity
entity.teleport(self.origin, self.angles, self.velocity)

if 'smoke' in self.classname or 'decoy' in self.classname:

entity.gravity = 0.4
entity.friction = 0.2
entity.elasticity = 0.45

entity.delay(1.0, self.detonate, (entity.index,))

def detonate(self, entity_index):

entity = Entity(entity_index)

if entity.velocity.length > 0.1:
entity.delay(1.0, self.detonate, (entity.index,))
return


# Temp fix
entity.set_property_bool("m_bDidSmokeEffect",True)

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 11:36 am
by marcowmadeira
PhantomDancer wrote:well, what exactly isnt working? does it still crash? the following code is working for me on windows.

Syntax: Select all

from commands import CommandReturn
from commands.say import SayCommand
from entities.entity import Entity
from listeners import OnEntitySpawned
from listeners.tick import Delay
from mathlib import Vector
from messages import SayText2
from players.entity import Player

saved_nades = {}

@OnEntitySpawned
def on_entity_spawned(base_entity):
if "projectile" in base_entity.classname:
Delay(0.01, on_created_projectile, (base_entity,))


@SayCommand(['.ts', '.throwsmoke'])
def throw_smoke(command, index, teamonly):
if index not in saved_nades or 'smokegrenade_projectile' not in saved_nades[index]:
SayText2("You don't have a smoke grenade saved").send(index)
return CommandReturn.BLOCK

saved_nades[index]['smokegrenade_projectile'].spawn()

return CommandReturn.BLOCK

def on_created_projectile(base_entity):
entity = Entity(base_entity.index)
if entity.owner is None:
return


player = Player(entity.owner.index)

if player.index not in saved_nades:
saved_nades[player.index] = {}

saved_nades[player.index][base_entity.classname] = SavedNade(entity)

class SavedNade:
def __init__(self, entity):
self.classname = entity.classname
self.origin = entity.origin
self.angles = entity.angles
self.velocity = Vector(
entity.velocity.x,
entity.velocity.y,
entity.velocity.z
)
self.owner = entity.owner


def spawn(self):
entity = Entity.create(self.classname)
entity.spawn()

if 'hegrenade' in self.classname or 'molotov' in self.classname:
entity.call_input('InitializeSpawnFromWorld')

# Teleport entity
entity.teleport(self.origin, self.angles, self.velocity)

if 'smoke' in self.classname or 'decoy' in self.classname:

entity.gravity = 0.4
entity.friction = 0.2
entity.elasticity = 0.45

entity.delay(1.0, self.detonate, (entity.index,))

def detonate(self, entity_index):

entity = Entity(entity_index)

if entity.velocity.length > 0.1:
entity.delay(1.0, self.detonate, (entity.index,))
return


# Temp fix
entity.set_property_bool("m_bDidSmokeEffect",True)


Oh, i thought i had to change the tick too, my bad, that way it works! Also noticed that when the smokes disapear, if you walk on the spot where the smoke detonated, you will get a grey screen, so added a delay to remove the entity.

Syntax: Select all

def detonate(self, entity_index):

entity = Entity(entity_index)

if entity.velocity.length > 0.1:
entity.delay(1.0, self.detonate, (entity.index,))
return

# Temp fix
if 'smoke' in entity.classname:
entity.set_property_bool("m_bDidSmokeEffect", True)
entity.delay(18.0, entity.remove)

Re: Detonate a smoke grenade

Posted: Tue Mar 28, 2017 12:50 pm
by satoon101