Auto Respawn

Release your plugins here!
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Auto Respawn

Postby Kill » Tue Oct 18, 2016 1:53 pm

About

Automatically respawn players after their death.


Translation
The plugin supports translation(autorespawn at ../resource/source-python/translations)


Cvars

The plugin will automatically generate a config file (can be found inside the folder ../cfg/source-python)

Code: Select all

autorespawn_enable 1 // Enable the plugin? can either be 1 or 0
autorespawn_delay 2 // Time to wait before spawning a player, in seconds. 0(zero) will instantly respawn the player
autorespawn_showmsg 1 // Show a message to the player before spawning? can either be 1 or 0
autorespawn_unlimited_buytime 1 // Unlimited buy time // can be either 1 or 0

The plugin has a public convar (autorespawn_version).

Installation
Extract the zip
Drag and drop
In server or autoexec(or manually using the server console)

Code: Select all

sp plugin load autorespawn


Thanks to
  • Ayuto
  • iPlayer
  • L'In20Cible.
  • satoon101

Download
autorespawn.zip
(2.76 KiB) Downloaded 58 times
Last edited by Kill on Sat Nov 05, 2016 5:23 pm, edited 12 times in total.
User avatar
L'In20Cible
Project Leader
Posts: 917
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Auto Respawn

Postby L'In20Cible » Tue Oct 18, 2016 2:34 pm

Cool plugin!

Here are few points:


  • Instead of having a function that call the spawn method on the passed player, you could simply delay that method to be called:

    Syntax: Select all

    Delay(cvars['autorespawn_delay'].get_int(), player.spawn)

    However, I would not recommend delaying any Player/Entity's method calls and/or passing them as argument. If the player leave the server/entity get removed before the call is made, you gonna either crash or your code will raise an error. In this specific case, I would rather recommend passing the index and recast the Player instance:

    Syntax: Select all

    # Into player_death...
    Delay(cvars['autorespawn_delay'].get_int(), respawn_player, player.index)

    def respawn_player(index):
    try:
    player = Player(index)
    except ValueError:
    # Player left the server, nothing to do here...
    return
    player.spawn()


    Another thing you should consider, is to store the Delay instances and cancel them on new round/map.

  • Like I mentioned here about TempEntity instances, I would recommend the same thing for messages. In your plugin, you could globalize the SayText2 instance and simply send it to the players instead of recreating the instance every time. Also, you should update the respawn_delay when the ConVar value is updated, otherwise time won't match if it is changed after the plugin has been loaded.

  • Instead of modifying the settings of the server by changing the value of mp_buytime, you could simply use a hook to allow players to buy at any time:

    Syntax: Select all

    from entities.entity import BaseEntity
    from entities.hooks import EntityCondition
    from entities.hooks import EntityPreHook
    from memory import make_object

    @EntityPreHook(EntityCondition.is_player, 'post_think')
    def pre_post_think(stack_data):
    if not (cvars['autorespawn_enable'].get_bool() and
    cvars['autorespawn_unlimited_buytime'].get_bool()):
    return
    entity = make_object(BaseEntity, stack_data[0])
    entity.set_network_property_bool('m_bInBuyZone', True)
    You could also add support so players could only buy for a specific amount of time after respawning or something like that.
User avatar
satoon101
Project Leader
Posts: 2323
Joined: Sat Jul 07, 2012 1:59 am

Re: Auto Respawn

Postby satoon101 » Tue Oct 18, 2016 3:09 pm

L'In20Cible wrote:
    However, I would not recommend delaying any Player/Entity's method calls and/or passing them as argument. If the player leave the server/entity get removed before the call is made, you gonna either crash or your code will raise an error. In this specific case, I would rather recommend passing the index and recast the Player instance:

I think I would rather pass in the player's userid. Another player could easily take over the disconnected player's index, especially with a higher respawn delay. Or at least store the Delay instances in a dictionary by the player's userid and cancel/remove the Delay when the player disconnects.


L'In20Cible wrote:
  • Like I mentioned here about TempEntity instances, I would recommend the same thing for messages. In your plugin, you could globalize the SayText2 instance and simply send it to the players instead of recreating the instance every time. Also, you should update the respawn_delay when the ConVar value is updated, otherwise time won't match if it is changed after the plugin has been loaded.

As an example:

Syntax: Select all

RESPAWN_MSG = SayText2(
message="{prefix} You'll be respawned in {respawn_delay} seconds"
)


...
delay_time = cvars['autorespawn_delay'].get_int()
if cvars['autorespawn_showmsg'].get_int():
RESPAWN_MSG.send(
player.index,
prefix=CHAT_PREFIX,
respawn_delay=delay_time
)
Delay(delay_time, respawn_player, player.userid)
Image
User avatar
iPlayer
Developer
Posts: 498
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Auto Respawn

Postby iPlayer » Tue Oct 18, 2016 3:14 pm

I'd also like to add that you should probably check if player is dead right before respawning them. Because if the game has already respawned them for any purpose (I don't know why - round restart, team swap, another plugin) and you perform player.spawn() on them again, the player will get teleported to a new spawnpoint. Now, depending on your respawn delay, they could've been already fighting somebody, and teleporting back to spawn is a bit frustrating.

And I agree with Satoon. I'd rather store the Delay objects and cancel them when player disconnects. That way you can still safely pass Player instance to them.
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
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Auto Respawn

Postby Kill » Tue Oct 18, 2016 3:38 pm

Thanks for the info guys!

L'In20Cible wrote:Cool plugin!

Here are few points:


  • Instead of having a function that call the spawn method on the passed player, you could simply delay that method to be called:

    Syntax: Select all

    Delay(cvars['autorespawn_delay'].get_int(), player.spawn)

    However, I would not recommend delaying any Player/Entity's method calls and/or passing them as argument. If the player leave the server/entity get removed before the call is made, you gonna either crash or your code will raise an error. In this specific case, I would rather recommend passing the index and recast the Player instance:

    Syntax: Select all

    # Into player_death...
    Delay(cvars['autorespawn_delay'].get_int(), respawn_player, player.index)

    def respawn_player(index):
    try:
    player = Player(index)
    except ValueError:
    # Player left the server, nothing to do here...
    return
    player.spawn()


    Another thing you should consider, is to store the Delay instances and cancel them on new round/map.

Example please? I don't quite understand that, or how to do so.

L'In20Cible wrote:
  • Like I mentioned here about TempEntity instances, I would recommend the same thing for messages. In your plugin, you could globalize the SayText2 instance and simply send it to the players instead of recreating the instance every time. Also, you should update the respawn_delay when the ConVar value is updated, otherwise time won't match if it is changed after the plugin has been loaded.


Watch the Convar change, I'll add that, but usually, I'll simply reload the plugin, don't You think?

L'In20Cible wrote:
  • Instead of modifying the settings of the server by changing the value of mp_buytime, you could simply use a hook to allow players to buy at any time:

    Syntax: Select all

    from entities.entity import BaseEntity
    from entities.hooks import EntityCondition
    from entities.hooks import EntityPreHook
    from memory import make_object

    @EntityPreHook(EntityCondition.is_player, 'post_think')
    def pre_post_think(stack_data):
    if not (cvars['autorespawn_enable'].get_bool() and
    cvars['autorespawn_unlimited_buytime'].get_bool()):
    return
    entity = make_object(BaseEntity, stack_data[0])
    entity.set_network_property_bool('m_bInBuyZone', True)
    You could also add support so players could only buy for a specific amount of time after respawning or something like that.


Thanks, but for the time being, I'll manipulate the buytime, as I don't know/have no idea on how to use the memory module.
User avatar
Ayuto
Project Leader
Posts: 1579
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Auto Respawn

Postby Ayuto » Tue Oct 18, 2016 5:29 pm

Kill wrote:
L'In20Cible wrote:
  • Like I mentioned here about TempEntity instances, I would recommend the same thing for messages. In your plugin, you could globalize the SayText2 instance and simply send it to the players instead of recreating the instance every time. Also, you should update the respawn_delay when the ConVar value is updated, otherwise time won't match if it is changed after the plugin has been loaded.


Watch the Convar change, I'll add that, but usually, I'll simply reload the plugin, don't You think?

L'In20Cible is talking about this piece:

Syntax: Select all

RESPAWN_MSG = "{prefix} You'll be respawned in {respawn_delay} seconds".format(
prefix=CHAT_PREFIX,
respawn_delay=cvars['autorespawn_delay'].get_int()
)
It's only evaluated once when the plugin loads, so the message will never get updated when you change the autorespawn_delay cvar. However, Satoon's solution also solves this problem.

Btw. you might want to change the prefix to something else. "[SP]" is kinda misleading.

And one last point: I'm not a big fan of cvars like "autorespawn_enable". Back in ES I saw a lot people doing that, but there is actually no need to do that. If you want to disable a plugin, you can simply unload it. This only introduces complexity and your code is growing for no reason.
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Auto Respawn

Postby Kill » Wed Oct 19, 2016 2:10 pm

Ayuto wrote:
Kill wrote:
L'In20Cible wrote:...


Thanks :)

Updated the plugin, added player check, translation, changed SayText2 and added a ConVar listener.
User avatar
Ayuto
Project Leader
Posts: 1579
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Auto Respawn

Postby Ayuto » Wed Oct 19, 2016 9:13 pm

I guess you got me wrong. You don't need the convar listener. Just remove the convar listener part.
User avatar
satoon101
Project Leader
Posts: 2323
Joined: Sat Jul 07, 2012 1:59 am

Re: Auto Respawn

Postby satoon101 » Thu Oct 20, 2016 2:55 am

Yeah, the reason that tracking the ConVar change was mentioned was to update the SayText2 message value when it was. However, the solution you went with, from my example, eliminates the need for that, as it gets the value at that exact moment when you send the message. Currently, your OnConVarChanged function doesn't actually do anything.

Also, I completely agree with this:
Ayuto wrote:And one last point: I'm not a big fan of cvars like "autorespawn_enable". Back in ES I saw a lot people doing that, but there is actually no need to do that. If you want to disable a plugin, you can simply unload it. This only introduces complexity and your code is growing for no reason.

There is no need for an enable/disable feature for the entire plugin. If someone wants to disable it, all they have to do is use:

Code: Select all

sp plugin unload <plugin>
Image
decompile
Senior Member
Posts: 289
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Auto Respawn

Postby decompile » Thu Oct 20, 2016 10:41 am

Those _enable cvars are mostly used through mapconfig' plugins, so instead of rather unloading the complete plugin, you just enable/disable the cvar on specific maps, but in the end its probably just as sp plugin unload.
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Auto Respawn

Postby Kill » Sun Oct 23, 2016 11:20 am

Ayuto wrote:I guess you got me wrong. You don't need the convar listener. Just remove the convar listener part.


Can You please show me some code to help me understand? Thanks!
User avatar
satoon101
Project Leader
Posts: 2323
Joined: Sat Jul 07, 2012 1:59 am

Re: Auto Respawn

Postby satoon101 » Sun Oct 23, 2016 12:06 pm

There is no code to show you. Again:
satoon101 wrote:Yeah, the reason that tracking the ConVar change was mentioned was to update the SayText2 message value when it was. However, the solution you went with, from my example, eliminates the need for that, as it gets the value at that exact moment when you send the message. Currently, your OnConVarChanged function doesn't actually do anything.
Image
decompile
Senior Member
Posts: 289
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Auto Respawn

Postby decompile » Sun Oct 23, 2016 12:07 pm

satoon101 wrote:There is no code to show you. Again:
satoon101 wrote:Yeah, the reason that tracking the ConVar change was mentioned was to update the SayText2 message value when it was. However, the solution you went with, from my example, eliminates the need for that, as it gets the value at that exact moment when you send the message. Currently, your OnConVarChanged function doesn't actually do anything.


So when Trying to get the config value, it will auto update when it gets changed?
Or did I understood it wrong?

I remember atleast that what he did, every sm plugin needs to do themselves.
User avatar
iPlayer
Developer
Posts: 498
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Auto Respawn

Postby iPlayer » Sun Oct 23, 2016 12:25 pm

decompile wrote:
satoon101 wrote:There is no code to show you. Again:
satoon101 wrote:Yeah, the reason that tracking the ConVar change was mentioned was to update the SayText2 message value when it was. However, the solution you went with, from my example, eliminates the need for that, as it gets the value at that exact moment when you send the message. Currently, your OnConVarChanged function doesn't actually do anything.


So when Trying to get the config value, it will auto update when it gets changed?
Or did I understood it wrong?

I remember atleast that what he did, every sm plugin needs to do themselves.


There're 2 or more approaches to go in Kill's plugin.

1.
Make SayText2 instance static and register OnConVarChanged listener, so that when the convar updates, the SayText2 instance is rebuilt.

2.
Rebuild SayText2 every time, and request convar "on demand". No listeners needed.

That's I believe where the confusion comes from. The problem is actually solved by creating static SayText2 instance, but sending it with the up-to-date arguments.
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
satoon101
Project Leader
Posts: 2323
Joined: Sat Jul 07, 2012 1:59 am

Re: Auto Respawn

Postby satoon101 » Sun Oct 23, 2016 1:55 pm

decompile wrote:So when Trying to get the config value, it will auto update when it gets changed?
Or did I understood it wrong?

In the plugin, where you send the message, you pass in the 'current' value of the ConVar in the **tokens:

Syntax: Select all

RESPAWN_MSG.send(
player.index,
prefix=CHAT_PREFIX,
respawn_delay=cvars['autorespawn_delay'].get_int()
)

So, when you pass in respawn_delay=cvars['autorespawn_delay'].get_int() , you are passing in the value of the ConVar at that exact moment.

Also, as far as your OnConVarChanged function:

Syntax: Select all

@OnConVarChanged
def on_convar_changed(convar, old_val):
if convar.name == info.basename + "_delay" and convar.get_int() != int(old_val):
from core import console_message
console_message("\n----------------------------------\n"
"[SP] ConVar change: {}, old value: {}, new value: {}\n"
"-----------------------------------\n".format(
convar.name,
old_val,
convar.get_int()
))
cvars['autorespawn_delay'] = convar

cvars['autorespawn_delay'] is already set to that ConVar. You're basically setting it to itself again. So, that function does absolutely nothing. But again, this function is completely unnecessary, because you are already passing the correct value in as the respawn_delay token.
Image
User avatar
satoon101
Project Leader
Posts: 2323
Joined: Sat Jul 07, 2012 1:59 am

Re: Auto Respawn

Postby satoon101 » Sun Oct 23, 2016 1:57 pm

iPlayer wrote:The problem is actually solved by creating static SayText2 instance, but sending it with the up-to-date arguments.

That's exactly what the plugin already does.
Image
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Auto Respawn

Postby Kill » Fri Nov 04, 2016 6:54 pm

Updated.
Removed the ConVar listener.
User avatar
Ayuto
Project Leader
Posts: 1579
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Auto Respawn

Postby Ayuto » Sat Nov 05, 2016 3:26 pm

Hey, now you are retrieving the value of those four convars once at the beginning, so a change of them has no effect in your plugin:

Syntax: Select all

ar_enabled = cvars['autorespawn_enable'].get_bool()
ar_delay = cvars['autorespawn_delay'].get_int()
ar_showmsg = cvars['autorespawn_showmsg'].get_bool()
ar_buytime = cvars['autorespawn_unlimited_buytime'].get_bool()
You need to do it like this:

Syntax: Select all

ar_enabled = cvars['autorespawn_enable']
ar_delay = cvars['autorespawn_delay']
ar_showmsg = cvars['autorespawn_showmsg']
ar_buytime = cvars['autorespawn_unlimited_buytime']

@Event("player_death")
def event_player_death(game_event):
if ar_enabled.get_bool():
player = Player.from_userid(game_event.get_int("userid"))
if ar_showmsg.get_bool():
RESPAWN_MSG.send(
player.index,
prefix=CHAT_PREFIX,
respawn_delay=ar_delay.get_int()
)
Delay(ar_delay.get_int(), respawn, player.userid)
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Auto Respawn

Postby Kill » Sat Nov 05, 2016 3:42 pm

Ayuto wrote:...

Aaaah, Thanks!
Updated!
User avatar
L'In20Cible
Project Leader
Posts: 917
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Auto Respawn

Postby L'In20Cible » Sat Nov 05, 2016 4:04 pm

Also, the following:

Syntax: Select all

Delay(ar_delay.get_int(), respawn, player.userid)

def respawn(userid):
try:
player = Player.from_userid(userid)
except ValueError:
return
if player.dead: # is player dead?
player.spawn()

Could now simply be:

Syntax: Select all

player.delay(ar_delay.get_int(), player.spawn)

Return to “Plugin Releases”

Who is online

Users browsing this forum: No registered users and 1 guest