Jump to content

Recommended Posts

Hello, I want to make the weregoose to fly on the cave ruins holes by editing some components that allowed it to walk on water. So there's components that allow this happen inside the script of woodie, I edited it and pasted it the "floater" component right next to the "drownable", still doesn't work.

local function SetWereDrowning(inst, mode)
    --V2C: drownable HACKS, using "false" to override "nil" load behaviour
    --     Please refactor drownable to use POST LOAD timing.
    if inst.components.drownable ~= nil then
        if mode == WEREMODES.GOOSE then
            if inst.components.drownable.enabled ~= false then
                inst.components.drownable.enabled = false
				inst.components.floater.enabled = true
                inst.Physics:ClearCollisionMask()
                inst.Physics:CollidesWith(COLLISION.GROUND)
                inst.Physics:CollidesWith(COLLISION.OBSTACLES)
                inst.Physics:CollidesWith(COLLISION.SMALLOBSTACLES)
                inst.Physics:CollidesWith(COLLISION.CHARACTERS)
                inst.Physics:CollidesWith(COLLISION.GIANTS)
                inst.Physics:Teleport(inst.Transform:GetWorldPosition())
            end
        elseif inst.components.drownable.enabled == false then
            inst.components.drownable.enabled = true
			inst.components.drownable.enabled = false
            if not inst:HasTag("playerghost") then
                inst.Physics:ClearCollisionMask()
                inst.Physics:CollidesWith(COLLISION.WORLD)
                inst.Physics:CollidesWith(COLLISION.OBSTACLES)
                inst.Physics:CollidesWith(COLLISION.SMALLOBSTACLES)
                inst.Physics:CollidesWith(COLLISION.CHARACTERS)
                inst.Physics:CollidesWith(COLLISION.GIANTS)
                inst.Physics:Teleport(inst.Transform:GetWorldPosition())
            end
        end
    end
end

[SPOILER/]

previously underneath inst.components.floater.enabled = true , I was removing those lines of code to see if the goose could ignore the abyss, but it didn't work, so yeah, any ideas? I'm dropping my woodie rework file, so ya'll can skim. It doesn't crash the game.

 

woodie.lua

Link to comment
Share on other sites

i think caves is just empty space but it could be that there is a world border as seen with most glitches when you could glitch out before with lureplants.

so in my opinion i think you need to check out the physics in the game or check if there is a way to freely go through the border a

Link to comment
Share on other sites

I just took a look at the gamefiles.
Since there is no ocean in caves, it has nothing to do with drownable.
The only problem is the collision with the borders. And here you can look at files from flying creatures which have:
inst.Physics:CollidesWith((TheWorld.has_ocean and COLLISION.GROUND) or COLLISION.WORLD)

So to be able to passt the borders, we have to make the goose to not collide with the World (the borders), but only with the ground.
In the function you already quoted, you see how to deal with collsion. First you Reset the collision with
inst.Physics:ClearCollisionMask()
Then you define with what the inst should collide.
Your function already contains the correct collisions, but it is only executed if you have the drownable component, which you only have if there is ocean. We could add the component, but this would have other side efffects, so we will use our own code with some functions from drownable:

(put the code into my next post)

Edited by Serpens
Link to comment
Share on other sites

Guys, I stressed out all the options there was availaible, but it didn't seem to work, I bet my money is that the drownable component has something to do with world limits but I gave up already and found a workaround which is adding inst.Physics:CollidesWith(COLLISION.LIMITS) to forms such as woodie, moose, beaver under  onbecamemoose/human/beaver and instead in onbecamegoose inst.Physics:ClearCollidesWith(COLLISION.LIMITS), thanks guys.

Link to comment
Share on other sites

I have the code mostly finished, just wait few minutes ;)

put this into modmain and you are done :) (no need to edit woodie.lua in any way, you never should edit original files, unless there is really no better solution) :

see code here:
https://forums.kleientertainment.com/forums/topic/111740-woodie-rework/?do=findComment&comment=1260395

 

Edited by Serpens
Link to comment
Share on other sites

worked like a charm, however it has a bug, on load it no longer can transverse borders but mine is bugless, I don't know how to fix it.

Now I want to make the moose have more damage while charging then normally attacking.

 

local function OnTackleStart(inst)
    if inst.sg.currentstate.name == "tackle_pre" then
        inst.sg.statemem.tackling = true
        inst.sg:GoToState("tackle_start")
		inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*2.535) 
		elseif inst.sg:HasStateTag("tackle_stop" or "tackle_collide") then 
	inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*1.69) 
        return true
    end
end

 

So what I did was add inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*2.535)  after inst.sg:GoToState("tackle_start"), but I want to revert back. I'm analyzing your code to further learn :D

The logic is to make the weremoose not that OP, make him one shot spider baddies and one shot hounds if you charge at them.

Edited by ColombianCam
Link to comment
Share on other sites

47 minutes ago, ColombianCam said:

worked like a charm, however it has a bug, on load it no longer can transverse borders but mine is bugless, I don't know how to fix it.

Now I want to make the moose have more damage while charging then normally attacking.

  Reveal hidden contents


local function OnTackleStart(inst)
    if inst.sg.currentstate.name == "tackle_pre" then
        inst.sg.statemem.tackling = true
        inst.sg:GoToState("tackle_start")
		inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*2.535) 
		elseif inst.sg:HasStateTag("tackle_stop" or "tackle_collide") then 
	inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*1.69) 
        return true
    end
end

 

So what I did was add inst.components.combat:SetDefaultDamage(TUNING.WEREMOOSE_DAMAGE*2.535)  after inst.sg:GoToState("tackle_start"), but I want to revert back. I'm analyzing your code to further learn :D

The logic is to make the weremoose not that OP, make him one shot spider baddies and one shot hounds if you charge at them.

lets first solve the first.
You are changing the woodie.lua. If this mod is only for you and you wont upload it anywhere okay, then edit the original file. But if you want to upload it, you should do it professional and only edit original files if there is really no other way.
The reason your code works on loading, is because the woodie.lua already handels this case, while in modmain we have to add our own code for that, and I forgot this.
And currently your code does not teleport woodie back to land when transforming back while being in "nothing", right?

Anyway, your idea is good, to use COLLISON.LIMTS instead. So we will change my code regarding this... (only wonder why the devs did not use this within SetWereDrowning)

I added the loading stuff now, but when loading while goose is within "nothing" of caves, I get teleported to the start portal shortly after. This should also happen with your solution, right?

Edited by Serpens
Link to comment
Share on other sites

9 minutes ago, ColombianCam said:

No I had no solution, sorry. Instead of making the person teleport can we make the player "die" sort of falling to his death and teleporting to the portal?

if you know an already exisiting animation for the falling, yes.

Link to comment
Share on other sites

55 minutes ago, ColombianCam said:

sorry if I'm not being quite responsive, I really just want to get the moose to do more damage while charging, I haven't played all day but mod so I feel angst.  I'm working on it.

normally you would try to use the tackler component to find out when the tackle starts (you already found this) and when the tackle ends. Unfortunately we dont have anything here to see if the tackle ends (at least I see nothing)

But you already found the stategraphs, eg tackle_stop. So we could instead change the stategraphs, with AddStategraphPostInit.

Spoiler

-- current problems:
-- when loading the game while goose is within "nothing" of caves, it will teleport to the start portal.
-- if you dont want to teleport to the next land position when goose transforms back to woodie, simply replace the relevant code within transform_person

-- ################
-- ### first some helper functions taken mostly from the drownable component, to find out if we are on water and where the next land ist

local function IsOverWater(inst,x,y,z) -- mostly taken from the drownable component
    local x, y, z = inst.Transform:GetWorldPosition()
    return not GLOBAL.TheWorld.Map:IsVisualGroundAtPoint(x, y, z)
        and GLOBAL.TheWorld.Map:GetTileAtPoint(x, y, z) ~= GLOBAL.GROUND.INVALID -- allow players to be out of bounds so that a number of mods will still work
        and inst:GetCurrentPlatform() == nil
end

local function NoHoles(pt) -- taken from the drownable component
    return not GLOBAL.TheWorld.Map:IsPointNearHole(pt)
end

local function NoPlayersOrHoles(pt) -- taken from the drownable component
    return not (GLOBAL.IsAnyPlayerInRange(pt.x, 0, pt.z, 2) or GLOBAL.TheWorld.Map:IsPointNearHole(pt))
end

local function Teleport(inst,target_x, target_y, target_z) -- mostly taken from the drownable component
    local radius = 2 + math.random() * 3

    local pt = GLOBAL.Vector3(target_x, target_y, target_z)
    local angle = math.random() * 2 * GLOBAL.PI
    local offset =
        GLOBAL.FindWalkableOffset(pt, angle, radius, 8, true, false, NoPlayersOrHoles) or
        GLOBAL.FindWalkableOffset(pt, angle, radius * 1.5, 6, true, false, NoPlayersOrHoles) or
        GLOBAL.FindWalkableOffset(pt, angle, radius, 8, true, false, NoHoles) or
        GLOBAL.FindWalkableOffset(pt, angle, radius * 1.5, 6, true, false, NoHoles)
    if offset ~= nil then
        target_x = target_x + offset.x
        target_z = target_z + offset.z
    end

    if inst.Physics ~= nil then
        inst.Physics:Teleport(target_x, target_y, target_z)
    elseif inst.Transform ~= nil then
        inst.Transform:SetPosition(target_x, target_y, target_z)
    end
end
-- ###### end of helper functions
-- #########################

if GLOBAL.TheNet:GetIsServer() then -- only do everything following for server, clients dont need it
   -- #######  -- this will change the damage for moose when tackling
    AddStategraphPostInit("wilson",function(sg)
        if sg.states.tackle_pre~=nil then
            local old_onexit = sg.states.tackle_pre.onexit
            local function new_onexit(inst,...)
                -- print("tackle_pre")
                inst.components.combat.externaldamagemultipliers:SetModifier("mycustommodifiername", 2.535)
                return old_onexit(inst,...)
            end
            sg.states.tackle_pre.onexit = new_onexit
        end
        if sg.states.tackle_stop~=nil then
            local old_onexit = sg.states.tackle_stop.onexit
            local function new_onexit(inst,...)
                -- print("tackle_stop")
                inst.components.combat.externaldamagemultipliers:RemoveModifier("mycustommodifiername")
                return old_onexit(inst,...)
            end
            sg.states.tackle_stop.onexit = new_onexit
        end
        if sg.states.tackle_collide~=nil then -- when colliding with something, tackle_stop is not called, so we have to revert the damage to normal here
            local old_onexit = sg.states.tackle_collide.onexit
            local function new_onexit(inst,...)
                -- print("tackle_collide")
                inst.components.combat.externaldamagemultipliers:RemoveModifier("mycustommodifiername")
                return old_onexit(inst,...)
            end
            sg.states.tackle_collide.onexit = new_onexit
        end
    end)

    -- ####### this will make goose fly on "nothing" from caves
    -- in case it is possible to transform from goose directly into another were form, without being woodie first, we need to adjust the code accordingly!
    AddPrefabPostInit("woodie",function(inst)
        if GLOBAL.TheWorld and GLOBAL.TheWorld:HasTag("cave") then
            inst:ListenForEvent("transform_person",function(inst,data) -- transforms back from data.mode to woodie
                if inst~=nil and data~=nil then
                    if data.mode=="goose" then -- if we just were goose, teleport on land if we are still within "nothing" and set physis back to normal
                        local x, y, z = inst.Transform:GetWorldPosition()
                        if IsOverWater(inst,x, y, z) then
                            local shore_x, shore_y, shore_z = GLOBAL.FindRandomPointOnShoreFromOcean(x, y, z)
                            Teleport(inst,shore_x, shore_y, shore_z) -- teleport back on land
                        end
                        inst.Physics:CollidesWith(GLOBAL.COLLISION.LIMITS) -- also ghosts can not travel through "nothing" of caves, so we dont have to catch ghosts here
                    end
                end
            end)
            inst:ListenForEvent("transform_wereplayer",function(inst,data) -- transforms from woodie to data.mode
                if inst~=nil and data~=nil then
                    if data.mode=="goose" then -- if we transform into goose, change our collision, so we can go over the world edges
                        inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)
                    end
                end
            end)
            -- if we just loaded the game and woodie is already a goose, the transform event is not fired, so we have to modify it here instead
            local old_OnPreLoad = inst.OnPreLoad
            local function new_OnPreLoad(inst,data,...)
                old_OnPreLoad(inst,data,...)-- call the old one
                if inst~=nil and data~=nil and data.isgoose then
                    inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)
                end
            end
            inst.OnPreLoad = new_OnPreLoad
        end
    end)
end

 

edit:
when colliding with something, tackle_stop is not called so we have to revert it back to default in both onexit functions (is already done in code above).
To make it perfect, you should use externaldamagemultipliers instead of changing the default damage, I also added it already in the code above.

Edited by Serpens
Link to comment
Share on other sites

39 minutes ago, ColombianCam said:

Hey dude, your script keeps crashing the game because of missing then or ends expected, I've tried fixing it but I can't.

hm, no, works fine at my side. Maybe you missed something when copy pasting?

edit:
the game loading while goose is within "nothing" will also be solved later today or tomorrow, someone found the relevant code: https://forums.kleientertainment.com/forums/topic/111771-how-to-disable-some-code-in-player_commonlua-onload-function/

 

Edited by Serpens
Link to comment
Share on other sites

15 minutes ago, ColombianCam said:

ok, thanks for the credits and good you got it working :)(maybe you should read and fix the mod description a bit, sometimes a few words are missing I think.. and since it is an old mod, maybe you should add some changelogs so people can see that it was updated for the new woodie.
 

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