· 7 years ago · Sep 24, 2018, 09:08 PM
1//----------------------------------//
2// Lobby 2010 - 2011
3//----------------------------------//
4
5--Set this to false and player scales will be stored to the database but not loaded anymore (defaults to 1.0)
6DisableScaleLoading = false;
7
8
9--Script begin
10
11if SERVER then
12 AddCSLuaFile( "resizer_main.lua" )
13end
14
15--Default data for players
16--accessible server and client side
17Sizing = { }
18Sizing.Default = {
19 StandingHull = {
20 Minimum = Vector( -16, -16, 00 ),
21 Maximum = Vector( 16, 16, 72 ),
22 },
23 DuckingHull = {
24 Minimum = Vector( -16, -16, 00 ),
25 Maximum = Vector( 16, 16, 36 ),
26 },
27 JumpPower = 160,
28 StepSize = 18,
29
30 --MaxRunSpeed = 1500,
31 --MaxWalkSpeed= 1500,
32 MaxStepSize = 500,
33 MaxHullScale = 3,
34
35 RunSpeed = 500,
36 WalkSpeed = 250,
37 Scale = Vector( ),
38 ViewOffset = Vector( 0, 0, 64 ),
39 ViewOffsetDuck = Vector( 0, 0, 28 ),
40 --AdjustToHeight = true,
41 }
42
43--lower the eye height for certain models which are smaller than regular human player models
44EyeAdjustments = {
45 ["models/characters/sh/tails.mdl"] = 0.45,
46 ["models/characters/sh/rouge.mdl"] = 0.6,
47 ["models/characters/sh/knuckles.mdl"] = 0.63,
48 ["models/characters/sh/knuckles.mdl"] = 0.6,
49 ["models/characters/sh/shadow.mdl"] = 0.6,
50 ["models/characters/sh/sonic.mdl"] = 0.6,
51 ["models/characters/sh/supershadow.mdl"] = 0.6,
52 ["models/characters/sh/rouge_sa2.mdl"] = 0.6,
53 ["models/characters/sh/amy.mdl"] = 0.6,
54 ["models/player/headcrab.mdl"] = 0.6
55
56
57 }
58
59
60--server side functions
61if SERVER then
62
63 --Main function - adjusts the player height of player v
64 local function AdjustSc(v)
65 local scale, adjust
66 local md = v:GetModel()
67
68 --detect the model eye height
69 psc = 1.0 --psc = player scale
70 if (EyeAdjustments[md]) then
71 psc=EyeAdjustments[md]
72 end
73
74 --each client has the ability to also set his personal eye scale - he can lower or raise his eye height
75 local eyeheight = v:GetInfo("resize_eyeoffset");
76
77 if eyeheight and tonumber(eyeheight) then
78 local eyescale = tonumber(eyeheight)
79 if(eyescale < 0) then
80 eyescale = 0
81 end;
82 psc = psc * eyescale;
83 end
84
85 --[[this variable decides whether to send adjustment commands for that player
86 (several adjustment commands slow down the server thus they are only called
87 when needed)]]--
88 adjust = false
89
90 --[[v.Progress is a variable for each player describing if a player is currently
91 growing or shrinking - if it is -1 then no process is running]]--
92 if v.Progress!=-1 then
93 adjust = true --in case a progress running adjust is always enabled
94 local add = FrameTime()*100;
95 v.Progress = v.Progress + add; --progress is going on
96 if (v.Progress >= v.EndProgress) then --progress completed
97 v.Scale = v.TargetScale --set player scale to target scale
98 v.Progress = -1; --process completed
99 else
100 if v.ExponentialScaling then
101 --depending on mathematical scaling way do the correct scale calculation
102 v.Scale = v.SourceScale * (1/2)^(v.Progress*v.ScaleSpeed)
103 else
104 v.Scale = v.SourceScale + v.Progress * v.ScaleSpeed
105 end
106 end
107 --store the player scale to a network float so that clients can read it
108 v:SetNWFloat("PlScale",v.Scale);
109 end
110
111 --incase the psc value changed set adjust to true
112 if not v.OldPsc then
113 adjust=true
114 elseif psc!=v.OldPsc then
115 adjust=true
116 end
117
118 --store psc value
119 v.OldPsc=psc
120
121 --set local variable
122 scale = v.Scale
123
124 if adjust then
125 local vsc=psc*scale
126
127 --adjust jump power
128 jumpscale = scale/math.sqrt(psc)
129 if(jumpscale<1) then --jump power shouldn't drop below normal, major issues
130 jumpscale=1
131 end
132 v:SetJumpPower( math.sqrt(jumpscale)*Sizing.Default.JumpPower )
133
134 --step size
135 local ss=scale*Sizing.Default.StepSize
136 if ss>Sizing.Default.MaxStepSize then --too high step size causes server issues!
137 ss=Sizing.Default.MaxStepSize
138 end
139 v:SetStepSize( ss )
140
141 --adjust view offset so that players have the felling of being small/tall
142 v:SetViewOffset( vsc*Sizing.Default.ViewOffset )
143 v:SetViewOffsetDucked( vsc*Sizing.Default.ViewOffsetDuck )
144 v:SetNetworkedFloat("PlViewOffset",vsc) --set a network float for that, the client needs it
145
146 --adjust hull scale
147 local hsc=vsc
148 if(hsc>Sizing.Default.MaxHullScale) then --do not go too high!
149 hsc=Sizing.Default.MaxHullScale
150 end
151 v:SetNetworkedFloat("PlHullScale",hsc) --client needs it!
152 v:SetHull( hsc*Sizing.Default.StandingHull.Minimum , hsc*Sizing.Default.StandingHull.Maximum )
153 v:SetHullDuck( hsc*Sizing.Default.DuckingHull.Minimum , hsc*Sizing.Default.DuckingHull.Maximum )
154 end
155
156 --adjust speed!
157 local ws=math.sqrt(scale)*Sizing.Default.WalkSpeed
158 local rs=math.sqrt(scale)*Sizing.Default.RunSpeed
159
160 gamemode.Call( "SetPlayerSpeed", v, ws, rs)
161
162 end
163
164 --gets executed every tick and runs the
165 --adjust function for all living players
166 local function Tick( )
167 local k, v
168
169 for k, v in pairs( player.GetAll( ) ) do
170 if v:Alive() then --only modify living players
171 AdjustSc(v)
172 end
173 end
174
175 end
176
177 hook.Add( "Tick", "Resizer.Tick", Tick )
178
179 --does the player allow being rescaled by others
180 function GetAllow(pl)
181 local allow=tonumber(pl:GetInfo("resize_allow"))
182
183 if allow then
184 if allow<=0 then
185 return false
186 else
187 return true
188 end
189 else
190 return true
191 end;
192 end
193
194 --store the target player size into the database
195 function StoreSize(pl, scale)
196 local name,lscale,allow,aallow;
197
198 lscale = pl.TargetScale
199 name = pl:UniqueID()
200 allow = GetAllow(pl);
201
202 if lscale>100 then
203 lscale=100
204 end
205
206 if allow then
207 aallow = 1
208 else
209 aallow = 0
210 end;
211
212 local entry_exists = sql.Query( "SELECT * FROM player_scales WHERE uniqueid = "..pl:UniqueID()..";" )
213
214 if ( !entry_exists ) then
215 sql.Query( "INSERT INTO player_scales VALUES ("..pl:UniqueID()..","..lscale..","..aallow..");");
216 else
217 sql.Query( "UPDATE player_scales SET scale="..lscale..",allowothers="..aallow.." WHERE uniqueid = "..pl:UniqueID()..";");
218 end
219
220 end
221
222 --read the player scale from the database if existing
223 --otherwise set default scales and default vars
224 function SetOrgScale( pl )
225 local name,scale,sztab,allow,result
226 name=pl:UniqueID()
227
228 --CreateTable();
229
230 if DisableScaleLoading then
231 result = false
232 else
233 result = sql.Query("SELECT * FROM player_scales WHERE uniqueid="..name..";");
234 end
235
236 if not result then
237 scale = 1
238 allow = 1
239 else
240 for k,row in pairs(result) do
241 scale = tonumber(row['scale']);
242 if row['allowothers']=="1" then
243 allow = 1
244 else
245 allow = 0
246 end
247 end
248 end
249
250 --set variables
251 pl:SetNetworkedFloat("PlScale",scale);
252 pl:SetNetworkedFloat("PlViewOffset",1);
253 pl:SetNetworkedFloat("PlHullScale",1);
254 pl:ConCommand("resize_allow "..allow);
255 pl.Scale = scale
256 pl.TargetScale = scale
257 pl.ScaleSpeed = 0
258 pl.EndProgress = 0;
259 pl.Progress = 0
260 pl.ExponentialScaling = true
261 AdjustSc(pl)
262 end
263 hook.Add( "PlayerInitialSpawn", "Resizer.InitScale", SetOrgScale );
264
265
266 --function for sending messages to the client screen
267 local SUCCESS = 1
268 local ERROR = 2
269
270 local function HudMSG( ply, message, type, print )
271 if( !type ) then type = SUCCESS end
272
273 if (type == SUCCESS) then
274 notify_type = "NOTIFY_GENERIC"
275 notify_sound = "ambient/water/drip" .. math.random(1, 4) .. ".wav"
276
277 elseif (type == ERROR) then
278 notify_type = "NOTIFY_ERROR"
279 notify_sound = "buttons/button10.wav"
280 end
281
282 ply:SendLua( "GAMEMODE:AddNotify( \"" .. message .. "\", " .. notify_type .. ", 5 ); surface.PlaySound( \"" .. notify_sound .. "\" )" )
283
284 if ( print ) then
285 ply:PrintMessage( HUD_PRINTCONSOLE, message )
286 end
287 end
288
289
290
291
292 local divider = math.log(1.0/2.0); --for exponential scaling
293
294 --function to call to set a player to wished scale
295 function ScalePlayer(pl, scale, endprogress, exponential, sendingplayer)
296 --am I allowed to do that
297 if !sendingplayer then
298 print("console is scaling a player.")
299 else
300 if ( pl:EntIndex()!=sendingplayer:EntIndex() and not GetAllow(pl) ) then
301 HudMSG(sendingplayer,"This player disallows external resizing",ERROR,false)
302 return
303 end
304 end
305
306 --make sure we do not scale anyone to 0
307 if scale <= 0 then
308 scale = 0.00001
309 end
310 --set the variables
311 if not pl.Scale then pl.Scale = scale end
312 pl.SourceScale = pl.Scale
313 pl.TargetScale = scale
314 pl.Progress = 0
315 pl.EndProgress = endprogress
316 pl.ExponentialScaling = exponential
317 if exponential then
318 pl.ScaleSpeed = math.log(pl.TargetScale / pl.Scale) / endprogress / divider;
319 else
320 pl.ScaleSpeed = (pl.TargetScale - pl.Scale) / endprogress;
321 end
322 --store network variables
323 pl:SetNetworkedFloat("PlScale",pl.SourceScale)
324 --store size to database
325 StoreSize(pl,pl.TargetScale)
326 end
327
328 --create database table if required
329 sql.Query("CREATE TABLE IF NOT EXISTS player_scales ( 'uniqueid' INT NOT NULL PRIMARY KEY, 'scale' DOUBLE NOT NULL, 'allowothers' BOOL NOT NULL);");
330end
331
332
333--client specific stuff
334if CLIENT then
335 --size update on client side
336 local function Tick( )
337 local k, v
338
339 for k, v in pairs( player.GetAll( ) ) do
340 --get scale and set model size and render bounds with it
341 local pscale = v:GetNetworkedFloat("PlScale")
342 if not pscale then
343 pscale = 1
344 end;
345 local ScaleVector = pscale * Vector(1,1,1)
346 v:SetModelScale( ScaleVector )
347 v:SetRenderBounds( pscale * Sizing.Default.StandingHull.Minimum, pscale * Sizing.Default.StandingHull.Maximum )
348
349 --get the view offset (shared function but executing it on client side fixes some screen shaking issues)
350 local vsc = v:GetNetworkedFloat("PlViewOffset")
351 if not vsc then
352 vsc = 1
353 end;
354 v:SetViewOffset( vsc*Sizing.Default.ViewOffset )
355 v:SetViewOffsetDucked( vsc*Sizing.Default.ViewOffsetDuck )
356
357 --get the player hull (again shared function but executing it on client side fixes some screen shaking issues)
358 local hsc = v:GetNetworkedFloat("PlHullScale")
359 if not hsc then
360 hsc = 1
361 end;
362 v:SetHull( hsc*Sizing.Default.StandingHull.Minimum , hsc*Sizing.Default.StandingHull.Maximum )
363 v:SetHullDuck( hsc*Sizing.Default.DuckingHull.Minimum , hsc*Sizing.Default.DuckingHull.Maximum )
364
365 end
366 end
367
368 hook.Add( "Tick", "Resizer.ClientTick", Tick )
369end
370
371function FindPlayer(name)
372 local playersFound = {}
373 for k,v in pairs(player.GetAll()) do
374 if v:Nick():match(name) then
375 playersFound[k] = v
376 end
377 end
378
379 if #playersFound > 1 then
380 print("Multiple players found!")
381 return
382 elseif #playersFound == 0 then
383 print("No players found!")
384 return
385 else
386 return playersFound[1]
387 end
388
389end
390
391concommand.Add("scale" , function(pl, cmd, args)
392 if SERVER then
393 //if pl:IsAdmin() == false then return end
394 local size = tonumber(args[1])
395 local ply = FindPlayer( args[2] )
396 if size then
397 ScalePlayer(pl, size/100, math.exp(1.1002*(10-6)), true, ply)
398 end
399 end
400end)