Ayuto / EventScripts-Emulator

A Source.Python plugin that is able to run EventScripts addons.
16 stars 9 forks source link

Playerset model bug #24

Open ManifestManah opened 5 years ago

ManifestManah commented 5 years ago

When you use the playerset model command it will set the player model to the intended model, so this part works flawlessly.

But if you later wish to change the player's model then using the command again the model will not be changed, and the same goes if you use it on any other player in the game. The first model that is being applied to someone on the server will be the model that is added to everyone the playerset model command is used on afterwards.

An example would be that I apply a barrel model to player1 and thereafter I apply a zombie model to player2. Player 1 will now look like a zombie and player two will also look like a zombie, although he was supposed to look like a zombie and the path would refer to the zombie model.

Code used for testing:

block model_barrel
{
    es playerset model event_var(userid) props_c17/oildrum001
    es_msg this is supposed to be a barrel model
}

block model_actual_zombie
{
    es playerset model event_var(userid) models/player/zombie
    es_msg this is supposed to be a zombie model
}

block model_pigeon
{
    es playerset model event_var(userid) pigeon
    es_msg this is supposed to be a pigeon model
}
Ayuto commented 4 years ago

My own test code (ignore this):

event player_say
{
    if (event_var(text) = 1) do
    {
        es playerset model event_var(userid) props_c17/oildrum001
        es_msg this is supposed to be a barrel model
    }
    else do
    {
        es playerset model event_var(userid) props/de_nuke/cinderblock_stack.mdl
        es_msg this is supposed to be a cinderblock_stack
    }
}
Ayuto commented 4 years ago

The problem seems to be es_math. Since es_math is implemented in Python in the emulator, there is no numeric limit. EventScripts has a numeric limit (float/4 bytes), so the following causes a data type overflow:

es_setinfo x 255
es_math x * 16777216
x
"x" = "-16777216" ( def. "" )
 - Custom server variable.

The emulator is actually calculating correctly, but it also needs to overflow to emulate es_math correctly.

es_setinfo x 255
es_math x * 16777216
x
"x" = "4278190080" ( def. "" )
 - Custom server variable.
Ayuto commented 4 years ago

After fixing es_math another difference has shown up.

// Emulator
es_setinfo x_old 38912
es_setinfo x_new 0
es_mathparse x_new "x_old or 1"

x_new
"x_new" = "38912" ( def. "" )
 - Custom server variable.

// EventScripts
es_setinfo x_old 38912
es_setinfo x_new 0
es_mathparse x_new "x_old or 1"
x_new
"x_new" = "38913" ( def. "" )
 - Custom server variable.
NosferatuJoe commented 3 years ago

I can confirm that this exact issue is still present with the latest emulator version.

Ayuto commented 3 years ago

Yes, it's because of the math issue mentioned previously. https://github.com/Ayuto/EventScripts-Emulator/issues/24#issuecomment-612224116

That's why this is still an open issue.

NosferatuJoe commented 3 years ago

Ok, I understand. Is there any way I can help with this? I'm not a programmer but I'd love to help in terms of testing on my CSGO server. I would even bounty (pay off) this bug since it's quite an important issue atm.

Anyways as always, thank you so much for all the effort you've put into the emulator.

NosferatuJoe commented 3 years ago

I did some extensive testing with @Xiazee and found the line which causes the issue.

Line 1673 in es_playergetset.txt: es playerset color server_var(_playergetset_userid) 255 255 255 255

The whole block works fine until that line, the playerset color resets the model to the previous one for some odd reason. You can test this by setting a delay of 2-3 seconds on the line and you'll see the model changing correctly and after the delay is over it'll switch back to the previous faulty model. Commenting out this line will fix the issue, but I'm pretty sure the line is needed to make sure the colors are reset upon changing races/models.

A temporary fix regarding wcs would be to use "es wcs_color" instead of "es playerset model", has been tested and works fine.

Ayuto commented 3 years ago

Thanks for your tests! The problem is simply the lack of time. Currently, I don't even have enough time to check Pull Requests.

Regarding the issue: yes, it's caused by re-/setting the color. Internally, it uses es_math and es_mathparse to do some calculations and the calculations are currently wrong. The es_math issue is already fixed, but there is still an issue with es_mathparse, which I mentioned here: https://github.com/Ayuto/EventScripts-Emulator/issues/24#issuecomment-612224116

NosferatuJoe commented 3 years ago

Thanks for your tests! The problem is simply the lack of time. Currently, I don't even have enough time to check Pull Requests.

Regarding the issue: yes, it's caused by re-/setting the color. Internally, it uses es_math and es_mathparse to do some calculations and the calculations are currently wrong. The es_math issue is already fixed, but there is still an issue with es_mathparse, which I mentioned here: #24 (comment)

No problem, it's ok. Just reporting whatever issues we find so it is atleast logged somewhere. I also wonder, can't we use "setColor" from "es_emulator\eventscripts_libs\python" as a replacement for playerset color? It seems to be a recode of it in python.:

 def setColor(self, r, g, b, a=None):
        """ Sets the player's color with RGBA format. The alpha value can be omitted. """
        color = int(r) + (int(g) << 8) + (int(b) << 16)
        if a is None:
            color += self.getColor()[3] << 24
        else:
            color += int(a) << 24
        if color >= 2**31: color -= 2**32
        es.setplayerprop(self.userid, "CBaseEntity.m_nRenderMode", es.getplayerprop(self.userid, "CBaseEntity.m_nRenderMode") | 1)
        es.setplayerprop(self.userid, "CBaseEntity.m_nRenderFX", es.getplayerprop(self.userid, "CBaseEntity.m_nRenderFX") | 256)
        es.setplayerprop(self.userid, "CBaseEntity.m_clrRender", color)
Ayuto commented 3 years ago

Sure, we could completly replace the playerget/set functionality with ES Python code or SP Python code, but then the issue with es_mathparse still exists. I would like to fix the root of the problem and don't want to fight the symptoms.

Ayuto commented 3 years ago

Sure, we could completly replace the playerget/set functionality with ES Python code or SP Python code, but then the issue with es_mathparse still exists. I would like to fix the root of the problem and don't want to fight the symptoms.