Jump to content

Help me with Projectiles


Recommended Posts

local function OnProjectileLaunch(inst, attacker, target, proj, projectile)

    inst.SoundEmitter:PlaySound("dontstarve_DLC003/characters/wheeler/air_horn/shoot")
	
    proj:AddTag("projectile")

    proj:AddComponent("projectile")
    proj.components.projectile:SetSpeed(35)
    proj.components.projectile:SetOnHitFn(OnHit)

    proj.persists = false

    -- If the projectile still exists in 2 seconds something went wrong
    proj.self_destruct = proj:DoTaskInTime(2, function() proj:Remove() end)

    inst.ammo = inst.ammo - 1

    inst.components.inventory:RemoveItemBySlot(1, false)
end

Hello everyone! Today I'm having a problem with my projectile, i'm currently porting Wheeler over from hamlet and I'm having this problem with one of her functions in the pew matic horn, 'proj' is a nil value and I need to add some things to the item wheeler is launching. However Idk how to do this, with items such as blowdarts it's easy since their projectiles already have these tags but wheelers pew matic horn takes any item and I need to add the nescessary lines to those items once launched. If anyone can tell me how to do this i'd be very happy.

Thanks for reading!

Link to comment
Share on other sites

If proj is nil, then you need to find out where the function is called, so you can see why it isn't being sent the proj parameter. If you don't know where OnProjectileLaunch or some other function is called, you can use "Find in files..." in Notepad++ or similar text editor, to search through the game-files. Why does it have both a proj and a projectile parameter :confused: Anyway, the code for Hamlet may be different for these things than in DST, so maybe the proj parameter isn't even part of the game code in DST. There are many things to consider when porting things from game to game.

Link to comment
Share on other sites

29 minutes ago, Ultroman said:

If proj is nil, then you need to find out where the function is called, so you can see why it isn't being sent the proj parameter. If you don't know where OnProjectileLaunch or some other function is called, you can use "Find in files..." in Notepad++ or similar text editor, to search through the game-files. Why does it have both a proj and a projectile parameter :confused: Anyway, the code for Hamlet may be different for these things than in DST, so maybe the proj parameter isn't even part of the game code in DST. There are many things to consider when porting things from game to game.

That's what I thought, the proj parameter isn't apart of DST, so I wanna see how else I could possibly add the tags and components?
(and ignore that projectile parameter. that was just me messing to see what could work)

Link to comment
Share on other sites

2 hours ago, Ultroman said:

Is the inst not the prefab instance of the item to be launched? It should be. Then that's the one you need to be adding components to.

No, this is in the Pew matics horn prefab(trusty_shooter) so inst would refer to the horn (Sorry for responding a bit late)

Link to comment
Share on other sites

It's a hard one, since the spawning and setup of the projectile happens in one function, LaunchProjectile, and it doesn't return the projectile. Depending on which point you have to intercept the projectile, you could overwrite the LaunchProjectile function of the weapon component on the horn, and do something after spawning the projectile.

Overwriting is bad, but sometimes you just have to do it, but in order to keep your mod up-to-date you then have to keep doing difference checks each update, to see if Klei has changed the original function, and then adopt those changes into your custom function.

You can do it like this in your weapon prefab LUA's fn() or master_postinit() function:

function inst.components.weapon:LaunchProjectile(attacker, target)
	if self.projectile ~= nil then
		if self.onprojectilelaunch ~= nil then
			self.onprojectilelaunch(self.inst, attacker, target)
		end

		local proj = SpawnPrefab(self.projectile)
		if proj ~= nil then
			-- Do something to the projectile here.
			if proj.components.projectile ~= nil then
				proj.Transform:SetPosition(attacker.Transform:GetWorldPosition())
				proj.components.projectile:Throw(self.inst, target, attacker)
				if self.inst.projectiledelay ~= nil then
					proj.components.projectile:DelayVisibility(self.inst.projectiledelay)
				end
			elseif proj.components.complexprojectile ~= nil then
				proj.Transform:SetPosition(attacker.Transform:GetWorldPosition())
				proj.components.complexprojectile:Launch(target:GetPosition(), attacker, self.inst)
			end
		end
	end
end

 

Edited by Ultroman
Link to comment
Share on other sites

15 minutes ago, Ultroman said:

It's a hard one, since the spawning and setup of the projectile happens in one function, LaunchProjectile, and it doesn't return the projectile. Depending on which point you have to intercept the projectile, you could overwrite the LaunchProjectile function of the weapon component on the horn, and do something after spawning the projectile.

Overwriting is bad, but sometimes you just have to do it, but in order to keep your mod up-to-date you then have to keep doing difference checks each update, to see if Klei has changed the original function, and then adopt those changes into your custom function.

You can do it like this in your weapon prefab LUA's fn() or master_postinit() function:


function inst.components.weapon:LaunchProjectile(attacker, target)
	if self.projectile ~= nil then
		if self.onprojectilelaunch ~= nil then
			self.onprojectilelaunch(self.inst, attacker, target)
		end

		local proj = SpawnPrefab(self.projectile)
		if proj ~= nil then
			-- Do something to the projectile here.
			if proj.components.projectile ~= nil then
				proj.Transform:SetPosition(attacker.Transform:GetWorldPosition())
				proj.components.projectile:Throw(self.inst, target, attacker)
				if self.inst.projectiledelay ~= nil then
					proj.components.projectile:DelayVisibility(self.inst.projectiledelay)
				end
			elseif proj.components.complexprojectile ~= nil then
				proj.Transform:SetPosition(attacker.Transform:GetWorldPosition())
				proj.components.complexprojectile:Launch(target:GetPosition(), attacker, self.inst)
			end
		end
	end
end

 

Thank you, I will try this code later today and come back if I need any help.

Link to comment
Share on other sites

2 hours ago, Ultroman said:

[snip]

Yes! Thank you so much, still some small problems like the shooter not taking stacked items or else it crashes.(and the fact that wheeler sometimes dodges infinitely)

I will come back if I need help with anything else.

Screenshot (82).png

Screenshot (83).png

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