Jump to content

Scripting Guidance


ttemplar

Recommended Posts

I'm currently working on a character mod with quite a few perks and i have run into a few complications while trying to implement some key features.
 
First I am trying to add a working re-loadable gun. I have tried to cannibalize the sewing component and sewing kit prefab. I have added a new action via modmain and that all works correctly. The action fires when the bullets are used and the character does the little working animation but then he says "I can't do that" and the weapon is not reloaded (repaired).
 
reload.lua

local reload = Class(function(self, inst)self.inst = instself.repair_value = 1end)function reload:DoReload(target, doer)if target.components.finiteuses and target.components.finiteuses:GetPercent() < 6 thentarget.components.finiteuses:Uses(self.repair_value)if self.inst.components.finiteuses thenself.inst.components.finiteuses:SetPercent(1)endif self.onreload thenself.onreload(self.inst, target, doer)endreturn trueendendfunction reload:CollectUseActions(doer, target, actions, right)--this... should be redone without using the fueled component... it's kind of weird.if target.components.finiteuses and target.components.finiteuses:GetPercent() < 6 thentable.insert(actions, ACTIONS.RELOADCOMP)endendreturn reload

 


bullets.lua
local assets={	Asset("ANIM", "anim/sewing_kit.zip"),}local function onfinished(inst)	inst:Remove()endlocal function onreload(inst, target, doer)	if doer.SoundEmitter then		doer.SoundEmitter:PlaySound("dontstarve/HUD/repair_clothing")	endendlocal function fn(Sim)	local inst = CreateEntity()	inst.entity:AddTransform()	inst.entity:AddAnimState()        MakeInventoryPhysics(inst)    inst.AnimState:SetBank("sewing_kit")    inst.AnimState:SetBuild("sewing_kit")    inst.AnimState:PlayAnimation("idle")        inst:AddComponent("finiteuses")    inst.components.finiteuses:SetMaxUses(TUNING.SEWINGKIT_USES)    inst.components.finiteuses:SetUses(TUNING.SEWINGKIT_USES)    inst.components.finiteuses:SetOnFinished( onfinished )        inst:AddComponent("reload")    inst.components.reload.repair_value = TUNING.SEWINGKIT_REPAIR_VALUE    inst.components.reload.onreload = onreload    ---------------------                       inst:AddComponent("inspectable")        inst:AddComponent("inventoryitem")    return instendreturn Prefab( "common/inventory/bullets", fn, assets) 

 


shotgun.lua
local assets={	Asset("ANIM", "anim/spear.zip"),	Asset("ANIM", "anim/swap_spear.zip"),}local prefabs = {    "impact",}local function onfinished(inst)	self.inst = inst    self.components.weapon:SetDamage(17)	self.components.weapon:SetRange(0, 0)endlocal function onequip(inst, owner)     owner.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")    owner.AnimState:Show("ARM_carry")     owner.AnimState:Hide("ARM_normal") endlocal function onunequip(inst, owner)    owner.AnimState:Hide("ARM_carry")    owner.AnimState:Show("ARM_normal")endlocal function onattack(inst, owner, target)	if owner.SoundEmitter then		owner.SoundEmitter:PlaySound("dontstarve/bee/beemine_explo")	end	local impactfx = SpawnPrefab("impact")    if impactfx and target then	    local follower = impactfx.entity:AddFollower()	    follower:FollowSymbol(target.GUID, target.components.combat.hiteffectsymbol, 0, 0, 0 )        impactfx:FacePoint(target.Transform:GetWorldPosition())    endendlocal function fn(Sim)	local inst = CreateEntity()	local trans = inst.entity:AddTransform()	local anim = inst.entity:AddAnimState()    MakeInventoryPhysics(inst)	    	    anim:SetBank("spear")    anim:SetBuild("spear")    anim:PlayAnimation("idle")        inst:AddTag("sharp")    inst:AddTag("firestaff")    inst:AddComponent("weapon")    inst.components.weapon:SetDamage(80)	inst.components.weapon:SetRange(8, 10)	inst.components.weapon.onattack = onattack        inst:AddComponent("finiteuses")    inst.components.finiteuses:SetMaxUses(6)    inst.components.finiteuses:SetUses(6)        --inst.components.finiteuses:SetOnFinished( onfinished )    inst:AddComponent("inspectable")        inst:AddComponent("inventoryitem")        inst:AddComponent("equippable")    inst.components.equippable:SetOnEquip( onequip )    inst.components.equippable:SetOnUnequip( onunequip )        return instendlocal function fire(inst)    inst.AnimState:PlayAnimation("dart_purple")endreturn Prefab( "common/inventory/shotgun", fn, assets) 

 

Also besides this hiccup I am trying to figure out how to make the gun stop firing when it is out of ammo(broken) as I don't want to remove it from the player when it is out of ammo.

 

And I know I can change the use animation of the shotgun by changing the tag under fn(Sim). However none of the ones already in the game fit with firing a shotgun. How does one go about adding new use animations or changing existing ones?

 

Any help is greatly appreciated! 

Link to comment
Share on other sites

  • Developer

I'm currently working on a character mod with quite a few perks and i have run into a few complications while trying to implement some key features.

 

First I am trying to add a working re-loadable gun. I have tried to cannibalize the sewing component and sewing kit prefab. I have added a new action via modmain and that all works correctly. The action fires when the bullets are used and the character does the little working animation but then he says "I can't do that" and the weapon is not reloaded (repaired).

 

reload.lua

local reload = Class(function(self, inst)self.inst = instself.repair_value = 1end)function reload:DoReload(target, doer)if target.components.finiteuses and target.components.finiteuses:GetPercent() < 6 thentarget.components.finiteuses:Uses(self.repair_value)if self.inst.components.finiteuses thenself.inst.components.finiteuses:SetPercent(1)endif self.onreload thenself.onreload(self.inst, target, doer)endreturn trueendendfunction reload:CollectUseActions(doer, target, actions, right)--this... should be redone without using the fueled component... it's kind of weird.if target.components.finiteuses and target.components.finiteuses:GetPercent() < 6 thentable.insert(actions, ACTIONS.RELOADCOMP)endendreturn reload

 

bullets.lua

local assets={	Asset("ANIM", "anim/sewing_kit.zip"),}local function onfinished(inst)	inst:Remove()endlocal function onreload(inst, target, doer)	if doer.SoundEmitter then		doer.SoundEmitter:PlaySound("dontstarve/HUD/repair_clothing")	endendlocal function fn(Sim)	local inst = CreateEntity()	inst.entity:AddTransform()	inst.entity:AddAnimState()        MakeInventoryPhysics(inst)    inst.AnimState:SetBank("sewing_kit")    inst.AnimState:SetBuild("sewing_kit")    inst.AnimState:PlayAnimation("idle")        inst:AddComponent("finiteuses")    inst.components.finiteuses:SetMaxUses(TUNING.SEWINGKIT_USES)    inst.components.finiteuses:SetUses(TUNING.SEWINGKIT_USES)    inst.components.finiteuses:SetOnFinished( onfinished )        inst:AddComponent("reload")    inst.components.reload.repair_value = TUNING.SEWINGKIT_REPAIR_VALUE    inst.components.reload.onreload = onreload    ---------------------                       inst:AddComponent("inspectable")        inst:AddComponent("inventoryitem")    return instendreturn Prefab( "common/inventory/bullets", fn, assets) 

 

shotgun.lua

local assets={	Asset("ANIM", "anim/spear.zip"),	Asset("ANIM", "anim/swap_spear.zip"),}local prefabs = {    "impact",}local function onfinished(inst)	self.inst = inst    self.components.weapon:SetDamage(17)	self.components.weapon:SetRange(0, 0)endlocal function onequip(inst, owner)     owner.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")    owner.AnimState:Show("ARM_carry")     owner.AnimState:Hide("ARM_normal") endlocal function onunequip(inst, owner)    owner.AnimState:Hide("ARM_carry")    owner.AnimState:Show("ARM_normal")endlocal function onattack(inst, owner, target)	if owner.SoundEmitter then		owner.SoundEmitter:PlaySound("dontstarve/bee/beemine_explo")	end	local impactfx = SpawnPrefab("impact")    if impactfx and target then	    local follower = impactfx.entity:AddFollower()	    follower:FollowSymbol(target.GUID, target.components.combat.hiteffectsymbol, 0, 0, 0 )        impactfx:FacePoint(target.Transform:GetWorldPosition())    endendlocal function fn(Sim)	local inst = CreateEntity()	local trans = inst.entity:AddTransform()	local anim = inst.entity:AddAnimState()    MakeInventoryPhysics(inst)	    	    anim:SetBank("spear")    anim:SetBuild("spear")    anim:PlayAnimation("idle")        inst:AddTag("sharp")    inst:AddTag("firestaff")    inst:AddComponent("weapon")    inst.components.weapon:SetDamage(80)	inst.components.weapon:SetRange(8, 10)	inst.components.weapon.onattack = onattack        inst:AddComponent("finiteuses")    inst.components.finiteuses:SetMaxUses(6)    inst.components.finiteuses:SetUses(6)        --inst.components.finiteuses:SetOnFinished( onfinished )    inst:AddComponent("inspectable")        inst:AddComponent("inventoryitem")        inst:AddComponent("equippable")    inst.components.equippable:SetOnEquip( onequip )    inst.components.equippable:SetOnUnequip( onunequip )        return instendlocal function fire(inst)    inst.AnimState:PlayAnimation("dart_purple")endreturn Prefab( "common/inventory/shotgun", fn, assets) 

 

Also besides this hiccup I am trying to figure out how to make the gun stop firing when it is out of ammo(broken) as I don't want to remove it from the player when it is out of ammo.

 

And I know I can change the use animation of the shotgun by changing the tag under fn(Sim). However none of the ones already in the game fit with firing a shotgun. How does one go about adding new use animations or changing existing ones?

 

Any help is greatly appreciated! 

Unfortunately you can't add or change existing animations just yet.

Link to comment
Share on other sites

Thanks for that information @Cheerio that will save me time digging around the .lua files for ways to do that i guess.

 

I figured out a way to stop the gun from firing when it is out of ammo(broken). In fact the way I set it up you can use the rifle to hit things with it once it is out of ammo. :p

 

The reloading still has me stumped though. As I said I think it should work fine but my char just says "I cant do that".

 

 

Thanks for the help.

Link to comment
Share on other sites

Ok, no problem pardon the mess as it is a WIP. @Malacath Thanks for replying and any help you can provide.

So, a short update would be

if act.target.components.reload then	return act.invobject.components.reload:DoReload(act.target, act.doer)end

This is the problem. The if-condition never evaluates to true, you can see that by adding a "return true" below that block. It will not fix your problem but you will see that this is the problem  ; )  I'll see if I can find out what's amiss there.

 

EDIT: Of course, I was stupid earlier. The target is the shotgun which doesn't have the "reload" component. So you might need to hook that up differently. Like gíve the shotgun a component that contains the function to reload. Something along those lines should work.

Link to comment
Share on other sites

Eureka! I have it. Thanks for pointing me in the right direction @Malakath. That action if-statement not returning true really had me stumped.

 

The way I set it up is; I added the reload component to the shotgun and added a variable to the reload component to return true or false if the item is ammunition (to prevent shotguns from loading shotguns :razz:). Then I added a ListenEvent for "precentchange" from finiteuses.lua to the shotgun prefab to change the shotguns ranged\melee component.

 

My character just swings the shotgun wildly when he fires it but I guess I'll have to live with that for now.

Link to comment
Share on other sites

Now I am looking for a way to add/change character properties when an item is in their inventory. For example I have added an ammunition box and I would like it to decrease the players movement speed while it is in their inventory.

 

I have looked around inventoryitems.lua and inventory.lua but so far I have been unable to find anything to hook into. I have been able to change the characters run\walk speed via OnPutInInventory in the inventoryitems component but I could not reverse the change.

 

I know that the equippable component has a GetWalkSpeedMult function but as I said I don't want the item to be equippable just in the players inventory.

 

Any help/tips are greatly appreciated.

Link to comment
Share on other sites

I don't know anything about scripting and technical stuff like this, but some suggestions:

 

Try using the blow dart animation for the gun.

To make it so the gun doesn't break when out of ammo, try and make it like the miner hat or lantern, where it just becomes unusable.

 

These might not work, so sorry if they don't.

Link to comment
Share on other sites

 

 
inst.components.inventoryitem:SetOnDroppedFn(handler)
inst.components.inventoryitem:SetOnPickupFn(handler)
inst.components.inventoryitem:SetOnPutInInventoryFn(handler)
 
Just a hint at starting points

 

I have used those inventory item functions to detect when the item is in the players inventory. However I guess what I am having trouble with is changing the players run/walk speeds in locomotor.lua and reverting them to normal after the item was dropped/removed from the players inventory.

Link to comment
Share on other sites

I have used those inventory item functions to detect when the item is in the players inventory. However I guess what I am having trouble with is changing the players run/walk speeds in locomotor.lua and reverting them to normal after the item was dropped/removed from the players inventory.

You don't use those functions to detect if an item is in the inventory. The functions are called when the appropriate thing happens, for example

local function OnPutInInventory(inst, owner)    owner.components.locomotor.runspeed = 0.1    owner.components.locomotor.walkspeed = 1000endinst.components.inventoryitem:SetOnPutInInventoryFn(OnPutInInventory)

will set the speed of the entity that puts the item in his/her inventory at the exact moment that it is put in the inventory.

You can use SetOnDroppedFn in a similiar fashion to revert to normal speed when dropping the item. Look up the signature of the functions in the appropriate component files.

Link to comment
Share on other sites

Thanks a lot everyone! I got the ammo box working seemingly quite well.

 

Now I am trying to work out a way to prevent the player from carrying more that one ammo box. For example if the player has one in their inventory and tries to pick up another it will just swap it out and drop the one in their inventory.

 

I have thought about creating a new component to control this. But is there some way I could use a tag to tell the game not to allow the player to have more than one in their inventory?

Link to comment
Share on other sites

Thanks a lot everyone! I got the ammo box working seemingly quite well.

 

Now I am trying to work out a way to prevent the player from carrying more that one ammo box. For example if the player has one in their inventory and tries to pick up another it will just swap it out and drop the one in their inventory.

 

I have thought about creating a new component to control this. But is there some way I could use a tag to tell the game not to allow the player to have more than one in their inventory?

Same thing. Use an OnPutInInventoryFn to check if the inventory already contains said item and if so drop it.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...