• My game mode is crashing when I make NPCs run, help?
    1 replies, posted
Hello, short introduction: I just signed up on these forums about 5 minutes ago and just started trying to script GMod about 2 days ago, so I'm a bit of a noob. I have been trying to make a custom game mode for me and my friend to play, and for the most part it works pretty well. There is only one problem though, one feature that is causing problems. The game mode is in the gm_bigcity map, and simply spawns a bunch of combine enemies with weapons all around the map continually (so as one dies, a new one spawns farther away), and the old ragdolls get cleaned up when players are far away and not looking at them. All that works great, but it's just one thing I added that messes up. See, a big part of my strategy when fighting enemies is simply using a sniper rifle (from an addon), so I did that, boom the enemy is dead... but then what? Nothing. All the NPCs around give little to no shit. To fix this, I made a feature using the OnNPCKilled callback which makes it so when one NPC dies, all the nearby NPCs will rush towards the position of the player that killed that NPC and also set them as an enemy. It works pretty well, well up until it fucking crashes the entire game. After a whole ton of experimentation, I find the issue! Sort of. By using to -condebug option, I find that this is always the last thing in the log whenever the game crashes. [I]"Bad SetLocalOrigin(1.#QNAN0,1.#QNAN0,1.#QNAN0) on npc_ak47"[/I]. It can actually be any weapon though, as I've tested it with all the weapons in the pack I got. So I think... it must be an issue with the weapons then, right? Not my fault? Well no, because it doesn't ever normally happen until I added that feature that makes the NPCs go after the killers. Also, it won't crash until I've shot and killed about 3 enemies. So... perhaps, I'm just setting the task on too many NPCs? I know it has to be related to this feature somehow because if you comment the function out, there won't be any crashes. Well, speaking of the task, I also notice that before it crashes if I wait, they'll run right past me! Now the best way I see of fixing this is by clearing their task schedule when they get near me, but it just seems like there might be a better way... better than using this debug run schedule. So maybe, there is a better way to make NPCs run? Maybe one of you kind souls can help me, I'll post my init.lua below (nothing in cl_init.lua), and I'll also post the addons it uses incase any of you are really kind enough to actually test it to get it working. Note I use the term "Ped" to refer to "NPC" simply because of my history with modding other games that refer to NPCs as Peds (short for pedestrian). The function that makes the nearby NPCs go towards the killers starts on line 201. Addons used: [url]http://steamcommunity.com/sharedfiles/filedetails/?id=180507408[/url] [url]http://steamcommunity.com/sharedfiles/filedetails/?id=181656972[/url] [url]http://steamcommunity.com/sharedfiles/filedetails/?id=231718148[/url] [CODE]-- Setup tables: gPlayerWeapons = {"fas2_ak47","fas2_m4a1","fas2_m82"} gNpcWeapons = {"NPC_AK47","NPC_FAL","NPC_Mossberg590","NPC_M1911","NPC_UMP45","NPC_MP5","NPC_P90","NPC_M249","NPC_HK416"} gNpcTypes = {"npc_combine_s","npc_metropolice"} -- Get counts: gPlayerWeapons.n = table.getn(gPlayerWeapons) gNpcWeapons.n = table.getn(gNpcWeapons) gNpcTypes.n = table.getn(gNpcTypes) -- Setup spawns: gSpawns = { { {950,-3444,-11135}, {946,-847,-11135}, {-1079,-832,-11135}, {-1074,-3424,-11135}, }, { {-5199,3369,-10671}, {-5186,3826,-10671}, {11871,3859,-10671}, {11577,3403,-10671}, }, { {12149,6619,-10671}, {12155,4458,-10671}, {12522,4327,-10671}, {12532,6508,-10671}, }, { {10103,6263,-11143}, {10119,5957,-11143}, {-1301,5983,-11143}, {-1402,6281,-11143}, }, { {4464,6433,-11135}, {5369,6433,-11135}, {5357,12798,-11135}, {4780,12802,-11135}, }, { {5461,4217,-11400}, {5368,5022,-11392}, {9862,5035,-11387}, {9831,4161,-11381}, }, { {7462,3973,-11407}, {8242,3968,-11407}, {8251,-1888,-11407}, {7455,-1920,-11407}, }, { {7389,-2350,-11407}, {8261,-2360,-11407}, {8297,-8733,-11407}, {7350,-8862,-11407}, }, { {5930,-5767,-11135}, {5999,-6126,-11143}, {-3699,-6123,-11143}, {-3705,-5805,-11143}, }, { {-3926,-3760,-11143}, {-4298,-3691,-11143}, {-4307,-10496,-11135}, {-3895,-10554,-11135}, }, { {425,1327,-11135}, {470,487,-11135}, {-3134,505,-11135}, {-3166,1289,-11135}, }, { {1427,-2420,-11143}, {1410,-2005,-11135}, {3638,-2026,-11135}, {3673,-2471,-11135}, }, } for i,c in ipairs(gSpawns) do local minx,maxx,miny,maxy,z for i,v in ipairs(c) do if not minx or v[1] < minx then minx = v[1] end if not maxx or v[1] > maxx then maxx = v[1] end if not miny or v[2] < miny then miny = v[2] end if not maxy or v[2] > maxy then maxy = v[2] end if not z or v[3] > z then z = v[3] end end c[1],c[2],c[3],c[4],c[5] = minx,maxx,miny,maxy,z end gSpawns.n = table.getn(gSpawns) -- Setup models: gPlayerModels = {} for k,m in pairs(player_manager.AllValidModels()) do util.PrecacheModel(m) table.insert(gPlayerModels,m) end gPlayerModels.n = table.getn(gPlayerModels) -- Player spawn: function GM:PlayerSpawn(player) -- Set position: player:SetPos(Vector(math.random(11832,12595),math.random(-3523,-2976),-11136)) player:SetEyeAngles(Angle(1.14,-166.11,0)) -- Give weapons: for i,w in ipairs(gPlayerWeapons) do F_GiveWeapon(player,w,3) end -- Set model: player:SetModel(gPlayerModels[math.random(1,gPlayerModels.n)]) end -- Main: function GM:Tick() if gStarted then -- Get players: gPlayers = player.GetHumans() -- Spawn/clean: if gPeds.n < 180 then F_Spawn() end if gDeadPeds.n > 20 then F_Clean() end end end -- Spawn enemies: gPeds = {n = 0} function F_Spawn() local loc = gSpawns[math.random(1,gSpawns.n)] local spawn = Vector(math.random(loc[1],loc[2]),math.random(loc[3],loc[4]),loc[5]) local canSpawn = true for i,player in ipairs(gPlayers) do if spawn:Distance(player:GetPos()) < 6000 or player:VisibleVec(spawn) then canSpawn = false break end end if canSpawn then local model = gNpcTypes[math.random(1,gNpcTypes.n)] local ped = ents.Create(model) if IsValid(ped) then ped:SetPos(spawn) ped:Spawn() ped:Give(gNpcWeapons[math.random(1,gNpcWeapons.n)]) table.insert(gPeds,ped) gPeds.n = gPeds.n + 1 end end end -- Clean dead enemies: gDeadPeds = {n = 0} hook.Add("OnEntityCreated","F_AddPeds",function(ped) if IsValid(ped) and ped:GetClass() == "prop_ragdoll" then table.insert(gDeadPeds,ped) gDeadPeds.n = gDeadPeds.n + 1 end end) function F_Clean() for i,ped in ipairs(gDeadPeds) do if IsValid(ped) then local pos,notVisible = ped:GetPos(),true for i,player in ipairs(gPlayers) do if pos:Distance(player:GetPos()) < 4000 or player:Visible(ped) then notVisible = false break end end if notVisible then ped:Remove() table.remove(gDeadPeds,i) gDeadPeds.n = gDeadPeds.n - 1 break end end end end -- Alert nearby peds when one dies: function GM:OnNPCKilled(victim,killer) if IsValid(victim) and IsValid(killer) and (killer:IsPlayer() or killer:IsNPC()) then local pos1,pos2 = victim:GetPos(),killer:GetPos() if pos1:Distance(pos2) > 1500 then for i,ped in ipairs(gPeds) do if ped == victim then table.remove(gPeds,i) gPeds.n = gPeds.n - 1 i = i - 1 elseif ped ~= killer and IsValid(ped) and ped:IsNPC() and pos1:Distance(ped:GetPos()) < 1500 then local enemy = ped:GetEnemy() if not IsValid(enemy) or ped:GetPos():Distance(enemy:GetPos()) > 2000 then -- not already near an enemy ped:ClearSchedule() ped:SetEnemy(killer) ped:SetLastPosition(pos2) ped:SetSchedule(SCHED_FORCED_GO_RUN) end end end end end end -- Wait for entities to initialize: function GM:Ini
Would you guys hate me for bumping this? Any ideas...? Please? I just wanna know why it's crashing or if there's a better way to make NPCs run.
Sorry, you need to Log In to post a reply to this thread.