PanAzej Posted July 16, 2016 Share Posted July 16, 2016 (edited) I'm making a throwable grenade item. However, I'd like it to be also usable as regular melee weapon. The problem is - character throws the item, no matter what. I tried setting up new actions for left and right mouse button. Still, on left click (melee) character just runs up to the enemy and throws the grenade. Here's what I did so far. Grenade's prefab: local assets = { -- Animation files used for the item. Asset("ANIM", "anim/ullapool_caber.zip"), Asset("ANIM", "anim/swap_ullapool_caber.zip"), Asset("ANIM", "anim/ullapool_caber_dud.zip"), Asset("ANIM", "anim/swap_ullapool_caber_dud.zip"), -- Inventory image and atlas file used for the item. Asset("ATLAS", "images/inventoryimages/ullapool_caber.xml"), Asset("IMAGE", "images/inventoryimages/ullapool_caber.tex"), Asset("ATLAS", "images/inventoryimages/ullapool_caber_dud.xml"), Asset("IMAGE", "images/inventoryimages/ullapool_caber_dud.tex"), } local function MakeDud(inst) inst.components.weapon:SetDamage(17) inst.components.weapon.onattack = nil if inst.components.explosive then inst:RemoveComponent("explosive") end if inst.components.complexprojectile then inst:RemoveComponent("complexprojectile") end if inst:HasTag("caber_throwable") then inst:RemoveTag("caber_throwable") end if not inst.components.fuel then inst:AddComponent("fuel") inst.components.fuel.fuelvalue = TUNING.SMALL_FUEL end if not inst.components.finiteuses then inst:AddComponent("finiteuses") inst.components.finiteuses:SetMaxUses(10) inst.components.finiteuses:SetUses(10) inst.components.finiteuses:SetOnFinished(inst.Remove) end if not inst.components.tool then inst:AddComponent("tool") -- to trigger 'break' animation end inst.components.inventoryitem.atlasname = "images/inventoryimages/ullapool_caber_dud.xml" inst.components.inventoryitem:ChangeImageName("ullapool_caber_dud") inst.AnimState:SetBank("ullapool_caber_dud") inst.AnimState:SetBuild("ullapool_caber_dud") inst.AnimState:PlayAnimation("swap") if inst.components.equippable and inst.components.equippable:IsEquipped() and inst.components.inventoryitem and inst.components.inventoryitem.owner then local owner = inst.components.inventoryitem.owner owner.AnimState:OverrideSymbol("swap_object", "swap_ullapool_caber_dud", "swap_ullapool_caber_dud") end inst.iscaberdud = true end local function ExplodeCaber(inst) local owner = nil local target = nil if inst.components.inventoryitem.owner and inst.components.inventoryitem.owner.components.combat and inst.components.inventoryitem.owner.components.combat.target then owner = inst.components.inventoryitem.owner target = owner.components.combat.target SpawnPrefab("explode_small").Transform:SetPosition(target.Transform:GetWorldPosition()) else SpawnPrefab("explode_small").Transform:SetPosition(inst.Transform:GetWorldPosition()) end --Change into a dud (if not thrown) if inst.components.equippable:IsEquipped() then MakeDud(inst) end end local function ForceExplosion(inst) if inst.components.explosive then inst.components.explosive:OnBurnt() end end local function onequip(inst, owner) if inst.iscaberdud == nil then owner.AnimState:OverrideSymbol("swap_object", "swap_ullapool_caber", "swap_ullapool_caber") else owner.AnimState:OverrideSymbol("swap_object", "swap_ullapool_caber_dud", "swap_ullapool_caber_dud") end owner.AnimState:Show("ARM_carry") owner.AnimState:Hide("ARM_normal") end local function onunequip(inst, owner) owner.AnimState:Hide("ARM_carry") owner.AnimState:Show("ARM_normal") end local function OnHitCaber(inst, attacker, target) ForceExplosion(inst) if inst.components.explosive then local x, y, z = inst.Transform:GetWorldPosition() local ents = TheSim:FindEntities(x, y, z, inst.components.explosive.explosiverange, nil, { "INLIMBO" }) for k, v in ipairs(ents) do if v:IsValid() and not v:IsInLimbo() then if v.components.combat ~= nil and (attacker.drunkscrumpy == nil or attacker.drunkscrumpy == 0) and not v:HasTag("demoman") then v.components.combat:GetAttacked(attacker, inst.components.explosive.explosivedamage*0.75, nil) -- ullapool caber when thrown (150 dmg) elseif v.components.combat ~= nil and (attacker.drunkscrumpy ~= nil and attacker.drunkscrumpy > 0) and not v:HasTag("demoman") then v.components.combat:GetAttacked(attacker, (inst.components.explosive.explosivedamage*0.75)*2, nil) -- CRIT ullapool caber when thrown (300 dmg) elseif v.components.combat ~= nil and (attacker.drunkscrumpy == nil or attacker.drunkscrumpy == 0) and v:HasTag("demoman") then v.components.combat:GetAttacked(attacker, (inst.components.explosive.explosivedamage*0.75)*0.5, nil) -- ullapool caber when thrown (150 dmg) elseif v.components.combat ~= nil and (attacker.drunkscrumpy ~= nil and attacker.drunkscrumpy > 0) and v:HasTag("demoman") then v.components.combat:GetAttacked(attacker, ((inst.components.explosive.explosivedamage*0.75)*2)*0.5, nil) -- CRIT ullapool caber when thrown (300 dmg) end v:PushEvent("explosion", { explosive = inst }) end end end inst:Remove() end local function onthrown(inst) inst:AddTag("NOCLICK") inst.persists = false inst.AnimState:PlayAnimation("spin_loop", true) inst.Physics:SetMass(1) inst.Physics:SetCapsule(0.2, 0.2) inst.Physics:SetFriction(0) inst.Physics:SetDamping(0) inst.Physics:SetCollisionGroup(COLLISION.CHARACTERS) inst.Physics:ClearCollisionMask() inst.Physics:CollidesWith(COLLISION.WORLD) inst.Physics:CollidesWith(COLLISION.OBSTACLES) inst.Physics:CollidesWith(COLLISION.ITEMS) end local function ReticuleTargetFn() local player = ThePlayer local ground = TheWorld.Map local x, y, z --Attack range is 8, leave room for error --Min range was chosen to not hit yourself (2 is the hit range) for r = 6.5, 3.5, -.25 do x, y, z = player.entity:LocalToWorldSpace(r, 0, 0) if ground:IsPassableAtPoint(x, y, z) then return Vector3(x, y, z) end end return Vector3(x, y, z) end local function getstatus(inst, viewer) return inst.iscaberdud == true and "DUD" or nil end local function onsave(inst, data) if data and inst.iscaberdud ~= nil then data.iscaberdud = inst.iscaberdud end end local function onpreload(inst, data) if data and data.iscaberdud ~= nil then inst.iscaberdud = data.iscaberdud end end local function onload(inst, data) if inst.iscaberdud ~= nil then MakeDud(inst) end end local function init() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.AnimState:SetBank("ullapool_caber") inst.AnimState:SetBuild("ullapool_caber") inst.AnimState:PlayAnimation("swap") inst:AddTag("caber") inst:AddTag("caber_throwable") inst.entity:SetPristine() inst:AddComponent("reticule") inst.components.reticule.targetfn = ReticuleTargetFn inst.components.reticule.ease = true if not TheWorld.ismastersim then return inst end inst:AddComponent("explosive") inst.components.explosive:SetOnExplodeFn(ExplodeCaber) inst.components.explosive.explosivedamage = TUNING.ULLAPOOL_CABER_DAMAGE -- default 200 inst.components.explosive.range = 6 inst.components.explosive.lightonexplode = false inst:AddComponent("weapon") inst.components.weapon:SetDamage(0) -- Explosion will deal damage inst.components.weapon:SetOnAttack(ForceExplosion) inst.components.weapon.attackrange = nil inst:AddComponent("inventoryitem") inst.components.inventoryitem.atlasname = "images/inventoryimages/ullapool_caber.xml" inst.components.inventoryitem.imagename = "ullapool_caber" inst:AddComponent("complexprojectile") inst.components.complexprojectile:SetHorizontalSpeed(15) inst.components.complexprojectile:SetGravity(-35) inst.components.complexprojectile:SetLaunchOffset(Vector3(.25, 1, 0)) inst.components.complexprojectile:SetOnLaunch(onthrown) inst.components.complexprojectile:SetOnHit(OnHitCaber) inst:AddComponent("equippable") inst.components.equippable:SetOnEquip(onequip) inst.components.equippable:SetOnUnequip(onunequip) inst.iscaberdud = nil inst:AddComponent("inspectable") inst.components.inspectable.getstatus = getstatus --inst:RemoveTag("projectile") --inst:RemoveTag("thrown") --inst:RemoveTag("throw") MakeHauntableLaunch(inst) inst.OnSave = onsave inst.OnPreLoad = onpreload inst.OnLoad = onload return inst end return Prefab("common/inventory/ullapool_caber", init, assets) And here's some new actions in modmain I tried making: -- Ullapolean Throw! ---------------------------------- local ULLATHROW = GLOBAL.Action({ priority= 10, distance= 10, mount_valid=true }) ULLATHROW.str = "Throw" ULLATHROW.id = "ULLATHROW" ULLATHROW.fn = function(act) if act.invobject and act.doer then if act.invobject.components.complexprojectile and act.invobject:HasTag("caber_throwable") 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.pos end projectile.components.complexprojectile:Launch(pos, act.doer) return true end end end end AddAction(ULLATHROW) local ullathrowing_handler = ActionHandler(ACTIONS.ULLATHROW, "throw") AddStategraphActionHandler("wilson", ullathrowing_handler) AddComponentAction("POINT", "complexprojectile", function(inst, doer, pos, actions, right) if inst:HasTag("caber") and inst:HasTag("caber_throwable") and right then table.insert(actions, ACTIONS.ULLATHROW) end end) AddComponentAction("EQUIPPED", "complexprojectile", function(inst, doer, target, actions, right) if inst:HasTag("caber") and inst:HasTag("caber_throwable") and right then table.insert(actions, ACTIONS.ULLATHROW) end end) AddStategraphActionHandler("wilson_client", ullathrowing_handler) -- Ullapolean Hit! ---------------------------------- local ULLAHIT = GLOBAL.Action({ priority= 11, distance= nil, canforce=true, mount_valid=true, rangecheckfn=nil }) ULLAHIT.str = "Attack" ULLAHIT.id = "ULLAHIT" ULLAHIT.fn = function(act) act.doer.components.combat:DoAttack(act.target) return true end AddAction(ULLAHIT) local ullahitting_handler = ActionHandler(ACTIONS.ULLAHIT, "attack") AddStategraphActionHandler("wilson", ullahitting_handler) AddComponentAction("SCENE", "combat", function(inst, doer, actions, right) if not right and doer:CanDoAction(ACTIONS.ULLAHIT) and inst:HasTag("caber") and inst:HasTag("caber_throwable") and inst.replica.health ~= nil and not inst.replica.health:IsDead() and inst.replica.combat ~= nil and inst.replica.combat:CanBeAttacked(doer) then table.insert(actions, ACTIONS.ULLAHIT) end end) AddStategraphActionHandler("wilson_client", ullahitting_handler) Any help is appreciated! Edited July 16, 2016 by PanAzej PHP-code colors make it easier to look at... Link to comment https://forums.kleientertainment.com/forums/topic/68895-grenade-problems/ Share on other sites More sharing options...
DarkXero Posted July 18, 2016 Share Posted July 18, 2016 Here I made waterballoons not turn into projectiles when attacking. watertest.lua Link to comment https://forums.kleientertainment.com/forums/topic/68895-grenade-problems/#findComment-794122 Share on other sites More sharing options...
PanAzej Posted July 18, 2016 Author Share Posted July 18, 2016 10 hours ago, DarkXero said: Here I made waterballoons not turn into projectiles when attacking. watertest.lua Huge thanks to you, again! So, it was 'weapon' component that was mainly screwing me over. Link to comment https://forums.kleientertainment.com/forums/topic/68895-grenade-problems/#findComment-794291 Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now