Howdy, Stranger!

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

ternary operator doesnt work with state.variables sugarcube

edited March 2017 in Help! with 2.0
i have two somekind of health bar in header and some code in passage to calculate the health bar and animate it, but some error popup and said bad evaluation:energyTotal is not defined
::PassageHeader
<div class="section-stats btcf">
	<div class="stats-wrapper energy-bar" data-status="energy-bar">
		<span>Energy</span>
		<div class="stats-bar">
	  		<div class="bar">
		  		<div class="hit"></div>
	  		</div>
		</div>
	</div>
	<div class="stats-wrapper hunger-bar" data-status="hunger-bar">
		<span>Hunger</span>
		<div class="stats-bar">
	  		<div class="bar">
		  		<div class="hit"></div>
	  		</div>
		</div>
	</div>
</div>
::Passage
<<script>>
$('.section-stats .stats-wrapper').each(function(index, el) {
	var dataStats = $(this).data('status');

	var eBar = $('.'+ dataStats +' .stats-bar'),
		bar = eBar.find('.bar');

	var varTotal = (dataStats = "energy-bar")?energyTotal:hungerTotal;
	var varName = (dataStats = "energy-bar")?energy:hunger;
	var varLoss = (dataStats = "energy-bar")?energyLoss:hungerLoss;

	var total = State.variables.varTotal,
		value = State.variables.varName,
		damage = State.variables.varLoss,
		barWidth = (value / total) * 100,
		delayReset = false;

	if (damage != 0) {
		value -= damage;
		barWidth = (value / total) * 100;
		State.variables.varName = value;
		State.variables.varLoss = 0;
		delayReset = true;
	}

	eBar.data('total', total);
	eBar.data('value', value);
	if (State.variables.varName <= State.variables.varTotal){
		if(State.variables.varName>0){
			bar.css('width', barWidth + "%");
		}else{
			bar.css('width', '0');
			State.variables.varName = 0
		}
	}else{
		bar.css('width', "100%");
		State.variables.varName = 100
	}
});
<</script>>

is using ternary operator is wrong ? or the whole concept is bad ? im using ternary operator because i want multiple health bar like.

any help will be appreciated, thx before.

Comments

  • The issue isn't ternary operator itself, but a variety of other errors in the surrounding code:
    • energyTotal, hungerTotal, energy, hunger, energyLoss & hungerLoss really aren't defined.
      As in, you have not declared those variables anywhere so the error message is being very literal.
    • You should be using === and !== to make true/false comparisons.
      The code (dataStats = "energy-bar") is setting dataStats to have the value "energy-bar", overwriting whatever was there before.
      After that point, dataStats definitely exists and has a value assigned to it ("energy-bar"), and so that code will always return true.
    • You should be using variables() to get at story variables.
      E.g. variables().varTotal instead of State.variables.varTotal
    • varTotal, varName and varLoss don't get used again: In your next line you declare total, value and damage and start using those instead.

    I must admit I'm having trouble figuring out how your code is intended to work. The above list is not intended to be exhaustive, I'm just trying to specifically address your concerns around ternary operators and story variables.
  • edited March 2017
    caberg wrote: »
    ternary operator doesnt work with state.variables sugarcube
    Please do not use a declarative title when asking a question. Especially, one that's incorrect.

    Rokiyo wrote: »
    • You should be using variables() to get at story variables.
      E.g. variables().varTotal instead of State.variables.varTotal
    There's absolutely nothing wrong with using State.variables. Technically, State.variables should be preferred over the varaibles() function, since all the latter does is return State.variables. By accessing State.variables directly, you save yourself an extra function call on each access of the story variable store—that isn't a huge deal, however, so I don't want to oversell it. An additional reason to possibly prefer State.variables is because of its sibling State.temporary, for which there is no function equivalent.

    The real variable store issue here is not caching the access to the store. If you're going to access either the story or temporary variable stores multiple times within a chuck of pure JavaScript, then you're better off caching the store—this is also not a huge deal, so I don't want to oversell it either. For example:
    → Caching the story variables store via the State.variables property
    var sv = State.variables;
    
    → Caching the story variables store via the variables() function
    var sv = variables();
    
    And using the cached store:
    var total = sv.varTotal,
    
  • edited March 2017
    Please do not use a declarative title when asking a question. Especially, one that's incorrect.
    oh im sorry for that, i'll be more careful in the next future.
    → Caching the story variables store via the State.variables property
    var sv = State.variables;
    
    → Caching the story variables store via the variables() function
    var sv = variables();
    
    And using the cached store:
    var total = sv.varTotal,
    
    ok so im edit a little based on your suggestion, but how to make this thing works ? its still show same error. (energyTotal is not defined)

    here's some little code that i have trouble with
    varTotal = (dataStats = "energy-bar")?energyTotal:hungerTotal,
    varName = (dataStats = "energy-bar")?energy:hunger,
    varLoss = (dataStats = "energy-bar")?energyLoss:hungerLoss,
    		
    sv = State.variables,
    		
    total = sv.varTotal,
    value = sv.varName,
    damage = sv.varLoss,
    

    i'm little know about javascript and i'm quite understand the energyTotal is not defined, but what should i do then to make this State.variables become dynamic ? or im wrong ?

    thx for the quick reply @TheMadExile and @Rokiyo
  • Rokiyo explained what was wrong with the assignment expressions where you're attempting to use the ternary operators. In conditional part of the ternarys you're using the assignment operator where you should be using an equality operator. For example, the following:
    varTotal = (dataStats = "energy-bar")?energyTotal:hungerTotal,
    varName = (dataStats = "energy-bar")?energy:hunger,
    varLoss = (dataStats = "energy-bar")?energyLoss:hungerLoss,
    
    Should be like the following instead:
    varTotal = (dataStats === "energy-bar")?energyTotal:hungerTotal,
    varName = (dataStats === "energy-bar")?energy:hunger,
    varLoss = (dataStats === "energy-bar")?energyLoss:hungerLoss,
    
  • edited March 2017
    unfortunately its still show the problem and i dont know what to do, maybe i give less of information about this. i'll give more sample then and fyi i use this code from @greyelf and customize a little for my need
    ::StoryInit
    <<set $energyTotal to 100>>
    <<set $energy to 80>>
    <<set $energyLoss to 0>>
    
    <<set $hungerTotal to 100>>
    <<set $hunger to 70>>
    <<set $hungerLoss to 0>>
    
    ::PassageHeader
    <div class="section-stats btcf">
    	<div class="stats-wrapper energy-bar" data-status="energy-bar">
    		<span>Energi</span>
    		<div class="stats-bar">
    	  		<div class="bar">
    		  		<div class="hit"></div>
    	  		</div>
    		</div>
    	</div>
    	<div class="stats-wrapper hunger-bar" data-status="hunger-bar">
    		<span>Makan</span>
    		<div class="stats-bar">
    	  		<div class="bar">
    		  		<div class="hit"></div>
    	  		</div>
    		</div>
    	</div>
    </div>
    
    ::StatsGen
    <<script>>
    $('.section-stats .stats-wrapper').each(function(index, el) {
    
    	var dataStats = $(this).data('status');
    	
    	var energyTotal = 0,
    		hungerTotal = 0,
    		energy = 0,
    		hunger = 0,
    		energyLoss = 0,
    		hungerLoss = 0;
    
    	var eBar = $('.'+ dataStats +' .stats-bar'),
    		bar = eBar.find('.bar'),
    
    		varTotal = (dataStats === "energy-bar")?energyTotal:hungerTotal,
    		varName = (dataStats === "energy-bar")?energy:hunger,
    		varLoss = (dataStats === "energy-bar")?energyLoss:hungerLoss,
    
    		sv = State.variables,
    
    		total = sv.varTotal,
    		value = sv.varName,
    		damage = sv.varLoss,
    		barWidth = (value / total) * 100,
    		delayReset = false;
    
    	if (damage != 0) {
    		value -= damage;
    		barWidth = (value / total) * 100;
    		State.variables.varName = value;
    		State.variables.varLoss = 0;
    		delayReset = true;
    	}
    
    	eBar.data('total', total);
    	eBar.data('value', value);
    	if (State.variables.varName <= State.variables.varTotal){
    		if(State.variables.varName>0){
    			bar.css('width', barWidth + "%");
    		}else{
    			bar.css('width', '0');
    			State.variables.varName = 0
    		}
    	}else{
    		bar.css('width', "100%");
    		State.variables.varName = 100
    	}
    });
    <</script>>
    

    the main problem is energyTotal is not defined, what i want by using ternary operator is below

    if element is energy-bar
    varTotal = State.variables.energyTotal;
    varName = State.variables.energy;
    varLoss = State.variables.energyLoss;
    

    if element is hunger-bar
    varTotal = State.variables.hungerTotal;
    varName = State.variables.hunger;
    varLoss = State.variables.hungerLoss;
    

    i hope this more clear to understand whats my problem and what i want, thx very much for any help, sorry for my bad english.
  • Try something like the following:
    ::StatsGen
    <<script>>
    $('.section-stats .stats-wrapper').each(function(index, el) {
    	var sv = State.variables;
    
    	var status = $(this).data('status');
    	var $eBar  = $('.' + status + ' .stats-bar');
    	var $bar   = $eBar.find('.bar');
    
    	var varName  = (status === 'energy-bar') ? 'energy' : 'hunger';
    	var varLoss  = varName + 'Loss';
    	var varTotal = varName + 'Total';
    
    	var value  = sv[varName];
    	var damage = sv[varLoss];
    	var total  = sv[varTotal];
    
    	if (damage !== 0) {
    		value -= damage;
    		sv[varName] = value;
    		sv[varLoss] = 0;
    	}
    
    	var barWidth = (value / total) * 100;
    
    	$eBar.data('total', total);
    	$eBar.data('value', value);
    
    	if (sv[varName] <= sv[varTotal]) {
    		if (sv[varName] > 0) {
    			$bar.css('width', barWidth + '%');
    		}
    		else {
    			$bar.css('width', '0');
    			sv[varName] = 0;
    		}
    	}
    	else {
    		$bar.css('width', '100%');
    		sv[varName] = 100;
    	}
    });
    <</script>>
    
  • WOW thx @TheMadExile its work now, now i know how to do that LOL
  • caberg wrote: »
    i hope this more clear to understand whats my problem and what i want, thx very much for any help, sorry for my bad english.
    Instead of evaluating the same condition three times (once for each ternary-operator) it makes more sense and is more efficient to do that evaluation only once.
    if (dataStats === "energy-bar") {
    	varTotal = State.variables.energyTotal;
    	varName = State.variables.energy;
    	varLoss = State.variables.energyLoss;
    } else {
    	varTotal = State.variables.hungerTotal;
    	varName = State.variables.hunger;
    	varLoss = State.variables.hungerLoss;
    }
    
Sign In or Register to comment.