Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

"pushing" objects into arrays or other objects?

edited July 2015 in Help! with 2.0
Hi everyone!

I've tried to look for answers regarding this topic in previous posts, to no avail. Sorry if it has been documented or asked and answered somewhere. I'm usin Twine 2 with SugarCube 2.

So I have an NPC database that is an object, with objects inside that are NPCs, with various types of datas, like so:
<<set $npcroaster to {
	anton : {
    	name : "Anton",
        strength : 1,
        intelligence : 1,
        honesty : 1,
        trust_in_pc : 0,
        feels_stronger_than_pc : 0,
        feels_smarter_than_pc : 0,
        currentloc : "tavern",
        alive : true,
        npcmoney : 22,
        npcinventory : $antoninventory,
        friendswith : $antonfriends,
        enemywith : $antonenemies,
        neutralwith : $antonneutrals,
        knows : $antonknows,
        },

In the above example, i've used variable names for readability, but that's not very relevant to the problem at hand (I believe).

My issue is that I'm trying to "push" objects into $npcroaster.anton.knows, each object being a "knowledge" the NPC acquires, complete with a name, description, and other attributes (like is this knowledge transferable or not, etc.).

I can't seem to find the correct syntax/method to do this, like you would for an array (<<set $array.push("string")>>).

Is this even possible?

Can an array contain objects? If yes, how do you "push" an object into an array, then retrieve its attributes?
[edit: nevermind the objects into array thing, since one cannot provide property names to an array literal, it wouldn't be much help for me, it's better to work with only objects]

Thanks in advance for your help !

(here is where I'm at currently, of course it doesn't seem to work:)
<<silently>><<set $tmpKeys to Object.keys($npcroaster)>>\
<<for $y to 0; $y lt $presentnpcs.length; $y++>>
	<<nobr>><<for $i to 0; $i lt $tmpKeys.length; $i++>>
		<<if $npcroaster[$tmpKeys[$i]].name is $presentnpcs[$y]>>
		<<set $npcroaster[$tmpKeys[$i]].knows.push($presentnpcsnewknowledge)>>
    <</if>>
	<</for>><</nobr>>
<</for>>
<<unset $tmpKeys>>\
<</silently>>
$presentnpcsnewknowledge is supposed to be an object.

Edit2: I've proceeded further with some testing.

I've set up $npcroaster like this:
<<set $npcroaster to {
	anton : {
    	name : "Anton",
        strength : 1,
        intelligence : 1,
        honesty : 1,
        trust_in_pc : 0,
        feels_stronger_than_pc : 0,
        feels_smarter_than_pc : 0,
        currentloc : "tavern",
        alive : true,
        npcmoney : 22,
        npcinventory : $antoninventory,
        friendswith : $antonfriends,
        enemywith : $antonenemies,
        neutralwith : $antonneutrals,
        knows : {
        	pcname : {
            name: "pcname",
            description: "you're named $pcbio.name.",
            spreadable : true,
            },
        	},
        },
},

then tested like this:
<<print $npcroaster.anton.knows.pcname.name>>
<<print $npcroaster.anton.knows.pcname.description>>
<<print $npcroaster.anton.knows.pcname.spreadable>>

<<nobr>>
/% setting up Player's location %/
<<set $pcstats.pcloc to "tavern">>
/% determining present NPCs in that location %/
<<display "Determine present NPCs">>
/% Displaying present NPCs %/
<<render "Presentnpcs display">>
/% setting up NPCs who are talked to %/
<<set $talkedtonpcs to ["Anton"]>>
<</nobr>>\

/% setting up new knowledge to be acquired %/
<<set $presentnpcsnewknowledge to {
		pcfatherdead : {
        	name : "pcfatherdead",
        	description : "your father is dead.",
        	spreadable : true,
            },
        }>>
        
/% spreading knowledge to talked to NPCs %/
<<silently>><<set $tmpKeys to Object.keys($npcroaster)>>\
<<for $y to 0; $y lt $presentnpcs.length; $y++>>
	<<nobr>><<for $i to 0; $i lt $tmpKeys.length; $i++>>
		<<if $npcroaster[$tmpKeys[$i]].name is $presentnpcs[$y]>>
		<<set $npcroaster[$tmpKeys[$i]].knows to ($npcroaster[$tmpKeys[$i]].knows + $presentnpcsnewknowledge)>>
    <</if>>
	<</for>><</nobr>>
<</for>>
<<unset $tmpKeys>>\
<</silently>>
<<print $npcroaster.anton.knows.pcfatherdead.name>>
<<print $npcroaster.anton.knows.pcfatherdead.description>>
<<print $npcroaster.anton.knows.pcfatherdead.spreadable>>

However, I'm getting some "Cannot read property 'name'/'description'/'spreadable' of undefined" errors on the final print macros -eventhough my debug says the setting seemed to work since it returns "knows: [object Object][object Object]"

I'm kind of lost :P

Comments

  • edited August 2015
    The issue with that <<set>> line is that you are trying to add two Objects together using a plus sign and that is not how you add new members to an Object, to do that you can use jQuery's extend method.

    Sometimes when testing how to do something it is a good idea to first use a simpler version of what you are trying to test. The following is based on your above examples:
    <<set $knows to {
    	pcname : {
        		name: "pcname",
            	description: "you're named $pcbio.name.",
            	spreadable : true,
    	}
    }>>
    
    <<set $presentnpcsnewknowledge to {
    	pcfatherdead : {
        		name : "pcfatherdead",
    		description : "your father is dead.",
            	spreadable : true
    	}
    }>>
    
    Before:
    knows keys: <<print Object.keys($knows)>>
    knows.pcname.name: <<print $knows.pcname.name>>
    pcfatherdead.name <<print $presentnpcsnewknowledge.pcfatherdead.name>>
    
    /% Add second object to the first object %/
    <<run jQuery.extend($knows, $presentnpcsnewknowledge)>>
    
    After:
    knows keys: <<print Object.keys($knows)>>
    knows.pcname.name: <<print $knows.pcname.name>>
    knows.pcfatherdead.name: <<print $knows.pcfatherdead.name>>
    

    So the line in your example should be change to something like the following:
    <<run jQuery.extend($npcroaster[$tmpKeys[$i]].knows, $presentnpcsnewknowledge)>>
    

  • Thank you greyelf!
Sign In or Register to comment.