luciano14443 Posted August 6, 2022 Share Posted August 6, 2022 what do i do to change the turkey for wendy local Vector3 = GLOBAL.Vector3 local dlcEnabled = GLOBAL.IsDLCEnabled(GLOBAL.REIGN_OF_GIANTS) local SEASONS = GLOBAL.SEASONS --[[ Table is as follows: enabled: is this a valid prefab to use (DLC restrictions or config file) prefab: prefab name brain: brain name. If a mob has this defined, will add a new PriorityNode to the brain to attack player. (leave this out if don't want to override brain function at all) RoG: Is this a Reign of Giants only mob? (Toggles enabled if DLC is not enabled). If not added, assumed to be false. CaveState: "open", "used", nil - This mob will only spawn when the cavestate condition is met. If not defined, ignore Season: restricts the season(s) this can come. If not defined...can come any season. mobMult: multiplier compared to normal hound values (how many to release) timeMult: how fast these come out compared to normal hounds. 0.5 is twice as fast. 2 is half speed. damageMult: how much damage it does compared to normal mob healthMult: how much health it has compared to its normal self dropMult: Modify the odds to drop something. This reduces every item in the drop table by this percent. --]] local MOB_LIST = { [1] = {enabled=true,prefab="hound",timeMult=1}, [2] = {enabled=true,prefab="merm",brain="mermbrain",mobMult=.75,timeMult=1.2}, [3] = {enabled=true,prefab="tallbird",brain="tallbirdbrain",mobMult=.75,timeMult=1.2}, [4] = {enabled=true,prefab="pigman",brain="pigbrain",timeMult=1}, [5] = {enabled=true,prefab="spider",brain="spiderbrain",mobMult=1.7,timeMult=.5}, [6] = {enabled=true,prefab="killerbee",brain="killerbeebrain",mobMult=2.2,maxMob=15,timeMult=.25,dropMult=.8}, [7] = {enabled=true,prefab="mosquito",brain="mosquitobrain",mobMult=2.75,maxMob=18,timeMult=.13,damageMult=2.2,dropMult=.5}, [8] = {enabled=true,prefab="lightninggoat",brain="lightninggoatbrain",RoG=true,mobMult=.75,timeMult=1.25}, [9] = {enabled=true,prefab="beefalo",brain="beefalobrain",mobMult=.75,timeMult=1.5}, [10] = {enabled=false,prefab="bat",brain="batbrain",CaveState="open",timeMult=1}, -- TODO: Bats crash game when attacked by other things. [11] = {enabled=false,prefab="rook",brain="rookbrain",timeMult=1}, -- These dudes don't work too well (mostly works, but they get lost) [12] = {enabled=true,prefab="knight",brain="knightbrain",timeMult=1.5,dropMult=.4}, -- Only drop half of the time [13] = {enabled=false,prefab="mossling",brain="mosslingbrain",RoG=true,Season={SEASONS.SPRING},timeMult=1}, -- Needs work. They wont get enraged. Also spawns moosegoose....so yeah [14] = {enabled=true,prefab="perd",brain="perdbrain",mobMult=2.5,maxMob=15,timeMult=.25,dropMult=.4}, [15] = {enabled=true,prefab="penguin",brain="penguinbrain",Season={SEASONS.WINTER},mobMult=2.5,maxMob=15,timeMult=.35,damageMult=.5}, [16] = {enabled=true,prefab="walrus",brain="walrusbrain",Season={SEASONS.WINTER},mobMult=.33, timeMult=3} } -- Lookup the table index by prefab name. Returns nil if not found local function getIndexByName(name) for k,v in pairs(MOB_LIST) do if v.prefab == name then return k end end end -- Check the config file and the DLC to disable some of the mobs local function disableMobs() for k,v in pairs(MOB_LIST) do if not dlcEnabled and v.RoG then print("Disabling RoG mob: " .. v.prefab) MOB_LIST[k].enabled = false end -- Get the config data for it local enabled = GetModConfigData(v.prefab) if enabled ~= nil and enabled == "off" then print("Disabling " .. v.prefab .. " due to config setting") MOB_LIST[k].enabled = false end end end disableMobs() --[[ ----------------------------------------------------- Update strings for warnings. TODO: Add updates for all characters --]] ----------------------------------------------------- STRINGS = GLOBAL.STRINGS local defaultPhrase = STRINGS.CHARACTERS.GENERIC.ANNOUNCE_HOUNDS STRINGS.CHARACTERS.GENERIC.ANNOUNCE_HOUNDS = "WTF WAS THAT!!" local warningCount = 1 -- Dumb function to get a dumb string for a dumb idea :P local function getDumbString(num) if num == 1 then return "ONE!" elseif num == 2 then return "TWO!" elseif num == 3 then return "THREE!" elseif num == 4 then return "FOUR!" else return "TOO MANY!" end end -- This is called after each verbal warning. If new strings are wanted, -- just check the warningCount. local function updateWarningString(index) if GLOBAL.GetPlayer() == nil then return end character = string.upper(GLOBAL.GetPlayer().prefab) if character == nil or character == "WILSON" then character = "GENERIC" end -- Wes doesn't have this defined. Other mod characters may not either. if STRINGS.CHARACTERS[character] == nil then return end prefab = MOB_LIST[index].prefab if prefab == nil then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = defaultPhrase elseif prefab == "merm" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Oh god, it smells like rotting fish." elseif prefab == "spider" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Sounds like a million tiny legs." elseif prefab == "tallbird" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Sounds like a murder...of tall birds." elseif prefab == "pigman" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Was that an oink?" elseif prefab == "killerbee" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Beeeeeeeeeeeeeeeeees!" elseif prefab == "mosquito" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "I hear a million teeny tiny vampires." elseif prefab == "lightninggoat" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Those giant dark clouds look ominous." elseif prefab == "beefalo" then if warningCount == 1 then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Earthquake?!?" else STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Wait, no...STAMPEDE!!!" end elseif prefab == "bat" then -- TODO: Increment the count each warning lol STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = getDumbString(warningCount) .. " Ah ah ah!" elseif prefab == "knight" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "The cavalry are coming!" elseif prefab == "perd" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Gobbles!!!" elseif prefab == "penguin" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "Oh no...they think I took their eggs!" elseif prefab == "walrus" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = "The hunter becomes the hunted." else STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = defaultPhrase end if character == "WX78" then STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS = string.upper(STRINGS.CHARACTERS[character].ANNOUNCE_HOUNDS) end end --------------------------------------------------------------------- local function getRandomMob() -- Generate a shuffled list from 1 to #MOB_LIST local t={} for i=1,#MOB_LIST do t=i end for i = 1, #MOB_LIST do local j=math.random(i,#MOB_LIST) t,t[j]=t[j],t end -- Return the first one that is enabled for k,v in pairs(t) do local pickThisMob = true if MOB_LIST[v].enabled then -- Check the various conditions if MOB_LIST[v].CaveState ~= nil then caveOpen = GLOBAL.ProfileStatsGet("cave_entrance_opened") caveUsed = GLOBAL.ProfileStatsGet("cave_entrance_used") if MOB_LIST[v].CaveState == "open" and caveOpen ~= nil and caveOpen == true then pickThisMob = true elseif MOB_LIST[v].CaveState == "used" and caveUsed ~= nil and caveUsed == true then pickThisMob = true else print("Skipping " .. tostring(MOB_LIST[v].prefab) .. " as mob because cavestate not met") if caveOpen ~= nil then print("CaveOpen: " .. tostring(caveOpen)) end if caveUsed ~= nil then print("CaveUsed: " .. tostring(caveUsed)) end pickThisMob = false end end -- Check for season restrictions if MOB_LIST[v].Season ~= nil then for key,season in pairs(MOB_LIST[v].Season) do if GLOBAL.GetSeasonManager().current_season ~= season then pickThisMob = false else pickThisMob = true break end end if not pickThisMob then print("Skipping " .. tostring(MOB_LIST[v].prefab) .. " as mob because season not met") end end -- Don't do spiders if the player is a 'spiderwhisperer' (webber) -- Note, these spiders won't follow the spiderhat like normal ones. if MOB_LIST[v].prefab == "spider" then if GLOBAL.GetPlayer() and GLOBAL.GetPlayer():HasTag("spiderwhisperer") then print("Not picking spiders...the player is a spiderwhisperer!") pickThisMob = false end end -- If this is still true, return this selection if pickThisMob then return v end end end -- If we are here...there is NOTHING in the list enabled and valid. -- This is strange. Just return hound I guess (even though -- hound is in the list and the user disabled it...) print("WARNING: No possible mobs to select from! Using Hound as default") return 1 end local function transformThings(inst) local playPos = Vector3(GLOBAL.GetPlayer().Transform:GetWorldPosition()) local naughtyPigs = TheSim:FindEntities(playPos.x,playPos.y,playPos.z, 80, {"SpecialPigman"}) for k,v in pairs(naughtyPigs) do local pigPos = Vector3(v.Transform:GetWorldPosition()) -- Strike lightning on pig (make it not burnable first) v:RemoveComponent("burnable") GLOBAL.GetSeasonManager():DoLightningStrike(pigPos) v:DoTaskInTime(1, function(inst) inst:AddComponent("burnable") end) v:PushEvent("transform_special_pigs",{inst=v}) end end -- Transforms a mob to an ice/fire version. -- Copies the ice/fire hound ondeath and gives -- a special drop. -- Also changes the color. local function makeMobSpecial(theMob, specialStats) -- Increase damage and decrease health local health = theMob.components.health:GetMaxHealth() theMob.components.health:SetMaxHealth(health*.66) local damage = theMob.components.combat.defaultdamage theMob.components.combat:SetDefaultDamage(damage*1.35) -- Add onDeath triggers if specialStats == "ice" then theMob.AnimState:SetMultColour(.75,.75,1,1) theMob:ListenForEvent("death", function(inst) -- Base game freeze hounds didn't freeze anything...strange if dlcEnabled then if not inst.components.freezable then -- Eh...it won't be there long enough to show this. This is -- just to set up the FX. GLOBAL.MakeMediumFreezableCharacter(inst, "hound_body") end inst.components.freezable:SpawnShatterFX() inst:RemoveComponent("freezable") local x,y,z = inst.Transform:GetWorldPosition() local ents = GLOBAL.TheSim:FindEntities(x, y, z, 4, {"freezable"}, {"FX", "NOCLICK","DECOR","INLIMBO"}) for i,v in pairs(ents) do if v.components.freezable then v.components.freezable:AddColdness(2) end end end -- Also drop a gem! if math.random() < .3 then inst.components.lootdropper:SpawnLootPrefab("bluegem") end inst.SoundEmitter:PlaySound("dontstarve/creatures/hound/icehound_explo", "explosion") end) else theMob.AnimState:SetMultColour(1,.5,.5,1) theMob:ListenForEvent("death", function(inst) if math.random() < .3 then inst.components.lootdropper:SpawnLootPrefab("redgem") end -- Make some fire! for k=1,3 do inst.components.lootdropper:SpawnLootPrefab("houndfire") end inst.SoundEmitter:PlaySound("dontstarve/creatures/hound/firehound_explo", "explosion") end) end end local function releaseRandomMobs(self) self.quakeMachine = GLOBAL.CreateEntity() self.quakeMachine.persists = false self.quakeMachine.entity:AddSoundEmitter() self.quakeMachine.soundIntensity = 0.01 self.currentIndex = nil ------------------------------------------------------------- -- I guess we have to store these mobs that we can tag them onLoad self.currentMobs = {} self.numMobsSpawned = 0 self.PrintMobList = function(self) for k,v in pairs(self.currentMobs) do print(k,v) end end self.AddMob = function(self,mob) if self.currentMobs[mob] == nil and mob then self.currentMobs[mob] = true self.numMobsSpawned = self.numMobsSpawned + 1 -- Listen for death events on these dudes mob.deathfn = function() self:RemoveMob(mob) end -- If the mob leaves, remove it from the list self.inst:ListenForEvent("death", mob.deathfn,mob) self.inst:ListenForEvent("onremove", mob.deathfn, mob ) --------------------------------------------------------------------------------- --Add All of the stuff for this mob here so we can persist on save states---- -- I've modified the mobs brains to be mindless killers with this tag mob:AddTag("houndedKiller") mob:AddTag("hostile") -- seems natural to set this -- This mob has no home anymore. It's set to kill. if mob.components.homeseeker then mob:RemoveComponent("homeseeker") end -- Just to be sure... if mob.components.knownlocations then mob.components.knownlocations:ForgetLocation("home") end -- Can't remove 'sleeper' tag as it causes the entity to throw errors. Just -- override the ShouldSleep functions if mob.components.sleeper ~= nil then local sleepFcn = function(self,inst) --[[ Just keep suggesting this mob attacks the player. These are merciless killers after all. "Should I sleep?" "NO! Attack that guy!" ... "Should I sleep?" "NO! Attack that guy!" --]] -- TODO: Seeing what happens when this is gone. mob.components.combat:SuggestTarget(GLOBAL.GetPlayer()) return false end local wakeFcn = function(self,inst) return true end mob.components.sleeper:SetSleepTest(sleepFcn) mob.components.sleeper:SetWakeTest(wakeFcn) end -- Pigs might transform! Hmm, beardbunny dudes are werebeasts too if mob.components.werebeast ~= nil then mob:AddTag("SpecialPigman") end -- Override the default KeepTarget for this mob. -- Basically, if it's currently targeting the player, continue to. -- If not, let it do whatever it's doing for now until it loses interest -- and comes back for the player. local origCanTarget = mob.components.combat.keeptargetfn local function keepTargetOverride(inst, target) -- TODO: Testing this if true then return inst.components.combat:CanTarget(target) end -- This wont get hit. Was original code. TODO : if above is better, remove this. if target:HasTag("player") and inst.components.combat:CanTarget(target) then return true else return origCanTarget and origCanTarget(inst,target) end end mob.components.combat:SetKeepTargetFunction(keepTargetOverride) -- Let's try this out. Give the players a chance. Basically, the mobs will look for something -- else to attack every once in a while... local function retargetfn(inst) thing = GLOBAL.FindEntity(inst, 20, function(guy) return not guy:HasTag("wall") and not guy:HasTag("houndedKiller") and inst.components.combat:CanTarget(guy) end) if thing then return thing end end -- TODO: Get this to work --if not mob.components.teamattacker then -- mob.components.combat:SetRetargetFunction(3, retargetfn) --end -- Set the min attack period to something...higher local currentAttackPeriod = mob.components.combat.min_attack_period mob.components.combat:SetAttackPeriod(math.max(currentAttackPeriod,3)) mob.components.combat:SuggestTarget(GLOBAL.GetPlayer()) -- Tweak the damage output of this mob based on the table local index = getIndexByName(mob.prefab) if index and MOB_LIST[index].damageMult then local mult = MOB_LIST[index].damageMult mob.components.combat:SetDefaultDamage(mult*mob.components.combat.defaultdamage) end -- Tweak the health of this mob based on the table if index and MOB_LIST[index].healthMult then local mult = MOB_LIST[index].healthMult mob.components.health:SetMaxHealth(mult*mob.components.health.maxhealth) end -- Tweak the drop rates for the mobs if index and MOB_LIST[index].dropMult then local mult = MOB_LIST[index].dropMult if mob.components.lootdropper.loot then local current_loot = mob.components.lootdropper.loot mob.components.lootdropper:SetLoot(nil) -- Create a loot_table from this (chance would be 1) for k,v in pairs(current_loot) do mob.components.lootdropper:AddChanceLoot(v,mult) end elseif mob.components.lootdropper.chanceloottable then local loot_table = GLOBAL.LootTables[mob.components.lootdropper.chanceloottable] if loot_table then mob.components.lootdropper:SetChanceLootTable(nil) for i,entry in pairs(loot_table) do local prefab = entry[1] local chance = entry[2]*mult mob.components.lootdropper:AddChanceLoot(prefab,chance) end end end end ------------------------------------------------------------------------------ end end -- end AddMob fcn self.RemoveMob = function(self,mob) if mob and self.currentMobs[mob] then self.currentMobs[mob] = nil self.numMobsSpawned = self.numMobsSpawned - 1 end end ----------------------------------------------------------------- -- Create some quake effects local function stampedeShake(self, duration, speed, scale) -- type,duration,speed,scale,maxdist GLOBAL.TheCamera:Shake("FULL", duration, speed, scale, 80) -- Increase the intensity for the next call (only start the sound once) if not self.quakeStarted then self.SoundEmitter:PlaySound("dontstarve/cave/earthquake", "earthquake") self.quakeStarted = true end self.SoundEmitter:SetParameter("earthquake", "intensity", self.soundIntensity) end self.quakeMachine.WarnQuake = stampedeShake local function endStampedeShake(self) self.quakeStarted = false self.SoundEmitter:KillSound("earthquake") self.soundIntensity = 0.01 end self.quakeMachine.EndQuake = endStampedeShake local function makeLouder(self) self.soundIntensity = self.soundIntensity + .04 self.SoundEmitter:SetParameter("earthquake","intensity",self.soundIntensity) end self.quakeMachine.MakeStampedeLouder = makeLouder self.quakeStarted = false local function ReleasePrefab(dt) local pt = Vector3(GLOBAL.GetPlayer().Transform:GetWorldPosition()) local spawn_pt = self:GetSpawnPoint(pt) if self.currentIndex == nil then -- Next wave hasn't been planned prefab,index = getRandomMob() else prefab = MOB_LIST[self.currentIndex].prefab end --print("HERE COMES A " .. prefab) if spawn_pt then -- TODO: Add a counter to the different mob types to modify how many come self.houndstorelease = self.houndstorelease - 1 -- Because I keep spawning them in the console... if self.houndstorelease <= 0 then self.houndstorelease = 0 end -- Increase chances of special mobs later on local specialMobChance = self.debugSpawn and 1 or self:GetSpecialHoundChance() -- If spiders...give a chance at warrior spiders if prefab == "spider" and math.random() < specialMobChance then prefab = "spider_warrior" end -- Make fire/ice versions of all hounds! local specialStats = nil -- Adjust the special mob chance by the number of mobs there are. -- 2x more mobs should have a 50% chance compared to normal, etc. local chanceMod = MOB_LIST[self.currentIndex].mobMult or 1 if math.random() < specialMobChance/chanceMod then if GLOBAL.GetSeasonManager():IsWinter() then if prefab == "hound" then prefab = "icehound" else specialStats = "ice" end else if prefab == "hound" then prefab = "firehound" else specialStats = "fire" end end end -- They spawn from lightning! if prefab == "lightninggoat" then GLOBAL.GetSeasonManager():DoMediumLightning() end -- This was in the original hounded...though it seems unused local day = GLOBAL.GetClock().numcycles local theMob = GLOBAL.SpawnPrefab(prefab) if theMob then -- This fcn will add it to our list and put a bunch of stuff on it self:AddMob(theMob) if specialStats then makeMobSpecial(theMob,specialStats) end -- This is stuff that happens when spawning (not onLoad). --------------------------------------------------------------------- -- Mosquitos should have a random fill rate instead of all being at 0 if theMob:HasTag("mosquito") then local fillUp = math.random(0,2) for i=0,fillUp do theMob:PushEvent("onattackother",{data=theMob}) end end ---------------------------------------------------------------------- -- If lightning goat...give it a chance to get struck by lightning local exciteGoat = function(self) local goatPos = Vector3(self.Transform:GetWorldPosition()) GLOBAL.GetSeasonManager():DoLightningStrike(goatPos) end if theMob:HasTag("lightninggoat") and math.random() < (.9*specialMobChance) then theMob:DoTaskInTime(math.max(5,10*math.random()),exciteGoat) end ----------------------------------------------------------------------- -- Hunting party is here! Make some friends! Assume the kids don't come. if theMob.prefab == "walrus" then local numHounds = 2 local leader = theMob for i=1,numHounds do print("Releasing pet hound") hound = GLOBAL.SpawnPrefab("icehound") if hound then -- TODO: These won't persist as followers... self:AddMob(hound) hound:AddTag("pet_hound") hound.Transform:SetPosition(spawn_pt:Get()) if not hound.components.follower then hound:AddComponent("follower") end hound.components.follower:SetLeader(leader) hound:FacePoint(pt) end end end ------------------------------------------------------------------------ -- Make them shadow dudes instead local transformToShadow = function(self) -- Only do this once we get close enough for dramatic effect local currentPos = Vector3(self.Transform:GetWorldPosition()) local playerPos = Vector3(GLOBAL.GetPlayer().Transform:GetWorldPosition()) if currentPos ~= nil and playerPos ~= nil then local currentDist = GLOBAL.distsq(currentPos,playerPos) if currentDist <= 50 then -- Don't turn every single one into a shadow dude... local index = getIndexByName(theMob.prefab) local mult = MOB_LIST[index].mobMult or 1 local meanOne = math.random() < (1/(mult*mult))+.15 if meanOne then shadowDude = GLOBAL.SpawnPrefab("crawlinghorror") shadowDude.components.combat:SuggestTarget(GLOBAL.GetPlayer()) shadowDude.Physics:Teleport(currentPos:Get()) else shadowDude = GLOBAL.SpawnPrefab("shadowskittish") shadowDude.Transform:SetPosition(currentPos:Get()) end shadowDude.previousPrefab = self.prefab self:Remove() -- TODO...should probably set a periodic task to turn them back -- when not insane :P else -- Check again (only if player is still crazy) if GLOBAL.GetPlayer().components.sanity:IsSane() then self.AnimState:SetMultColour(1,1,1,1) self.task:Cancel() self.task = nil else -- Flicker local black = math.max(.15,math.random()*.5) --self.AnimState:SetMultColour(black,black,black,math.random()*.5) self.AnimState:SetMultColour(0,0,0,math.max(.3,math.random()*.5)) end end end end if GLOBAL.GetPlayer().components.sanity and GLOBAL.GetPlayer().components.sanity:IsCrazy() then -- TODO: Make this a bit cleaner so it doesn't get out of control... if theMob.prefab ~= "walrus" then theMob.task = theMob:DoPeriodicTask(.15,transformToShadow) end end theMob.Physics:Teleport(spawn_pt:Get()) theMob:FacePoint(pt) -- Stuff to do after all of the mobs are released if self.houndstorelease == 0 then -- Transform the pigs to werepigs if theMob:HasTag("SpecialPigman") and math.random() < (1.2*specialMobChance) then self.inst:DoTaskInTime(5, function(inst) transformThings() end) end end end -- if theMob end -- spawn_pt self.calcNextReleaseTime = (self.houndstorelease > 0) end self.ReleaseHound = ReleasePrefab local origPlanFunction = self.PlanNextHoundAttack local function planNextAttack(self, prefabIndex) origPlanFunction(self) -- Set the next type of mob print("Planning next attack...") if prefabIndex and prefabIndex > 0 and prefabIndex <= #MOB_LIST then print("Prefab selection overwrite") self.currentIndex = prefabIndex else self.currentIndex = getRandomMob() end local mult = MOB_LIST[self.currentIndex].mobMult or 1 local max = MOB_LIST[self.currentIndex].maxMob or nil -- Always spawn at least 1 local numHounds = math.max(1,self.houndstorelease*mult) if max then numHounds = math.max(max,numHounds) end print("numHounds: " .. numHounds) -- Round to nearest int self.houndstorelease = numHounds % 1 >= .5 and math.ceil(numHounds) or math.floor(numHounds) print("Next Attack: " .. self.houndstorelease .. " " .. MOB_LIST[self.currentIndex].prefab) updateWarningString(self.currentIndex) -- Reset the warning counter warningCount = 1 end self.PlanNextHoundAttack = planNextAttack local origOnUpdate = self.OnUpdate local function newOnUpdate(self,dt) -- Stuff to do before calling hounded:OnUpdate local didWarnFirst = self.announcewarningsoundinterval -------------------------------------------------------- origOnUpdate(self,dt) -------------------------------------------------------- -- Stuff to do after calling hounded:OnUpdate local didWarnSecond = self.announcewarningsoundinterval -- Modify the next release time based on the current prefab if self.timetoattack <= 0 then local timeMult = MOB_LIST[self.currentIndex].timeMult or 1 if timeMult ~= 1 and self.calcNextReleaseTime then local orig = self.timetonexthound self.timetonexthound = self.timetonexthound * timeMult self.calcNextReleaseTime = false end end -- If beefalo are coming, start the stampede effects if MOB_LIST[self.currentIndex].prefab == "beefalo" then if self.timetoattack < self.warnduration and self.timetoattack > 0 and not self.quakeMachine.quakeStarted then -- This is kind of hackey...but i want the quake to INCREASE over time, not decrease. -- The camerashake only has functions that decrease... local interval = self.timetoattack / 2 --self.quakeMachine:DoTaskInTime(0, function(self) self:WarnQuake(interval*2, .015, .1) end) self.quakeMachine:WarnQuake(interval*2,.015,.1) -- Camera shake decreases in intensity as it goes on...but I want it to INCREASE!! self.quakeMachine:DoTaskInTime(1*interval, function(self) self:WarnQuake(interval*2, .02, .1) end) self.quakeMachine:DoTaskInTime(2*interval, function(self) self:WarnQuake(interval*2, .025, .1) end) self.quakeMachine.quakeStarted = true local interval = self.timetoattack/5 for i=1, 5 do self.quakeMachine:DoTaskInTime(i*interval, function(self) self:MakeStampedeLouder() end) end -- Schedule quake to end self.quakeMachine:DoTaskInTime(self.timetoattack+5, function(self) self:EndQuake() end) end -- If lightning goats are coming, start some weather effects elseif MOB_LIST[self.currentIndex].prefab == "lightninggoat" then if self.timetoattack < self.warnduration and self.timetoattack > 0 and not self.inst.overcastStarted then -- We're in the warning interval. Lets make some clouds (only if it's day) self.inst.overcastStarted = true if GLOBAL.GetClock():IsDay() then self.inst.startColor = GLOBAL.GetClock().currentColour print(self.inst.startColor) -- Get the curent cloud cover currentClouds = GLOBAL.GetSeasonManager():GetWeatherLightPercent() -- If there is more than 50% cloud cover...don't make it even darker! if (1-currentClouds) < .5 then -- The clock uses the absolute day color already. Don't need to -- adjust to this. Just adjusting initially so we don't make it flash brighter, THEN -- get darker. Instead, start at current cloud cover and add MORE! -- Make some (more) clouds! These are supposed to be ominous! self.inst.endColor = GLOBAL.Point(0,0,0) self.inst.endColor.x = .5*currentClouds*self.inst.startColor.x self.inst.endColor.y = .5*currentClouds*self.inst.startColor.y self.inst.endColor.z = .5*currentClouds*self.inst.startColor.z -- Make it darker GLOBAL.GetClock():LerpAmbientColour(self.inst.startColor, self.inst.endColor, self.timetoattack-8) local makeCloudsGoAway = function(self) -- Don't fix the color if it went to dusk as that would break the color if GLOBAL.GetClock():IsDay() then GLOBAL.GetClock():LerpAmbientColour(self.endColor,self.startColor,3) end self.overcastStarted = false end -- When done...transition back to normal color local cloudTime = 8*(self.houndstorelease+1) + self.timetoattack self.inst:DoTaskInTime(cloudTime, makeCloudsGoAway) end end -- Schedule some distant thunder sound fx local interval = self.timetoattack/6 for i=1,5 do self.inst:DoTaskInTime(i*interval*(math.random()+1), function(self) GLOBAL.GetPlayer().SoundEmitter:PlaySound("dontstarve/rain/thunder_far","far_thunder") GLOBAL.GetPlayer().SoundEmitter:SetParameter("far_thunder", "intensity", .02*i) end) end end end -- In this case...hounded issued a verbal warning. Update the strings to next warning if didWarnFirst < didWarnSecond and self.timetoattack > 0 then warningCount = warningCount + 1 updateWarningString(self.currentIndex) end end self.OnUpdate = newOnUpdate local origOnSave = self.OnSave local function newOnSave(self) data = origOnSave(self) -- If this is empty...then don't bother saving anything. if GLOBAL.next(data) ~= nil then data.currentIndex = self.currentIndex local mobs = {} for k,v in pairs(self.currentMobs) do saved = true table.insert(mobs, k.GUID) end data.mobs = mobs return data end end self.OnSave = newOnSave local origOnLoad = self.OnLoad local function newOnLoad(data, newEnts) origOnLoad(self,newEnts) local test = data.currentIndex self.currentIndex = newEnts.currentIndex or nil if self.currentIndex == nil then print("Could not load index. Planning next attack") self:PlanNextHoundAttack() else updateWarningString(self.currentIndex) end end self.OnLoad = newOnLoad self.LoadPostPass = function(self,newents,savedata) if savedata and savedata.mobs then for k,v in pairs(savedata.mobs) do local targ = newents[v] if targ then self:AddMob(targ.entity) end end end end -- Helper function to start an attack. local function fn(self,timeToAttack) if self.timetoattack > 31 then -- Can Pass in the time if wanted... if timeToAttack == nil then timeToAttack = 30 end print("Starting hound attack in: " .. timeToAttack) self.timetoattack = timeToAttack end end self.StartAttack = fn end AddComponentPostInit("hounded",releaseRandomMobs) local function transformFcn(inst) if inst:HasTag("SpecialPigman") then inst.components.werebeast:SetWere() -- Don't sleep! inst.components.sleeper:SetSleepTest(sleepFcn) inst.components.sleeper:SetWakeTest(wakeFcn) -- Keep going for the player after transform inst.components.combat:SuggestTarget(GLOBAL.GetPlayer()) end end --------------------------------------------------------------------------- -- PIGMAN override to add listen event --------------------------------------------------------------------------- local function AddPigmanTransformEvent(inst) inst:ListenForEvent("transform_special_pigs",transformFcn) end AddPrefabPostInit("pigman",AddPigmanTransformEvent) --------------------------------------------------------------------------- -- Brain Modifications --------------------------------------------------------------------------- local ipairs = GLOBAL.ipairs local function MakeMobChasePlayer(brain) --[[ Make this the top of the priority node. Basically, if they have the insane tag (we add it above), they will prioritize chasing and attempting to kill the player before doing normal things. Update - maybe should make all mobs attack walls now since they are crazy --]] local function KillKillDieDie(inst) -- Chase for 60 seconds, target distance 60 return GLOBAL.ChaseAndAttack(inst,60,60) end attackWall = GLOBAL.WhileNode(function() return brain.inst:HasTag("houndedKiller") end, "Get The Coward", GLOBAL.AttackWall(brain.inst) ) chaseAndKill = GLOBAL.WhileNode(function() return brain.inst:HasTag("houndedKiller") end, "Kill Kill", KillKillDieDie(brain.inst)) -- Find the root node. Insert this WhileNode at the top. -- Well, we'll put it after "OnFire" (if it exists) so it will still panic if on fire local fireindex = 0 for i,node in ipairs(brain.bt.root.children) do if node.name == "Parallel" and node.children[1].name == "OnFire" then fireindex = i end end -- Tell the brain "Attack the player...unless there is a wall in the way, get that instead" table.insert(brain.bt.root.children, fireindex+1, chaseAndKill) table.insert(brain.bt.root.children, fireindex+1, attackWall) -- The plan was to give the players a small break by having the mobs stop for a snack...but they don't -- ever seem to want to to id. TODO! -- Make the mobs have a snack every so often local function EatFoodAction(inst) if inst.components.eater then local target = GLOBAL.FindEntity(inst, 30, function(item) return inst.components.eater:CanEat(item) and item:IsOnValidGround() end) if target then return GLOBAL.BufferedAction(inst, target, GLOBAL.ACTIONS.EAT) end end end haveASnack = GLOBAL.DoAction(brain.inst, EatFoodAction, "Eat Food", true ) -- If the brain already has this...don't add it again. Else, add it to the end local hasAction = false for i,node in ipairs(brain.bt.root.children) do if node.name == "Parallel" and node.children[1].name == "Eat Food" then -- Already eats...don't add it again hasAction = true break end end -- TODO: Fix snack code if false then if not hasAction then -- Just insert at end table.insert(brain.bt.root.children, haveASnack) end end -- Debug string to see that my KillKillDieDie was added --print("Brain for " .. tostring(brain.inst.name)) --for i,node in ipairs(brain.bt.root.children) do -- print("\t"..node.name.." > "..(node.children and node.children[1].name or "")) --end --print("\n") end -- Insert this brain for each mob that has it defined in MOB_LIST (if DLC allows) for k,v in pairs(MOB_LIST) do local skip if v.brain and (not dlcEnabled and v.RoG) then skip = true end if v.brain and not skip then AddBrainPostInit(v.brain,MakeMobChasePlayer) end end --------------------------------------------------------------------------- -- Generate a new special hound effect if this has never been loaded before --------------------------------------------------------------------------- local function firstTimeLoad() -- Don't load anything if in a cave if not GLOBAL.GetWorld():IsCave() then if GLOBAL.GetWorld().components.hounded.currentIndex == nil then print("First time loading this mod. Generating new hound attack.") GLOBAL.GetWorld().components.hounded:PlanNextHoundAttack() else print("Current Mob Planned: " .. MOB_LIST[GLOBAL.GetWorld().components.hounded.currentIndex].prefab) end end end AddSimPostInit(function() firstTimeLoad() end) --------------------------------------------------------------------------- -- Don't increase naughtyness for killing these things --------------------------------------------------------------------------- local removedNaughty = function(self) local origFcn = self.onkilledother local newKillFcn = function(self,victim) if not victim:HasTag("houndedKiller") then origFcn(self,victim) end end self.onkilledother = newKillFcn end AddComponentPostInit("kramped",removedNaughty) Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.