Jump to content

Recommended Posts

I want to make character where you can right click on an item/ other player and they would be yanked toward you (with a cooldown), sorta like teleporting but there's like a 0.5s period where they're dragged across the map lol. I don't even know where to start i've been looking for similar mod but no luck so far :c

image.png.b6ad5372b301873603d24845caa44fa6.png

something like this, can anyone help me

I think the difficulty lies in in the animation.

On the code side, you can immobilize the player with something similar to the third freeze attack of the Deerclops. To move the player, surely the game has a function to do that.

I will search in the code and, if i find something useful, i will let you know

  • Like 1

The function that immobilize the player is:

--V2C: Calling this direclty isn't great; :AddColdness instead!
function Freezable:Freeze(freezetime)
    if self.inst.entity:IsVisible() and not (self.inst.components.health ~= nil and self.inst.components.health:IsDead()) then
        if self.onfreezefn ~= nil then
            self.onfreezefn(self.inst)
        end

        if self.diminishingtask ~= nil then
            --Restart decay timer
            self.diminishingtask:Cancel()
            self.diminishingtask = self.inst:DoPeriodicTask(30, DecayExtraResist, nil, self)
        end

        local prevState = self.state
        self.state = states.FROZEN
        self:StartWearingOff(freezetime)
        self:UpdateTint()

        if self.inst.brain ~= nil then
            self.inst.brain:Stop()
        end

        if self.inst.components.combat ~= nil then
            self.inst.components.combat:SetTarget(nil)
        end

        if self.inst.components.locomotor ~= nil then
            self.inst.components.locomotor:Stop()
        end

        if self.state ~= prevState then
			self.inst:PushEvent("freeze")
            if self.diminishingreturns then
                self:SetExtraResist((self.extraresist or 0) + self.resistance * .25)
            end
        end
    end
end

Sorry v2c, we need to call it directly!

In fact we only need to call:

if self.inst.components.combat ~= nil then 
  self.inst.components.combat:SetTarget(nil) -- This immobilizes the player, stopping attacks.
end

if self.inst.components.locomotor ~= nil then
  self.inst.components.locomotor:Stop() -- This immobilizes the player, stopping movement.
end

and, if you need to apply an animation to immobilized player, you can modify:

if self.state ~= prevState then
  self.inst:PushEvent("freeze")
  if self.diminishingreturns then
    self:SetExtraResist((self.extraresist or 0) + self.resistance * .25)
  end
end

I don't know what diminishingreturns is, but I think you can remove it from the function and just push an event to notify the immobilized player to change their animation state to one more convenient for you.

Hmm, I haven't found any function to move the player. The closest thing is Player_inst.Physics:Teleport(x,y,z), but it's instantaneous. You can't use DoTaskInTime because the animation looks weird, and if the player goes over water, they do the drowning animation.

In my opinion, a better solution is to use teleport to TP the player to your side and make them invisible. Create a prefab (for FX only) with the player's skin and move it to your side. When the prefab reaches your side, remove it and make the player visible again.

15 hours ago, FerniFrenito said:

Hmm, I haven't found any function to move the player. The closest thing is Player_inst.Physics:Teleport(x,y,z), but it's instantaneous. You can't use DoTaskInTime because the animation looks weird, and if the player goes over water, they do the drowning animation.

 

hmmm, im looking around and it seems like you can just disable drowning temporary like moose/goose in the Reign of Runts mod, so maybe thats not an issue

 

15 hours ago, FerniFrenito said:

In my opinion, a better solution is to use teleport to TP the player to your side and make them invisible. Create a prefab (for FX only) with the player's skin and move it to your side. When the prefab reaches your side, remove it and make the player visible again.

i'm saving teleporting as a last resort cuz i do think being dragged along the way is funny lol

 

tbh tho, i have no idea how to do the moving part, based on what i know so far i can only imagine something like a DoPeriodicTask that quickly teleport the player a tiny bit until they're next to you but idk

I found this mod that's doing the same thing i want but with item https://steamcommunity.com/sharedfiles/filedetails/?id=1819208941

RETRIEVE_VIA_FISHINGROD.fn = function(act)
	--confirm there is an item lost to the sea
    if act.target and act.target.components.inventoryitem
	and act.target.components.inventoryitem.canbepickedup and not act.target.components.inventoryitem:IsHeld() then
		local pt = act.target:GetPosition()
		--confirm this thing is on water (including IslandAdventures support)
		if TheWorld.Map:InternalIsPointOnWater(pt.x, pt.z) or act.target.IsOnWater and act.target:IsOnWater() then
			--rescue the item
			-- act.invobject.components.fishingrod:StartRetrieving(act.target, act.doer)

			if act.doer or act.invobject then
				--LaunchAt(inst, launcher, target, speedmult, startheight, startradius, randomangleoffset)
				LaunchAt(act.target, act.target, act.doer or act.invobject, 4, nil, nil, 0) --TODO 0 for preview loop
				act.target.components.inventoryitem:SetLanded(false, true)
			end

			if act.invobject then
				act.invobject:PushEvent("fishingcollect", {fish = act.target})
			end
			if act.doer then
				act.doer:PushEvent("fishingcollect", {fish = act.target})
			end

			return true
		end
	end
end

i tried to repurpose the code so it can target players/monster on land but doesnt work :c it did work on birds though, im not sure what i'm missing


    if act.target  then
		if act.doer or act.invobject then
			if act.target.Physics then
				if act.target.components.drownable ~= nil then
					if act.target.components.drownable.enabled ~= false then
						act.target.components.drownable.enabled = false --disable drowning
						
					end
				end
				
				--turn target into projectile to throw at you
				act.target:AddComponent("projectile")
				act.target:AddComponent("weapon")
				act.target.components.weapon:SetDamage(0)
				act.target.components.projectile:SetSpeed(40)

				
				if act.target and act.target.brain and act.target.sample_projectilestun ~= true then
					act.target.sample_projectilestun = true
					act.target.brain:Stop()
					if act.target.components.locomotor then
						act.target.components.locomotor:Stop()
						
					end
				end
			
				
				--Pulling
				act.target:DoTaskInTime(0.1,function()act.target.components.projectile:Throw(act.target, act.doer) end)

				--Return target to normal
				act.target:DoTaskInTime(1,function()
					act.target:RemoveComponent("projectile")
					act.target:RemoveComponent("weapon")
						if act.target.components.drownable ~= nil then
							if act.target.components.drownable.enabled == false then
								act.target.components.drownable.enabled = true
								if act.target.brain ~= nil then
									act.target.brain:Start()
									act.target.sample_projectilestun = nil
								end
						
							end
						end
				end)
			end
				

			
				
			end


			return true
		
	end

here's what i came up with so far, the pulling works but there's a lot of issues, sometimes the brain just doesn't turn back on and the target just stand still idling

On 9/4/2025 at 8:23 PM, FerniFrenito said:

In fact we only need to call:

if self.inst.components.combat ~= nil then 
  self.inst.components.combat:SetTarget(nil) -- This immobilizes the player, stopping attacks.
end

if self.inst.components.locomotor ~= nil then
  self.inst.components.locomotor:Stop() -- This immobilizes the player, stopping movement.
end

 

im not sure if i dont something wrong but this doesn't seem to do anything at all, both player and mob still can move, which if they do would cancel the grab mid way

 

Try this:

--Return target to normal
act.target:DoTaskInTime(1,function()
    act.target:RemoveComponent("projectile")
    act.target:RemoveComponent("weapon")
    if act.target.components.drownable ~= nil and (not act.target.components.drownable.enabled) then
        act.target.components.drownable.enabled = true
    end
    if act.target.brain ~= nil then
      act.target.brain:Start()
      act.target.sample_projectilestun = nil
    end
  end)

Your original code only start the brain if the target has drownable component.

1 hour ago, FerniFrenito said:

Try this:

--Return target to normal
act.target:DoTaskInTime(1,function()
    act.target:RemoveComponent("projectile")
    act.target:RemoveComponent("weapon")
    if act.target.components.drownable ~= nil and (not act.target.components.drownable.enabled) then
        act.target.components.drownable.enabled = true
    end
    if act.target.brain ~= nil then
      act.target.brain:Start()
      act.target.sample_projectilestun = nil
    end
  end)

Your original code only start the brain if the target has drownable component.

oooohh nice catch, thanks! it seems to work properly now, the brain stuff that is. it still sometime get interrupted mid way but i dont know why. can i just upload the mod folder here and you check it for me? 👉👈

2 hours ago, amazingGob said:

oooohh nice catch, thanks! it seems to work properly now, the brain stuff that is. it still sometime get interrupted mid way but i dont know why. can i just upload the mod folder here and you check it for me? 👉👈

Yes, but before try this:

...
act.target.components.projectile:SetSpeed(40)

if act.target then  
  if act.target.brain then
  	act.target.brain:Stop()
  end
  if act.target.components and act.target.components.locomotor then
    act.target.components.locomotor:Stop()
  end
  if (act.target.sample_projectilestun ~= nil) and (not act.target.sample_projectilestun) then
    act.target.sample_projectilestun = true
  end
end

 

Edited by FerniFrenito
15 hours ago, FerniFrenito said:

Yes, but before try this:

...
act.target.components.projectile:SetSpeed(40)

if act.target then  
  if act.target.brain then
  	act.target.brain:Stop()
  end
  if act.target.components and act.target.components.locomotor then
    act.target.components.locomotor:Stop()
  end
  if (act.target.sample_projectilestun ~= nil) and (not act.target.sample_projectilestun) then
    act.target.sample_projectilestun = true
  end
end

 

I added it and it didnt't seem to change anything ¯\_(ツ)_/¯ 

 

i changed a bunch of stuff since, mainly turning off player input with

 act.target.components.playercontroller:Enable(false)

 

here's the mod file

 

pulling.zip

I resolve the bug i guess.

--Pulling
act.target:DoTaskInTime(0.1,function()
    act.target.sg:GoToState("idle") -- Go to idle
    act.target.sg:AddStateTag("busy") -- Busy to make the state uninterrupted
    act.target.components.projectile:Throw(act.target, act.doer)
  end)

--Return target to normal
act.target:DoTaskInTime(1,function()
    act.target:RemoveComponent("projectile")
    act.target:RemoveComponent("weapon")
    act.target.sg:RemoveStateTag("busy") -- Remove busy tag 
    if act.target.components.drownable ~= nil then

Now the hounds don't stop when you hug them.
Although there's another bug, for some reason when I try to lure birds, they sometimes get drawn far away in another direction.

Edited by FerniFrenito
  • Like 1

I got it!.

modmain.lua

I don't know why Projectile:RotateToTarget() doesn't work properly, but it does work for the boomerang (the only game object that uses that function). I need to override the function; now your ability works.

Should I report this as a bug? (Apparently, the fixed function doesn't affect the boomerang)

modmain.lua (That's different modmain.lua) I improved the code so that instead of returning to normal after a predetermined time, it does so instantly after colliding with the player.

Edited by FerniFrenito
  • Like 1

OMG thank you!!! it works exactly how i want it now!!!

3 hours ago, FerniFrenito said:

I improved the code so that instead of returning to normal after a predetermined time, it does so instantly after colliding with the player.

oohh but would there be an issue if the target miss the player?

17 minutes ago, amazingGob said:

OMG thank you!!! it works exactly how i want it now!!!

oohh but would there be an issue if the target miss the player?

don't worry, that's imposible, the thing you hug follows the player like the boomerang, but the speed is so high that you don't even notice it, since you don't have time to move. The only way to avoid it hitting you is to use commands, but even then, it will catch up with you sooner or later.

  • Like 1

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...