Aquaterion Posted January 8, 2015 Share Posted January 8, 2015 (edited) Problem with Followers. I'm trying to implement the Damaged Chess Followers into the game, and when one spawns, it works finebut when I spawn a second one, the first one crashes the game with the following error: Note: Knight was the First follower, Bishop was the second follower. Error: [string "scripts/prefabs/knight.lua"]:75: variable 'myleader' is not declared LUA ERROR stack traceback: =[C]:-1 in (global) error (C) <-1--1> scripts/strict.lua:23 in () ? (Lua) <21-26> t = table: 0D252968 n = myleader scripts/prefabs/knight.lua:75 in (local) fn (Lua) <72-81> guy = 116929 - bishop_nightmare (valid:true) myLeader = 115771 - wilson (valid:true) theirLeader = 115771 - wilson (valid:true) scripts/simutil.lua:40 in (global) FindEntity (Lua) <33-45> inst = 116730 - knight_nightmare (valid:true) radius = 10 fn = function - scripts/prefabs/knight.lua:72 musttags = nil canttags = nil mustoneoftags = nil x = 394.32562255859 y = -1.8167193971408e-008 z = -107.9944152832 ents = table: 2D3B8EA0 k = 14 v = 116929 - bishop_nightmare (valid:true) scripts/prefabs/knight.lua:72 in (field) targetfn (Lua) <63-83> inst = 116730 - knight_nightmare (valid:true) homePos = (454.33, 0.00, -197.60) myPos = (394.33, -0.00, -107.99) scripts/components/combat.lua:154 in (method) TryRetarget (Lua) <149-164> self = hiteffectsymbol = spring defaultdamage = 40 keeptargetfn = function - scripts/prefabs/knight.lua:85 inst = 116730 - knight_nightmare (valid:true) retargetperiod = 3 hitrange = 3 keeptargettimeout = 0.73333331942558 lasttargetGUID = 116561 pvp_damagemod = 1 lastdoattacktime = 166.20000866801 laststartattacktime = 165.63334197178 retargettask = PERIODIC 116730: 3.000000 nextbattlecrytime = 175.01722322884 lastattacker = 116832 - hound (valid:false) losetargetcallback = function - scripts/components/combat.lua:235 targetfn = function - scripts/prefabs/knight.lua:63 _ = table: 2D102788 playerdamagepercent = 1 scripts/components/combat.lua:146 in (field) fn (Lua) <145-147> inst = 116730 - knight_nightmare (valid:true) scripts/scheduler.lua:170 in (method) OnTick (Lua) <144-199> self = running = table: 12FAF768 waitingfortick = table: 12FAF740 tasks = table: 12FAF6F0 waking = table: 2D3B7CF8 attime = table: 12FAF830 hibernating = table: 12FAF808 tick = 5336 k = PERIODIC 116730: 3.000000 v = true already_dead = nil scripts/scheduler.lua:380 in (global) RunScheduler (Lua) <378-386> tick = 5336 scripts/update.lua:134 in () ? (Lua) <118-180> dt = 0.033333335071802 tick = 5336 i = 5336 Knight Code as found in the game: local assets = { Asset("ANIM", "anim/knight.zip"), Asset("ANIM", "anim/knight_build.zip"), Asset("ANIM", "anim/knight_nightmare.zip"), Asset("SOUND", "sound/chess.fsb"), } local prefabs = { "gears", "thulecite_pieces", "nightmarefuel", } local brain = require "brains/knightbrain" SetSharedLootTable( 'knight', { {'gears', 1.0}, {'gears', 1.0}, }) SetSharedLootTable( 'knight_nightmare', { {'gears', 1.0}, {'nightmarefuel', 0.6}, {'thulecite_pieces', 0.5}, }) local SLEEP_DIST_FROMHOME = 1 local SLEEP_DIST_FROMTHREAT = 20 local MAX_CHASEAWAY_DIST = 40 local MAX_TARGET_SHARES = 5 local SHARE_TARGET_DIST = 40 local function ShouldSleep(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if not (homePos and distsq(homePos, myPos) <= SLEEP_DIST_FROMHOME*SLEEP_DIST_FROMHOME) or (inst.components.combat and inst.components.combat.target) or (inst.components.burnable and inst.components.burnable:IsBurning() ) or (inst.components.freezable and inst.components.freezable:IsFrozen() ) then return false end local nearestEnt = GetClosestInstWithTag("character", inst, SLEEP_DIST_FROMTHREAT) return nearestEnt == nil end local function ShouldWake(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if (homePos and distsq(homePos, myPos) > SLEEP_DIST_FROMHOME*SLEEP_DIST_FROMHOME) or (inst.components.combat and inst.components.combat.target) or (inst.components.burnable and inst.components.burnable:IsBurning() ) or (inst.components.freezable and inst.components.freezable:IsFrozen() ) then return true end local nearestEnt = GetClosestInstWithTag("character", inst, SLEEP_DIST_FROMTHREAT) return nearestEnt end local function Retarget(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if (homePos and distsq(homePos, myPos) > TUNING.KNIGHT_TARGET_DIST*TUNING.KNIGHT_TARGET_DIST) and not (inst.components.follower and inst.components.follower.leader) then return end local newtarget = FindEntity(inst, TUNING.KNIGHT_TARGET_DIST, function(guy) local myLeader = inst.components.follower and inst.components.follower.leader local theirLeader = guy.components.follower and guy.components.follower.leader local bothFollowingSamePlayer = myLeader and (myLeader == theirLeader) and myleader:HasTag("player") return (guy:HasTag("character") or guy:HasTag("monster") ) and not (guy:HasTag("chess") and (guy.components.follower and not guy.components.follower.leader)) and not bothFollowingSamePlayer and not (inst.components.follower and inst.components.follower.leader == guy) and inst.components.combat:CanTarget(guy) end) return newtarget end local function KeepTarget(inst, target) if (inst.components.follower and inst.components.follower.leader) then return true end local homePos = inst.components.knownlocations:GetLocation("home") local targetPos = Vector3(target.Transform:GetWorldPosition() ) return homePos and distsq(homePos, targetPos) < MAX_CHASEAWAY_DIST*MAX_CHASEAWAY_DIST end local function OnAttacked(inst, data) local attacker = data and data.attacker if attacker and attacker:HasTag("chess") then return end inst.components.combat:SetTarget(attacker) inst.components.combat:ShareTarget(attacker, SHARE_TARGET_DIST, function(dude) return dude:HasTag("chess") end, MAX_TARGET_SHARES) end local function RememberKnownLocation(inst) inst.components.knownlocations:RememberLocation("home", Vector3(inst.Transform:GetWorldPosition())) end local function fn_common(build) local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.entity:AddNetwork() MakeCharacterPhysics(inst, 50, .5) inst.DynamicShadow:SetSize(1.5, .75) inst.Transform:SetFourFaced() inst.AnimState:SetBank("knight") inst.AnimState:SetBuild(build) inst:AddTag("monster") inst:AddTag("hostile") inst:AddTag("chess") inst:AddTag("knight") if not TheWorld.ismastersim then return inst end inst.entity:SetPristine() inst.kind = "" inst:AddComponent("locomotor") inst.components.locomotor.walkspeed = TUNING.KNIGHT_WALK_SPEED inst:SetStateGraph("SGknight") inst:SetBrain(brain) inst:AddComponent("sleeper") inst.components.sleeper:SetWakeTest(ShouldWake) inst.components.sleeper:SetSleepTest(ShouldSleep) inst.components.sleeper:SetResistance(3) inst:AddComponent("health") inst:AddComponent("combat") inst.components.combat.hiteffectsymbol = "spring" inst.components.combat:SetAttackPeriod(TUNING.KNIGHT_ATTACK_PERIOD) inst.components.combat:SetRetargetFunction(3, Retarget) inst.components.combat:SetKeepTargetFunction(KeepTarget) inst.components.health:SetMaxHealth(TUNING.KNIGHT_HEALTH) inst.components.combat:SetDefaultDamage(TUNING.KNIGHT_DAMAGE) inst.components.combat:SetAttackPeriod(TUNING.KNIGHT_ATTACK_PERIOD) inst:AddComponent("lootdropper") inst.components.lootdropper:SetChanceLootTable('knight') inst:AddComponent("inspectable") inst:AddComponent("knownlocations") inst:DoTaskInTime(1*FRAMES, RememberKnownLocation) inst:AddComponent("follower") MakeMediumBurnableCharacter(inst, "spring") MakeMediumFreezableCharacter(inst, "spring") MakeHauntablePanic(inst) inst:ListenForEvent("attacked", OnAttacked) return inst end local function fn() local inst = fn_common("knight_build") if not TheWorld.ismastersim then return inst end inst.kind = "" return inst end local function nightmarefn() local inst = fn_common("knight_nightmare") if not TheWorld.ismastersim then return inst end inst.kind = "_nightmare" inst.components.lootdropper:SetChanceLootTable("knight_nightmare") return inst end return Prefab("chessboard/knight", fn, assets, prefabs), Prefab("cave/monsters/knight_nightmare", nightmarefn, assets, prefabs) Bishop Code as found in the game: local assets = { Asset("ANIM", "anim/bishop.zip"), Asset("ANIM", "anim/bishop_build.zip"), Asset("ANIM", "anim/bishop_nightmare.zip"), Asset("SOUND", "sound/chess.fsb"), } local prefabs = { "gears", "bishop_charge", "purplegem", } local brain = require "brains/bishopbrain" SetSharedLootTable( 'bishop', { {'gears', 1.0}, {'gears', 1.0}, {'purplegem', 1.0}, }) SetSharedLootTable( 'bishop_nightmare', { {'purplegem', 1.0}, {'nightmarefuel', 0.6}, {'thulecite_pieces', 0.5}, }) local SLEEP_DIST_FROMHOME = 1 local SLEEP_DIST_FROMTHREAT = 20 local MAX_CHASEAWAY_DIST = 40 local MAX_TARGET_SHARES = 5 local SHARE_TARGET_DIST = 40 local function ShouldSleep(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if not (homePos and distsq(homePos, myPos) <= SLEEP_DIST_FROMHOME*SLEEP_DIST_FROMHOME) or (inst.components.combat and inst.components.combat.target) or (inst.components.burnable and inst.components.burnable:IsBurning() ) or (inst.components.freezable and inst.components.freezable:IsFrozen() ) then return false end local nearestEnt = GetClosestInstWithTag("character", inst, SLEEP_DIST_FROMTHREAT) return nearestEnt == nil end local function ShouldWake(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if (homePos and distsq(homePos, myPos) > SLEEP_DIST_FROMHOME*SLEEP_DIST_FROMHOME) or (inst.components.combat and inst.components.combat.target) or (inst.components.burnable and inst.components.burnable:IsBurning() ) or (inst.components.freezable and inst.components.freezable:IsFrozen() ) then return true end local nearestEnt = GetClosestInstWithTag("character", inst, SLEEP_DIST_FROMTHREAT) return nearestEnt end local function Retarget(inst) local homePos = inst.components.knownlocations:GetLocation("home") local myPos = Vector3(inst.Transform:GetWorldPosition() ) if (homePos and distsq(homePos, myPos) > TUNING.BISHOP_TARGET_DIST*TUNING.BISHOP_TARGET_DIST) and not (inst.components.follower and inst.components.follower.leader) then return end local newtarget = FindEntity(inst, TUNING.BISHOP_TARGET_DIST, function(guy) local myLeader = inst.components.follower and inst.components.follower.leader local theirLeader = guy.components.follower and guy.components.follower.leader local bothFollowingSamePlayer = myLeader and (myLeader == theirLeader) and myleader:HasTag("player") return (guy:HasTag("character") or guy:HasTag("monster") ) and not (inst.components.follower and inst.components.follower.leader == guy) and not bothFollowingSamePlayer and not (guy:HasTag("chess") and (guy.components.follower and not guy.components.follower.leader)) and inst.components.combat:CanTarget(guy) end) return newtarget end local function KeepTarget(inst, target) if (inst.components.follower and inst.components.follower.leader) then return true end local homePos = inst.components.knownlocations:GetLocation("home") local targetPos = Vector3(target.Transform:GetWorldPosition() ) return homePos and distsq(homePos, targetPos) < MAX_CHASEAWAY_DIST*MAX_CHASEAWAY_DIST end local function ShareTargetFn(dude) return dude:HasTag("chess") end local function OnAttacked(inst, data) local attacker = data and data.attacker if attacker and attacker:HasTag("chess") then return end inst.components.combat:SetTarget(attacker) inst.components.combat:ShareTarget(attacker, SHARE_TARGET_DIST, ShareTargetFn, MAX_TARGET_SHARES) end local function EquipWeapon(inst) if inst.components.inventory and not inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then local weapon = CreateEntity() --[[Non-networked entity]] weapon.entity:AddTransform() weapon:AddComponent("weapon") weapon.components.weapon:SetDamage(inst.components.combat.defaultdamage) weapon.components.weapon:SetRange(inst.components.combat.attackrange, inst.components.combat.attackrange+4) weapon.components.weapon:SetProjectile("bishop_charge") weapon:AddComponent("inventoryitem") weapon.persists = false weapon.components.inventoryitem:SetOnDroppedFn(inst.Remove) weapon:AddComponent("equippable") inst.components.inventory:Equip(weapon) end end local function RememberKnownLocation(inst) inst.components.knownlocations:RememberLocation("home", Vector3(inst.Transform:GetWorldPosition())) end local function common_fn(build) local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.entity:AddNetwork() MakeCharacterPhysics(inst, 50, .5) inst.DynamicShadow:SetSize(1.5, .75) inst.Transform:SetFourFaced() inst.AnimState:SetBank("bishop") inst.AnimState:SetBuild(build) inst:AddTag("monster") inst:AddTag("hostile") inst:AddTag("chess") inst:AddTag("bishop") if not TheWorld.ismastersim then return inst end inst.entity:SetPristine() inst:AddComponent("lootdropper") inst:AddComponent("locomotor") inst.components.locomotor.walkspeed = TUNING.BISHOP_WALK_SPEED inst:SetStateGraph("SGbishop") inst:SetBrain(brain) inst:AddComponent("sleeper") inst.components.sleeper:SetWakeTest(ShouldWake) inst.components.sleeper:SetSleepTest(ShouldSleep) inst.components.sleeper:SetResistance(3) inst:AddComponent("combat") inst.components.combat.hiteffectsymbol = "waist" inst.components.combat:SetAttackPeriod(TUNING.BISHOP_ATTACK_PERIOD) inst.components.combat:SetRange(TUNING.BISHOP_ATTACK_DIST) inst.components.combat:SetRetargetFunction(3, Retarget) inst.components.combat:SetKeepTargetFunction(KeepTarget) inst:AddComponent("health") inst.components.health:SetMaxHealth(TUNING.BISHOP_HEALTH) inst.components.combat:SetDefaultDamage(TUNING.BISHOP_DAMAGE) inst.components.combat:SetAttackPeriod(TUNING.BISHOP_ATTACK_PERIOD) inst:AddComponent("inventory") inst:AddComponent("inspectable") inst:AddComponent("knownlocations") inst:DoTaskInTime(1*FRAMES, RememberKnownLocation) inst:DoTaskInTime(1, EquipWeapon) inst:AddComponent("follower") MakeMediumBurnableCharacter(inst, "waist") MakeMediumFreezableCharacter(inst, "waist") MakeHauntablePanic(inst) inst:ListenForEvent("attacked", OnAttacked) return inst end local function bishop_fn() local inst = common_fn("bishop_build") if not TheWorld.ismastersim then return inst end inst.components.lootdropper:SetChanceLootTable('bishop') inst.kind = "" inst.soundpath = "dontstarve/creatures/bishop/" inst.effortsound = "dontstarve/creatures/bishop/idle" return inst end local function bishop_nightmare_fn() local inst = common_fn("bishop_nightmare") if not TheWorld.ismastersim then return inst end inst.components.lootdropper:SetChanceLootTable('bishop_nightmare') inst.kind = "_nightmare" inst.soundpath = "dontstarve/creatures/bishop_nightmare/" inst.effortsound = "dontstarve/creatures/bishop_nightmare/rattle" return inst end return Prefab("chessboard/bishop", bishop_fn, assets, prefabs), Prefab("cave/monsters/bishop_nightmare", bishop_nightmare_fn, assets, prefabs) Any help would be appreciated. Edited January 8, 2015 by Aquaterion Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/ Share on other sites More sharing options...
Sarcen Posted January 8, 2015 Share Posted January 8, 2015 The bug is just a typo klei madelocal bothFollowingSamePlayer = myLeader and (myLeader == theirLeader) and myleader:HasTag("player")the last myleader has a lower case L. Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/#findComment-598711 Share on other sites More sharing options...
Aquaterion Posted January 8, 2015 Author Share Posted January 8, 2015 The bug is just a typo klei madelocal bothFollowingSamePlayer = myLeader and (myLeader == theirLeader) and myleader:HasTag("player")the last myleader has a lower case L. Ah thanks, Silly Klei for that typo, and silly me for not checking well. Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/#findComment-598856 Share on other sites More sharing options...
Developer SethR Posted January 8, 2015 Developer Share Posted January 8, 2015 Fixed it up locally. Sorry about that! Will be out in the next patch, most likely. Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/#findComment-598947 Share on other sites More sharing options...
Aquaterion Posted January 8, 2015 Author Share Posted January 8, 2015 Fixed it up locally. Sorry about that! Will be out in the next patch, most likely.Ah Awesome, Just maybe if u wanna fix it too, chessjunk.lua had some problems with "end"s if I remember, it had 2 extra ones. Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/#findComment-598981 Share on other sites More sharing options...
Developer SethR Posted January 8, 2015 Developer Share Posted January 8, 2015 Ah Awesome, Just maybe if u wanna fix it too, chessjunk.lua had some problems with "end"s if I remember, it had 2 extra ones. Chessjunk is a caves thing and we haven't gotten to updating it quite yet. In time! (I will keep this in mind as something to watch out for when we do get there) Link to comment https://forums.kleientertainment.com/forums/topic/48697-multiple-followers-crash/#findComment-598985 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now