Jump to content

Grenades and Lonliness!


Recommended Posts

New Years Is coming! I hope everyone enjoys going to Food-Coma because that's what gonna happen with me at my New Years Eve Feast~ Oh, and lots of drinking of...apple cider :grin:

 

Anyway I need some help with my new character~

 

2 Perks:

 

1. I need something like the waterballoon, but instead it explodes on impact(and also players are immune to the damage). Sort of like the Grenade mod on the workshop. But from what I've heard, that mods code is outdated and causes crashes.

 

2.I need my character to lose sanity quite fast when it's not around players because it gets lonely. Returns to normal sanity loss when near players.

 

I appreciate the help! Happy New Years everyone!

Edited by rons0n
Link to comment
Share on other sites

1. I need something like the waterballoon, but instead it explodes on impact(and also players are immune to the damage). Sort of like the Grenade mod on the workshop. But from what I've heard, that mods code is outdated and causes crashes.

 

Explosive waterballoon:

local waterballoon_assets = {    Asset("ANIM", "anim/waterballoon.zip"),    Asset("ANIM", "anim/swap_waterballoon.zip"),}local waterballoon_prefabs = {    "explode_small",}local function DoExplode(self)    local explosiverange = 5    local stacksize = self.inst.components.stackable ~= nil and self.inst.components.stackable:StackSize() or 1    local totaldamage = self.explosivedamage * stacksize    local x, y, z = self.inst.Transform:GetWorldPosition()    -- Players are off limits now    local ents = TheSim:FindEntities(x, y, z, explosiverange, nil, { "INLIMBO", "player" })    for i, v in ipairs(ents) do        if v ~= self.inst and v:IsValid() and not v:IsInLimbo() then            if v.components.workable ~= nil and v.components.workable:CanBeWorked() then                v.components.workable:WorkedBy(self.inst, self.buildingdamage)            end            --Recheck valid after work            if v:IsValid() and not v:IsInLimbo() then                if self.lightonexplode and                    v.components.fueled == nil and                    v.components.burnable ~= nil and                    not v.components.burnable:IsBurning() and                    not v:HasTag("burnt") then                    v.components.burnable:Ignite()                end                if v.components.combat ~= nil then                    v.components.combat:GetAttacked(self.inst, totaldamage, nil)                end                v:PushEvent("explosion", { explosive = self.inst })            end        end    endendlocal function OnExplodeFn(inst)    SpawnPrefab("explode_small").Transform:SetPosition(inst.Transform:GetWorldPosition())    DoExplode(inst.components.explosive)endlocal function OnHitWater(inst, attacker, target)    inst.components.explosive:OnBurnt()endlocal function common_fn(bank, build, anim, tag, isinventoryitem)    local inst = CreateEntity()    inst.entity:AddTransform()    inst.entity:AddAnimState()    inst.entity:AddSoundEmitter()    inst.entity:AddNetwork()    if isinventoryitem then        MakeInventoryPhysics(inst)    else        inst.entity:AddPhysics()        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)    end    if tag ~= nil then        inst:AddTag(tag)    end    inst.AnimState:SetBank(bank)    inst.AnimState:SetBuild(build)    inst.AnimState:PlayAnimation(anim, true)    inst.entity:SetPristine()    if not TheWorld.ismastersim then        return inst    end    inst:AddComponent("locomotor")    inst:AddComponent("complexprojectile")    return instendlocal function onequip(inst, owner)    owner.AnimState:OverrideSymbol("swap_object", "swap_waterballoon", "swap_waterballoon")    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 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)endlocal 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)endlocal function waterballoon_fn()    local inst = common_fn("waterballoon", "waterballoon", "idle", "projectile", true)    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(OnExplodeFn)    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE    -- So explosion doesn't affect anything, including players    inst.components.explosive.explosiverange = 0    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(OnHitWater)    inst:AddComponent("weapon")    inst.components.weapon:SetDamage(0)    inst.components.weapon:SetRange(8, 10)    inst:AddComponent("inspectable")    inst:AddComponent("inventoryitem")    inst.components.inventoryitem.imagename = "waterballoon"    inst:AddComponent("stackable")    inst:AddComponent("equippable")    inst.components.equippable:SetOnEquip(onequip)    inst.components.equippable:SetOnUnequip(onunequip)    inst.components.equippable.equipstack = true    return instendSTRINGS.NAMES.GRENADE = "Grenade"STRINGS.CHARACTERS.GENERIC.DESCRIBE.GRENADE = "It's a... explosive thing."return Prefab("grenade", waterballoon_fn, waterballoon_assets, waterballoon_prefabs)
2.I need my character to lose sanity quite fast when it's not around players because it gets lonely. Returns to normal sanity loss when near players.
local function sanityfn(inst)	-- Debuff, dusk/night debuff value	local delta = -0.08	-- Full bonus each player contributes	-- 0.08 for 1 player being enough to be close, 0.04 for 2 players required, 0.026 for 3, 0.02 for 4	local sz = 0.04    for i, v in ipairs(AllPlayers) do		if not (v == inst or v:HasTag("playerghost")) then			-- Other player needs to be within 10 units of distance for full sz bonus to apply, 10 * 10 = 100			local distsq = inst:GetDistanceSqToInst(v) - 100			delta = delta + sz / math.max(1, distsq)		end    end    return math.min(0, delta)endlocal function master_postinit(inst)	inst.components.sanity.custom_rate_fn = sanityfnend
Edited by DarkXero
Link to comment
Share on other sites

@DarkXero, New Year, same old awesome answers from you. Thanks! Though I think there was a slight misunderstanding, I wanted the explosion to hurt everyone but the players, but If thats not possible then i'm content with this. Just have to make it suuuper expensive!

 

I hope it doesn't bother but I do have one more question:

 

    local function OnEquip(inst, owner)		owner.components.combat:SetAreaDamage(7, 1)        owner.AnimState:OverrideSymbol("swap_object", "swap_elpheltshotgun", "swap_elpheltshotgun")        owner.AnimState:Show("ARM_carry")        owner.AnimState:Hide("ARM_normal")    end     local function OnUnequip(inst, owner)		owner.components.combat.remove:SetAreaDamage(7, 1)        owner.AnimState:Hide("ARM_carry")        owner.AnimState:Show("ARM_normal")    end

 

I made it so onequip of this particular weapon, her range attacks do AOE damage but when I tried to remove that ability on unequip it crashed. I think it's because simply slapping the word 'remove' does not actually do anything as I have no idea what I'm doing. What should I replace it with?

 

Regardless, hope I'm not burdening you with questions!

 

Edited by rons0n
Link to comment
Share on other sites

Though I think there was a slight misunderstanding, I wanted the explosion to hurt everyone but the players

 

That's why I put

inst.components.explosive.explosiverange = 0

and then make a custom explosion function, that takes player tags into account.

 

That way no players are harmed, allies or even the thrower itself.

 

I think it's because simply slapping the word 'remove' does not actually do anything as I have no idea what I'm doing. What should I replace it with?
local function OnEquip(inst, owner)    owner.components.combat:SetAreaDamage(7, 1)    owner.AnimState:OverrideSymbol("swap_object", "swap_elpheltshotgun", "swap_elpheltshotgun")    owner.AnimState:Show("ARM_carry")    owner.AnimState:Hide("ARM_normal")end local function OnUnequip(inst, owner)    owner.components.combat:SetAreaDamage(nil, nil)    owner.AnimState:Hide("ARM_carry")    owner.AnimState:Show("ARM_normal")end
Link to comment
Share on other sites

@DarkXero, Thanks DarkXero but

inst.components.explosive.explosiverange = 0

still makes everything invulnerable(Trees, birds, houses, etc) when I just needed the players to be the invulnerable ones. Maybe I missed something?

 

The grenade:

local elpheltbomb_assets = {    Asset("ANIM", "anim/elpheltbomb.zip"),    Asset("ANIM", "anim/swap_elpheltbomb.zip"),	    Asset("ATLAS", "images/inventoryimages/elpheltbomb.xml"),    Asset("IMAGE", "images/inventoryimages/elpheltbomb.tex"),} local elpheltbomb_prefabs = {    "explode_small",} local function Explode(self)    local stacksize = self.inst.components.stackable ~= nil and self.inst.components.stackable:StackSize() or 1    local totaldamage = self.explosivedamage * stacksize     local x, y, z = self.inst.Transform:GetWorldPosition()    -- Players are off limits now    local ents = TheSim:FindEntities(x, y, z, self.explosiverange, nil, { "INLIMBO", "player" })     for i, v in ipairs(ents) do        if v ~= self.inst and v:IsValid() and not v:IsInLimbo() then            if v.components.workable ~= nil and v.components.workable:CanBeWorked() then                v.components.workable:WorkedBy(self.inst, self.buildingdamage)            end             --Recheck valid after work            if v:IsValid() and not v:IsInLimbo() then                if self.lightonexplode and                    v.components.fueled == nil and                    v.components.burnable ~= nil and                    not v.components.burnable:IsBurning() and                    not v:HasTag("burnt") then                    v.components.burnable:Ignite()                end                 if v.components.combat ~= nil then                    v.components.combat:GetAttacked(self.inst, totaldamage, nil)                end                 v:PushEvent("explosion", { explosive = self.inst })            end        end    endend local function OnExplodeFn(inst)    SpawnPrefab("explode_small").Transform:SetPosition(inst.Transform:GetWorldPosition())    Explode(inst.components.explosive)end local function OnHitWater(inst, attacker, target)    inst.components.explosive:OnBurnt()end local function common_fn(bank, build, anim, tag, isinventoryitem)    local inst = CreateEntity()     inst.entity:AddTransform()    inst.entity:AddAnimState()    inst.entity:AddSoundEmitter()    inst.entity:AddNetwork()     if isinventoryitem then        MakeInventoryPhysics(inst)    else        inst.entity:AddPhysics()        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)    end     if tag ~= nil then        inst:AddTag(tag)    end     inst.AnimState:SetBank(bank)    inst.AnimState:SetBuild(build)    inst.AnimState:PlayAnimation(anim, true)     inst.entity:SetPristine()     if not TheWorld.ismastersim then        return inst    end     inst:AddComponent("locomotor")     inst:AddComponent("complexprojectile")     return instend local function onequip(inst, owner)    owner.AnimState:OverrideSymbol("swap_object", "swap_elpheltbomb", "swap_elpheltbomb")    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 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 elpheltbomb_fn()    local inst = common_fn("elpheltbomb", "elpheltbomb", "idle", "projectile", true)     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(OnExplodeFn)    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE    -- So explosion doesn't affect anything, including players    inst.components.explosive.explosiverange = 0     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(OnHitWater)     inst:AddComponent("weapon")    inst.components.weapon:SetDamage(0)    inst.components.weapon:SetRange(8, 10)     inst:AddComponent("inspectable")		inst.entity:AddLight()    inst.Light:Enable(true)    inst.Light:SetRadius(2)    inst.Light:SetFalloff(.6)    inst.Light:SetIntensity(0.9)    inst.Light:SetColour(153/255,0/155,0/255)     inst:AddComponent("inventoryitem")    inst.components.inventoryitem.imagename = "elpheltbomb"    inst.components.inventoryitem.atlasname = "images/inventoryimages/elpheltbomb.xml"     inst:AddComponent("stackable")     inst:AddComponent("equippable")    inst.components.equippable:SetOnEquip(onequip)    inst.components.equippable:SetOnUnequip(onunequip)    inst.components.equippable.equipstack = true     return instend STRINGS.NAMES.ELPHELTBOMB = "Elphelt's Strawberry Grenade!"STRINGS.CHARACTERS.GENERIC.DESCRIBE.ELPHELTBOMB = "Oh how delicious! Wait why is it ticking?" return Prefab("elpheltbomb", elpheltbomb_fn, elpheltbomb_assets, elpheltbomb_prefabs)

Also the OnEquip and OnUnequip thing worked like a charm. I should've guessed thats what I had to do Dx.

 

I'm running out of unique ways to say thank you, so heres a normal thank you! Hope you don't mind

Link to comment
Share on other sites

still makes everything invulnerable(Trees, birds, houses, etc) when I just needed the players to be the invulnerable ones. Maybe I missed something?

 

Yes, I realized later that I missed something and edited my post, should have mentioned it. It now works.

 

The range is still 0, but instead of using self.explosiverange, I use a local variable with the true range.

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