Jump to content

The good Switcheroo


Recommended Posts

So I have a certain new character who I wish to switch places of the creature he casts the spell on, and I'm curious how would I go about that. By switching places I mean switching coordinates between each other.

Link to comment
Share on other sites

Not 100% sure how experienced you are with modding or coding in general, but a general tip (which you may already know and have looked at). When you are trying to do something and there is already something somewhat like it in the project... use it or as much of it as you can.

The following code is from the staff.lua (specifically the purple staff section).

 

local function teleport_thread(inst, caster, teletarget, loctarget)    local ground = TheWorld    local t_loc = nil    if loctarget then        t_loc = loctarget:GetPosition()    else        t_loc = getrandomposition(caster)    end    local teleportee = teletarget    local pt = teleportee:GetPosition()    if teleportee.components.locomotor then        teleportee.components.locomotor:StopMoving()    end    inst.components.finiteuses:Use(1)    if ground.topology.level_type == "cave" then        TheCamera:Shake("FULL", 0.3, 0.02, .5, 40)        ground.components.quaker:MiniQuake(3, 5, 1.5, teleportee)        return    end    if teleportee.components.health ~= nil then        teleportee.components.health:SetInvincible(true)    end    --#v2c hacky way to prevent lightning from igniting us    local preventburning = teleportee.components.burnable ~= nil and not teleportee.components.burnable.burning    if preventburning then        teleportee.components.burnable.burning = true    end    ground:PushEvent("ms_sendlightningstrike", pt)    if preventburning then        teleportee.components.burnable.burning = false    end    teleportee:Hide()    if teleportee.DynamicShadow ~= nil then        teleportee.DynamicShadow:Enable(false)    end    if caster and caster.components.sanity then        caster.components.sanity:DoDelta(-TUNING.SANITY_HUGE)    end    ground:PushEvent("ms_forceprecipitation", true)    local isplayer = teleportee:HasTag("player")    if isplayer then        teleportee.components.playercontroller:Enable(false)        teleportee:ScreenFade(false, 2)        Sleep(3)    end    if teleportee.Physics ~= nil then        teleportee.Physics:Teleport(t_loc.x, 0, t_loc.z)    else        teleportee.Transform:SetPosition(t_loc.x, 0, t_loc.z)    end    if isplayer then        teleportee:SnapCamera()        teleportee:ScreenFade(true, 1)        Sleep(1)        teleportee.components.playercontroller:Enable(true)    end    if loctarget and loctarget.onteleto then        loctarget.onteleto(loctarget)    end    --#v2c hacky way to prevent lightning from igniting us    preventburning = teleportee.components.burnable ~= nil and not teleportee.components.burnable.burning    if preventburning then        teleportee.components.burnable.burning = true    end    ground:PushEvent("ms_sendlightningstrike", t_loc)    if preventburning then        teleportee.components.burnable.burning = false    end    teleportee:Show()    if teleportee.DynamicShadow ~= nil then        teleportee.DynamicShadow:Enable(true)    end    if teleportee.components.health ~= nil then        teleportee.components.health:SetInvincible(false)    end    if isplayer then        teleportee.sg:GoToState("wakeup")        teleportee.SoundEmitter:PlaySound("dontstarve/common/staffteleport")    endendlocal function teleport_targets_sort_fn(a, b)    return a.distance < b.distanceendlocal function teleport_func(inst, target)    local mindistance = 1    local caster = inst.components.inventoryitem.owner    local tar = target or caster    if not caster then caster = tar end    local pt = tar:GetPosition()    local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 9000, {"telebase"})    if #ents <= 0 then        --There's no bases, active or inactive. Teleport randomly.        inst.task = inst:StartThread(function() teleport_thread(inst, caster, tar) end)        return    end    local targets = {}    for k,v in pairs(ents) do        local v_pt = v:GetPosition()        if distsq(pt, v_pt) >= mindistance * mindistance then            table.insert(targets, {base = v, distance = distsq(pt, v_pt)})         end    end    table.sort(targets, teleport_targets_sort_fn)    for i = 1, #targets do        local teletarget = targets[i]        if teletarget.base and teletarget.base.canteleto(teletarget.base) then            inst.task = inst:StartThread(function() teleport_thread(inst, caster, tar, teletarget.base) end)            return        end    end    inst.task = inst:StartThread(function() teleport_thread(inst, caster, tar) end)end

 

The reason I am showing this to you is because the teleportation functions are here. I have not tried any of this and I am fairly new to the don't starve modding stuff but I have been coding in lua for awhile (mostly small stuff tho). So anyway I would look at that stuff and get rid of the random location stuff and focus more on the getting of positions for the targets. So in place of having one target (like in this code) you would have two that would both be moving locations.

 

I didnt exactly do a whole lot of checking around in this code, but I was looking around in the staff file for some other code and I remembered seeing your post so I looked for about a minute for what seemed like the right set of stuff. Might make no sense out of context.

 

 For more context go to the staff.lua file located at [\Don't Starve Together Beta\data\scripts\prefabs].

I would like to mention one more time that I in no way wrote or changed this file and therefor take no credit.

 

Hope this helped some! Sorry if it didnt...

Link to comment
Share on other sites

@rons0n

Assuming you already have the stategraph state and the stategraph action handler, and maybe a component related to it, you could do something like this:

AddAction("SWITCHEROO","Exchange places", function(act)    if act.target and CanBeCastedOn(act.target, act.pos) then        local target_pos = Point(act.target.Transform:GetWorldPosition())        act.target.Transform:SetPosition(act.doer.Transform:GetWorldPosition())		act.doer.Transform:SetPosition(target_pos)		        return true    endend)
EDIT: Whoops, had some lines inverted. Edited by Ryuushu
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...