Jump to content

Turning a projectile into an ability


Recommended Posts

I currently have an throwable explosive projectile in my mod, thrown by holding it in your hand and clicking where you want to throw it. I want to move it to pressing a key to throw it, but I don't know how I could do that. Is there some way I could spawn the item as already thrown, and have it be thrown towards the cursor?

Link to comment
Share on other sites

c_spawn "throwable_explosive"  --it will spawn your item on the cursor's location,

Napsack in DST works like grenade, its prefab name is "sleepbomb", maybe there you will find workaround of classic throw action.

You can definitely remove item from your hand and spawn it on desired location, but the step between previous two will be tricky part. I don't even know where to start. You need to play throw animation, but to cursor's location, sheeeeit my brain has melted down.

I recon the best method would be copying throw action and make it triggered by a keyboard button. This shouldn't be hard, but I don't know how to do the magic stuff inside modmain to make it happen.

Edited by Yakuzashi
  • Like 1
Link to comment
Share on other sites

13 minutes ago, Yakuzashi said:

c_spawn "throwable_explosive"  --it will spawn your item on the cursor's location,

Napsack in DST works like grenade, its prefab name is "sleepbomb", maybe there you will find workaround of classic throw action.

You can definitely remove item from your hand and spawn it on desired location, but the step between previous two will be tricky part. I don't even know where to start. You need to play throw animation, but to cursor's location, sheeeeit my brain has melted down.

I recon the best method would be copying throw action and make it triggered by a keyboard button. This shouldn't be hard, but I don't know how to do the magic stuff inside modmain to make it happen.

The problem is, the way I want it to flow would involve the player not stopping to do a throw animation, and ideally I would want the explosive to exist outside of the inventory, as the ability is infinite and just on a cool down.

Link to comment
Share on other sites

Yes, you can do this. Assuming you are using the toss action (or any action at all), all you need to do is create a buffered action and then push it to the player to perform it. When you send your RPC, you'll want to get the world position of the mouse from TheInput and pass the x and z coordinates as extra variables (individually, as last time I checked you could not pass tables through an RPC). You can pass the y coordinate as well, but it doesn't really make a difference (just references height). Then on the server, use this position data to create a BufferedAction object of the TOSS action and have the player perform it, like so:

local buffaction = BufferedAction(player, nil, ACTIONS.TOSS, invobject, pos)
player.components.playercontroller:DoAction(buffaction)

I'm skipping some steps but the principle is there.

Edited by Ziro2k
  • Like 2
Link to comment
Share on other sites

On 11/28/2020 at 7:23 AM, Ziro2k said:

Yes, you can do this. Assuming you are using the toss action (or any action at all), all you need to do is create a buffered action and then push it to the player to perform it. When you send your RPC, you'll want to get the world position of the mouse from TheInput and pass the x and z coordinates as extra variables (individually, as last time I checked you could not pass tables through an RPC). You can pass the y coordinate as well, but it doesn't really make a difference (just references height). Then on the server, use this position data to create a BufferedAction object of the TOSS action and have the player perform it, like so:


local buffaction = BufferedAction(player, nil, ACTIONS.TOSS, invobject, pos)
player.components.playercontroller:DoAction(buffaction)

I'm skipping some steps but the principle is there.

I did some research by searching through every mod and script I could find, and I couldn't help myself all that well. I got it to a point where I'm passing the position of my mouse to the buffered action, but every time I try to execute the TOSS my character says "I can't do that", seemingly a Wilson fallback line of some sort indicating a failure. I'm not sure why this happens, but I suspect I'm not defining my inventory object correctly. I would post what I've done but I'm not able to at the moment. Should invobject be the slot to take from or the name of the prefab I want to use? Ideally I would want it to just spawn the prefab directly, as the item it's throwing won't actually exist in the inventory.

Link to comment
Share on other sites

5 hours ago, TheSkylarr said:

I did some research by searching through every mod and script I could find, and I couldn't help myself all that well. I got it to a point where I'm passing the position of my mouse to the buffered action, but every time I try to execute the TOSS my character says "I can't do that", seemingly a Wilson fallback line of some sort indicating a failure. I'm not sure why this happens, but I suspect I'm not defining my inventory object correctly. I would post what I've done but I'm not able to at the moment. Should invobject be the slot to take from or the name of the prefab I want to use? Ideally I would want it to just spawn the prefab directly, as the item it's throwing won't actually exist in the inventory.

This is the function that the TOSS action uses to validate the action, found in actions.lua:

ACTIONS.TOSS.fn = function(act)
    if act.invobject and act.doer then
        if act.invobject.components.complexprojectile and act.doer.components.inventory then
            local projectile = act.doer.components.inventory:DropItem(act.invobject, false)
            if projectile then
                local pos = nil
                if act.target then
                    pos = act.target:GetPosition()
                    projectile.components.complexprojectile.targetoffset = {x=0,y=1.5,z=0}
                else
                    pos = act:GetActionPoint()
                end
                projectile.components.complexprojectile:Launch(pos, act.doer)
                return true
            end
        end
    end
end

If this function doesn't return true, then you enter that failure state with the "I can't do that" line and nothing happens. Invobject needs to be the item you're throwing, not just the same prefab, and it has to be in the character's inventory (note that equipped items are still considered in the inventory). It also needs to have the complexprojectile component. I'm not sure how the item you're throwing won't exist in the player's inventory, are you generating it spontaneously, like an ability? I assumed from your first post that it's a physical object because you mentioned that you had to equip it and then throw it, unless it's similar to a "gun" and the projectiles are a sort of ammo.

  • Like 1
Link to comment
Share on other sites

6 hours ago, Ziro2k said:

This is the function that the TOSS action uses to validate the action, found in actions.lua:


ACTIONS.TOSS.fn = function(act)
    if act.invobject and act.doer then
        if act.invobject.components.complexprojectile and act.doer.components.inventory then
            local projectile = act.doer.components.inventory:DropItem(act.invobject, false)
            if projectile then
                local pos = nil
                if act.target then
                    pos = act.target:GetPosition()
                    projectile.components.complexprojectile.targetoffset = {x=0,y=1.5,z=0}
                else
                    pos = act:GetActionPoint()
                end
                projectile.components.complexprojectile:Launch(pos, act.doer)
                return true
            end
        end
    end
end

If this function doesn't return true, then you enter that failure state with the "I can't do that" line and nothing happens. Invobject needs to be the item you're throwing, not just the same prefab, and it has to be in the character's inventory (note that equipped items are still considered in the inventory). It also needs to have the complexprojectile component. I'm not sure how the item you're throwing won't exist in the player's inventory, are you generating it spontaneously, like an ability? I assumed from your first post that it's a physical object because you mentioned that you had to equip it and then throw it, unless it's similar to a "gun" and the projectiles are a sort of ammo.

Ah okay, I figured I could get away with having Invobject go to a function that spawns the prefab, but I suppose not. My item already has the complexprojectile component as well. The thing about it not existing in the inventory, is it IS an ability, I just had it working on an item because I had no idea how else to do it before I asked here. Is there some way I might be able to either spawn the prefab right there and make it work, or somehow have an invisible inventory slot where an infinite amount of my item exists?

One final question, does the item have to be in an equipped slot, or even be equipable? It doesn't say that in the script here.

Link to comment
Share on other sites

1 hour ago, TheSkylarr said:

Is there some way I might be able to either spawn the prefab right there and make it work, or somehow have an invisible inventory slot where an infinite amount of my item exists?

Your best bet in this case is to create your own action (with AddAction) based off of the TOSS action above. The action function for it would look pretty much identical, except that you would remove any references to act.invobject and you would change the fourth line above to:

local projectile = SpawnPrefab("yourprojectilenamehere")

thus spawning your projectile spontaneously upon use.

1 hour ago, TheSkylarr said:

One final question, does the item have to be in an equipped slot, or even be equipable? It doesn't say that in the script here.

No, that is not a requirement.

Link to comment
Share on other sites

1 hour ago, Ziro2k said:

Your best bet in this case is to create your own action (with AddAction) based off of the TOSS action above. The action function for it would look pretty much identical, except that you would remove any references to act.invobject and you would change the fourth line above to:


local projectile = SpawnPrefab("yourprojectilenamehere")

thus spawning your projectile spontaneously upon use.

No, that is not a requirement.

Alright, I'll take a look into this! Thanks for the help so far, you're freaking amazing, kind of a teacher honestly.

Link to comment
Share on other sites

I got stuck on this a few hours after you helped me. When I attempt to use my own actions, the server crashes with

[string "scripts/bufferedaction.lua"]:15: attempt to index local 'action' (a nil value)

This confuses me heavily, why is my action nil? I'm pretty sure it exists, as it's right above the buffered actions that's crashing the game.

I also have a second problem, it seems like my action isn't going through on the client side somehow. If I change the buffered action back to ACTIONS.TOSS, like I had it before, my character moves without any animation, and then just stands still and does nothing. I'm assuming the movement is to get into range to TOSS, but I'm not sure why my character just sits there afterwards and doesn't even TOSS.

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