mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
Upload
This commit is contained in:
355
lua/autorun/hlr/autoreplace.lua
Normal file
355
lua/autorun/hlr/autoreplace.lua
Normal file
@@ -0,0 +1,355 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
if CLIENT then return end
|
||||
print("Executing Half-Life Resurgence auto replace script...")
|
||||
|
||||
-- https://developer.valvesoftware.com/wiki/Half-Life.fgd
|
||||
-- https://developer.valvesoftware.com/wiki/Half_Life_2.fgd
|
||||
|
||||
local replaceTbl_Entities = {
|
||||
-- Half-Life 1 --
|
||||
["monster_alien_grunt"] = "npc_vj_hlr1_aliengrunt",
|
||||
["monster_nihilanth"] = "npc_vj_hlr1_nihilanth",
|
||||
["monster_tentacle"] = "npc_vj_hlr1_tentacle",
|
||||
["monster_alien_slave"] = "npc_vj_hlr1_alienslave",
|
||||
["monster_bigmomma"] = "npc_vj_hlr1_gonarch",
|
||||
["monster_bullchicken"] = "npc_vj_hlr1_bullsquid",
|
||||
["monster_gargantua"] = "npc_vj_hlr1_garg",
|
||||
["monster_human_assassin"] = "npc_vj_hlr1_assassin_female",
|
||||
["monster_babycrab"] = "npc_vj_hlr1_headcrab_baby",
|
||||
-- ["monster_human_grunt"] = {"npc_vj_hlr1_hgrunt","npc_vj_hlrof_hgrunt","npc_vj_hlrof_hgrunt_med","npc_vj_hlrof_hgrunt_eng"},
|
||||
["monster_human_grunt"] = "npc_vj_hlr1_hgrunt",
|
||||
["monster_cockroach"] = "npc_vj_hlr1_cockroach",
|
||||
["monster_houndeye"] = "npc_vj_hlr1_houndeye",
|
||||
["monster_scientist"] = "npc_vj_hlr1_scientist",
|
||||
["monster_sitting_scientist"] = "npc_vj_hlr1_scientist",
|
||||
["monster_snark"] = "npc_vj_hlr1_snark",
|
||||
["monster_zombie"] = {"npc_vj_hlr1_zombie","npc_vj_hlr1_zombie","npc_vj_hlr1_zombie","npc_vj_hlrof_zombie_sec","npc_vj_hlrof_zombie_sec","npc_vj_hlrof_zombie_soldier"},
|
||||
["monster_headcrab"] = "npc_vj_hlr1_headcrab",
|
||||
["monster_alien_controller"] = "npc_vj_hlr1_aliencontroller",
|
||||
["monster_barney"] = "npc_vj_hlr1_securityguard",
|
||||
["monster_turret"] = "npc_vj_hlr1_turret",
|
||||
["monster_miniturret"] = "npc_vj_hlr1_turret_small",
|
||||
["monster_sentry"] = "npc_vj_hlr1_sentry",
|
||||
["monster_barnacle"] = "npc_vj_hlr1_barnacle",
|
||||
["monster_ichthyosaur"] = "npc_vj_hlr1_ichthyosaur",
|
||||
["monster_gman"] = "npc_vj_hlr1_gman",
|
||||
["monster_apache"] = "npc_vj_hlr1_apache",
|
||||
["monster_osprey"] = "npc_vj_hlr1_osprey",
|
||||
["monster_turret"] = "npc_vj_hlr1_cturret",
|
||||
["monster_miniturret"] = "npc_vj_hlr1_cturret_mini",
|
||||
-- Half-Life 2 --
|
||||
["npc_advisor"] = "npc_vj_hlr2_com_advisor",
|
||||
["npc_alyx"] = "npc_vj_hlr2_alyx",
|
||||
["npc_antlion"] = "npc_vj_hlr2_antlion",
|
||||
["npc_antlion_worker"] = "npc_vj_hlr2_antlion_worker",
|
||||
["npc_antlionguard"] = "npc_vj_hlr2_antlion_guard",
|
||||
["npc_barney"] = "npc_vj_hlr2_barney",
|
||||
["npc_citizen"] = "npc_vj_hlr2_citizen",
|
||||
["npc_combine_s"] = "npc_vj_hlr2_com_soldier",
|
||||
["npc_combinegunship"] = "npc_vj_hlr2_com_gunship",
|
||||
["npc_crabsynth"] = "npc_vj_hlr2_com_crab",
|
||||
["npc_fastzombie"] = "npc_vj_hlr2_zombie_fast",
|
||||
["npc_gman"] = "npc_vj_hlr2_gman",
|
||||
["npc_headcrab"] = "npc_vj_hlr2_headcrab",
|
||||
["npc_headcrab_black"] = "npc_vj_hlr2_headcrab_poison",
|
||||
["npc_headcrab_fast"] = "npc_vj_hlr2_headcrab_fast",
|
||||
["npc_helicopter"] = "npc_vj_hlr2_com_chopper",
|
||||
["npc_hunter"] = "npc_vj_hlr2_com_hunter",
|
||||
["npc_metropolice"] = "npc_vj_hlr2_com_civilp",
|
||||
["npc_monk"] = "npc_vj_hlr2_father_grigori",
|
||||
["npc_mortarsynth"] = "npc_vj_hlr2_com_mortar",
|
||||
["npc_poisonzombie"] = "npc_vj_hlr2_zombie_poison",
|
||||
["npc_sniper"] = "npc_vj_hlr2_com_sniper",
|
||||
["npc_stalker"] = "npc_vj_hlr2_com_stalker",
|
||||
["npc_strider"] = "npc_vj_hlr2_com_strider",
|
||||
["npc_turret_ceiling"] = "npc_vj_hlr2_com_ceilingturret",
|
||||
["npc_turret_floor"] = "npc_vj_hlr2_com_sentry",
|
||||
["npc_zombie"] = "npc_vj_hlr2_zombie",
|
||||
["npc_zombine"] = "npc_vj_hlr2_zombine",
|
||||
["prop_vehicle_apc"] = "npc_vj_hlr2_com_apc",
|
||||
}
|
||||
|
||||
local replaceTbl_Weapons = {
|
||||
-- Half-Life 2 --
|
||||
["weapon_357"] = "weapon_vj_357",
|
||||
["weapon_alyxgun"] = "weapon_vj_hlr2_alyxgun",
|
||||
["weapon_annabelle"] = "weapon_vj_hlr2_annabelle",
|
||||
["weapon_ar2"] = "weapon_vj_ar2",
|
||||
["weapon_crossbow"] = "weapon_vj_crossbow",
|
||||
["weapon_crowbar"] = "weapon_vj_crowbar",
|
||||
["weapon_pistol"] = "weapon_vj_9mmpistol",
|
||||
["weapon_rpg"] = "weapon_vj_hlr2_rpg",
|
||||
["weapon_shotgun"] = "weapon_vj_spas12",
|
||||
["weapon_smg1"] = "weapon_vj_smg1",
|
||||
["weapon_stunstick"] = "weapon_vj_hlr2_stunstick"
|
||||
}
|
||||
|
||||
local essentialTbl = { -- Will expand upon this later, I recommend we add support for custom HLR packs to add their own data to the auto-replace script (Example: Half-Life 2 HLR pack adding Kleiner or Breen to the auto-script)
|
||||
-- Half-Life 2 --
|
||||
npc_vj_hlr2_alyx=true,
|
||||
npc_vj_hlr2_barney=true,
|
||||
npc_vj_hlr2_father_grigori=true,
|
||||
}
|
||||
|
||||
-- Before Create
|
||||
local replaceOptions = {
|
||||
-- If its an antlion guardian, then make sure to spawn that variant!
|
||||
["npc_antlionguard"] = function(ent, replaceEnt)
|
||||
return (ent:GetSkin() == 0 and "npc_vj_hlr2_antlion_guard") or "npc_vj_hlr2_antlion_guardian"
|
||||
end,
|
||||
-- Handle citizen / refugee / rebel variants
|
||||
["npc_citizen"] = function(ent, replaceEnt)
|
||||
for key, val in pairs(ent:GetKeyValues()) do
|
||||
if key == "citizentype" then
|
||||
if val == 0 or val == 1 then
|
||||
return "npc_vj_hlr2_citizen"
|
||||
elseif val == 2 then
|
||||
return "npc_vj_hlr2_refugee"
|
||||
elseif val == 3 or val == 4 then
|
||||
return "npc_vj_hlr2_rebel"
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
-- Handle combine soldier variants
|
||||
["npc_combine_s"] = function(ent, replaceEnt)
|
||||
local mdl = ent:GetModel()
|
||||
if mdl == "models/combine_soldier.mdl" then
|
||||
return (ent:GetSkin() == 0 and "npc_vj_hlr2_com_soldier") or "npc_vj_hlr2_com_shotgunner"
|
||||
elseif mdl == "models/combine_soldier_prisonguard.mdl" then
|
||||
return (ent:GetSkin() == 0 and "npc_vj_hlr2_com_prospekt") or "npc_vj_hlr2_com_prospekt_sg"
|
||||
elseif mdl == "models/combine_super_soldier.mdl" then
|
||||
return "npc_vj_hlr2_com_elite"
|
||||
end
|
||||
end,
|
||||
-- Check for resistance turrets!
|
||||
["npc_turret_floor"] = function(ent, replaceEnt)
|
||||
return ent:HasSpawnFlags(SF_FLOOR_TURRET_CITIZEN) and "npc_vj_hlr2_res_sentry" or "npc_vj_hlr2_com_sentry"
|
||||
end
|
||||
}
|
||||
|
||||
-- Before Spawn
|
||||
local replacePreSpawn = {
|
||||
["npc_citizen"] = function(ent, newEnt)
|
||||
if string.find(ent:GetModel(), "female") then
|
||||
newEnt.Human_Gender = 1
|
||||
else
|
||||
newEnt.Human_Gender = 0
|
||||
end
|
||||
end,
|
||||
["npc_metropolice"] = function(ent, newEnt)
|
||||
for key, val in pairs(ent:GetKeyValues()) do
|
||||
if key == manhacks && val == 0 then
|
||||
newEnt.Metrocop_CanHaveManhack = false
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
-- After Spawn
|
||||
local afterSpawned = {
|
||||
|
||||
}
|
||||
|
||||
// lua_run PrintTable(Entity(1):GetEyeTrace().Entity:GetTable())
|
||||
local defPos = Vector(0, 0, 0)
|
||||
|
||||
local gStatePrecriminal = false
|
||||
local gStateAntlionFri = false
|
||||
|
||||
-- Prepare the HL1 and HL2 tables (This includes ALL NPCs!)
|
||||
local allNPCs = list.Get("NPC")
|
||||
local allHLR = {}
|
||||
local allHLR1 = {}
|
||||
local allHLR2 = {}
|
||||
timer.Simple(0.01, function()
|
||||
for k, _ in pairs(allNPCs) do
|
||||
-- This should capture all the HL2 NPCs
|
||||
if string.StartWith(k, "npc_vj_hlr2") then
|
||||
table.insert(allHLR, k)
|
||||
table.insert(allHLR2, k)
|
||||
-- This should capture all the HL1 NPCs because many of them are "hlrof", "hlr1", "hlrsv", "hlrdc", etc.
|
||||
elseif string.StartWith(k, "npc_vj_hlr") then
|
||||
table.insert(allHLR, k)
|
||||
table.insert(allHLR1, k)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
hook.Add("OnEntityCreated", "VJ_HLR_AutoReplace_EntCreate", function(ent)
|
||||
local class = ent:GetClass()
|
||||
local rEnt = VJ_PICK(replaceTbl_Entities[class])
|
||||
if rEnt then
|
||||
-- Make sure the game is loaded
|
||||
if game && game.GetGlobalState then
|
||||
gStatePrecriminal = game.GetGlobalState("gordon_precriminal") == 1
|
||||
end
|
||||
-- Check if it's HL1 & HL2 and stop if it's not supposed to continue
|
||||
local isHL1 = string.StartWith(class, "monster_")
|
||||
if isHL1 then
|
||||
if GetConVar("vj_hlr_autoreplace_hl1"):GetInt() == 0 then
|
||||
return
|
||||
end
|
||||
elseif GetConVar("vj_hlr_autoreplace_hl2"):GetInt() == 0 then
|
||||
return
|
||||
end
|
||||
timer.Simple(0.01, function()
|
||||
if IsValid(ent) then
|
||||
local worldName = ent.GetName && ent:GetName() or nil
|
||||
//if worldName == "rocketman" then return end -- Makes Odessa work a little bit
|
||||
//local spawnAnim = ent:GetSequenceName(ent:GetSequence())
|
||||
-- Spawn the correct entity (Ex: different combine or rebels/citizens)
|
||||
if replaceOptions[class] then
|
||||
rEnt = replaceOptions[class](ent, rEnt) or rEnt
|
||||
end
|
||||
-- FUN OPTION: Randomized NPC System
|
||||
if GetConVar("vj_hlr_autoreplace_random"):GetInt() == 1 then
|
||||
if GetConVar("vj_hlr_autoreplace_randommix"):GetInt() == 1 then
|
||||
rEnt = VJ_PICK(allHLR) or rEnt
|
||||
else
|
||||
if isHL1 then
|
||||
rEnt = VJ_PICK(allHLR1) or rEnt
|
||||
else
|
||||
rEnt = VJ_PICK(allHLR2) or rEnt
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Start the actual final entity --
|
||||
local newClass = VJ_PICK(rEnt)
|
||||
local newEnt = ents.Create(newClass)
|
||||
if !IsValid(newEnt) then MsgN("Entity [" .. newClass .. "] not valid (missing pack?), keeping original entity") return end
|
||||
-- Certain entities need some checks before spawn (Ex: Citizen gender)
|
||||
if replacePreSpawn[class] then
|
||||
replacePreSpawn[class](ent, newEnt)
|
||||
end
|
||||
newEnt:SetPos(ent:GetPos() + Vector(0, 0, (class == "monster_barnacle" && -1) or 4))
|
||||
newEnt:SetAngles(ent:GetAngles())
|
||||
if IsValid(ent:GetParent()) then newEnt:SetParent(ent:GetParent()) end
|
||||
if worldName && worldName != "" then newEnt:SetName(worldName) end
|
||||
newEnt:Spawn()
|
||||
newEnt:Activate()
|
||||
-- Handle naming
|
||||
if worldName && worldName != "" then -- Scripted NPC
|
||||
newEnt.DisableWandering = true
|
||||
end
|
||||
-- Handle weapon
|
||||
local wep = ent.GetActiveWeapon && ent:GetActiveWeapon() or false -- In case GetActiveWeapon is not in the ent's metatable
|
||||
//print(worldName, wep)
|
||||
if IsValid(wep) then
|
||||
local foundWep = replaceTbl_Weapons[wep:GetClass()]
|
||||
newEnt:Give(VJ_PICK(foundWep))
|
||||
end
|
||||
-- Handle enemy
|
||||
local ene = ent.GetEnemy && ent:GetEnemy() or false -- In case GetEnemy is not in the ent's metatable
|
||||
if IsValid(ene) then
|
||||
newEnt:SetEnemy(ene)
|
||||
end
|
||||
-- Handle key values
|
||||
for key, val in pairs(ent:GetSaveTable()) do
|
||||
//print(ent, newEnt, key, val)
|
||||
key = tostring(key)
|
||||
if key == "health" then
|
||||
newEnt:SetHealth(val)
|
||||
elseif key == "max_health" then
|
||||
newEnt:SetMaxHealth(val)
|
||||
-- elseif key == "m_bSequenceLoops" && val == true && newEnt:GetInternalVariable("sequence") != -1 then
|
||||
-- newEnt.Old_AnimTbl_IdleStand = newEnt.AnimTbl_IdleStand
|
||||
-- newEnt.AnimTbl_IdleStand = {VJ_SequenceToActivity(newEnt,newEnt:GetInternalVariable("sequence"))}
|
||||
-- newEnt:SetState(VJ_STATE_ONLY_ANIMATION_NOATTACK)
|
||||
-- newEnt:VJ_ACT_PLAYACTIVITY(newEnt:GetInternalVariable("sequence"),true,false,false)
|
||||
elseif key == "m_vecLastPosition" then
|
||||
if val != defPos then
|
||||
newEnt:SetLastPosition(val)
|
||||
newEnt:VJ_TASK_GOTO_LASTPOS("TASK_WALK_PATH")
|
||||
end
|
||||
elseif key == "m_bShouldPatrol" && val == false then
|
||||
newEnt.DisableWandering = true
|
||||
-- Not what I thought it was, actual variable is m_LookDist using the function SetDistLook
|
||||
-- Which both of them can't be accessed in Lua...
|
||||
//elseif key == "m_flDistTooFar" then
|
||||
//newEnt.SightDistance = val
|
||||
end
|
||||
end
|
||||
//newEnt.SightDistance = 2048 -- Default Source engine sight distance...
|
||||
-- Handle spawn flags
|
||||
//if ent:HasSpawnFlags(SF_NPC_LONG_RANGE) then
|
||||
//newEnt.SightDistance = 6000
|
||||
//end
|
||||
newEnt:SetKeyValue("spawnflags", ent:GetSpawnFlags())
|
||||
if ent:HasSpawnFlags(SF_CITIZEN_NOT_COMMANDABLE) then
|
||||
newEnt.FollowPlayer = false
|
||||
end
|
||||
//print(ent:GetInternalVariable("m_bShouldPatrol"))
|
||||
-- Handle Gordon precriminal game state
|
||||
if gStatePrecriminal == true then -- Toggles friendly-AI for the intro of Half-Life 2
|
||||
//newEnt.DisableWandering = true
|
||||
newEnt.DisableFindEnemy = true
|
||||
newEnt.DisableMakingSelfEnemyToNPCs = true
|
||||
newEnt.FriendsWithAllPlayerAllies = true
|
||||
newEnt.FollowPlayer = false
|
||||
newEnt.Behavior = VJ_BEHAVIOR_PASSIVE
|
||||
newEnt.VJ_AutoScript_OldClass = newEnt.VJ_NPC_Class
|
||||
newEnt.VJ_NPC_Class = {"CLASS_PLAYER_ALLY", "CLASS_COMBINE"}
|
||||
newEnt.VJ_AutoScript_Reset = true
|
||||
end
|
||||
-- Things to run after it's fully spawned (EX: Turret sight distance)
|
||||
if afterSpawned[rEnt] then
|
||||
afterSpawned[rEnt](ent, newEnt)
|
||||
end
|
||||
-- Handle Essential NPCs
|
||||
if GetConVar("vj_hlr_autoreplace_essential"):GetInt() == 1 && essentialTbl[newClass] then
|
||||
newEnt.GodMode = true
|
||||
end
|
||||
-- FUN OPTION: Make them all allied together against players
|
||||
if GetConVar("vj_hlr_autoreplace_alliedagainstply"):GetInt() == 1 then
|
||||
newEnt.VJ_NPC_Class = {"CLASS_HALF_LIFE_AGAINST_PLAYERS"}
|
||||
end
|
||||
-- print(ent:GetClass(), ent:GetInternalVariable("GameEndAlly"))
|
||||
-- Set the starting animation AND velocity
|
||||
local vel = ent:GetVelocity()
|
||||
timer.Simple(0.01, function()
|
||||
if IsValid(newEnt) then
|
||||
//newEnt:VJ_ACT_PLAYACTIVITY(spawnAnim, true, false, false)
|
||||
if vel:Length() > 0 then
|
||||
newEnt:SetGroundEntity(NULL)
|
||||
newEnt:SetVelocity(vel)
|
||||
end
|
||||
end
|
||||
end)
|
||||
undo.ReplaceEntity(ent, newEnt)
|
||||
ent:Remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("Think", "VJ_HLR_AutoReplace_Think", function()
|
||||
-- Make sure the game is loaded
|
||||
if game && game.GetGlobalState then
|
||||
gStatePrecriminal = game.GetGlobalState("gordon_precriminal") == 1
|
||||
gStateAntlionFri = game.GetGlobalState("antlion_allied") == 1
|
||||
end
|
||||
for _,v in ipairs(ents.GetAll()) do
|
||||
if v:IsNPC() then
|
||||
if !gStatePrecriminal && v.VJ_AutoScript_Reset then
|
||||
v.VJ_NPC_Class = v.VJ_AutoScript_OldClass
|
||||
v.VJ_AutoScript_Reset = false
|
||||
end
|
||||
if gStateAntlionFri && v.VJ_HLR_Antlion then
|
||||
table.insert(v.VJ_NPC_Class,"CLASS_PLAYER_ALLY")
|
||||
v.PlayerFriendly = true
|
||||
v.FriendsWithAllPlayerAllies = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user