Purswader Posted January 2, 2015 Share Posted January 2, 2015 (edited) 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.requirelocal Ingredient = GLOBAL.Ingredientlocal RECIPETABS = GLOBAL.RECIPETABSlocal STRINGS = GLOBAL.STRINGSlocal ACTIONS = GLOBAL.ACTIONSlocal Action = GLOBAL.Actionlocal TECH = GLOBAL.TECHlocal 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.GetPlayerAddMinimapAtlas("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) endendfor k,v in pairs(GLOBAL.MODCHARACTERLIST) do AddPrefabPostInit(v, ModCharacterInit)endGIRKeyHandler = 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()[/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 chunkError error! We tried displaying an error but TheFrontEnd isn't ready yet... [/codesyntax] Any help would be appreciated. Edited January 2, 2015 by Purswader Link to comment Share on other sites More sharing options...
Kzisor Posted January 2, 2015 Share Posted January 2, 2015 (edited) 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")endendFor more information check out: http://www.lua.org/pil/6.2.html Edited January 2, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Purswader Posted January 2, 2015 Author Share Posted January 2, 2015 @Kzisor, thank you for your help, but i already deleted the local environment, i updated my crash and code just a few minutes ago Link to comment Share on other sites More sharing options...
Kzisor Posted January 2, 2015 Share Posted January 2, 2015 @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 More sharing options...
Purswader Posted January 2, 2015 Author Share Posted January 2, 2015 (edited) @Kzisor, thank you again, but i got that going just a few minutes before and was just about to change my question again ^^ just thinking about how to explain it right now Edited January 2, 2015 by Purswader Link to comment Share on other sites More sharing options...
Purswader Posted January 2, 2015 Author Share Posted January 2, 2015 @Kzisor, do you know how i can implement the function GIRKeyHandler:OnRawKey into my prefab script? Cause there i cant access the GLOBAL variables. Link to comment Share on other sites More sharing options...
Kzisor Posted January 2, 2015 Share Posted January 2, 2015 (edited) @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") endendtheGIRKeyHandler = 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 January 2, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Kzisor Posted January 2, 2015 Share Posted January 2, 2015 @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 = instself.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") endend 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 More sharing options...
Purswader Posted January 2, 2015 Author Share Posted January 2, 2015 @Kzisor, i tryed and it workes just wonderful. I will make my thing and let u know if ran into some problems. But for now thank you very much. Link to comment Share on other sites More sharing options...
Purswader Posted January 3, 2015 Author Share Posted January 3, 2015 (edited) @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 January 3, 2015 by Purswader Link to comment Share on other sites More sharing options...
Kzisor Posted January 4, 2015 Share Posted January 4, 2015 (edited) @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 January 4, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Purswader Posted January 4, 2015 Author Share Posted January 4, 2015 @Kzisor, I'm glad to hear that you are working on it. I can't get this wo work, but i'm still trying. Link to comment Share on other sites More sharing options...
Kzisor Posted January 4, 2015 Share Posted January 4, 2015 @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 = instself.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") endend return KeyHandler Link to comment Share on other sites More sharing options...
Purswader Posted January 4, 2015 Author Share Posted January 4, 2015 @Kzisor, i was talking about that client thing , but thank you ^^ Link to comment Share on other sites More sharing options...
Kzisor Posted January 4, 2015 Share Posted January 4, 2015 (edited) @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.lualocal 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 = ThePlayer if (key and not down) and not IsPaused() then player:PushEvent("keypressed", {player = player, key = key}) endend return KeyHandler modmain.lua/character prefab.lualocal function OnKeyPressed(inst, data)if data.player == GLOBAL.ThePlayer thenprint(tostring(data.key))endend Wilson = function(self)self:AddComponent("keyhandler") self:ListenForEvent("keypressed", OnKeyPressed) return selfend AddPrefabPostInit("wilson", Wilson) This will do exactly what you are wanting to do. Edited January 4, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Purswader Posted January 4, 2015 Author Share Posted January 4, 2015 @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. Link to comment Share on other sites More sharing options...
Kzisor Posted January 4, 2015 Share Posted January 4, 2015 @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.") endendend Link to comment Share on other sites More sharing options...
Purswader Posted January 4, 2015 Author Share Posted January 4, 2015 (edited) @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 January 4, 2015 by Purswader Link to comment Share on other sites More sharing options...
Kzisor Posted January 4, 2015 Share Posted January 4, 2015 (edited) @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 January 4, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Purswader Posted January 4, 2015 Author Share Posted January 4, 2015 @Kzisor, doesn't seem to work, i even triedlocal function OnKeyPressed(inst, data)if data.player == ThePlayer thenif data.key == KEY_T thenprint("test")endendendand there was no output Link to comment Share on other sites More sharing options...
Kzisor Posted January 5, 2015 Share Posted January 5, 2015 @Kzisor, doesn't seem to work, i even triedlocal function OnKeyPressed(inst, data)if data.player == ThePlayer thenif data.key == KEY_T thenprint("test")endendendand 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 More sharing options...
Purswader Posted January 5, 2015 Author Share Posted January 5, 2015 @Kzisor, here u go gir.lua Link to comment Share on other sites More sharing options...
Kzisor Posted January 5, 2015 Share Posted January 5, 2015 @Purswader, If you remove the 'if data.key == KEY_T then' statement does it print test on any key press? Link to comment Share on other sites More sharing options...
Purswader Posted January 5, 2015 Author Share Posted January 5, 2015 @Kzisor, my testers are all asleep by now, i will try tomorrow Link to comment Share on other sites More sharing options...
rezecib Posted January 5, 2015 Share Posted January 5, 2015 @Purswader, GLOBAL.ThePlayer? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now