CyberosLeopard Posted February 27, 2022 (edited) Edit: I'm trying to set-up some ZScript so that if the player presses some keys, say X or C, that a few things can happen. So far I have been able to create methods within a child of the DoomPlayer class that are called when the player hits these keys. The next step is for these methods to call other methods within objects that are created within this child. These objects (do correct me if I'm wrong, but I think the term might be 'controllers') have getter/setter methods that I would like to access. I'm apologising now if this thread breaks forum etiquette, I'm not familiar with starting these. Also, I know that this issue is very much programming 101 but I'm no programmer. I was trying to resolve this issue by myself some months ago, but I simply cannot do this and I've been putting off asking for help ever since. As the title states, I need some help instantiating some classes so that I can call some methods/functions from them. Specifically, I'm trying to create two objects within a child of the DoomPlayer class, with these objects being related to each other. Declaring them is fine, but I cannot seem to assign them a value (that is, 'Var object = Class();' or something like that); the error of 'unexpected '=' Expecting identifier' is printed in the terminal with GZDoom not launching. I have been using https://github.com/jekyllgrim/ZScript_Basics/ and while their guide has helped me with a few bits here and there, the section regarding pointers has not helped much, unfortunately. I'm providing some reference/example code that, hopefully, might explain things a little better than the above. Class P : DoomPlayer { Children ch1, ch2; Default { } override void BeginPlay () { self.ch1 = //this is where I'm now stuck... } //Also, I'm guessing that I should be using 'self'. void C_Key () { self.ch1.get(); } void X_Key () { self.ch2.set(); } } Just a little note, creating the objects via 'Child1 ch1;' and the same for the second also seems to work, I just like using the parent (which I'm guessing is probably the incorrect way of doing things...) Class Children : Inventory { virtual void Get () { } virtual void Set () { } } Class Child1 : Children { override void Get () { } } Child2 is the same as Child1 for the purpose of this post. Thank you for your time. Edited March 7, 2022 by CyberosLeopard This is now more specific to my problem, at the cost of maybe being less helpful to others in the future (not that anyone would likely have this much difficulty). 0 Quote Share this post Link to post
jaeden Posted February 27, 2022 (edited) Creating a new (non-actor) object in ZScript is done by syntax new("<class name>"). So yours would be ch1 = new("Child1"); Also you cannot initialize variables in class body. You need to initialize them in a method (best is probably in a BeginPlay() method override) Hopefully this helps. Edited February 27, 2022 by jaeden 1 Quote Share this post Link to post
CyberosLeopard Posted March 1, 2022 Thank you for your help. I've realised that I should have been less ambiguous and stated that the 'Children' class was inheriting from PowerupGiver; unfortunately the example you gave doesn't quite work. However, having been re-reading the ZDoom wiki article on PowerupGiver and I'm thinking it's probably a mistake to use it in the first place. I think I should be able to work it out from here. Thanks again. 0 Quote Share this post Link to post
CyberosLeopard Posted March 7, 2022 I am really, truly sorry for furthering this tread, but I don't think I'm able to work this out by myself. I'll update and amend the first post with a few additions, and to try and clarify some points; I think I was being a bit too ambiguous. I have ran through a few different permutations of creating an object of Child1: with at best ch1 holding a null value and when one of its methods are called, GZDoom crashes; at worst, GZDoom is not launching due to errors relating to not being able to convert pointers or not finding a global identifier. I don't exactly understand what I need to do. Ultimately looking at Jekyllgrim's ZScript basics (in the first post) and https://zdoom.org/wiki/Using_pointers_in_ZScript/ for reference, I think it is safe to say that a parameter is needed to instantiate the object. However, I am unsure to what parameter Inventory takes when being instantiated. I have had a quick look over on Github (https://github.com/coelckers/gzdoom/blob/master/wadsrc/static/zscript/actors/inventory/inventory.zs), but I'm not able to understand most of it, nor can I find Inventory's constructor (I've probably over looked it). Thanks again. 0 Quote Share this post Link to post
CyberosLeopard Posted July 31, 2023 I am really sorry for necro-ing this thread, but this has been eating away at the back of my head for the last few weeks being as I have found a solution to this problem. Updating this thread might, might help someone else out there (and if it doesn't, at least I'm adding a conclusion). I found the following ZDoom forum thread that held a fix to a different, but related problem regarding changing the value of variables within projectiles fired from a weapon: https://forum.zdoom.org/viewtopic.php?f=122&t=69719 Unfortunately, with me being a little on the slower side of things (a bit of an understatement, I know) I didn’t grasp that a ZDoom wiki page that I had read prior implicitly states that one is required to make a pointer and then cast said pointer: (https://zdoom.org/wiki/Using_pointers_in_ZScript). This is ultimately where I got stuck. So... what worked for me is giving the children (Child1 and-or Child2) to the player via ‘GiveInventory’ within the player’s BeginPlay() method, and saving the result in a boolean. From here, check if said boolean is true (just a precaution) and if so call ‘FindInventory’ and saving its result in a global variable (I used a type ‘Actor’). Doing those steps will save a pointer, which can be cast. For example: ‘let varname = Child1 (self.globalvarname)’. Finally, accessing the cast’s functions is as simple as ‘varname.function()’. Annoyingly, I’ve been trying to get this all working since around June/July of 2021, and in my typical stupidity it has taken around two years which would only really require another person a few hours at most… Take care. 0 Quote Share this post Link to post
ramon.dexter Posted July 31, 2023 (edited) Well, show your code. It is quite impossible to give any advice from your description, sorry. And for better, tells us what you want to make. Not the code side, just try your best to describe what you intent to achieve. Maybe there is another solution, that is completely oblivious to you. My experience with zscript is that one goal could be achieved through many completely valid and possible ways. Here, take a look at code I used in one of my inventory items. The item could be activated and deactivated, has its own 'magazine' that acts as a energy for the said item, which could be recharged. That's not important here. You could take a look at how I've modified the Use() to have more than one output. override bool Use (bool Pickup) { let pawn = wastelandRanger(owner); TextureID id_I_NED1 = TexMan.CheckForTexture("I_NED1", 0, 0); TextureID id_I_NED2 = TexMan.CheckForTexture("I_NED2", 0, 0); // check charge // checks for charge if player presses 'activate item' and 'use' keys together if ( pawn.GetPlayerInput(MODINPUT_BUTTONS)&BT_USE ) { pawn.A_Log(String.Format( "%s%i%s", stringtable.localize("$M_nightEyeDev_battsLeft1"), self.charge, stringtable.localize("$M_nightEyeDev_battsLeft2"))); } // reload // reloads item if player presses 'activate item' and 'user1' else if ( pawn.GetPlayerInput(MODINPUT_BUTTONS)&BT_USER1 ) { int finalLoad = 100 - self.charge; if ( self.charge == 100 || pawn.CountInv("EnergyPod") < finalLoad ) { pawn.A_Log("$M_nightEyeDev_cantReload"); } else { if ( pawn.CountInv("EnergyPod") >= finalLoad ) { pawn.TakeInventory("EnergyPod", finalLoad); self.charge += finalload; pawn.A_Log(String.Format( "%s%i%s", stringtable.localize("$M_nightEyeDev_battsReloaded1"), finalload, stringtable.localize("$M_nightEyeDev_battsReloaded2"))); } } } // turn off // else if ( self.inUse == 1 ) { self.inUse = 0; self.animCounter = 0; self.bUNDROPPABLE = 0; pawn.A_StartSound("flashlight/off", CHAN_5); self.icon = id_I_NED1; } // turn off if depleted // else if ( self.charge == 0 ) { pawn.A_Log("$M_nightEyeDev_battsDepleted"); self.inUse = 0; self.animCounter = 0; self.bUNDROPPABLE = 0; pawn.A_StartSound("flashlight/off", CHAN_5); self.icon = id_I_NED1; } // start // else { self.inUse = 1; self.bUNDROPPABLE = 1; pawn.A_StartSound("flashlight/on", CHAN_5); self.icon = id_I_NED2; } return false; //disable normal use } Also, you could use the keypress check in Tick() override. Like I said, many ways to achieve one goal :) Edited July 31, 2023 by ramon.dexter 1 Quote Share this post Link to post
CyberosLeopard Posted August 1, 2023 Key Configuration: Spoiler addkeysection "Mod" myMod addmenukey "Do a thing" bind0 defaultbind e bind0 alias bind0 "netevent dothing" Event Handler: Spoiler Class NewEventHandler : EventHandler { override void NetworkProcess (ConsoleEvent keyhit) { //I did try inputprocess, but there was a scope issue if (keyhit.Name == "dothing") { //This checks if a key has been hit, and if so, calls a function let p = DoomPlayer (players [keyhit.Player].mo); //within the player. p.DoThing (); } } } Player Class: Spoiler Class NewPlayer : DoomPlayer { Actor thing; override void BeginPlay () { Super.BeginPlay(); bool temp = GiveInventory ("Child1", 1); if (temp == True) { self.thing = FindInventory ("Child1"); if (self.thing == null) { A_Log ("Error");} } } override void DoThing () { if (Health >= 1) { let thisthing = Child1 (self.thing); thisthing.Execute (); } } } Child1: Spoiler Class Child1 : Inventory { Default {} void Execute () { A_Log ("Doing a thing!"); owner.GiveInventory ("ArmorBonus", 1); } } I'm hoping that covers about everything. In regards to what I'm trying to make, I hope you don't mind but I'd really rather not talk about it :) But for this thread, I simply was looking for a way to... well, do a thing via pressing a key. Also thank you for your code and time. While I only have the faintest understanding of it, it's good to know of other possibilities. I'll have to look into GetPlayerInput() along with checking for key-presses in a Tick() method at some point. 0 Quote Share this post Link to post
ramon.dexter Posted August 2, 2023 Rather not talk about it? Good luck then. When asking for help, you have to answer all qustions required. Valid answer is not 'i want to keep it secret'. When you want to have secrets, you're on your own. Sorry. 0 Quote Share this post Link to post
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.