Jump to content

Recommended Posts

I am a javascript developer and i am making a modded character for dst. Everything is going fine, but i am not very experienced at lua (i know some of its basics concepts tho)  and i would like if somebody could explain to me how do i make something like this to my character: A teleport that is just like wortox's soul hop, but instead of using souls, it uses 50 sanity. I also need to know how to change the "soul hop" text to something else and how to change the soul hop animation to the same animation that plays when somebody leaves wanda's time rift. I would be really gratefull if somebody could help me with that.

I am looking for this exact information and have been sifting the forum for days and trying all kinds of code.

So far I have gotten the soulhop action to show up with right click and the hopping animation to play (with the little red clouds), but my character doesn't actually move.

local function WBlink(act)
	local act_pos = act:GetActionPoint()
    if act.invobject ~= nil then
        if act.invobject.components.blinkstaff ~= nil then
            return act.invobject.components.blinkstaff:Blink(act_pos, act.doer)
        end
    elseif act.doer ~= nil
        and act.doer.sg ~= nil
        and act.doer.sg.currentstate.name == "portal_jumpin_pre"
        and act_pos ~= nil
        and act.doer.components.inventory ~= nil
        and act.doer.components.inventory:Has("nightmarefuel", 1) then
        act.doer.sg:GoToState("portal_jumpin", act_pos)
		inst.Transform:SetPosition(x, y, z)
        return true

    end
end


GLOBAL.ACTIONS.BLINK.fn = function(act)
    return WBlink(act)
end

This code might be useful to someone, I put it in Modmain.lua and also used bits of wortox's code in my character's prefab file. I really don't know what I'm doing and I'm finding it difficult to find relevant files to dissect.

 

Another approach to teleporting/blinking that i've seen is RPC handlers

Another is just using a custom item with the blinkstaff component

	inst:AddComponent("blinkstaff")
    inst.components.blinkstaff.onblinkfn = onblink

 

Edited by sorrynameused
5 hours ago, sorrynameused said:

I really don't know what I'm doing and I'm finding it difficult to find relevant files to dissect.

Hi, I have a WIP custom character with a Soulhop style teleport that I was working on a year ago.

I struggled to find a mod with what I was looking for until I found this one https://steamcommunity.com/sharedfiles/filedetails/?id=1627850106&searchtext=pandora

It turned out that what I was missing was creating the "[teleportname].lua" in my components folder in which AddAction is used to actually tell the game what should happen when the mouse is right clicked.

I hope this helps you out. I've taken a really long break from my character since and can't really remember the details, but referencing that mod and Wortox's code is how I ultimately got him to work.

 

I figured out how to add wortox's teleport by adding this code to the character prefab, there's a lot of redundant code but it works and I didn't care to learn anything more than what I needed :P

 

local function GetSouls(inst)
    local souls = inst.components.inventory:FindItems(IsSoul)
    local count = 0
    for i, v in ipairs(souls) do
        count = count + GetStackSize(v)
    end
    return souls, count
end

local function OnSoulHop(inst)
    if inst._checksoulstask ~= nil then
        inst._checksoulstask:Cancel()
    end
    --inst._checksoulstask = inst:DoTaskInTime(.5, CheckSoulsRemovedAfterAnim, "wortox_portal_jumpout")
end

local function PutSoulOnCooldown(item)
    if not IsSoul(item) then
        return
    end

    if item.components.rechargeable ~= nil then
        item.components.rechargeable:Discharge(TUNING.WORTOX_FREEHOP_TIMELIMIT)
    end
end

local function RemoveSoulCooldown(item)
    if not IsSoul(item) then
        return
    end

    if item.components.rechargeable ~= nil then
        item.components.rechargeable:SetPercent(1)
    end
end

local function SetNetvar(inst)
    if inst.player_classified ~= nil then
        assert(inst._freesoulhop_counter >= 0 and inst._freesoulhop_counter <= 7, "Player _freesoulhop_counter out of range: "..tostring(inst._freesoulhop_counter))
        inst.player_classified.freesoulhops:set(inst._freesoulhop_counter)
    end
end

local function ClearSoulhopCounter(inst)
    inst._freesoulhop_counter = 0
    inst._soulhop_cost = 0
    SetNetvar(inst)
end

local function FinishPortalHop(inst)
    if inst._freesoulhop_counter > 0 then
        if inst.components.inventory ~= nil then
            inst.components.inventory:ConsumeByName("nightmarefuel", math.max(math.ceil(inst._soulhop_cost), 1))
        end
        ClearSoulhopCounter(inst)
    end
end

local function TryToPortalHop(inst, souls, consumeall)
    local invcmp = inst.components.inventory
    if invcmp == nil then
        return false
    end

    souls = souls or 1
    local _, soulscount = GetSouls(inst)
    if soulscount < souls then
        return false
    end

    inst._freesoulhop_counter = inst._freesoulhop_counter + souls
    inst._soulhop_cost = inst._soulhop_cost + souls

    if not consumeall and inst._freesoulhop_counter < TUNING.WORTOX_FREEHOP_HOPSPERSOUL then
        inst._soulhop_cost = inst._soulhop_cost - souls -- Make it free.
        invcmp:ForEachItem(PutSoulOnCooldown)
    else
        invcmp:ForEachItem(RemoveSoulCooldown)
        inst:FinishPortalHop()
    end
    SetNetvar(inst)

    return true
end

local function OnFreesoulhopsChanged(inst, data)
    inst._freesoulhop_counter = data and data.current or 0
end

local function CanBlinkTo(pt)
    return TheWorld.Map:IsPassableAtPoint(pt:Get()) and not TheWorld.Map:IsGroundTargetBlocked(pt) -- NOTES(JBK): Keep in sync with blinkstaff. [BATELE]
end

local function CanBlinkFromWithMap(pt)
    return true -- NOTES(JBK): Change this if there is a reason to anchor Wortox when trying to use the map to teleport.
end

local function ReticuleTargetFn(inst)
    return ControllerReticle_Blink_GetPosition(inst, inst.CanBlinkTo)
end

local function CanSoulhop(inst, souls)
    if inst.replica.inventory:Has("nightmarefuel", 1) then
        local rider = inst.replica.rider
        if rider == nil or not rider:IsRiding() then
            return true
        end
    end
    return false
end

local function GetPointSpecialActions(inst, pos, useitem, right)
    if right and useitem == nil then
        local canblink
        if inst.checkingmapactions then
            canblink = inst.CanBlinkFromWithMap(inst:GetPosition())
        else
            canblink = inst.CanBlinkTo(pos)
        end
        if canblink and inst.CanSoulhop and inst:CanSoulhop() then
            return { ACTIONS.BLINK }
        end
    end
    return {}
end

local function OnSetOwner(inst)
    if inst.components.playeractionpicker ~= nil then
        inst.components.playeractionpicker.pointspecialactionsfn = GetPointSpecialActions
    end
end

local function OnSave(inst, data)
    data.freehops = inst._freesoulhop_counter
    data.soulhopcost = inst._soulhop_cost
end

local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)
	inst._freesoulhop_counter = 0
    inst._soulhop_cost = 0
    inst:DoTaskInTime(0, SetNetvar)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end
          
          
          
          
-- This initializes for both the server and client. Tags can be added here.

local common_postinit = function(inst) 
    inst:AddTag("soulstealer")
	inst:AddTag("souleater")
	inst:AddComponent("reader")

	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "damian.tex" )

    inst._freesoulhop_counter = 0
    inst.CanSoulhop = CanSoulhop
    inst.CanBlinkTo = CanBlinkTo
	inst.CanBlinkFromWithMap = CanBlinkFromWithMap
    inst:ListenForEvent("setowner", OnSetOwner)

    inst.CanBlinkFromWithMap = CanBlinkFromWithMap
    inst:ListenForEvent("setowner", OnSetOwner)

    inst:AddComponent("reticule")
    inst.components.reticule.targetfn = ReticuleTargetFn
    inst.components.reticule.ease = true
end
local master_postinit = function(inst)
	inst.OnLoad = onload
    inst.OnNewSpawn = onload
	inst.TryToPortalHop = TryToPortalHop
    inst.FinishPortalHop = FinishPortalHop
	
	
    inst:AddComponent("souleater")

    inst._checksoulstask = nil
	
	inst:ListenForEvent("soulhop", OnSoulHop)
	
end

A bit jury rigged but it's functional. If you take the time, you can sift through it and get rid of redundant code. Not sure if any of this interacts with the wortox character since I haven't tested it on a server with a wortox character, but it would likely be fixed if some of the local functions had unique names, most of them seem to already be unique to the character prefab and don't reference anything outside of it, so it should be safe to rename several of them.

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
×
  • Create New...