Jump to content

Recommended Posts

Well to be more precise I was wondering if it was possible to replicate's the rook's ability to charge and smash things on a character. 

 

I have tried the simple man's approach by copying over the code that are related to the charge ability and inserted into the modmain and labeled it under the local function of charge. I've also made the character     inst:AddTag("chess") for simplicity sake.

local function Retarget(inst)    local homePos = inst.components.knownlocations:GetLocation("home")    if (homePos ~= nil and inst:GetDistanceSqToPoint(homePos:Get()) > MAX_CHASEAWAY_DIST_SQ)        and (inst.components.follower == nil or inst.components.follower.leader == nil) then        --no leader, and i'm far from home        return    end    local myLeader = inst.components.follower ~= nil and inst.components.follower.leader or nil    return FindEntity(inst, TUNING.ROOK_TARGET_DIST,        function(guy)            if myLeader == guy then                return            end            local theirLeader = guy.components.follower ~= nil and guy.components.follower.leader or nil            return (myLeader == nil or myLeader ~= theirLeader) --check same leader                and (theirLeader ~= nil or not guy:HasTag("chess")) --can't hit other chess pieces unless they are following someone else                and inst.components.combat:CanTarget(guy)        end,        { "_combat", "_health" }, --see entityreplica.lua        { "INLIMBO" },        { "character", "monster" }    )endlocal function KeepTarget(inst, target)    if (inst.components.follower ~= nil and inst.components.follower.leader ~= nil) or        (inst.sg ~= nil and inst.sg:HasStateTag("running")) then        return true    end    local homePos = inst.components.knownlocations:GetLocation("home")    return homePos ~= nil and inst:GetDistanceSqToPoint(homePos:Get()) <= MAX_CHASEAWAY_DIST_SQendlocal function IsChess(dude)    return dude:HasTag("chess")endlocal function OnAttacked(inst, data)    if data ~= nil and data.attacker ~= nil and not data.attacker:HasTag("chess") then        inst.components.combat:SetTarget(data.attacker)        inst.components.combat:ShareTarget(data.attacker, SHARE_TARGET_DIST, IsChess, MAX_TARGET_SHARES)    endendlocal function ClearRecentlyCharged(inst, other)    inst.recentlycharged[other] = nilendlocal function onothercollide(inst, other)    if not other:IsValid() then        return    elseif other:HasTag("smashable") then        --other.Physics:SetCollides(false)        other.components.health:Kill()    elseif other.components.workable ~= nil and other.components.workable.workleft > 0 then        SpawnPrefab("collapse_small").Transform:SetPosition(other.Transform:GetWorldPosition())        other.components.workable:Destroy(inst)    elseif not inst.recentlycharged[other] and other.components.health ~= nil and not other.components.health:IsDead() then        inst.recentlycharged[other] = true        inst:DoTaskInTime(3, ClearRecentlyCharged, other)        inst.components.combat:DoAttack(other, inst.weapon)        inst.SoundEmitter:PlaySound("dontstarve/creatures/rook/explo")    endendlocal function oncollide(inst, other)    if not (other ~= nil and other:IsValid() and inst:IsValid())        or other:HasTag("player")        or Vector3(inst.Physics:GetVelocity()):LengthSq() < 42 then        return    end    for i, v in ipairs(AllPlayers) do        v:ShakeCamera(CAMERASHAKE.SIDE, .5, .05, .1, inst, 40)    end    inst:DoTaskInTime(2 * FRAMES, onothercollide, other)end

Then set a command to listen for the keystroke to trigger the charge function so the player won't be ramming head first into everything randomly. Needless to say it doesn't work :/ .

 inst.components.keyhandler:AddActionListener("horo", TUNING.HORO.KEY, "charge")
Edited by Hyaciao
local function onothercollide(inst, other)	if not other:IsValid() then		return	elseif other:HasTag("smashable") then		other.components.health:Kill()	elseif other.components.workable ~= nil and other.components.workable.workleft > 0 then		SpawnPrefab("collapse_small").Transform:SetPosition(other.Transform:GetWorldPosition())		other.components.workable:Destroy(inst)	endendlocal function oncollide(inst, other)	if not (other ~= nil and other:IsValid() and inst:IsValid())	or other:HasTag("player")	or Vector3(inst.Physics:GetVelocity()):LengthSq() < 2 then		return	end	for i, v in ipairs(AllPlayers) do		if not (v == inst) then			v:ShakeCamera(CAMERASHAKE.SIDE, .5, .05, .1, inst, 40)		end	end	inst:DoTaskInTime(2 * FRAMES, onothercollide, other)end-- then on master_postinitinst.Physics:SetCollisionCallback(oncollide)

That should give you the rook's ability to smash rocks and trees.

 

In combination with a key handler, you can do it like this, on modmain:

local SpawnPrefab = GLOBAL.SpawnPrefablocal function onothercollide(inst, other)	if not other:IsValid() then		return	elseif other:HasTag("smashable") then		other.components.health:Kill()	elseif other.components.workable ~= nil and other.components.workable.workleft > 0 then		SpawnPrefab("collapse_small").Transform:SetPosition(other.Transform:GetWorldPosition())		other.components.workable:Destroy(inst)	endendlocal Vector3 = GLOBAL.Vector3AllPlayers = GLOBAL.AllPlayerslocal FRAMES = GLOBAL.FRAMESlocal function oncollide(inst, other)	if not (other ~= nil and other:IsValid() and inst:IsValid())	or other:HasTag("player")	or Vector3(inst.Physics:GetVelocity()):LengthSq() < 2 then		return	end	for i, v in ipairs(AllPlayers) do		if not (v == inst) then			v:ShakeCamera(CAMERASHAKE.SIDE, .5, .05, .1, inst, 40)		end	end	inst:DoTaskInTime(2 * FRAMES, onothercollide, other)endTheInput = GLOBAL.TheInputlocal KEY_H = GLOBAL.KEY_HAddModRPCHandler(modname, "HOROCHARGE", function(player)	player.charge = not player.charge	if player.charge then		player.Physics:SetCollisionCallback(oncollide)	else		player.Physics:SetCollisionCallback(nil)	endend)AddPrefabPostInit("horo", function(inst)	inst.charge = false	TheInput:AddKeyDownHandler(KEY_H, function()		SendModRPCToServer(MOD_RPC[modname]["HOROCHARGE"])	end)end)

To activate your charge state with the H key.

It's 99% probably human error on my part (everything runs fine) but it does not seem to read the H keystroke. I'll assume it's something to do with how I tried to use the keyhandler.

In the mean time, thank you as always. I don't even know how you do it so fast.

 

Unrelated: I'm actually really curious if you just see all this like it's another language. I've been trying my best to wrap my head around it and I can only make bits and pieces of everything.

@Hyaciao,

 

1) Where it says "horo", next to the AddPrefabPostInit, are you putting your character's prefab name?

2) You are putting either only one or the other code, right? The first shows the part with the collide functionality and goes in the character prefab, the second has the collide functionality and the rpc implementation all in modmain. Only one goes. Use the second, its complete.

 

There is no keyhandler component, so that line of yours shouldn't work.

Unless I'm missing something, are you using Kzisor's keyhandler component?

 

I made bits and pieces of everything for months. I study compsci, so I just have programming experience, that helped me memorize the syntax of lua and the design paradigms applied in don't starve.

Edited by DarkXero

@DarkXero

 

1) Yep. "horo.lua" is the file name so there was nothing I need to change there. I switch the key to "R" but I doubt there should be any relevance. I made sure to switch all the H keys to R as well.

AddPrefabPostInit("horo", function(inst)    inst.charge = false    TheInput:AddKeyDownHandler(KEY_R, function()        SendModRPCToServer(MOD_RPC[modname]["HOROCHARGE"])    end)end)

2. Yep I'm using only the 2nd part (inserted into the modmain). I noted down the first set of code for future references note.

Yes Kzisor's keyhandler is the only one I could locate. I'm aware it was beyond me to even attempt making one so I use the one that was available.

-- Following was created by DarkXero local SpawnPrefab = GLOBAL.SpawnPrefab local function onothercollide(inst, other)    if not other:IsValid() then        return    elseif other:HasTag("smashable") then        other.components.health:Kill()    elseif other.components.workable ~= nil and other.components.workable.workleft > 0 then        SpawnPrefab("collapse_small").Transform:SetPosition(other.Transform:GetWorldPosition())        other.components.workable:Destroy(inst)    endend local Vector3 = GLOBAL.Vector3AllPlayers = GLOBAL.AllPlayerslocal FRAMES = GLOBAL.FRAMES local function oncollide(inst, other)    if not (other ~= nil and other:IsValid() and inst:IsValid())    or other:HasTag("player")    or Vector3(inst.Physics:GetVelocity()):LengthSq() < 2 then        return    end     for i, v in ipairs(AllPlayers) do        if not (v == inst) then            v:ShakeCamera(CAMERASHAKE.SIDE, .5, .05, .1, inst, 40)        end    end     inst:DoTaskInTime(2 * FRAMES, onothercollide, other)end TheInput = GLOBAL.TheInputlocal KEY_R = GLOBAL.KEY_R AddModRPCHandler(horo, "HOROCHARGE", function(player)    player.charge = not player.charge    if player.charge then        player.Physics:SetCollisionCallback(oncollide)    else        player.Physics:SetCollisionCallback(nil)    endend) AddPrefabPostInit("horo", function(inst)    inst.charge = false    TheInput:AddKeyDownHandler(KEY_R, function()        SendModRPCToServer(MOD_RPC[horo]["HOROCHARGE"])    end)end)
Edited by Hyaciao
AddModRPCHandler(horo, "HOROCHARGE", function(player)    player.charge = not player.charge    if player.charge then        player.Physics:SetCollisionCallback(oncollide)    else        player.Physics:SetCollisionCallback(nil)    endend)  AddPrefabPostInit("horo", function(inst)    inst.charge = false    TheInput:AddKeyDownHandler(KEY_R, function()        SendModRPCToServer(MOD_RPC[horo]["HOROCHARGE"])    end)end)

@Hyaciao,

When I copied your code, I ended up copy pasting mine, so I couldn't see errors.

 

But here's the problem.

 

The horo, without the "" should be modname here.

Use modname, modname is a mod environment variable that has a string with your mod's name.

Pretty nice for a unique ID for RPCs.

 

horo is a variable with a nil value, it was never defined.

"horo" has to remain that, as it is a string that will be used to reference the horo prefab generated by the horo file.

 

What I wanted was the entire mod zipped, with assets, so I don't have to go renaming everything and copypasting everything to be able to generate a dummy to test code.

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
×
  • Create New...