I am trying to create a plugin where I have several entities in my map, (Instantiated through my Zone class), and I want these Zones to draw and redraw their outline beams periodically. I don't need the timing to be super precise, I just need it to be reliably recalled repeatedly throughout the lifetime of the Zone object. I am wondering what is the best way to achieve this. I would prefer if the behaviour could be contained within the Zone class itself, rather than calling it for each current Zone object through a master loop such as @OnTick. I have so far tried using time.sleep() and asyncio.sleep(), but both of these functions cause the server to time-out.
Another way to reach my end goal would be if I could spawn the beams to last forever, then manually destroy them if the Zone is removed, but I am not sure if this is possible or if it will cause issues for players who join after the Zones are first created.
Thanks, Disco
Looping a Timed Task in Many Objects
- Hymns For Disco
- Member
- Posts: 32
- Joined: Wed Nov 22, 2017 7:18 am
- Contact:
Re: Looping a Timed Task in Many Objects
Re: Looping a Timed Task in Many Objects
Hymns For Disco wrote:Another way to reach my end goal would be if I could spawn the beams to last forever [...]
Unfortunately, that's not possible.
- Hymns For Disco
- Member
- Posts: 32
- Joined: Wed Nov 22, 2017 7:18 am
- Contact:
Re: Looping a Timed Task in Many Objects
Thank you for your response. I have tried using both Repeat() and Delay() in my Zone class, but both of these functions cause the server to immediately freeze. Here is my code
Syntax: Select all
class TimerZone:
def __init__(self, zone_origin):
self.min = Vector(-100, -100, 0)
self.max = Vector(100, 100, 100)
self.prop = Entity.create('prop_dynamic_override')
self.prop.origin = zone_origin
self.prop.set_model(Model('models/props/de_train/barrel.mdl'))
self.prop.effects |= 32;
self.prop.set_property_ushort('m_Collision.m_usSolidFlags', 12)
self.prop.spawn()
self.prop.mins = self.min
self.prop.maxs = self.max
self.prop.solid_type = 2
self.draw_beams()
def draw_beams(self):
box(
RecipientFilter(),
self.prop.origin + self.min,
self.prop.origin + self.max,
alpha=255,
blue=0,
green=0,
red=255,
amplitude=0,
end_width=1,
life_time=3,
start_width=1,
fade_length=0,
flags=0,
frame_rate=255,
halo=Model('materials/sprites/laserbeam.vmt'),
model=Model('materials/sprites/laserbeam.vmt'),
start_frame=0
)
Repeat(5.0, self.draw_beams(), running=True, time_elapsed=0)
Edit: I made a double mistake on this post. First, put the Repeat function there since I tried switching, and the args are actually wrong. The real problem was that I should have used Delay(5.0, self.draw_beams) <<<< Without "()" after the function name since it needs to call the function itself, not the functions return value.
Last edited by L'In20Cible on Wed Nov 22, 2017 11:26 pm, edited 1 time in total.
Reason: code → python
Reason: code → python
- L'In20Cible
- Project Leader
- Posts: 1533
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: Looping a Timed Task in Many Objects
Hey, welcome to the forums! First of all, please use the PYTHON syntax when posting python code as it makes it easier to read. As for your code, this is normal that it freeze because it creates an infinite recursion. Every time the draw_beams method is called, it creates a new Repeat instance and re-call itself over and over creating new Repeat on every calls that continue re-calling itself, etc. You want to start the Repeat into your __init__ method so it only gets instantiated once for your object. However, this also means it will never stop even when the object is deleted. Are you creating multiple instances of TimerZone or only a single globalized one?
EDIT: How about inheriting from Entity directly instead? So using Entity.delay will automatically gets cancelled when the entity is removed.
Tho, creating an invisible prop seems useless. You could simply render the effect at a location... proposing that in case you have other things planned for the entity... which I would assume you need for its Touching functions, right? In such case you could simply use a trigger_multiple.
EDIT: How about inheriting from Entity directly instead? So using Entity.delay will automatically gets cancelled when the entity is removed.
Syntax: Select all
from effects import box
from engines.precache import Model
from entities.entity import BaseEntity
from entities.entity import Entity
from filters.recipients import RecipientFilter
from mathlib import Vector
class TimerZone(Entity):
min = Vector(-100, -100, 0)
max = Vector(100, 100, 100)
@classmethod
def create(cls, zone_origin):
prop = cls(BaseEntity.create('prop_dynamic_override').index)
prop.origin = zone_origin
prop.set_model(Model('models/props/de_train/barrel.mdl'))
prop.effects |= 32;
prop.set_property_ushort('m_Collision.m_usSolidFlags', 12)
prop.spawn()
prop.mins = cls.min
prop.maxs = cls.max
prop.solid_type = 2
prop.draw_beams()
return prop
def draw_beams(self):
origin = self.origin
box(
RecipientFilter(),
origin + self.mins,
origin + self.maxs,
alpha=255,
blue=0,
green=0,
red=255,
amplitude=0,
end_width=1,
life_time=3,
start_width=1,
fade_length=0,
flags=0,
frame_rate=255,
halo=Model('materials/sprites/laserbeam.vmt'),
model=Model('materials/sprites/laserbeam.vmt'),
start_frame=0
)
self.delay(5, self.draw_beams)
from players.entity import Player
player = Player(1)
prop = TimerZone.create(player.origin)
Tho, creating an invisible prop seems useless. You could simply render the effect at a location... proposing that in case you have other things planned for the entity... which I would assume you need for its Touching functions, right? In such case you could simply use a trigger_multiple.
- Hymns For Disco
- Member
- Posts: 32
- Joined: Wed Nov 22, 2017 7:18 am
- Contact:
Re: Looping a Timed Task in Many Objects
L'In20Cible wrote:[...]
Thanks for your reply.
First, yes I am creating multiple instances of the TimerZone class, and also creating child classes of TimerZone to override functions for events such as touch, start_touch, end_touch etc. As well as change beam color per zone class.
I am making an invisible zone to essentially serve the same purpose as a trigger_multiple so I can bind the touch events for other parts of my plugin. I could use trigger_multiple, but as far as I can tell trigger_multiple and prop_dynamic_override work exactly the same when I substitute them in my code. I am using the latter because that is what someone had recommended to me for this use. The Entity.delay function seems to work well for this case, however I am simply calling self.prop.delay instead of self.delay along with changing the parent class. This way, as long as I delete the self.prop entity when deleting an instance of the TimerZone class, the loop shouldn't continue indefinitely.
Re: Looping a Timed Task in Many Objects
Welcome to the forums :)
I believe Invincible proposed using trigger_multiple's OnStartTouch output, which is possible to listen to using OnEntityOutput listener. This way you don't need to hook anything, and you'll also be able to utilize trigger's own filtering/flag system that would, for example, filter out all entities besides players.
I believe Invincible proposed using trigger_multiple's OnStartTouch output, which is possible to listen to using OnEntityOutput listener. This way you don't need to hook anything, and you'll also be able to utilize trigger's own filtering/flag system that would, for example, filter out all entities besides players.
/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.
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam
Hail, Companion. [...] Hands to yourself, sneak thief.
- L'In20Cible
- Project Leader
- Posts: 1533
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: Looping a Timed Task in Many Objects
iPlayer is correct. Using the output would be preferred, I remember some issues with hooking the virtual touch methods. Tho I think it was only post ones? Can't remember.
As for inheriting from Entity, I think this would be the best approach. Simply because you can delegate their creation to an EntityDictionary which will cleanup for you on round/map ends. But all implementation are fine, go with the one you are the most comfortable with.
As for inheriting from Entity, I think this would be the best approach. Simply because you can delegate their creation to an EntityDictionary which will cleanup for you on round/map ends. But all implementation are fine, go with the one you are the most comfortable with.
Re: Looping a Timed Task in Many Objects
About those touch hook issues... Apart from removing the entity in a pre-hook and not cancelling the call (it's not touch-specific), there were issues with teleporting inside of the touch-related hooks, they are noted in the discussion of #157.
/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.
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam
Hail, Companion. [...] Hands to yourself, sneak thief.
Return to “Plugin Development Support”
Who is online
Users browsing this forum: No registered users and 37 guests