Howdy, Stranger!

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

Really Noobish Question (Simple if-else Statements) (SugarCube)

Well, here I am thinking I know just a little bit about Twine and Javascript, and I'm having this ridiculous brain fart.

Here's my JavaScript in a Script passage -



window.ArmorPiece = function(Slot, Name, Description, Armor){
this.Slot = Slot;
this.Name = Name;
this.Description = Description;
this.Armor = Armor;
};



window.Player = {
Armor: {
Head: NaN,
Torso: NaN,
Hands: NaN,
Legs: NaN,
Feet: NaN,
}

}
window.Nothing = new ArmorPiece(Player.Armor.Torso, "Nothing", "You Don't Have Anything Equiped In This Slot.", 0);
window.Hat = new ArmorPiece(Player.Armor.Head, "Hat", "A Simple Hat, With A Random Logo On It And Such.", 5);
window.Shirt = new ArmorPiece(Player.Armor.Torso, "Shirt", "A Mundane, Plain White T-Shirt.", 5);
window.Player.Armor.Head = Hat;
window.Player.Armor.Torso = Shirt;
Might not be the most effective, (actually, I know it probably isn't), but it works, well to a point.

So I have a little tester in my Start passage that displays Armor information -
<center><h1>Head</h1></center>
<<print $Player.Armor.Head.Name>>
<<print $Player.Armor.Head.Description>>
<hr>
<center><h1>Torso</h1></center>
<<print $Player.Armor.Torso.Name>>
<<print $Player.Armor.Torso.Description>>
<<if $Player.Armor.Torso neq Nothing>><<click "Unequip" "Start">><<set $Player.Armor.Torso = Nothing>><</click>><</if>>
<hr>

So, clicking the unequip link does what it's supposed to, it unequips the shirt, and shows the "Nothing" Name and Description, but what's really leaving me scratching my head is why the preceding "if" statement doesn't seem to be registering. I would have thought I had the if else rules down by now (in Twee and JavaScript), alas, I realized apparently I don't.

I don't think I'm totally illiterate though, and I would assume the error lays somewhere within the setup of the ArmorPiece and Player Objects. In that, something about the layout Twee's if else doesn't understand.

I tried converting "Nothing" by setting <<set $Nothing = Nothing>>, but that doesn't seem to be working either.

I know this is really basic, but all I can do is ask. (And Facepalm)

Thanks for reading, and I never mind a good critiquing. 

Comments

  • The answer is simple, every time you change passages the built-in java-script engine clones all the $variables (and their properties) so the originals can be added to the History sub-system.

    So the second time the IF gets executed the instance of the ArmorPiece object that is stored within the $Player.Armor.Torso variable is no longer the same one as the one stored in window.Nothing, even thought both of these instances of ArmorPiece have the same property values. (eg Slot, Name, Description, Armor)
  • greyelf wrote:

    The answer is simple, every time you change passages the built-in java-script engine clones all the $variables (and their properties) so the originals can be added to the History sub-system.

    So the second time the IF gets executed the instance of the ArmorPiece object that is stored within the $Player.Armor.Torso variable is no longer the same one as the one stored in window.Nothing, even thought both of these instances of ArmorPiece have the same property values. (eg Slot, Name, Description, Armor)


    Any workaround to achieve what I'm trying to do?
  • If your creating a RPG and don't need to allow the Player to undo their choices then you can disable the History Tracking sub-system via the  config.disableHistoryTracking option.

    Otherwise you could add a property to the ArmorPiece prototype that is only set true in the Nothing instance and test against that instead

    window.ArmorPiece = function(Slot, Name, Description, Armor){
    this.Slot = Slot;
    this.Name = Name;
    this.Description = Description;
    this.Armor = Armor;
    this.isNothing = false;
    };

    window.Nothing = new ArmorPiece(Player.Armor.Torso, "Nothing", "You Don't Have Anything Equiped In This Slot.", 0);
    window.Nothing.isNothing = true;

    window.Hat = new ArmorPiece(Player.Armor.Head, "Hat", "A Simple Hat, With A Random Logo On It And Such.", 5);

    :: Start
    <<if not $Player.Armor.Torso.isNothing>><<click "Unequip" "Start">><<set $Player.Armor.Torso = Nothing>><</click>><</if>>

  • EcnelOvelam wrote:

    window.Player = {
    Armor: {
    Head: NaN,
    Torso: NaN,
    Hands: NaN,
    Legs: NaN,
    Feet: NaN,
    }
    }


    NaN (floating point: Not a Number) is not null.  Also, statements end in semi-colons.  That should be:

    window.Player = {
    Armor : {
    Head : null,
    Torso : null,
    Hands : null,
    Legs : null,
    Feet : null
    }
    };

    greyelf wrote:

    If your creating a RPG and don't need to allow the Player to undo their choices then you can disable the History Tracking sub-system via the  config.disableHistoryTracking option.


    Sadly, that will not solve the issue here (I assume you were thinking it would).  Even with config.disableHistoryTracking enabled, the $variable store is still cloned every turn.  This is to keep the turn-by-turn behavior w/r/t $variables consistent between the two modes.  All config.disableHistoryTracking does is limit the history stack to one state (i.e. the stack is popped just before a new state is about to be pushed).


    @EcnelOvelam: I'd probably have suggested something similar to what greyelf just did (i.e. the isNothing property).  You could do it other ways (e.g. like checking the Name: &lt;&lt;if $Player.Armor.Torso.Name neq &quot;Nothing&quot;&gt;&gt;), however, doing it as a separate property is cleaner and allows you to change the name of your Nothing armor in the future without having to redo all your conditional checks.
  • @TheMadExile
    TheMadExile wrote:

    NaN (floating point: Not a Number) is not null.

    I'm aware of the differences between NaN and null.
    I assumed he was using NaN to track that the property had never been assigned a value vs null meaning the property currently has no value, its a technique I have seen used before.

    [quote]
    Sadly, that will not solve the issue here (I assume you were thinking it would).  Even with config.disableHistoryTracking enabled, the $variable store is still cloned every turn.

    I will have to remember this.
    Have you thought about allowing the objects' clone method to be aware of the flag and having it returning a reference to the original object if the flag is set, this should allow the rest of the related code to stay unaware that it is not dealing with a new instance (clone) of the object.
  • greyelf wrote:

    I'm aware of the differences between NaN and null.
    I assumed he was using NaN to track that the property had never been assigned a value vs null meaning the property currently has no value, its a technique I have seen used before.


    I never said you weren't.  I was responding to EcnelOvelam (check the origin of my quote there).

    Personally, I thought they were just confused about what to do there, especially considering that they immediately set some of those very properties (and so, they're obviously not checking those for undefined-ness).  /shrug


    greyelf wrote:

    Have you thought about allowing the objects' clone method to be aware of the flag and having it returning a reference to the original object if the flag is set, this should allow the rest of the related code to stay unaware that it is not dealing with a new instance (clone) of the object.


    If you actually meant an object's custom clone() method, then that is already possible.  On the other hand, if you meant SugarCube's clone() function (and simply misspoke), then I have not thought about it, since, as I noted in my previous reply, the whole reason why I didn't do that to begin with was to keep the turn-by-turn behavior consistent.

    Regardless, it's largely a moot point, however, since neither the delta coding code nor the serialization code will preserve referential relationships.  So, even if clone() did preserve referential relationships (either by caching references or simply by not cloning at all), relationships would be lost as soon as either a history navigation was triggered (since all non-active history stacks are delta encoded, and most serialized as well) or a save was loaded (since all saves are both delta encoded and serialized).
Sign In or Register to comment.