Garry's Mod

Garry's Mod

RagMod Reworked
 This topic has been pinned, so it's probably important
n-gon  [developer] Jun 7, 2022 @ 1:13pm
Documentation & API
Setup

Below is example code on how to detect RagMod installation and use its hooks
local RagmodEnabled for k, v in pairs(engine.GetAddons()) do if v.wsid == "2817879135" and v.mounted == true then -- Ragmod Reworked exists! Add the module RagmodEnabled = true require("ragmod") break end end -- Stop if ragmod wasn't found if not RagmodEnabled then return end -- Add a command to ragdoll concommand.Add("ragmod_test",function(ply,cmd,args,argStr) local ragdoll = ragmod:TryToRagdoll(ply) -- This tries to ragdoll a player if IsValid(ragdoll) then print("Successfully ragdolled!") end end) -- Detect ragdolls get possessed hook.Add("RM_RagdollReady","my_hook", function(ragdoll, owner, possessor) print("Ragdoll is now ready to use! ", ragdoll, owner, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor on server and client ragdoll:GetOwningPlayer() -- This now returns a valid possessor on server and client end)local RagmodEnabled for k, v in pairs(engine.GetAddons()) do if v.wsid == "2817879135" and v.mounted == true then -- Ragmod Reworked exists! Add the module RagmodEnabled = true require("ragmod") break end end -- Stop if ragmod wasn't found if not RagmodEnabled then return end -- Add a command to ragdoll concommand.Add("ragmod_test", function(ply, cmd, args, argStr) local ragdoll = ragmod:TryToRagdoll(ply) -- This tries to ragdoll a player if IsValid(ragdoll) then print("Successfully ragdolled!") end end) -- Detect ragdolls get possessed hook.Add("RM_RagdollReady", "my_hook", function(ragdoll, owner, possessor) print("Ragdoll is now ready to use! ", ragdoll, owner, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor on server and client ragdoll:GetOwningPlayer() -- This now returns a valid possessor on server and client end) -- Other hooks: -- Detect ragdolls spawning hook.Add("RM_RagdollSpawned", "my_hook1", function(ragdoll) print("Ragdoll created ", ragdoll, ragdoll:GetClass()) end) -- Detect ragdoll get assigned an owner hook.Add("RM_OwnerInitialized", "my_hook2", function(ragdoll, owner) print("Ragdoll owner confirmed ", ragdoll, owner) ragdoll:GetOwningPlayer() -- This now returns a valid owner end) -- Detect ragdolls get possessed hook.Add("RM_RagdollPossessed", "my_hook3", function(ragdoll, possessor) print("Ragdoll possessed ", ragdoll, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor if SERVER then ragdoll:GetOwningPlayer() -- This now returns a valid possessor on the server end end) -- Other hooks: -- Detect ragdolls spawning hook.Add("RM_RagdollSpawned", "my_hook1", function(ragdoll) print("Ragdoll created ", ragdoll, ragdoll:GetClass()) end) -- Detect ragdoll get assigned an owner hook.Add("RM_OwnerInitialized", "my_hook2", function(ragdoll, owner) print("Ragdoll owner confirmed ", ragdoll, owner) ragdoll:GetOwningPlayer() -- This now returns a valid owner end) -- Detect ragdolls get possessed hook.Add("RM_RagdollPossessed", "my_hook3", function(ragdoll, possessor) print("Ragdoll possessed ", ragdoll, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor if SERVER then ragdoll:GetOwningPlayer() -- This now returns a valid possessor on the server end end)



Ragdolls

RagMod ragdolls are prop_ragdoll based fake scripted entities[wiki.facepunch.com]
They can be identified with ragmod:IsRagmodRagdoll(ent)

The ragdolls have several methods you can use to get information about the ragdoll

NOTE: Do not use GM:NetworkEntityCreated or GM:OnEntityCreated hooks to detect RagMod ragdolls, especially on the client! The ragdoll won't have its properties setup yet.
Use the RagMod hooks, like RM_RagdollReady

Ragdoll methods
These exist on the RagMod ragdoll Entities
Note on clientside: These methods might not yet be valid if the hooks haven't been called. Please use the RM_RagdollReady hook to know when the ragdoll has initialized.
Alternatively, the ragdolls have their ragdoll.Ragmod_Initialized property set to true when these methods have been added to their tables.

Player Ragdoll:GetPossessor() Description: Gets the player who is playing as this ragdoll. Usually the same as the owner. Returns: 1. Player The owner or NULL

Player Ragdoll:GetOwningPlayer() Description: Gets the player this ragdoll was created from. Returns: 1. Player The owner or NULL

General methods
RagMod module functions are all in the "ragmod" table

Ragdoll ragmod:TryToRagdoll(Player ply) Description: Tries to ragdoll a player Arguments: 1. Player ply The player to ragdoll Returns: 1. Ragdoll The created ragdoll entity or NULL

boolean ragmod:IsRagmodRagdoll(Entity ragdoll) Description: Checks if the given entity is a RagMod ragdoll Arguments: 1. Entity ragdoll The ragdoll to check Returns: true if the ragdoll is from RagMod. Can return false on clients right after spawn


boolean ragmod:IsRagdoll(Player ply) Description: Checks if the player is a ragdoll Arguments: 1. Player ply The player who we are checking Returns: true if the player is a ragdoll, false otherwise

Ragdoll ragmod:GetRagmodRagdoll(Player ply) Description: Returns the ragdoll this player is controlling Arguments: 1. Player ply The player who we are checking Returns: 1. Ragdoll The ragdoll entity or NULL if not a ragdoll

number ragmod:GetPossessTime(Player ply) Description: Use to find out when a player possessed a ragdoll Arguments: 1. Player ply The player who we are checking Returns: 1. float Time in seconds when the player ragdolled (since game start)

number ragmod:GetTimeSincePossess(Player ply) Description: Use to find out how long a player has possessed a ragdoll Arguments: 1. Player ply The player who we are checking Returns: 1. float Time in seconds since when the player ragdolled


Hooks
This is probably the hook you want to use:
(SHARED) RM_RagdollReady( Ragdoll ragdoll, Player owner, Player possessor) Description: Called when the ragdoll has both it's owner and possessor. This means the ragdoll has fully initialized. If you are looking for a simple hook to detect when a new ragdoll is ready, this is probably it. Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. Player owner The ragdoll origin player 3. Player possessor The player controlling the ragdoll

(SERVER) RM_RagdollTakeDamage( Ragdoll ragdoll, CTakeDamageInfo dmginfo, table extraDmginfo) Description: Called when a ragdoll takes damage. Note that damage might be scaled to 0 Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. CTakeDamageInfo dmginfo Damage the ragdoll took 3. table extraDmginfo Extra info Use extra info like this: extraDmginfo:GetHitGroup() to get hit hitgroup extraDmginfo:GetHitBone() to get hit bone id


The hooks below are called before RM_RagdollReady.
The ragdoll is not fully initialized yet at these hooks, so only use if you know what you are doing
(SERVER) RM_RagdollCreated( Ragdoll ragdoll) Description: Called when a ragdoll is created, but not yet spawned or assigned an owner. Arguments: 1. Ragdoll ragdoll The ragdoll entity

(SHARED) RM_RagdollSpawned( Ragdoll ragdoll) Description: Called when a ragdoll has spawned. On server the ragdoll should have been assigned an owner at this point. On the client neither the owner nor the possessor (usually the same player) is not valid yet. (See: RM_RagdollPossessed and RM_OwnerInitialized) The ragdoll has had its physics initialized here. Arguments: 1. Ragdoll ragdoll The ragdoll entity

(SHARED) RM_RagdollPossessed( Ragdoll ragdoll, Player possessor) Description: Called when a player starts possessing a ragdoll Arguments: 1. Ragdoll ragdoll The ragdoll entity 1. Player possessor The player now controlling the ragdoll or NULL

(SHARED) RM_OwnerInitialized( Ragdoll ragdoll, Player owner) Description: Called when a ragdoll has been assigned an owner On server the ragdoll hasn't spawned yet On clients the ragdoll could have spawned already Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. Player owner The ragdoll owner
Last edited by n-gon; Jun 16, 2022 @ 2:25am
< >
Showing 1-5 of 5 comments
n-gon  [developer] Jun 10, 2022 @ 4:23pm 
Permission Hooks

Used to prevent default RagMod behaviour.
Function similarly to normal Garry's Mod hooks:
Return False to prevent, nothing/nil to allow other addons to use them.
Example
-- Only let admins roll hook.Add("RM_CanMove", "my_move_blocker", function(ragdoll, move) if move == "roll" then if not ragdoll:GetPossessor():IsAdmin() then return false end end end) -- Only allow admins to fly (If flight is enabled in the settings) hook.Add("RM_CanAction", "my_action_blocker", function(ply, action) if action == "fly" then if not ply:IsAdmin() then return false end end end) -- Prevent players named "Foo" from enjoying ragmod :( hook.Add("RM_CanRagdoll", "my_rag_blocker", function(ply) if ply:Nick() == "Foo" then return false end end)


Hook List
(SERVER) boolean RM_CanRagdoll( Player ply ) Description: Called to check whether player should be allowed to ragdoll. Will be called whenever TryToRagdoll is used to ragdoll. Won't be called if a ragdoll is manually created with ragmod:SpawnRagdoll and possessed with ragmod:PossessRagdoll Arguments: 1. Player ply The player trying to ragdoll Returns: 1. boolean False to prevent, nothing to allow


(SERVER) boolean RM_CanMove( Ragdoll ragdoll, string action ) Description: Called by ragdolls to check if a movement type is allowed Arguments: 1. Ragdoll ragdoll The ragdoll 2. string movetype The move identifier Returns: 1. boolean Return false to prevent, nothing to allow Possible move identifiers: fly - Flying roll - Rolling limbs - Reaching grab - Grabbing

(SHARED) boolean RM_CanAction( Player ply, string action ) Description: Allows more low level access than RM_CanMove, use that if possible Called by RagMod to check if an action is blocked. Called on clients before sending the input. Returning false on clients means the server will never even call this. Note that RagMod might prevent actions even after this hook. Arguments: 1. Player ply The player trying to ragdoll 2. string action The action identifier Returns: 1. boolean Return false to prevent, nothing to allow Possible action identifiers: ragdolize - Manual ragdolling unpossess - Getting up from ragdolling fly - Flying reach_right - Reaching right hand reach_left - Reaching left hand cam_cycle - (Client only) Cycle through view modes show_controls - (Client only) Toggle control help window open_menu - (Client only) Open RagMod menu
(SERVER) boolean RM_CanRagdoll( Player ply ) Description: Called to check whether player should be allowed to ragdoll. Will be called whenever TryToRagdoll is used to ragdoll. Won't be called if a ragdoll is manually created with ragmod:SpawnRagdoll and possessed with ragmod:PossessRagdoll Arguments: 1. Player ply The player trying to ragdoll Returns: 1. boolean False to prevent, nothing to allow


(SERVER) boolean RM_CanReach( Ragdoll ragdoll, string limbName ) Description: Called by ragdolls to check if reaching with a limb is allowed Arguments: 1. Ragdoll ragdoll The ragdoll 2. string limbName The limb name Returns: 1. boolean Return false to prevent, nothing to allow Possible limb names: arm_right arm_left leg_right leg_left
(SERVER) boolean RM_CanGrab( Ragdoll ragdoll, string limbName, Entity grabEnt, number physObjId ) Description: Called by ragdolls to check if reaching with a limb is allowed Arguments: 1. Ragdoll ragdoll The ragdoll 2. string limbName The limb name 3. Entity grabEnt The entity we are about to grab 4. number physObjId The id of the entity's physics object we are about to grab Returns: 1. boolean Return false to prevent, nothing to allow Possible limb names: Same as RM_CanReach
(SERVER) boolean RM_CanPlaySound( Ragdoll ragdoll, string soundType ) Description: Called by ragdolls to check if playing a sound is allowed. Only called if user hasn't disabled the sound type in the RagMod settings. Arguments: 1. Ragdoll ragdoll The ragdoll 2. string soundType The sound that's about to be played Returns: 1. boolean Return false to prevent, nothing to allow Possible sound types: ragdoll - Sounds played when player ragdolls from any of the default triggers pain - Sounds played when ragdoll takes damage.
(SHARED) boolean RM_CanChangeCamera(Player ply) Description: Called when RagMod tries to calculate or change the ragdoll view for a player. Returning false on client stops ragmod from using GM:CalcView. Will default to spectator chasecam. Note: If you use your own GM:CalcView, make sure to update RagMod with the new view using RM_CustomRagdollCamera Arguments: 1. Player ply The player, LocalPlayer() on client Returns: 1. boolean False to prevent, nothing to allow


(SERVER) Vector, Angle RM_CustomRagdollCamera(Ragdoll ragdoll, Player ply) Description: Called if RM_CanChangeCamera was used to prevent RagMod camera angles. If you block the custom view with RM_CanChangeCamera, RagMod uses ply:EyePos() and ply:EyeAngles() for movement to calculate where the player is looking. If you are overriding CalcView, you should provide RagMod with the players actual view position and angles here. Note that this is only called on the server and does not change the player's view point by itself. Arguments: 1. Ragdoll ragdoll The ragdoll the player is possessing 2. Player ply The player that RagMod needs the view for Returns: 1. Vector View origin 2. Angle View angle
Last edited by n-gon; Jun 20, 2022 @ 8:05am
n-gon  [developer] Jun 13, 2022 @ 4:33pm 
Example: Camera Override

This example shows how to prevent ragmod from changing the clientside view when ragdolling.
When changing the CalcView, you'll need to tell RagMod serverside where the new player camera position is.
-- Prevent RagMod from changing the camera hook.Add("RM_CanChangeCamera", "my_view_blocker", function(ply) return false end) -- Add our custom CalcView that places the camera behind the ragdoll's eyes hook.Add("CalcView", "my_custom_calcview", function(ply, inOrigin, inAngles, inFov) if not ragmod:IsRagdoll(ply) then return end local ragdoll = ragmod:GetRagmodRagdoll(ply) -- On the client the ragdoll methods might not be valid yet if not IsValid(ragdoll) or not ragdoll.Ragmod_Initialized then return end local ragEyePos, ragEyeAngle = ragdoll:GetRagdollEyes() local newPos = ragEyePos - ragEyeAngle:Forward() * 20 local customView = { origin = newPos, angles = ragEyeAngle, fov = inFov } return customView end) -- SERVER: Tell RagMod where the player is looking at, -- since it doesn't know where the camera is looking at on the client hook.Add("RM_CustomRagdollCamera", "my_custom_view", function(ragdoll, ply) local ragEyePos, ragEyeAngle = ragdoll:GetRagdollEyes() local newPos = ragEyePos - ragEyeAngle:Forward() * 20 -- This is what RagMod will use for movement return newPos, ragEyeAngle end)
n-gon  [developer] Jun 13, 2022 @ 4:37pm 
Example: Camera Override

This example shows how to prevent ragmod from changing the clientside view when ragdolling.
When changing the CalcView, you'll need to tell RagMod serverside where the new player camera position is.
-- Prevent RagMod from changing the camera hook.Add("RM_CanChangeCamera", "my_view_blocker", function(ply) return false end) -- Add our custom CalcView that places the camera behind the ragdoll's eyes hook.Add("CalcView", "my_custom_calcview", function(ply, inOrigin, inAngles, inFov) if not ragmod:IsRagdoll(ply) then return end local ragdoll = ragmod:GetRagmodRagdoll(ply) -- On the client the ragdoll methods might not be valid yet if not IsValid(ragdoll) or not ragdoll.Ragmod_Initialized then return end local ragEyePos, ragEyeAngle = ragdoll:GetRagdollEyes() local newPos = ragEyePos - ragEyeAngle:Forward() * 20 local customView = { origin = newPos, angles = ragEyeAngle, fov = inFov } return customView end) -- SERVER: Tell RagMod where the player is looking at, -- since it doesn't know where the camera is looking at on the client hook.Add("RM_CustomRagdollCamera", "my_custom_view", function(ragdoll, ply) local ragEyePos, ragEyeAngle = ragdoll:GetRagdollEyes() local newPos = ragEyePos - ragEyeAngle:Forward() * 20 -- This is what RagMod will use for movement return newPos, ragEyeAngle end)
Markolokoy Apr 17, 2024 @ 1:32am 
how to use?
Originally posted by n-gon:
Setup

Below is example code on how to detect RagMod installation and use its hooks
local RagmodEnabled for k, v in pairs(engine.GetAddons()) do if v.wsid == "2817879135" and v.mounted == true then -- Ragmod Reworked exists! Add the module RagmodEnabled = true require("ragmod") break end end -- Stop if ragmod wasn't found if not RagmodEnabled then return end -- Add a command to ragdoll concommand.Add("ragmod_test",function(ply,cmd,args,argStr) local ragdoll = ragmod:TryToRagdoll(ply) -- This tries to ragdoll a player if IsValid(ragdoll) then print("Successfully ragdolled!") end end) -- Detect ragdolls get possessed hook.Add("RM_RagdollReady","my_hook", function(ragdoll, owner, possessor) print("Ragdoll is now ready to use! ", ragdoll, owner, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor on server and client ragdoll:GetOwningPlayer() -- This now returns a valid possessor on server and client end)local RagmodEnabled for k, v in pairs(engine.GetAddons()) do if v.wsid == "2817879135" and v.mounted == true then -- Ragmod Reworked exists! Add the module RagmodEnabled = true require("ragmod") break end end -- Stop if ragmod wasn't found if not RagmodEnabled then return end -- Add a command to ragdoll concommand.Add("ragmod_test", function(ply, cmd, args, argStr) local ragdoll = ragmod:TryToRagdoll(ply) -- This tries to ragdoll a player if IsValid(ragdoll) then print("Successfully ragdolled!") end end) -- Detect ragdolls get possessed hook.Add("RM_RagdollReady", "my_hook", function(ragdoll, owner, possessor) print("Ragdoll is now ready to use! ", ragdoll, owner, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor on server and client ragdoll:GetOwningPlayer() -- This now returns a valid possessor on server and client end) -- Other hooks: -- Detect ragdolls spawning hook.Add("RM_RagdollSpawned", "my_hook1", function(ragdoll) print("Ragdoll created ", ragdoll, ragdoll:GetClass()) end) -- Detect ragdoll get assigned an owner hook.Add("RM_OwnerInitialized", "my_hook2", function(ragdoll, owner) print("Ragdoll owner confirmed ", ragdoll, owner) ragdoll:GetOwningPlayer() -- This now returns a valid owner end) -- Detect ragdolls get possessed hook.Add("RM_RagdollPossessed", "my_hook3", function(ragdoll, possessor) print("Ragdoll possessed ", ragdoll, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor if SERVER then ragdoll:GetOwningPlayer() -- This now returns a valid possessor on the server end end) -- Other hooks: -- Detect ragdolls spawning hook.Add("RM_RagdollSpawned", "my_hook1", function(ragdoll) print("Ragdoll created ", ragdoll, ragdoll:GetClass()) end) -- Detect ragdoll get assigned an owner hook.Add("RM_OwnerInitialized", "my_hook2", function(ragdoll, owner) print("Ragdoll owner confirmed ", ragdoll, owner) ragdoll:GetOwningPlayer() -- This now returns a valid owner end) -- Detect ragdolls get possessed hook.Add("RM_RagdollPossessed", "my_hook3", function(ragdoll, possessor) print("Ragdoll possessed ", ragdoll, possessor) ragdoll:GetPossessor() -- This now returns a valid possessor if SERVER then ragdoll:GetOwningPlayer() -- This now returns a valid possessor on the server end end)



Ragdolls

RagMod ragdolls are prop_ragdoll based fake scripted entities[wiki.facepunch.com]
They can be identified with ragmod:IsRagmodRagdoll(ent)

The ragdolls have several methods you can use to get information about the ragdoll

NOTE: Do not use GM:NetworkEntityCreated or GM:OnEntityCreated hooks to detect RagMod ragdolls, especially on the client! The ragdoll won't have its properties setup yet.
Use the RagMod hooks, like RM_RagdollReady

Ragdoll methods
These exist on the RagMod ragdoll Entities
Note on clientside: These methods might not yet be valid if the hooks haven't been called. Please use the RM_RagdollReady hook to know when the ragdoll has initialized.
Alternatively, the ragdolls have their ragdoll.Ragmod_Initialized property set to true when these methods have been added to their tables.

Player Ragdoll:GetPossessor() Description: Gets the player who is playing as this ragdoll. Usually the same as the owner. Returns: 1. Player The owner or NULL

Player Ragdoll:GetOwningPlayer() Description: Gets the player this ragdoll was created from. Returns: 1. Player The owner or NULL

General methods
RagMod module functions are all in the "ragmod" table

Ragdoll ragmod:TryToRagdoll(Player ply) Description: Tries to ragdoll a player Arguments: 1. Player ply The player to ragdoll Returns: 1. Ragdoll The created ragdoll entity or NULL

boolean ragmod:IsRagmodRagdoll(Entity ragdoll) Description: Checks if the given entity is a RagMod ragdoll Arguments: 1. Entity ragdoll The ragdoll to check Returns: true if the ragdoll is from RagMod. Can return false on clients right after spawn


boolean ragmod:IsRagdoll(Player ply) Description: Checks if the player is a ragdoll Arguments: 1. Player ply The player who we are checking Returns: true if the player is a ragdoll, false otherwise

Ragdoll ragmod:GetRagmodRagdoll(Player ply) Description: Returns the ragdoll this player is controlling Arguments: 1. Player ply The player who we are checking Returns: 1. Ragdoll The ragdoll entity or NULL if not a ragdoll

number ragmod:GetPossessTime(Player ply) Description: Use to find out when a player possessed a ragdoll Arguments: 1. Player ply The player who we are checking Returns: 1. float Time in seconds when the player ragdolled (since game start)

number ragmod:GetTimeSincePossess(Player ply) Description: Use to find out how long a player has possessed a ragdoll Arguments: 1. Player ply The player who we are checking Returns: 1. float Time in seconds since when the player ragdolled


Hooks
This is probably the hook you want to use:
(SHARED) RM_RagdollReady( Ragdoll ragdoll, Player owner, Player possessor) Description: Called when the ragdoll has both it's owner and possessor. This means the ragdoll has fully initialized. If you are looking for a simple hook to detect when a new ragdoll is ready, this is probably it. Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. Player owner The ragdoll origin player 3. Player possessor The player controlling the ragdoll

(SERVER) RM_RagdollTakeDamage( Ragdoll ragdoll, CTakeDamageInfo dmginfo, table extraDmginfo) Description: Called when a ragdoll takes damage. Note that damage might be scaled to 0 Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. CTakeDamageInfo dmginfo Damage the ragdoll took 3. table extraDmginfo Extra info Use extra info like this: extraDmginfo:GetHitGroup() to get hit hitgroup extraDmginfo:GetHitBone() to get hit bone id


The hooks below are called before RM_RagdollReady.
The ragdoll is not fully initialized yet at these hooks, so only use if you know what you are doing
(SERVER) RM_RagdollCreated( Ragdoll ragdoll) Description: Called when a ragdoll is created, but not yet spawned or assigned an owner. Arguments: 1. Ragdoll ragdoll The ragdoll entity

(SHARED) RM_RagdollSpawned( Ragdoll ragdoll) Description: Called when a ragdoll has spawned. On server the ragdoll should have been assigned an owner at this point. On the client neither the owner nor the possessor (usually the same player) is not valid yet. (See: RM_RagdollPossessed and RM_OwnerInitialized) The ragdoll has had its physics initialized here. Arguments: 1. Ragdoll ragdoll The ragdoll entity

(SHARED) RM_RagdollPossessed( Ragdoll ragdoll, Player possessor) Description: Called when a player starts possessing a ragdoll Arguments: 1. Ragdoll ragdoll The ragdoll entity 1. Player possessor The player now controlling the ragdoll or NULL

(SHARED) RM_OwnerInitialized( Ragdoll ragdoll, Player owner) Description: Called when a ragdoll has been assigned an owner On server the ragdoll hasn't spawned yet On clients the ragdoll could have spawned already Arguments: 1. Ragdoll ragdoll The ragdoll entity 2. Player owner The ragdoll owner
i ant readin all that
< >
Showing 1-5 of 5 comments
Per page: 1530 50