[QUOTE=JasonMan34;49785732]I used a TTTBeginRound hook, with a timer of 1 second, and it worked fine. May I ask what exactly did you try to do?[/QUOTE]
I tried the same exact thing, Worked fine for singleplayer yet when trying to implement it into the server I host, it didn't seem to want to work. By putting it in like
[lua]hook.Add("TTTBeginRound", "PS ReEquip", function()
timer.Simple(1, function()
if !IsValid(self) then return end
for item_id, item in pairs(self.PS_Items) do
local ITEM = PS.Items[item_id]
if item.Equipped then
ITEM:OnEquip(self, item.Modifiers)
end
end
end)
end)[/lua]
or inside the full first part of sv_player_extension.lua
[lua]function Player:PS_PlayerSpawn()
if not self:PS_CanPerformAction() then return end
-- TTT ( and others ) Fix
if TEAM_SPECTATOR != nil and self:Team() == TEAM_SPECTATOR then return end
if TEAM_SPEC != nil and self:Team() == TEAM_SPEC then return end
-- Murder Spectator Fix (they don't specify the above enums when making teams)
-- [url]https://github.com/mechanicalmind/murder/blob/master/gamemode/sv_spectate.lua#L15[/url]
if self.Spectating then return end
timer.Simple(1, function()
if !IsValid(self) then return end
for item_id, item in pairs(self.PS_Items) do
local ITEM = PS.Items[item_id]
if item.Equipped then
ITEM:OnEquip(self, item.Modifiers)
end
end
end)
hook.Add("TTTBeginRound", "PS ReEquip", function()
timer.Simple(1, function()
if !IsValid(self) then return end
for item_id, item in pairs(self.PS_Items) do
local ITEM = PS.Items[item_id]
if item.Equipped then
ITEM:OnEquip(self, item.Modifiers)
end
end
end)
end)
end[/lua]
Seemed like the place to put it since it was the function being called on spawn and was the one that was resetting the skins, though again.
Not too experienced with lua myself, so couldnt exactly figure out how to make it so if they were alive no change would happen but if they had died during the pre-round it would do its job and equip the skin.
Thanks for the reply!
[QUOTE=MPan1;49790034]stuff[/QUOTE]
Okay so that "works" but it only seems to be able to send the strings to the client that is sending it from the start. If you try to make an if LocalPlayer() == X then DoRelay(Player(Number),string) end then or even just trying to send the local player's name it stops and nothing print out. Is it limited only to the person that sent it?
[QUOTE=ArtikNinetail;49790125]Okay so that "works" but it only seems to be able to send the strings to the client that is sending it from the start. If you try to make an if LocalPlayer() == X then DoRelay(Player(Number),string) end then or even just trying to send the local player's name it stops and nothing print out. Is it limited only to the person that sent it?[/QUOTE]
Wait, so what are you trying to do with that relay thing? Also, explanation coming soon hopefully :P
[editline]22nd February 2016[/editline]
Actually, have you tried printing
[CODE]
LocalPlayer() == whatever player you're trying
[/CODE]
To see if it comes up as true?
[QUOTE=MPan1;49790172]Wait, so what are you trying to do with that relay thing? Also, explanation coming soon hopefully :P[/QUOTE]
I'm trying to have player 1 send a string to player 2. It's going to be used for a little computer prompt thing that players can use to message each other sort of.
[QUOTE=MPan1;49790172]
Actually, have you tried printing
[CODE]
LocalPlayer() == whatever player you're trying
[/CODE]
To see if it comes up as true?[/QUOTE]
It's weird because it only runs it from the client that is sending it. What's odd is that I tried making a debugging code: [code]if CLIENT then
if LocalPlayer() == Player(156) then
LocalPlayer():SendLua(
LocalPlayer():ConCommand("say Artik's dick is so big, my throat hurts just saying it")
)
end
end
[/code]
And if I run it shared not a single player says anything including the person that is supposed to say it, but if I run it on "Only All Clients" then it works.
If I do [code]
if CLIENT then
LocalPlayer():SendLua(
LocalPlayer():ConCommand("say Artik's dick is so big, my throat hurts just saying it")
)
end
[/code] then only I say anything on shared and everyone says it on "Only All Clients". Shouldn't all players say it?
[B]Bad explanation:[/B]
The first thing that makes this relay work is the serverside bit (util.AddNetworkString) that adds the network string of 'stringrelay'.
You need to do the network-string-adding-bit since network strings are pretty much the same things as hooks, since they need an identifier to avoid overwriting eachother.
After the network string has been added, you can now call the network string on the client (to send a net message to the server) as well as the server (to send a net message to the client).
The example code thingy there calls the network string on the CLIENT first, in the DoRelay function. It starts the net message, and writes two things in the message - the receiver (who is the player who is going to be sent the message afterward), and the string you want them to receive.
Then, it uses net.SendToServer to send these two things inside a net message- to the server. The server then runs the function being defined in the net.Receive bit. This function gets run with two parameters, the length of the net message, and the player who sent it. I didn't use any of those things since they aren't needed.
Anyway, in this function, the server uses net.ReadEntity to read the player entity that just got written, and net.ReadString to read the string that just got written.
Then, it simply starts the net message again, but this time, it only sends the string that got read in the net message. Then, it uses the net.Send function with the player that should receive the net message for the argument.
That makes it so the server will send the message to the client that you put in the message.
Then, this message sent from the server gets sent back to the client- but only to the client you defined before. On their side, net.Receive gets called, and the function at that part gets run.
In this function, it simply prints the read string.
[B]Sorry for this looking so long, I'm not good at making simple things sound simple[/B]
[editline]22nd February 2016[/editline]
[QUOTE=ArtikNinetail;49790182]It's weird because it only runs it from the client that is sending it. What's odd is that I tried making a debugging code: [code]if CLIENT then
if LocalPlayer() == Player(156) then
LocalPlayer():SendLua(
LocalPlayer():ConCommand("say Artik's dick is so big, my throat hurts just saying it")
)
end
end
[/code]
And if I run it shared not a single player says anything including the person that is supposed to say it, but if I run it on "Only All Clients" then it works.[/QUOTE]
By the way, I think the reason that's happening is because [URL="https://wiki.garrysmod.com/page/Player/SendLua"]SendLua[/URL] needs a string to work, and you gave it a function.
If you made it a string like this:
[CODE]
LocalPlayer():SendLua( [[LocalPlayer():ConCommand("say Artik's dick is so big, my throat hurts just saying it")]] )
[/CODE]
Then it might work
[QUOTE=MPan1;49790231]lotsa stuff[/QUOTE]
Damn good info. Hopefully we can get someone to explain why it can't send info from one exact player like [code] if LocalPlayer() == Player(151) then DoRelay(Player(155),LocalPlayer():Nick()) end[/code]
[QUOTE=bobbleheadbob;49789256]Is there any way to get the size of a Docked panel?
I want to make a square item, but when I pnl:Dock(LEFT) I can't use pnl:SetWide(pnl:GetTall())[/QUOTE]
By doing pnl:InvalidateParent(true) on the docked panel, those functions will give the correct measures
[QUOTE=naTlatsyrC;49790123]--stuff--[/QUOTE]
First of all, in your 2nd code, you placed hook.Add inside a function - this will simply generate errors.
In your 1st code, self is undefined, that's why it doesn't work for you.
Instead, you'll have to loop through all the players (Use [URL="http://wiki.garrysmod.com/page/player/GetAll"]player.GetAll()[/URL]), and check if the player has the item equipped (Use ply:PS_HasItemEquipped).
[QUOTE=JasonMan34;49790568]First of all, in your 2nd code, you placed hook.Add inside a function - this will simply generate errors.
In your 1st code, self is undefined, that's why it doesn't work for you.
Instead, you'll have to loop through all the players (Use [URL="http://wiki.garrysmod.com/page/player/GetAll"]player.GetAll()[/URL]), and check if the player has the item equipped (Use ply:PS_HasItemEquipped).[/QUOTE]
Thank you for the information!
I'll try to work on it sometime later today with your reccomendations in mind!
I'll post another here in thanks or if I have anymore questions once I've fiddled with it!
Again really appreciate your help ^^
So about my last inquiry: [sp]Without looking at this thread because I found my last questions which I hoped were possible... were not possible, I HAD to use hooks to control individual weapon pickup, ammo, and "last weapon" auto-switching. (I actually never tried the autoswitchfrom variable though, might be more efficient if it works but I could probably implement the net string "wepLastInv" into another weapon too, for reasons other than selecting the last used weapon)[/sp]
Anyway, I've seen people do armor using ENT:FollowBone(Ent,bID) before (assumably) but... if someone shoots at a Player wearing this armor, does the armor block the shots or would I still need to write code to handle it?
I've once again modified my code heavily. Still can't quite figure out what to do. If this goes on I guess I'll have to create a separate thread.. *sigh*
[CODE]
if ( self.Owner:HasWeapon( self.Data.Class ) ) then
local weap = ents.Create( self.Data.Class )
weap:SetPos( self.Owner:TraceFromEyes( 100 ).HitPos + Vector( 0, 0, 15 ) )
if(self.Owner.lastWep ~= nil && IsValid(weap))then
self.Owner.lastWep:Remove()
print("This has run 1")
--self.Owner.lastWep = nil
end
weap:Spawn()
weap:SetNWEntity("Owner",self.Owner)
self.Owner.lastWep = weap
SPropProtection.PlayerMakePropOwner( self.Owner, weap )
hook.Add("WeaponEquip","TestAndWhatNot", function(weapon)
local Owner = weapon:GetNWEntity("Owner")
if(IsValid(Owner.lastWep) && Owner.lastWep ~= nil && Owner:IsPlayer())then
Owner.lastWep = nil
end
end)
else
self.Owner:Give( self.Data.Class )
end
for k, v in pairs( self.Data.Cost ) do
self.Owner:DecResource( k, v )
end
end[/CODE]
Making a new weapon will remove any older weapons that have been crafted. However, it should only do that if said weapons haven't been picked up by a player. When I pick up a weapon that has been crafted it errors with:
[ERROR] gamemodes/gmstranded/gamemode/processes.lua:1115: attempt to index a string value with bad key ('lastWep' is not part of the string library)
1. error - [C]:-1
2. __index - lua/includes/extensions/string.lua:310
3. v - gamemodes/gmstranded/gamemode/processes.lua:1115
4. unknown - lua/includes/modules/hook.lua:84
1115 refers to the "Owner.lastWep = nil" line. I can't quite figure out how to solve this. Any help?
[QUOTE=Author.;49790509]By doing pnl:InvalidateParent(true) on the docked panel, those functions will give the correct measures[/QUOTE]
Thank you Authorgami.
So im trying to find if a player (LocalPlayer()) is inside a box using [IMG]http://wiki.garrysmod.com/favicon.ico[/IMG] [URL="http://wiki.garrysmod.com/page/ents/FindInBox"]ents.FindInBox[/URL] and then this happened to my game "Client Lua Stack Leak[1]! 0> UNKNOWN (usercmd)" any help on what im doing wrong would be appreciated.
Code:
[CODE]
local EntsInBox = ents.FindInBox(Vector(-2927.851563, -32.067402, -511.968750), Vector(-1200.898560, -2063.968750, -178.487885))
local InSpawn = false
for _, v in pairs(EntsInBox)do
if LocalPlayer() == v then
InSpawn = true
else
InSpawn = false
end
end
[/CODE]
[QUOTE=zippy36jr;49795829]So im trying to find if a player (LocalPlayer()) is inside a box using [IMG]http://wiki.garrysmod.com/favicon.ico[/IMG] [URL="http://wiki.garrysmod.com/page/ents/FindInBox"]ents.FindInBox[/URL] and then this happened to my game "Client Lua Stack Leak[1]! 0> UNKNOWN (usercmd)" any help on what im doing wrong would be appreciated.
Code:
[CODE]
local EntsInBox = ents.FindInBox(Vector(-2927.851563, -32.067402, -511.968750), Vector(-1200.898560, -2063.968750, -178.487885))
local InSpawn = false
for _, v in pairs(EntsInBox)do
if LocalPlayer() == v then
InSpawn = true
else
InSpawn = false
end
end
[/CODE][/QUOTE]
Where are you running that?
:snip:
[QUOTE=MPan1;49796198]Where are you running that?
:snip:[/QUOTE]
Im running it client side.
How do I use a default HL2 weapon icon? I tried drawing a "character" with surface.SetFont( "HalfLife2" ) inside DrawWeaponSelection, but it says that HalfLife2 is not a valid font.
[QUOTE=MaxShadow;49797908]How do I use a default HL2 weapon icon? I tried drawing a "character" with surface.SetFont( "HalfLife2" ) inside DrawWeaponSelection, but it says that HalfLife2 is not a valid font.[/QUOTE]
Use CreditsLogo
[QUOTE=zippy36jr;49797757]Im running it client side.[/QUOTE]
He means the hook or in what cases are you running that at?
I have another problem. My swep doesn't fire. I added a new ammo type with this:
[CODE]game.AddAmmoType( { name = "soundgrenade" , maxcarry = 3} )
if ( CLIENT ) then language.Add( "soundgrenade_ammo", "Sound Grenade" ) end
SWEP.Primary.Recoil = 0
SWEP.Primary.Delay = 0
SWEP.Primary.Damage = 0
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = 1
SWEP.Primary.Reload = 0
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "soundgrenade"[/CODE]
However, it seems like the game is not adding it at all. If I do "self.Owner:GetAmmoCount(self.Primary.Ammo) == 0" in PrimaryFire, the weapon fires normally, but if I use "> 0" it doesn't. I also don't see any message when I pick up the weapon, and I don't have any ammo counter on the edge of the screen. Do I have to do something else to add a custom ammo type?
I'm looping through all players with
[code] for k, v in pairs(player.GetAll()) [/code]
and trying to find a way to detect if the player v is clicking mouse1. I need this to detect when he fires. I've tried :KeyDown( IN_ATTACK ), it worked but only when it was me pressing mouse1. I need to detect other players aswell. And this is all CLIENT SIDE. Any tips?
Has the GMA size limit changed? I'm trying to update my addon (Which was fine yesterday at 339MB) but today it keeps failing. Even when I manage to get it down to 240MB.
[QUOTE=Jertz;49800001]I'm looping through all players with
[code] for k, v in pairs(player.GetAll()) [/code]
and trying to find a way to detect if the player v is clicking mouse1. I need this to detect when he fires. I've tried :KeyDown( IN_ATTACK ), it worked but only when it was me pressing mouse1. I need to detect other players aswell. And this is all CLIENT SIDE. Any tips?[/QUOTE]
This should be better than iterating through all players constantly:
[url]https://wiki.garrysmod.com/page/GM/KeyPress[/url]
Also, I'm not sure if the key presses are networked to all clients. Even if they are networked (probably not), it will not work with players outside your PVS. You need to run it serverside, and send a message to the client (you).
Can someone describe me how to unload texture from gmod buffer? Or resize texture to 1x1 by using lua? Please.
[QUOTE=zippy36jr;49795829]So im trying to find if a player (LocalPlayer()) is inside a box using [IMG]http://wiki.garrysmod.com/favicon.ico[/IMG] [URL="http://wiki.garrysmod.com/page/ents/FindInBox"]ents.FindInBox[/URL] and then this happened to my game "Client Lua Stack Leak[1]! 0> UNKNOWN (usercmd)" any help on what im doing wrong would be appreciated.
Code:
[CODE]
local EntsInBox = ents.FindInBox(Vector(-2927.851563, -32.067402, -511.968750), Vector(-1200.898560, -2063.968750, -178.487885))
local InSpawn = false
for _, v in pairs(EntsInBox)do
if LocalPlayer() == v then
InSpawn = true
else
InSpawn = false
end
end
[/CODE][/QUOTE]
try
[CODE]
local EntsInBox = ents.FindInBox(Vector(-2927.851563, -32.067402, -511.968750), Vector(-1200.898560, -2063.968750, -178.487885))
local InSpawn = false
for _, v in pairs(EntsInBox)do
if v:IsPlayer() then
if LocalPlayer():GetPos() == v:GetPos() then
InSpawn = true
else
InSpawn = false
end
end
end
[/CODE]
if you get the same error after this post the rest of your code.
[code]
AddCSLuaFile()
SWEP.HoldType = "normal"
if CLIENT then
SWEP.PrintName = "Truth Serum"
SWEP.Slot = 7
SWEP.ViewModelFOV = 10
SWEP.EquipMenuData = {
type = "item_weapon",
desc = "A one time use tester."
};
SWEP.Icon = "vgui/ttt/icon_tester"
end
SWEP.Base = "weapon_tttbase"
SWEP.ViewModel = "models/weapons/v_crowbar.mdl"
SWEP.WorldModel = "models/weapons/w_slam.mdl"
SWEP.DrawCrosshair = false
SWEP.ViewModelFlip = false
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Primary.Delay = 9999999
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.Secondary.Delay = 999999
SWEP.Kind = WEAPON_EQUIP2
SWEP.CanBuy = {ROLE_DETECTIVE}
SWEP.AllowDrop = true
SWEP.NoSights = true
if SERVER then
function SWEP:PrimaryAttack()
local trace = self.Owner:GetEyeTrace().Entity
if( trace:IsValid() && trace:IsPlayer() ) then
local nearEnts = ents.FindInSphere(self.Owner:GetPos(), 150)
if (table.HasValue(nearEnts, trace )) then
if( trace.KillTable ) then
for k, v in ipairs (trace.KillTable) do
trace:ConCommand("say "..v);
end
else
SaySomethingRandom( trace );
end
self:Remove()
else
self.Owner:PrintMessage(HUD_PRINTTALK, "Player not in range")
end
end
end
hook.Add("TTTBeginRound", "ResetKillTable", function()
for k,v in pairs(player.GetAll()) do
v.KillTable = nil
end
end)
hook.Add("PlayerDeath", "AddKillTable", function( victim, weapon, attacker )
if( victim:IsPlayer() and attacker:IsPlayer() ) then
attacker.KillTable = attacker.KillTable or {}
table.insert(attacker.KillTable, "I killed "..victim:Name()..".")
end
end)
function SaySomethingRandom( ply )
local stuff = {"Sometimes, I bury my head into the ground and pretend I'm a carrot.", "If 2+2 is 4, and 5+5 is 10, then what is 2+5?", "You got 99 problems but me killing someone ain't one."}
ply:ConCommand("say "..table.Random(stuff))
end
end
function SWEP:OnDrop()
self:Remove()
end
function SWEP:Reload()
return false
end
function SWEP:OnRemove()
if CLIENT and IsValid(self.Owner) and self.Owner == LocalPlayer() and self.Owner:Alive() then
RunConsoleCommand("lastinv")
end
end
if CLIENT then
function SWEP:Initialize()
self:AddHUDHelp("applyTruthSerum", nil, true)
return self.BaseClass.Initialize(self)
end
end
function SWEP:Deploy()
if SERVER and IsValid(self.Owner) then
self.Owner:DrawViewModel(false)
end
return true
end
function SWEP:DrawWorldModel()
end
function SWEP:DrawWorldModelTranslucent()
end
[/code]
How would I get this SWEP to print out ALL the values of the table when used. It prints out just ONE value and it's the first one.
Solved it by noticing the issue was the say command in console being spammed. Worked around it using this..
[code]
function SWEP:PrimaryAttack()
local trace = self.Owner:GetEyeTrace().Entity
if( trace:IsValid() && trace:IsPlayer() ) then
local nearEnts = ents.FindInSphere(self.Owner:GetPos(), 150)
if (table.HasValue(nearEnts, trace )) then
if( trace.KillTable ) then
self.Owner.targetNumKilled = table.Count(trace.KillTable)
if self.Owner.targetNumKilled == 1 then
trace:ConCommand("say "..table.GetFirstValue(trace.KillTable))
else
trace:ConCommand("say ".."I've killed "..self.Owner.targetNumKilled.." people, including "..table.GetFirstValue(trace.KillNames).." and "..table.GetLastValue(trace.KillNames)..".")
end
else
SaySomethingRandom( trace );
end
self:Remove()
else
self.Owner:PrintMessage(HUD_PRINTTALK, "Player not in range")
end
end
end
hook.Add("TTTBeginRound", "ResetKillTable", function()
for k,v in pairs(player.GetAll()) do
v.KillTable = nil
end
end)
hook.Add("PlayerDeath", "AddKillTable", function( victim, weapon, attacker )
if( victim:IsPlayer() and attacker:IsPlayer() ) then
attacker.KillTable = attacker.KillTable or {}
attacker.KillNames = attacker.KillNames or {}
table.insert(attacker.KillTable, "I killed "..victim:Name()..".")
table.insert(attacker.KillNames, victim:Name())
end
end)
[/code]
[QUOTE=MaxShadow;49800112]This should be better than iterating through all players constantly:
[url]https://wiki.garrysmod.com/page/GM/KeyPress[/url]
Also, I'm not sure if the key presses are networked to all clients. Even if they are networked (probably not), it will not work with players outside your PVS. You need to run it serverside, and send a message to the client (you).[/QUOTE]
Yeah, I already got it working with having serverside lua, but I was trying to manage do this only clientside so I could run it clientside on servers. It's sounds weird if this isn't possible as this can be done even on E2.. E2 runs on the server so I guess.
[QUOTE=Jertz;49805034]It's sounds weird if this isn't possible as this can be done even on E2.. E2 runs on the server so I guess.[/QUOTE]
All functions in E2 are ran server-side, even if it should be done client-side, it's defined server-side
[lua]function Player:PS_PlayerSpawn()
if not self:PS_CanPerformAction() then return end
-- TTT ( and others ) Fix
if TEAM_SPECTATOR != nil and self:Team() == TEAM_SPECTATOR then return end
if TEAM_SPEC != nil and self:Team() == TEAM_SPEC then return end
-- Murder Spectator Fix (they don't specify the above enums when making teams)
-- [url]https://github.com/mechanicalmind/murder/blob/master/gamemode/sv_spectate.lua#L15[/url]
if self.Spectating then return end
timer.Simple(1, function()
if !IsValid(self) then return end
for item_id, item in pairs(self.PS_Items) do
local ITEM = PS.Items[item_id]
if item.Equipped then
ITEM:OnEquip(self, item.Modifiers)
end
end
end)
end
hook.Add("TTTBeginRound", "PS ReEquip", function()
local self = player.GetAll()
timer.Simple(1, function()
if !IsValid(self) then return end
if self:PS_HasItemEquipped(id) then end
for item_id, item in pairs(self.PS_Items) do
local ITEM = PS.Items[item_id]
if item.Equipped then
ITEM:OnEquip(self, item.Modifiers)
end
end
end)
end)[/lua]
^ was the attempted fix I made, out of the function as well as the other recommendations, but it still dosen't seem to want to work. Sorry I'm abit of an amature >. <
JasonMan34's help was very much appreciated and I feel like slowly getting closer to getting it fixed aswell as learning a increasingly greater deal !
What's the easiest way to disable certain keys? I'm aware of how to disable jumping, however I tried a similar way to disable 'W' and 'S' keys.
[lua]
local TeamAllow = {
[TEAM_HSW] = {IN_JUMP},
[TEAM_SIDEWAYS] = {IN_FORWARD, IN_BACK},
}
hook.Add( "SetupMove", "DisableKeys", function( ply, mvd, cmd )
if TeamAllow[ply:Team()] then
for k,v in pairs(TeamAllow[ply:Team()]) do
if mvd:KeyDown( v ) then
mvd:RemoveKeys( v )
end
end
end
end )[/lua]
No errors, but only jump is being removed from players. You are still able to move back and forward.
This code is used for HL2's view model bob:
[code]float CBaseHL2MPCombatWeapon::CalcViewmodelBob( void )
{
static float bobtime;
static float lastbobtime;
float cycle;
CBasePlayer *player = ToBasePlayer( GetOwner() );
//Assert( player );
//NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
{
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
return 0.0f;// just use old value
}
//Find the speed of the player
float speed = player->GetLocalVelocity().Length2D();
//FIXME: This maximum speed value must come from the server.
// MaxSpeed() is not sufficient for dealing with sprinting - jdw
speed = clamp( speed, -320, 320 );
float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
lastbobtime = gpGlobals->curtime;
//Calculate the vertical bob
cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX;
cycle /= HL2_BOB_CYCLE_MAX;
if ( cycle < HL2_BOB_UP )
{
cycle = M_PI * cycle / HL2_BOB_UP;
}
else
{
cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
}
g_verticalBob = speed*0.005f;
g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
//Calculate the lateral bob
cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2;
cycle /= HL2_BOB_CYCLE_MAX*2;
if ( cycle < HL2_BOB_UP )
{
cycle = M_PI * cycle / HL2_BOB_UP;
}
else
{
cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
}
g_lateralBob = speed*0.005f;
g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
return 0.0f;
}
void CBaseHL2MPCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
{
Vector forward, right;
AngleVectors( angles, &forward, &right, NULL );
CalcViewmodelBob();
// Apply bob, but scaled down to 40%
VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
// Z bob a bit more
origin[2] += g_verticalBob * 0.1f;
// bob the angles
angles[ ROLL ] += g_verticalBob * 0.5f;
angles[ PITCH ] -= g_verticalBob * 0.4f;
angles[ YAW ] -= g_lateralBob * 0.3f;
VectorMA( origin, g_lateralBob * 0.8f, right, origin );
}[/code]
I converted it to Lua like so:
[code]local function angvecs( angle, fwd, right )
local sr, sp, sy, cr, cp, cy
sp, cp = math.sin( math.rad( angle.p ) ),
math.cos( math.rad( angle.p ) )
sy, cy = math.sin( math.rad( angle.y ) ),
math.cos( math.rad( angle.y ) )
sr, cr = math.sin( math.rad( angle.r ) ),
math.cos( math.rad( angle.r ) )
fwd.x = cp*cy
fwd.y = cp*sy
fwd.z = -sp
right.x = (-1*sr*sp*cy+-1*cr*-sy)
right.y = (-1*sr*sp*sy+-1*cr*cy)
right.z = -1*sr*cp
end
local function vecma( start, scale, direction, dest )
dest.x=start.x+direction.x*scale
dest.y=start.y+direction.y*scale
dest.z=start.z+direction.z*scale
end
local BOB_CYCLE_MAX = 0.45
local BOB_UP = 0.5
local latbob, vertbob = 0, 0
local function calcbob( ent )
local cycle, bobtime, lastbobtime = 0.0, 0.0, 0.0
local speed = ent:GetVelocity():Length2D()
speed = math.Clamp( speed, -320, 320 )
local offset = math.Remap( speed, 0, 320, 0.0, 1.0 )
bobtime = bobtime + ( CurTime() - lastbobtime ) * offset
lastbobtime = CurTime()
-- afaik converting a float
-- to an int in c++ just floors the target number
cycle = bobtime - math.floor((bobtime/BOB_CYCLE_MAX)*BOB_CYCLE_MAX)
cycle = cycle / BOB_CYCLE_MAX
if ( cycle < BOB_UP ) then
cycle = math.pi * cycle / BOB_UP
else
cycle = math.pi + math.pi*(cycle-BOB_UP)/(1-BOB_UP)
end
vertbob = speed*0.005
vertbob = vertbob*0.3 + vertbob*0.7*math.sin(cycle)
vertbob = math.Clamp( vertbob, -7.0, 4.0 )
cycle = bobtime - math.floor((bobtime/BOB_CYCLE_MAX*2)*BOB_CYCLE_MAX*2)
cycle = cycle / BOB_CYCLE_MAX*2
if ( cycle < BOB_UP ) then
cycle = math.pi * cycle / BOB_UP
else
cycle = math.pi + math.pi*(cycle-BOB_UP)/(1-BOB_UP)
end
latbob = speed*0.005
latbob = latbob*0.3 + latbob*0.7*math.sin(cycle)
latbob = math.Clamp( latbob, -7.0, 4.0 )
end
function SWEP:GetViewModelPosition( pos, ang )
local forward, right = Vector( 0, 0, 0 ), Vector( 0, 0, 0 )
angvecs( ang, forward, right )
calcbob( self.Owner )
print(vertbob)
vecma( pos, vertbob * 0.1, forward, pos )
pos.z = pos.z + vertbob * 0.1
ang.p = ang.p - vertbob * 0.4
ang.y = ang.y - latbob * 0.3
ang.r = ang.r + vertbob * 0.5
vecma( pos, latbob * 0.8, right, pos )
return pos, ang
end[/code]
Why isn't this working? All I get is extremely jittery movement.
However, I have noticed that for the view model source code, they only apply the view bob when prediction isn't being used. Should I try the same?
Sorry, you need to Log In to post a reply to this thread.