Detonate a smoke grenade

Please post any questions about developing your plugin here. Please use the search function before posting!
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Detonate a smoke grenade

Postby marcowmadeira » Tue Mar 21, 2017 1:18 pm

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.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: Detonate a smoke grenade

Postby satoon101 » Fri Mar 24, 2017 1:27 am

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.
Image
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Fri Mar 24, 2017 1:36 am

They have their own detonation method based on this, is there a way to call that function?
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: Detonate a smoke grenade

Postby satoon101 » Sat Mar 25, 2017 5:42 am

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.
Image
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Detonate a smoke grenade

Postby Ayuto » Sat Mar 25, 2017 10:06 am

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
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Sat Mar 25, 2017 10:24 am

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.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: Detonate a smoke grenade

Postby satoon101 » Sat Mar 25, 2017 2:07 pm

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.
Image
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Sat Mar 25, 2017 3:51 pm

Still not working, now it just crashes the server.

http://puu.sh/uXZJQ/a2e4b90292.png
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Detonate a smoke grenade

Postby Ayuto » Mon Mar 27, 2017 3:53 pm

Please post the code to reproduce the crash (a copy and pasteable plugin) including the output of "sp info".
User avatar
PhantomDancer
Member
Posts: 42
Joined: Wed Mar 15, 2017 10:39 am
Location: The Great Arctic Hemispheres

Re: Detonate a smoke grenade

Postby PhantomDancer » Mon Mar 27, 2017 5:18 pm

entity.set_property_int("m_nSmokeEffectTickBegin",entity.get_property_int("m_nLastThinkTick"))
User avatar
PhantomDancer
Member
Posts: 42
Joined: Wed Mar 15, 2017 10:39 am
Location: The Great Arctic Hemispheres

Re: Detonate a smoke grenade

Postby PhantomDancer » Mon Mar 27, 2017 7:42 pm

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")
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: Detonate a smoke grenade

Postby satoon101 » Mon Mar 27, 2017 11:20 pm

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.
Image
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Tue Mar 28, 2017 1:40 am

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"
Last edited by marcowmadeira on Tue Mar 28, 2017 7:53 am, edited 1 time in total.
User avatar
PhantomDancer
Member
Posts: 42
Joined: Wed Mar 15, 2017 10:39 am
Location: The Great Arctic Hemispheres

Re: Detonate a smoke grenade

Postby PhantomDancer » Tue Mar 28, 2017 5:38 am

if you use the following, does that create your desired "poping" effect? :

Syntax: Select all

entity.set_property_bool("m_bDidSmokeEffect",True)
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Tue Mar 28, 2017 7:55 am

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.
User avatar
PhantomDancer
Member
Posts: 42
Joined: Wed Mar 15, 2017 10:39 am
Location: The Great Arctic Hemispheres

Re: Detonate a smoke grenade

Postby PhantomDancer » Tue Mar 28, 2017 10:06 am

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)
marcowmadeira
Junior Member
Posts: 11
Joined: Wed Apr 27, 2016 11:54 am

Re: Detonate a smoke grenade

Postby marcowmadeira » Tue Mar 28, 2017 11:36 am

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)
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Re: Detonate a smoke grenade

Postby satoon101 » Tue Mar 28, 2017 12:50 pm

Image

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 20 guests