Jump to content

How to add a new key function


Recommended Posts

Basicly i want my character to change his animations and perks etc, by pressing a key. But i can't get this to work, cause i keep crashing or basicly nothing happens. Here is my code modmain.lua:

[codesyntax]

local require = GLOBAL.require
local Ingredient = GLOBAL.Ingredient
local RECIPETABS = GLOBAL.RECIPETABS
local STRINGS = GLOBAL.STRINGS
local ACTIONS = GLOBAL.ACTIONS
local Action = GLOBAL.Action
local TECH = GLOBAL.TECH
local WorldSanityMonsterSpawner = require("components.WorldSanityMonsterSpawner")
local TheInput = require("input")

STRINGS.NAMES.GIR = "GIR"
STRINGS.CHARACTER_TITLES.gir = "Information Retrieval Unit"
STRINGS.CHARACTER_NAMES.gir = "GIR"
STRINGS.CHARACTER_DESCRIPTIONS.gir = "*Lovely little robot"--\n*Dies from water"
STRINGS.CHARACTER_QUOTES.GIR = "\"I love this show! \""
STRINGS.CHARACTERS.GIR = require "speech_gir"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.GIR = "Lovely little robot"
STRINGS.CHARACTERS.GIR.DESCRIBE.GIR = {"Hello.", "Hi."}
STRINGS.CHARACTERS.WICKERBOTTOM.DESCRIBE.GIR = ("I like to examine that unit.")
STRINGS.CHARACTERS.WAXWELL.DESCRIBE.GIR = ("How did you get here?")
STRINGS.CHARACTERS.WOODIE.DESCRIBE.GIR = ("It looks funny, Lucy.")
STRINGS.CHARACTERS.WOLFGANG.DESCRIBE.GIR = ("It's small. I could try eat it")
STRINGS.CHARACTERS.WENDY.DESCRIBE.GIR = ("It smells like meat.")
STRINGS.CHARACTERS.WX78.DESCRIBE.GIR = ("DAMAGED STANDARD-ISSUE INFORMATION RETRIVAL UNIT.")


STRINGS.CHARACTERS.GIR.ANNOUNCE_NOSANITY = "Yes, my master!"    

PrefabFiles = {
    "gir",
}

ComponentsFiles = {
    "WorldSanityMonsterSpawner",
}

Assets = {
    Asset( "IMAGE", "images/saveslot_portraits/gir.tex"),
    Asset( "ATLAS", "images/saveslot_portraits/gir.xml"),
    
    Asset( "IMAGE", "images/selectscreen_portraits/gir.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/gir.xml" ),

    Asset( "IMAGE", "images/selectscreen_portraits/gir_silho.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/gir_silho.xml" ),

    Asset( "IMAGE", "bigportraits/gir.tex" ),
    Asset( "ATLAS", "bigportraits/gir.xml" ),

    Asset( "IMAGE", "minimap/gir.tex" ),
    Asset( "ATLAS", "minimap/gir.xml" ),
    
    Asset("SOUNDPACKAGE", "sound/gir.fev"),
    Asset("SOUND", "sound/gir_bank01.fsb"),
        
    Asset( "IMAGE", "images/avatars/avatar_gir.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_gir.xml" ),
    
    Asset( "IMAGE", "images/avatars/avatar_ghost_gir.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_ghost_gir.xml" ),
    }

GetPlayer = GLOBAL.GetPlayer
AddMinimapAtlas("minimap/gir.xml")



RemapSoundEvent( "dontstarve/characters/gir/death_voice", "gir/characters/gir/death_voice" )
RemapSoundEvent( "dontstarve/characters/gir/hurt", "gir/characters/gir/hurt" )
RemapSoundEvent( "dontstarve/characters/gir/talk_LP", "gir/characters/gir/talk_LP" )


GLOBAL.STRINGS.CHARACTERS.gir = GLOBAL.require("speech_gir")

AddModCharacter("gir")
table.insert(GLOBAL.CHARACTER_GENDERS.MALE, "gir")

for k, v in pairs(CHARACTERLIST) do
    if v.prefab ~= "wx78" then
        AddPrefabPostInit(v, ModCharacterInit)
    end
end


for k,v  in pairs(GLOBAL.MODCHARACTERLIST) do
    AddPrefabPostInit(v, ModCharacterInit)
end

GIRKeyHandler = Class(function(self)   
    self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
end)

function GIRKeyHandler:OnRawKey(key, down)
    if (key == KEY_T and not down) then
        print("test")
    end
end

theGIRKeyHandler = GIRKeyHandler()

[/codesyntax]

with this version i get the error log.txt:

[codesyntax]

[string "scripts/input.lua"]:124: attempt to index field 'onkey' (a nil value)
LUA ERROR stack traceback:
        scripts/input.lua(124,1) in function 'AddKeyHandler'
        ../mods/gir together/modmain.lua(90,1) in function '_ctor'
        scripts/class.lua(181,1) in function 'GIRKeyHandler'
        ../mods/gir together/modmain.lua(99,1) in main chunk
        =[C] in function 'xpcall'
        scripts/util.lua(455,1) in function 'RunInEnvironment'
        scripts/mods.lua(309,1) in function 'InitializeModMain'
        scripts/mods.lua(290,1) in function 'LoadMods'
        scripts/main.lua(245,1) in function 'ModSafeStartup'
        scripts/main.lua(293,1)
        =[C] in function 'SetPersistentString'
        scripts/mainfunctions.lua(24,1) in function 'SavePersistentString'
        scripts/modindex.lua(76,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(63,1) in function 'BeginStartupSequence'
        scripts/main.lua(292,1) in function 'callback'
        scripts/modindex.lua(342,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(322,1) in function 'Load'
        scripts/main.lua(291,1) in main chunk
Error error! We tried displaying an error but TheFrontEnd isn't ready yet...  

[/codesyntax]

 

Any help would be appreciated.

Edited by Purswader
Link to comment
Share on other sites

You are trying to add a local variable which to GIRKeyHandler, yet you are trying to call a global variable from within your key press functionality.

 

Try something along these lines:

GIRKeyHandler.OnRawKey = function(key, down)if (key == KEY_T and not down) thenprint("test")endend

For more information check out: http://www.lua.org/pil/6.2.html

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, thank you for your help, but i already deleted the local environment, i updated my crash and code just a few minutes ago

 

Here is the working code:

 

local TheInput = GLOBAL.TheInputlocal KEY_T = GLOBAL.KEY_T GIRKeyHandler = Class(function(self)       self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )end)     function GIRKeyHandler:OnRawKey(key, down)     if (key == KEY_T and not down) then         print("test")     endendtheGIRKeyHandler = GIRKeyHandler()
Link to comment
Share on other sites

@Purswader, should be as simple as the following:

 

GIRKeyHandler = Class(function(self)   
    self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
end)
 
    function GIRKeyHandler:OnRawKey(key, down)
     if (key == KEY_T and not down) then
         print("test")
     end
end

theGIRKeyHandler = GIRKeyHandler()

 

Inside script/prefabs folder TheInput and Key_T is already global.

 

EDIT:

However, it's not going to be that simple as I just tested that. I think it would probably work if you added it in the modmain.lua and initialize it as a component and simple add it as a component to GIR.

Edited by Kzisor
Link to comment
Share on other sites

@Purswader, okay so after some testing I figured out how to properly implement this as a component. Now you will need to adjust it the way you want but in order to do anything with it with your character all you have to do is inst:AddComponent("keyhandler") in your character file.

 

Add a keyhandler.lua file under the scripts/components folder and put this code in it.

 

local KeyHandler = Class(function(self, inst)
self.inst = inst
self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
end)
 
function KeyHandler:OnRawKey(key, down)
  if (key == KEY_T and not down) then
      print("test")
  end
end
 

return KeyHandler

 

 

This worked whenever I tested it if you have troubled let me know and I'll upload a working concept mod.

Link to comment
Share on other sites

@Kzisor, i have one minor problem, if the game is paused or you try to chat or use the console, the function will also be applied. Of course it should only be applied when active playing. I will look how to do this, but maybe you work faster. ^^

 

Edit:

and it wont work, if you are not the host.

 

Edit:

if the host presses T things changing on my character. Thats somehow funny.

Edited by Purswader
Link to comment
Share on other sites

@Kzisor, i have one minor problem, if the game is paused or you try to chat or use the console, the function will also be applied. Of course it should only be applied when active playing. I will look how to do this, but maybe you work faster. ^^

 

Edit:

and it wont work, if you are not the host.

 

Edit:

if the host presses T things changing on my character. Thats somehow funny.

 

I'm still figuring out how to get it to work on the client side. Once I figure that out, I might be able to figure out how to only make it work by said player.

 

Edit:

Forgot to mention that if you only want it to work when the game is running you need to add this if statement.

 

if IsPaused() then return end

 

Alternatively you could add 'not IsPaused()' to the already provided if statement.

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, I'm glad to hear that you are working on it. I can't get this wo work, but i'm still trying.

 

Here is the updated code which makes it work only when the game is actively running.

 

local KeyHandler = Class(function(self, inst)
self.inst = inst
self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
end)
 
function KeyHandler:OnRawKey(key, down)
  if (key == KEY_T and not down) and not IsPaused() then
      print("test")
  end
end
 
return KeyHandler
Link to comment
Share on other sites

@Kzisor, i was talking about that client thing ;), but thank you ^^

 

I got that working as well, although I had to change the code a little.

 

KeyHandler.lua

local KeyHandler = Class(function(self, inst)

self.inst = inst
self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
end)
 
function KeyHandler:OnRawKey(key, down)
local player = ThePlayer
  if (key and not down) and not IsPaused() then
      player:PushEvent("keypressed", {player = player, key = key})
  end
end
 
return KeyHandler
 
modmain.lua/character prefab.lua
local function OnKeyPressed(inst, data)
if data.player == GLOBAL.ThePlayer then
print(tostring(data.key))
end
end
 
Wilson = function(self)
self:AddComponent("keyhandler")
 
self:ListenForEvent("keypressed", OnKeyPressed)
 
return self
end
 
AddPrefabPostInit("wilson", Wilson)
 
This will do exactly what you are wanting to do.
Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, first of all, you are awesome. I will try this in a few minutes. Can you please explain where i have to define which key must be pressed? i'm not able to figuere that out on my first look at your code.

 

You define which key you specifically want to listen for by altering this function.

 

local function OnKeyPressed(inst, data)

if data.player == GLOBAL.ThePlayer then
   if data.key == GLOBAL.KEY_T then
      print("KEY_T has been pressed.")
   end
end
end
Link to comment
Share on other sites

@Kzisor, k i have some difficulties implementing your code, where should i put the secound one? If i try modmain the character.lua doesn't no the function OnKeyPressed(inst, data) and if i put it all in the character file it doesn't know the GLOBAL variable.

 

Edit:
wait i think i got it.

 

Edit:

It does not work the way i did it. On hosting it worked fine, but on client side not. I show you what i did:

 

keyhandler.lua (in components)

local KeyHandler = Class(function(self, inst)self.inst = instself.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )end)function KeyHandler:OnRawKey(key, down)local player=ThePlayerif (key and not down) and not IsPaused() thenplayer:PushEvent("keypressed",{player = player,key = key})endendreturn KeyHandler

 

and in the gir.lua (in prefabs)

local function OnKeyPressed(inst, data)if data.player == ThePlayer thenif data.key == KEY_T thenif (inst.strength=="normal" or inst.strength=="mighty") thenlocal damage_mult = 0.9local health_max = 150local hunger_rate = 1.7local scale = 0.9local speed = 1.1inst.AnimState:SetBuild("gir_dog")inst.strength="dog"inst.Transform:SetScale(scale,scale,scale)inst.components.hunger:SetRate(hunger_rate*TUNING.WILSON_HUNGER_RATE)inst.components.combat.damagemultiplier = damage_multinst.components.locomotor.walkspeed = (TUNING.WILSON_WALK_SPEED * speed)inst.components.locomotor.runspeed = (TUNING.WILSON_RUN_SPEED * speed)inst.components.sanity.dapperness = 0local health_percent = inst.components.health:GetPercent()inst.components.health:SetMaxHealth(health_max)inst.components.health:SetPercent(health_percent, true)elseif (inst.strength=="dog" and inst.components.sanity.current < 85) theninst.strength="mighty"elseif (inst.strength=="dog" and inst.components.sanity.current > 85) theninst.strength="normal"endendendend

 

and he has inst:ListenForEvent("keypressed", OnKeyPressed) ofc

Edited by Purswader
Link to comment
Share on other sites

@Purswader, the problem you are faced with has to do with networking. In order for your client to be able to change things on the server, you must sent a request to the server to have them changed. Instead of setting the components on the client side you must set the replica on the client side.

 

Try the following:

local function OnKeyPressed(inst, data)if data.player == ThePlayer thenif data.key == KEY_T thenif (inst.strength=="normal" or inst.strength=="mighty") thenlocal damage_mult = 0.9local health_max = 150local hunger_rate = 1.7local scale = 0.9local speed = 1.1inst.AnimState:SetBuild("gir_dog")inst.strength="dog"inst.Transform:SetScale(scale,scale,scale)inst.replica.hunger:SetRate(hunger_rate*TUNING.WILSON_HUNGER_RATE)inst.components.combat.damagemultiplier = damage_multinst.components.locomotor.walkspeed = (TUNING.WILSON_WALK_SPEED * speed)inst.components.locomotor.runspeed = (TUNING.WILSON_RUN_SPEED * speed)inst.replica.sanity.dapperness = 0local health_percent = inst.replica.health:GetPercent()inst.replica.health:SetMaxHealth(health_max)inst.replica.health:SetPercent(health_percent, true)elseif (inst.strength=="dog" and inst.replica.sanity.current < 85) theninst.strength="mighty"elseif (inst.strength=="dog" and inst.replica.sanity.current > 85) theninst.strength="normal"endendendend

 

Combat Replica does not have a damage multiplier and locomoter doesn't have a replica so for those you will need to be creative in the way in which you adjust them.

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, doesn't seem to work, i even tried

local function OnKeyPressed(inst, data)if data.player == ThePlayer thenif data.key == KEY_T thenprint("test")endendend

and there was no output :(

 

Post your entire gir.lua file for me so I can see what it looks like. You should at least be getting output from print. Remember that you still need to assign the keyhandler component to gir.

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