Skip to content

Commit

Permalink
Reuse shadowhands as dream snatchers
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Helsley <[email protected]>
  • Loading branch information
mhelsley committed Sep 30, 2016
1 parent fb828de commit 648060e
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 22 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ TEX=~/.games/dont_starve/mods/mod_tools/png
ANIM=~/.games/dont_starve/mods/mod_tools/scml


# TODO anim/dream_tentacle.zip anim/dream_hand.zip
all: images/modicon.tex images/dreamsnatcher.tex images/minimap.tex anim/dreamsnatcher.zip anim/dreams.zip
mv -f images/modicon.tex $(CURDIR)
mv -f images/modicon.xml $(CURDIR)
Expand All @@ -18,7 +19,7 @@ reset:
-@killall dontstarve_steam 2> /dev/null

install: all
rsync -camOJWi --exclude=.git --exclude=art --exclude=old-art --exclude=art-src --exclude=Makefile --exclude='*~' --exclude='*.png' --exclude='*.kra' --exclude='*.swp' ./ ~/.games/dont_starve/mods/DreamSnatcher
rsync -camOJWi --exclude=.git --exclude=art --exclude=old-art --exclude=old-src --exclude=art-src --exclude=.gitignore --exclude=Makefile --exclude='*~' --exclude='*.png' --exclude='*.kra' --exclude='*.swp' ./ ~/.games/dont_starve/mods/DreamSnatcher

clean:
find $(CURDIR) -name '*.tex' -print0 | xargs -r0 rm
Expand Down
8 changes: 8 additions & 0 deletions modmain.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ STRINGS.NAMES.DREAM_ITEM = "Dream"
STRINGS.NAMES.DREAM = "Dream"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.DREAM = "What an odd dream!"

STRINGS.NAMES.DREAM_TENTACLE_ITEM = "Dream feeding filament"
STRINGS.NAMES.DREAM_TENTACLE = "Dream feeding filament"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.DREAM_TENTACLE = "It pulses and beats like a grotesque ethereal heart!"

STRINGS.NAMES.DREAM_HAND_ITEM = "Dream feeding sucker"
STRINGS.NAMES.DREAM_HAND = "Dream feeding sucker"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.DREAM_HAND = "It makes a hideous sucking sound as it reaps its stygian harvest!"

PrefabFiles = { "dreamsnatcher", "dream", }

Assets = {
Expand Down
4 changes: 2 additions & 2 deletions scripts/components/dreamer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ function Dreamer:StartDreaming()
-- No nearby dreamsnatcher to link with
return
end
self.snatcher:Attach(self)
self.snatcher:Attach(self.inst)
end

function Dreamer:StopDreaming()
if self.dream then
self.dream:Over()
end
if self.snatcher then
self.snatcher:Detach(self)
self.snatcher:Detach(self.inst)
end
self.dream = nil
self.snatcher = nil
Expand Down
185 changes: 166 additions & 19 deletions scripts/prefabs/dreamsnatcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,14 @@ local function find_or_spawn_raven(inst)
end

local function onwake(inst)
inst.SoundEmitter:PlaySound("dontstarve/sanity/shadowhand_creep", "creeping")
--inst.SoundEmitter:PlaySound("dontstarve/sanity/shadowhand_creep", "creeping")
inst.Light:Enable(true)
--inst.AnimState:PlayAnimation("active_idle", true)
find_or_spawn_raven(inst)
end

local function onsleep(inst)
inst.SoundEmitter:KillSound("creeping")
--inst.SoundEmitter:KillSound("creeping")
inst.Light:Enable(false)
if inst.components.occupiable:IsOccupied() then
-- HACK re-enable harvesting
Expand All @@ -234,10 +234,12 @@ end
local function onnear(inst)
inst.SoundEmitter:PlaySound("dontstarve/rain/thunder_close", "rumble")
-- TheCamera:Shake(shakeType, duration, speed, scale)
-- See components/quaker.lua
-- See components/quaker.lua -- TODO no idea what "40" is!
local duration = 100000000
local scale = 0.2
TheCamera:Shake("FULL", duration, 0.02, scale, 40)
local intensity = math.min(100.0, inst.insanity)/100.0
local scale = 0.2*intensity
local speed = 0.02*intensity
TheCamera:Shake("FULL", duration, speed, scale, 40)
end

local function onfar(inst)
Expand Down Expand Up @@ -302,10 +304,13 @@ local function onload(inst, data)
if data and data.line then
inst.line = data.line
end
if data and data.insanity then
inst.insanity = data.insanity
end
if GetClock():IsDay() then
inst.AnimState:PlayAnimation("idle", true)
elseif GetClock():IsDusk() or GetClock():IsNight() then
--- TODO onwake(inst)
--- TODO onwake(inst) ??
end
end

Expand All @@ -314,6 +319,7 @@ local function onsave(inst, data)
data = {}
end
data.line = inst.line
data.insanity = inst.insanity
end

local function fn(Sim)
Expand All @@ -322,6 +328,7 @@ local function fn(Sim)

local shadow = inst.entity:AddDynamicShadow()
shadow:SetSize(1, .5)
shadow:Enable(true)

local anim = inst.entity:AddAnimState()
anim:SetBank("dreamsnatcher") -- Entity Name in Spriter (top level)
Expand Down Expand Up @@ -361,24 +368,164 @@ local function fn(Sim)
inst:ListenForEvent("gotosleep", onsleep)

inst:AddComponent("lootdropper")
inst.DropLoot = function()
inst.components.lootdropper:SpawnLootPrefab("nightmarefuel")
inst.insanity = 0
inst.CollectSanity = function(inst, dreamer, duration)
if dreamer.components.sanity then
-- We've already collected the sanity over time.
-- Stop collecting via the sanity callbacks
inst:RemoveEventCallback("sanitydelta", dreamer.sanitysuckfn)
inst:RemoveEventCallback("gosane", dreamer.sanefn)
inst:RemoveEventCallback("goinsane", dreamer.insanefn)
dreamer.sanitysuckfn = nil
dreamer.sanefn = nil
dreamer.insanefn = nil
else
if duration >= 15 then -- 0.5*TUNING.seg_time
inst.insanity = inst.insanity + duration*TUNING.SANITYAURA_TINY
end
end

-- Roughly speaking, somebody has to go insane to make one
-- nightmare fuel.
local INSANITY_THRESH = 100*(1.0 - TUNING.SANITY_BECOME_INSANE_THRESH)

while inst.insanity >= INSANITY_THRESH do
inst.insanity = inst.insanity - INSANITY_THRESH
inst.components.lootdropper:SpawnLootPrefab("nightmarefuel")
end
if inst.insanity < 0 then
inst.insanity = 0
end
end

inst.attached_dreamers = {}
inst.Attach = function(dreamer)
attached_dreamers[dreamer] = dreamer
-- TODO start a dream tentacle + hand then move the below
-- to the portion where it reaches the dreamer
if dreamer.dream then
dreamer.dream:Disturb()
inst:ListenForEvent("onattachdreamer", function(inst, dreamer)
local dream = dreamer.components.dreamer.dream
if dream then
dream:Disturb()
inst.attached_dreamers[dreamer].start = GetTime()
end
if dreamer.components.sanity then
dreamer.sanitysuckfn = function(event)
-- All sanity lost accumulates towards
-- spawning nightmarefuel
local delta = event.oldpercent - event.newpercent
-- BUT Sleepers with positive sanity gain wipe
-- out any accumulation.
if delta < 0 then
inst.insanity = 0
return
end
inst.insanity = inst.insanity + delta
end
dreamer.sanefn = function(event)
-- Sleepers that go sane wipe out accumulation
inst.insanity = 0
end
dreamer.insanefn = function(event)
-- Sleepers that go insane boost nightmare
-- production alot!
inst.insanity = inst.insanity + 100
end
inst:ListenForEvent("sanitydelta", dreamer.sanitysuckfn)
inst:ListenForEvent("gosane", dreamer.sanefn)
inst:ListenForEvent("goinsane", dreamer.insanefn)
end
end)
inst.Attach = function(inst, dreamer)
if not dreamer then
return
end
if inst.attached_dreamers[dreamer] then
return
end
local hand = SpawnPrefab("shadowhand")--"dreaming/dream_hand")
hand:AddTag("notarget")
hand:AddTag("notraptrigger")
hand.persists = false
RemovePhysicsColliders(hand)
hand.Physics:SetCollisionGroup(COLLISION.SANITY)
hand.Physics:CollidesWith(COLLISION.SANITY)
--hand.Physics:CollidesWith(COLLISION.WORLD)
hand.Physics:SetMass(10) -- Needs nonzero mass otherwise it never moves!
hand.arm = nil

-- Critical HACKS
-- Removing player proximity ensures the shadowhand never
-- starts searching for a fire.
hand:RemoveComponent("playerprox")
-- Removing the daytime callback ensures the hand works for
-- nocturnal dreamers too.
hand:RemoveEventCallback("daytime", hand.dissipatefn, GetWorld())
-- Removing this prevents the shadow arm and hand from being
-- saved and thus ensures that the above hacks are always
-- applied.
hand:RemoveComponent("knownlocations")

hand.Transform:SetPosition(inst.Transform:GetWorldPosition())

-- Tune sanity loss to account for extended contact
hand.components.sanityaura.aura = -TUNING.SANITYAURA_TINY

hand.SeekDreamer = function(hand, snatcher, dreamer)
hand:ClearBufferedAction()
hand.components.locomotor:Clear()
hand.arm = SpawnPrefab("shadowhand_arm")
hand.arm.persists = false
hand.arm:AddTag("notarget")
hand.arm:AddTag("notraptrigger")
hand.arm.Transform:SetPosition(hand.Transform:GetWorldPosition())
hand.arm:FacePoint(Vector3(dreamer.Transform:GetWorldPosition()))
hand.arm.components.stretcher:SetStretchTarget(hand)
hand.components.locomotor.walkspeed = 2
hand.components.locomotor:SetReachDestinationCallback(function(h)
assert(h == hand)
hand.SoundEmitter:KillAllSounds()
snatcher:PushEvent("onattachdreamer", dreamer)
end)
hand.components.locomotor:GoToEntity(dreamer, nil, false)
end
hand.Retract = function(hand)
hand.components.locomotor:Clear()
hand.components.locomotor.walkspeed = 10
hand.AnimState:PlayAnimation("grab_pst")
hand.SoundEmitter:PlaySound("dontstarve/sanity/shadowhand_creep", "creeping")
hand.components.locomotor:SetReachDestinationCallback(function(h)
assert(h == hand)
hand.SoundEmitter:KillAllSounds()
hand.arm:Remove()
hand:Remove()
end)
hand.components.locomotor:GoToEntity(hand.arm, nil, false)
end
inst.attached_dreamers[dreamer] = { ["hand"] = hand, ["start"] = nil }
hand:SeekDreamer(inst, dreamer)
end

inst.Detach = function(dreamer)
attached_dreamers[dreamer] = nil
-- TODO cancel a dream tentacle + hand
inst:DropLoot()
inst.Detach = function(inst, dreamer)
if not dreamer then
return
end
local tuple = inst.attached_dreamers[dreamer]
if not tuple then
return
end
local hand = tuple.hand
if not hand then
return
end
local duration
if not tuple.start then
duration = 0
else
duration = GetTime() - tuple.start
end
inst.attached_dreamers[dreamer] = nil
-- TODO could *almost* trigger "startaction" and avoid
-- writing our own Retract function.
hand:ClearBufferedAction()
hand:Retract()
inst:CollectSanity(dreamer, duration)
end

inst:AddComponent("occupiable")
Expand All @@ -389,7 +536,7 @@ local function fn(Sim)
inst.components.playerprox.onfar = onfar

inst:AddComponent("sanityaura")
inst.components.sanityaura.aura = -TUNING.SANITY_TINY
inst.components.sanityaura.aura = -TUNING.SANITYAURA_TINY

--inst:AddComponent("finiteuses")
--inst.components.finiteuses:SetMaxUses(TUNING.TENT_USES)
Expand Down

0 comments on commit 648060e

Please sign in to comment.