ninidelos

[Solved ]How do I make a staff unusable when sanity is low?

Recommended Posts

ninidelos    0

Hi o/

First of all, sorry for my bad english. Haven't practiced much lately.

So... I started making a character a couple days ago and wanted to give her an unbreakeable firestaff that sucked a lot of sanity each use (a not so good emergency light). The problem I'm having is that she can still cast fireballs even when her sanity ends. There's a piece of code in the firestaff that reduces sanity but nothing to check whether the character has enough to spend.

I don't know how to code, tried adding many different forms of if/else sanity checks, and nothing worked. I don't really remember what the game crash logs told me were wrong and didn't take screenshots but I guess sometimes it was because I tried comparing a table to a number or assigned nil to some variable. I might have misplaced something too.

I've got the feeling that this is something easy to solve if you know what you're doing, but that's not my case.

So I need help figuring out how to make the staff unusable when sanity <50.

I'm adding the script just in case. I think I have to add something in the onattack_red function but don't know what nor where.

wrenstaff.lua

Edited by ninidelos
solved

Share this post


Link to post
Share on other sites
AkaiNight    19

im not sure if its work but you can try to change 

attacker.components.sanity ~= nil 

with

owner.components.sanity <= 30 --as example

or im still not sure but you can try this one too

 

change 

if not target:IsValid() then

with

if not target:IsValid() or owner.components.sanity >= 29 then

 

Edited by AkaiNight
  • GL Happy 1

Share this post


Link to post
Share on other sites
ninidelos    0
Spoiler
4 hours ago, AkaiNight said:

im not sure if its work but you can try to change 



attacker.components.sanity ~= nil 

with



owner.components.sanity <= 30 --as example

or im still not sure but you can try this one too

 

change 



if not target:IsValid() then

with



if not target:IsValid() or owner.components.sanity >= 29 then

 

 

@AkaiNight thanks for the ideas. I couldn't make it work though.

So for both changes I got "variable 'owner' is not declared"

tried adding the following in 'local function commonfn(colour, tags, hasskin)' but the error was still the same

	local owner = inst.components.inventoryitem:GetGrandOwner()

then I added 'owner' to the line

local function onattack_red(inst, attacker, target, skipsanity, owner)

and got "attempt to index local 'owner' (a nil value)" (as I said, when it comes to coding, I don't really know what I'm doing (^-^;) )

 

I thought of making adding an if/else statement inside onattack_red without changing what was already given by the game but couldn't get it to work. Still havin issues with an undeclared variable 'owner'.

Spoiler

local function onattack_red(inst, attacker, target, skipsanity)
  -- ADDED A LINE HERE --
    if owner.components.sanity >= 50 then
  -- AND A COUPLE IN THE END -- scroll down if not interested in te chunk --
		if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
        attacker.components.sanity:DoDelta(-TUNING.SANITY_HUGE)
    end

    attacker.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")

    if not target:IsValid() then
        --target killed or removed in combat damage phase
        return
    elseif target.components.burnable ~= nil and not target.components.burnable:IsBurning() then
        if target.components.freezable ~= nil and target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        elseif target.components.fueled == nil
            or (target.components.fueled.fueltype ~= FUELTYPE.BURNABLE and
                target.components.fueled.secondaryfueltype ~= FUELTYPE.BURNABLE) then
            --does not take burnable fuel, so just burn it
            if target.components.burnable.canlight or target.components.combat ~= nil then
                target.components.burnable:Ignite(true)
            end
        elseif target.components.fueled.accepting then
            --takes burnable fuel, so fuel it
            local fuel = SpawnPrefab("cutgrass")
            if fuel ~= nil then
                if fuel.components.fuel ~= nil and
                    fuel.components.fuel.fueltype == FUELTYPE.BURNABLE then
                    target.components.fueled:TakeFuelItem(fuel)
                else
                    fuel:Remove()
                end
            end
        end
    end

    if target.components.freezable ~= nil then
        target.components.freezable:AddColdness(-1) --Does this break ice staff?
        if target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        end
    end

    if target.components.sleeper ~= nil and target.components.sleeper:IsAsleep() then
        target.components.sleeper:WakeUp()
    end

    if target.components.combat ~= nil then
        target.components.combat:SuggestTarget(attacker)
    end

    target:PushEvent("attacked", { attacker = attacker, damage = 0, weapon = inst })
  --HERE--
  else
    inst.components.talker:Say("I'm out of brain juice", 0.1,true)
  end
  --TILL HERE --
end    

 

So the problem now seems to be that I don't know how to declare nor where to put the variable "owner". :?

Share this post


Link to post
Share on other sites
ninidelos    0
21 minutes ago, AkaiNight said:

try to change owner with attacker we are trying to specify the minumum sanity vaule for being able to attack

when I do that it says "attempt to compare table with number"

 

I had another idea but it's not workin either.

I tried writing a function to check the amount of sanity called "brainjuice" (it might be completly wrong since I made it up looking at other codes)

this function is supposed to be called by "inst.components.weapon:SetOnAttack(brainjuice)" and should run the function "onattack_red" when sanity > 49.

	local function brainjuice(owner)
		if owner.components.sanity >= 50 then
			return onattack_red
		else
			inst.components.talker:Say("I'm out of brain juice", 0.1,true)
		end
	end

but, as I said, that is not working. it says "attempt to compare number with nil". tried with "attacker" instead and got the same result.

 

Share this post


Link to post
Share on other sites
AkaiNight    19

Well i have 1 last idea i hope it will work

local function onattack_red(inst, attacker, target, skipsanity, owner)
    if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
        attacker.components.sanity:DoDelta(-TUNING.SANITY_HUGE)
    end

    attacker.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")

	if owner.components.sanity and owner.components.sanity >= 30 then

    if not target:IsValid() then
        --target killed or removed in combat damage phase
        return
    elseif target.components.burnable ~= nil and not target.components.burnable:IsBurning() then
        if target.components.freezable ~= nil and target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        elseif target.components.fueled == nil
            or (target.components.fueled.fueltype ~= FUELTYPE.BURNABLE and
                target.components.fueled.secondaryfueltype ~= FUELTYPE.BURNABLE) then
            --does not take burnable fuel, so just burn it
            if target.components.burnable.canlight or target.components.combat ~= nil then
                target.components.burnable:Ignite(true)
            end
        elseif target.components.fueled.accepting then
            --takes burnable fuel, so fuel it
            local fuel = SpawnPrefab("cutgrass")
            if fuel ~= nil then
                if fuel.components.fuel ~= nil and
                    fuel.components.fuel.fueltype == FUELTYPE.BURNABLE then
                    target.components.fueled:TakeFuelItem(fuel)
                else
                    fuel:Remove()
                end
            end
        end
    end

    if target.components.freezable ~= nil then
        target.components.freezable:AddColdness(-1) --Does this break ice staff?
        if target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        end
    end

    if target.components.sleeper ~= nil and target.components.sleeper:IsAsleep() then
        target.components.sleeper:WakeUp()
    end

    if target.components.combat ~= nil then
        target.components.combat:SuggestTarget(attacker)
    end

    target:PushEvent("attacked", { attacker = attacker, damage = 0, weapon = inst })
end
end

 

Share this post


Link to post
Share on other sites
ninidelos    0
Spoiler
35 minutes ago, AkaiNight said:

Well i have 1 last idea i hope it will work



local function onattack_red(inst, attacker, target, skipsanity, owner)
    if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
        attacker.components.sanity:DoDelta(-TUNING.SANITY_HUGE)
    end

    attacker.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")

	if owner.components.sanity and owner.components.sanity >= 30 then

    if not target:IsValid() then
        --target killed or removed in combat damage phase
        return
    elseif target.components.burnable ~= nil and not target.components.burnable:IsBurning() then
        if target.components.freezable ~= nil and target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        elseif target.components.fueled == nil
            or (target.components.fueled.fueltype ~= FUELTYPE.BURNABLE and
                target.components.fueled.secondaryfueltype ~= FUELTYPE.BURNABLE) then
            --does not take burnable fuel, so just burn it
            if target.components.burnable.canlight or target.components.combat ~= nil then
                target.components.burnable:Ignite(true)
            end
        elseif target.components.fueled.accepting then
            --takes burnable fuel, so fuel it
            local fuel = SpawnPrefab("cutgrass")
            if fuel ~= nil then
                if fuel.components.fuel ~= nil and
                    fuel.components.fuel.fueltype == FUELTYPE.BURNABLE then
                    target.components.fueled:TakeFuelItem(fuel)
                else
                    fuel:Remove()
                end
            end
        end
    end

    if target.components.freezable ~= nil then
        target.components.freezable:AddColdness(-1) --Does this break ice staff?
        if target.components.freezable:IsFrozen() then
            target.components.freezable:Unfreeze()
        end
    end

    if target.components.sleeper ~= nil and target.components.sleeper:IsAsleep() then
        target.components.sleeper:WakeUp()
    end

    if target.components.combat ~= nil then
        target.components.combat:SuggestTarget(attacker)
    end

    target:PushEvent("attacked", { attacker = attacker, damage = 0, weapon = inst })
end
end

 

 

it says: attempt to index local 'owner' (a nil value)

 

Hum... I'll keep trying and searching a solution. For now I'll leave a cleaned up version of the script for anyone who wants to check it out. I removed some stuff from the staff.lua that I was sure weren't necessary.

 

wand.lua

Share this post


Link to post
Share on other sites
ninidelos    0

okay, so I learned a few things while tweaking the staff and solved this problem with the following:

local function onattack_red(inst, attacker, target, skipsanity)

	local owner = inst.components.inventoryitem.owner
	local brainjuice = owner.components.sanity.current
	if brainjuice >= 30 then

		if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
    	    attacker.components.sanity:DoDelta(-TUNING.SANITY_HUGE)
			inst.components.fueled:DoDelta(-TUNING.NIGHTSTICK_FUEL*0.1)
   		 end
-- chunk I'm not adding here --
	else
		inst.components.talker:Say("I'm out of brain juice...", 1,true)
	end
end

now I just need to learn how to stop the fireball animation from triggering when the attack fails

Share this post


Link to post
Share on other sites
AkaiNight    19

Maybe something like that?

local function onattack_red(inst, attacker, target, skipsanity)

	local owner = inst.components.inventoryitem.owner
	local brainjuice = owner.components.sanity.current
	
	if brainjuice < 30 then
    return
                      
    else

		if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
    	    attacker.components.sanity:DoDelta(-TUNING.SANITY_HUGE)
			inst.components.fueled:DoDelta(-TUNING.NIGHTSTICK_FUEL*0.1)
   		 end
-- chunk I'm not adding here --
	else
		inst.components.talker:Say("I'm out of brain juice...", 1,true)
	end
end

 

Share this post


Link to post
Share on other sites
ninidelos    0

I don't think that will work, you basically just changed the order of what I wrote.

mine is like

Spoiler

if a is true 
	-> attack (chunk)
else
	-> say this (and consequently don't attack)

 

an yours is 

Spoiler

if a is true
	-> do nothing
else
	-> attack
else (if a is false and the previous else doesn't apply)
	->speak

 

I believe the problem is linked to the following part

    inst.components.weapon:SetOnAttack(onattack_red)
	-- has the attack swing animation

	--and
    inst.components.weapon:SetProjectile("fire_projectile")
	-- has the projectile animation

So in order to fix the issue I might have to create/change the weapon component

Edited by ninidelos

Share this post


Link to post
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