PDA

View Full Version : Creating a New List Type/Class/etc



LordEntrails
September 3rd, 2019, 00:24
So I've got the need to create a couple of new sets of lists in my ruleset. I'm basing this off the Inventory lists system in CoreRPG, but am stuck due to my lack of coding knowledge.

I starting by duplicating the "<list_charinv", "<button_iedit" & "<button_iadd" sections from "record_char_inventory.xml" to "record_char_main.xml" and editing as follows (and putting them inside a frame);

<list_defenses name="defenselist"> <anchored to="defensesframe">
<top offset="40" />
<left offset="15" />
<right offset="-20" />
<bottom offset="-15" />
</anchored>
</list_defenses>
<scrollbar>
<anchored to="defenselist" />
<target>defenselist</target>
</scrollbar>


<button_iedit name="defenselist_iedit">
<anchored to="defenselist" position="aboveright" offset="5,10" />
<target>defenselist</target>
</button_iedit>
<button_iadd name="defenselist_iadd">
<anchored to="defenselist_iedit" position="lefthigh" offset="5,0" />
<target>defenselist</target>
</button_iadd>


xxx

I then duplicated the "record_char_inventory.xml" file to "record_char_defenses.xml" file and changed the windowclass name as follows;

<windowclass name="ship_defenseitem">
...


I copied "char_invlist.lua" to "ship_defenses.lua" and changed the update function to;

function update()
local bEditMode = (window.defenseslist_iedit.getValue() == 1);
window.idelete_header.setVisible(bEditMode);
for _,w in ipairs(getWindows()) do
w.idelete.setVisibility(bEditMode);
end
end



I added the includefile to base.xml;

<includefile source="campaign/record_char_defenses.xml" />
I wondered about an include for "ship_defenses.lua", but "char_invlist.lua" doesn't have one.

I added the "list_defense" windowclass template to the "template_char.xml" as follows;

<template name="list_defenses">
<windowlist>
<child></child>
<child><backcolor>1A40301E</backcolor></child>
<datasource>.defenses</datasource>
<class>ship_defenseitem</class>
<allowdelete />
<script file="campaign/scripts/ship_defenses.lua" />
</windowlist>



But now I'm getting the following error when I click the edit button to add a new defense. Maybe I need to initialize a variable or create the database field or...? Anyway, my Find in Files has failed to indicate what I'm missing :(

Script Error: [string "campaign/scripts/ship_defenses.lua"]:72: attempt to index field 'defenseslist_iedit' (a nil value)


Help would be appreciated, as I've spent an hour plus on just this error :(

Paul Pratt
September 3rd, 2019, 01:50
LordEntrails,

(window.defenseslist_iedit.getValue() == 1);

should be:

(window.defenselist_iedit.getValue() == 1);

extraneous "s"

LordEntrails
September 3rd, 2019, 04:19
*lol* Thanks Paul. See I would never make it professionally!

I corrected that, but I'm still getting the error. Entries are created, so that is good (not sure it was doing that before). But the console still throws that error every time I click or add. I'll go back through and check it all and see if I can find whatever mistakes I made.

damned
September 3rd, 2019, 05:09
Use Find in Files and search for:

defenseslist
defenseslist_iedit
_iedit

and see if you can track it down.

Paul Pratt
September 3rd, 2019, 06:16
Is the script error still :Script Error: [string "campaign/scripts/ship_defenses.lua"]:72: attempt to index field 'defenseslist_iedit' (a nil value)

or

did it at least change to: Script Error: [string "campaign/scripts/ship_defenses.lua"]:72: attempt to index field 'defenselist_iedit' (a nil value)

?

Just curious. If it changed then we need to figure out why the defenselist_iedit is returning nil and not a value as expected. If it is the same error, then as damned said, there is another misspelling somewhere.

LordEntrails
September 3rd, 2019, 15:40
Should have clarified. It's the same message except it's now line 73. i.e.

window.idelete_header.setVisible(bEditMode);
I've got to go to work, so I will track this down tonight when I get home. Thanks to both of you. I'll let you know tonight if I'm still stuck or what the solution is.
Appreciate it :)

LordEntrails
September 4th, 2019, 04:23
I can't figure it out, but I do have a thought that maybe someone can help me figure out.

The error is;

Script Error: [string "campaign/scripts/ship_defenses.lua"]:73: attempt to index field 'idelete_header' (a nil value)
Script Error: [string "campaign/scripts/ship_defenses.lua"]:73: attempt to index field 'idelete_header' (a nil value)


Line 73 is the "window.idelete" part of;


function update()
local bEditMode = (window.defenselist_iedit.getValue() == 1);
window.idelete_header.setVisible(bEditMode);
for _,w in ipairs(getWindows()) do
w.idelete.setVisibility(bEditMode);
end
end

But I think the actual problem comes from the 'record_char_defenses.xml' where I define the windowclass 'defenselist'. I thought I could just duplicate the default windowclass and give it the new name and leave everything internal to it the same (until I figure out how to remove/add fields to my desire), but maybe that's not right? Here's the complete code for the windowclass, if I'm right as to what needs to be updated. But I'm clueless of what inside of here would need to be changed.


<windowclass name="ship_defenseitem">
<margins control="0,0,0,2" />
<script>
function onInit()
getDatabaseNode().onDelete = onDelete;
end
function onDelete(node)
ItemManager.onCharRemoveEvent(node);
end
</script>
<sheetdata>
<hidden_record_isidentified name="isidentified"><class>item</class><ignorehost /></hidden_record_isidentified>


<number_charinv name="count">
<bounds>5,2,20,20</bounds>
<tabtarget next="name" />
<default>1</default>
</number_charinv>


<genericcontrol name="rightanchor">
<anchored width="0" height="0">
<top />
<right />
</anchored>
<invisible />
</genericcontrol>
<button_idelete name="idelete">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-5" />
</anchored>
</button_idelete>
<linkcontrol_id name="shortcut">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-2" />
</anchored>
<class>item</class>
<readonly />
</linkcontrol_id>
<button_char_inv_carried name="carried">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-5" />
</anchored>
</button_char_inv_carried>
<number_charinv name="weight">
<anchored width="30" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-10" />
</anchored>
<delaykeyupdate />
<tabtarget prev="location" />
</number_charinv>
<string_charinvloc name="location">
<anchored width="80" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-10" />
</anchored>
<tabtarget next="weight" prev="nonid_name" />
</string_charinvloc>


<string_charinvname name="name">
<anchored position="insidetopleft" offset="35,2" height="20">
<right parent="rightanchor" anchor="left" relation="current" offset="-5" />
</anchored>
<tabtarget next="nonid_name" prev="count" />
</string_charinvname>
<string_charinvname name="nonid_name">
<anchored position="insidetopleft" offset="35,2" height="20">
<right parent="rightanchor" anchor="left" relation="current" offset="-5" />
</anchored>
<empty textres="library_recordtype_empty_nonid_item" />
<invisible />
<tabtarget next="location" prev="name" />
</string_charinvname>
</sheetdata>
</windowclass>

damned
September 4th, 2019, 04:41
When you cant see it in the files you think it is - use find in files

Things like button_idelete have a definition somewhere else - so find in files on that and see what comes up.

And somewhere else might be in your code or in anything it is layered on.

LordEntrails
September 4th, 2019, 05:27
I did Find in Files, I swear :)
But I will look again tomorrow to see if I can find where it's defined :)
Thanks for keeping me pointed in the right direction!

damned
September 4th, 2019, 05:57
lets try another possible tack...

is this your code?


function update()
local bEditMode = (window.inventorylist_iedit.getValue() == 1);
window.idelete_header.setVisible(bEditMode);
for _,w in ipairs(getWindows()) do
w.idelete.setVisibility(bEditMode);
end
end

try inserting:
Debug.chat("bEditMode: ", bEditMode );
at line 73.
is it bEditMode that is nil?

Paul Pratt
September 4th, 2019, 06:40
LordEntrails,

In the CoreRPG record_char_inventory there is a field idelete_header, in fact there are a few headers. See below.


<genericcontrol name="idelete_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<disabled />
</genericcontrol>
<genericcontrol name="shortcut_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-2" />
</anchored>
<disabled />
</genericcontrol>
<genericcontrol name="carried_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<icon>char_inv_carried_header</icon>
<tooltip textres="char_tooltip_itemcarried" />
</genericcontrol>

The .xml snippet you shared it the "item" or the information on the way the list will look. The above information is contained in the window information. In record_char_inventory it is the first part <root>
<windowclass name="charsheet_inventory">. Read what follows that. It sets up the window information that will house the list. The headers are contained there. If you have a custom window to display your list in, then add the headers above and should work.

LordEntrails
September 7th, 2019, 17:37
lets try another possible tack...

is this your code?


function update()
local bEditMode = (window.inventorylist_iedit.getValue() == 1);
window.idelete_header.setVisible(bEditMode);
for _,w in ipairs(getWindows()) do
w.idelete.setVisibility(bEditMode);
end
end

try inserting:
Debug.chat("bEditMode: ", bEditMode );
at line 73.
is it bEditMode that is nil?

Thanks, so here's my new code (with line numbers);


71 function update()
72 local bEditMode = (window.defenselist_iedit.getValue() == 1);
73 Debug.chat("bEditMode: ", bEditMode );
74 window.idelete_header.setVisible(bEditMode);
75 for _,w in ipairs(getWindows()) do
76 w.idelete.setVisibility(bEditMode);
77 end
78 end


Here's what shows up in chat;

s'bEditMode: ' | bFALSE
s'bEditMode: ' | bFALSE


Here's what the console give me when I open a charactersheet;

Script Error: [string "isidentified"]:1: attempt to index field 'nonid_name' (a nil value)
Script Error: [string "campaign/scripts/ship_defenses.lua"]:74: attempt to index field 'idelete_header' (a nil value)
Script Error: [string "campaign/scripts/ship_defenses.lua"]:74: attempt to index field 'idelete_header' (a nil value)




I'll work on what Paul suggested next as I don't quite get what this means or if the debug statement is actually working or is telling us.

Thanks again.

LordEntrails
September 7th, 2019, 17:49
Thanks Paul, I think I understand that part and what you are saying/suggesting. Or atleast I think I know what I need to modify to get the fields I need/want. Not sure I know just what changes to make there yet. If it helps and anyone has time to actually look, I will attached the current version of the ruleset (looks like I will have to restart, 7-Zip is not behaving).

But here's the windowclass that I'm working on defining in the 'record_char_defenses.xml file;


<windowclass name="ship_defenseitem">
<margins control="0,0,0,2" />
<script>
function onInit()
getDatabaseNode().onDelete = onDelete;
end
function onDelete(node)
ItemManager.onCharRemoveEvent(node);
end
</script>
<sheetdata>
<hidden_record_isidentified name="isidentified"><class>item</class><ignorehost /></hidden_record_isidentified>


<number_charinv name="count">
<bounds>5,2,20,20</bounds>
<tabtarget next="name" />
<default>1</default>
</number_charinv>


<genericcontrol name="rightanchor">
<anchored width="0" height="0">
<top />
<right />
</anchored>
<invisible />
</genericcontrol>
<button_idelete name="idelete">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-5" />
</anchored>
</button_idelete>
<linkcontrol_id name="shortcut">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-2" />
</anchored>
<class>item</class>
<readonly />
</linkcontrol_id>
<button_char_inv_carried name="carried">
<anchored width="20" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-5" />
</anchored>
</button_char_inv_carried>

<!--
<number_charinv name="weight">
<anchored width="30" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-10" />
</anchored>
<delaykeyupdate />
<tabtarget prev="location" />
</number_charinv>
-->
<number_defenseuses name="uses">
<anchored width="30" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-10" />
</anchored>
</number_defenseuses>

<string_charinvloc name="location">
<anchored width="80" height="20">
<top offset="2" />
<right parent="rightanchor" anchor="left" relation="relative" offset="-10" />
</anchored>
<tabtarget next="weight" prev="nonid_name" />
</string_charinvloc>


<string_charinvname name="name">
<anchored position="insidetopleft" offset="35,2" height="20">
<right parent="rightanchor" anchor="left" relation="current" offset="-5" />
</anchored>
<tabtarget next="nonid_name" prev="count" />
</string_charinvname>

</sheetdata>
</windowclass>

Paul Pratt
September 7th, 2019, 20:34
LordEntrails,
You should have something like this. I am not sure the layout works, this is from the base CoreRPG

First

<genericcontrol name="idelete_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<disabled />
</genericcontrol>
<genericcontrol name="shortcut_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-2" />
</anchored>
<disabled />
</genericcontrol>
<genericcontrol name="carried_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<icon>char_inv_carried_header</icon>
<tooltip textres="char_tooltip_itemcarried" />
</genericcontrol>

Then


<list_defenses name="defenselist">
<anchored to="defensesframe">
<top offset="40" />
<left offset="15" />
<right offset="-20" />
<bottom offset="-15" />
</anchored>
</list_defenses>
<scrollbar>
<anchored to="defenselist" />
<target>defenselist</target>
</scrollbar>


<button_iedit name="defenselist_iedit">
<anchored to="defenselist" position="aboveright" offset="5,10" />
<target>defenselist</target>
</button_iedit>
<button_iadd name="defenselist_iadd">
<anchored to="defenselist_iedit" position="lefthigh" offset="5,0" />
<target>defenselist</target>
</button_iadd>

Your error seems to generate from this part of the Lua

71 function update()
72 local bEditMode = (window.defenselist_iedit.getValue() == 1);
73 Debug.chat("bEditMode: ", bEditMode );
74 window.idelete_header.setVisible(bEditMode);
75 for _,w in ipairs(getWindows()) do
76 w.idelete.setVisibility(bEditMode);
77 end

It can't find the "idelete_header" in order to setVisible and continue the script. Adding the .xml above should take care of that.

If you are using shortcuts and carried in a similar fashion, then add the carried and shortcut headers above as well or you will get errors too.

LordEntrails
September 8th, 2019, 00:49
Thanks Paul. I will investigate and let you know what I find. I finally got back and attached is the ruleset if desired. Will post once I get this resolved or get more info etc.
(edit, file too large. Will figure that out later. Back to coding!)

LordEntrails
September 8th, 2019, 01:02
So Find In Files shows that idelete_header is defined in 2 locations. Might that be the problem? One is in 'record_char_inventory.xml' and the other in 'record_char_defenses.xml'

Both show the same code;


<genericcontrol name="idelete_header">
<anchored to="rightanchor" width="20" height="20">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<disabled />
</genericcontrol>


I tried commenting out one of the definitions but still get the identical errors and debug message in chat.(see post #12).

Now I don't really understand the edit mode, but if the value of bEditMode is false, then ...?
Maybe do I need to initialize the value of idelete_header so the console error of a nil value doesn't happen?

I'm going to work on the fields for the frame for now and will get back to this error later (or when someone can point me in another direction or re-point me to what I'm missing!)

Bidmaron
September 8th, 2019, 05:28
LE, I haven't followed this whole discussion, but what Paul is telling you is correct. You cannot rely upon a declaration of idelete_header in another file unless you are using a template, which Idelete_header is not: it is a control in those other two declarations and not a template. Assuming you put Paul's xml into your window xml code, that will define your own idelete_header which you can then reference as your own window control. That should get you in business.

Trenloe
September 9th, 2019, 23:09
As has been mentioned - the name of a FG control is unique purely within a specific <sheetdata> section of a windowclass. Only templates can be re-used - and the template name becomes the XML tag of the control within <sheetdata>.

Secondly, if FG is reporting "nil" error, then it means that specific named object (control, variable, etc.) doesn't exist within the scope of the script that is running. What scope does the LUA that raises the error execute with? That is, does it execute within the <windowclass> (the LUA is associated with the windowclass via a <script> entry) or is the scope within a specific control (the <script> entry is within the XML of a control) or outside of the GUI (a global script package)? How/where does the actual code run? Identify where the code is actually running and then look why the code is reporting the "nil" error - in your case this is the code not being able to access a named control, if that named control can't be accessed within the scope of the code then it won't be able to find it, and hence raise the "nil" error.

LordEntrails
September 12th, 2019, 00:08
Thanks all. life has kept me from getting back to this, but what you are all saying makes sense. I'll let you know either way once I do get back to it (probably tomorrow or this weekend).