Post new topic    
Metal Slime
Send private message
Confusion...? 
 PostThu Jul 12, 2012 5:32 pm
Send private message Reply with quote
So, here is my issue. I have two seperate parts of the same script that are set up in basically the same manner. One works:

Code:
switch (flynnbackbone) do (

case (flynnbackbone >= 1 && check tag (43) == false) do (
set tag (43,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist))

case (flynnbackbone >=5 && check tag (44) == false) do (
set tag (44,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist))

case (flynnbackbone >=10 && check tag (45) == false) do (
set tag (45,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist))

case (flynnbackbone >=15 && check tag (46) == false) do (
set tag (46,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist))

case (flynnbackbone >=20 && check tag (47) == false) do (
set tag (47,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist))
)


...While the other does not:
Code:
switch (flynnmarksman) do (

case (flynnmarksman >= 1 && check tag (58) == false) do (
set tag (58,on)
teach spell (find hero (hero:Flynn),atk:Tracking))

case (flynnmarksman >=5 && check tag (59) == false) do (
set tag (59,on)
teach spell (find hero (hero:Flynn),atk:CalledShot))

case (flynnmarksman >=10 && check tag (60) == false) do (
set tag (60,on)
teach spell (find hero (hero:Flynn),atk:Eagle Eye))

case (flynnmarksman >=15 && check tag (61) == false) do (
set tag (61,on)
teach spell (find hero (hero:Flynn),atk:Discharge))

case (flynnmarksman >=20 && check tag (62) == false) do (
set tag (62,on)
teach spell (find hero (hero:Flynn),atk:Snipe))
)


...The problem is that the character does NOT learn ANY spells, no matter how high the "flynnmarksman" variable becomes. On the other hand, the character's "elemental" resistances are changed accordingly. I've tested the second script by placing a "show text box (x)" line in it. The text box shows, so that part of the script DOES run. It just doesn't teach the spells, for some reason!
Hey, I just met you, and this is crazy... So here's some lunchmeat... Sandwich, maybe?
Super Slime
Send private message
 
 PostThu Jul 12, 2012 10:14 pm
Send private message Reply with quote
That is not how you use a switch.

This is how switch works:

Code:
switch(my variable) do (
  case(1) do (something) # my variable is 1
  case(2) do (something) # my variable is 2
)


You should really just change your cases into if-thens.
Mega Tact v1.1
Super Penguin Chef
Wizard Blocks
Liquid Metal King Slime
Send private message
 
 PostFri Jul 13, 2012 1:13 am
Send private message Reply with quote
Mogri is right. The switch command chooses between numbered blocks of code and all the numbers have to be different. You can't use boolean true/false in a case. All the true conditions become 1 and all the false conditions become 0, so the cases are all invalid.

The real question here is not why does the second one fail, but why does the first one work?

You could rewrite this using a bunch of nested if/then/else blocks, but I think the results will be cleaner if you do something like this (untested code):

Code:

while (true) do ( # not really an endless loop because of the break commands

if (flynnbackbone >= 1 && check tag (43) == false) then (
set tag (43,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist)
break)

if (flynnbackbone >=5 && check tag (44) == false) then (
set tag (44,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist)
break)

if (flynnbackbone >=10 && check tag (45) == false) then (
set tag (45,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist)
break)

if (flynnbackbone >=15 && check tag (46) == false) then (
set tag (46,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist)
break)

if (flynnbackbone >=20 && check tag (47) == false) then (
set tag (47,on)
flynnmeleeresist := hero base elemental resist as int (hero:Flynn,0)
flynnnewmeleeresist := flynnmeleeresist -- 5
set hero base elemental resist (hero:Flynn,0,flynnnewmeleeresist)
break)

break # this extra break is needed to stop the loop if none of the conditions were true
)
Metal King Slime
Send private message
 
 PostFri Jul 13, 2012 1:29 am
Send private message Reply with quote
James means "while(true)" instead of "switch(true)" of course. But the later would actually work if you replaced the 'if's with 'case's!

But I wouldn't suggest doing that, because I'm thinking of making future versions of HSpeak forbid cases containing expressions. (I'll probably keep support for existing scripts to be on the safe side).

I'm not a fan of the "while(true) do (... break)" construct to do fake goto's (much worse than goto's in my opinion). I think part of the solution is to add an 'else if' statement which lets you omit the brackets after the 'else' and not have to do any nesting.

Also, cool, someone modifying hero elemental resists. I worry about commands like that never been used, like some others I've added...
Liquid Metal King Slime
Send private message
 
 PostFri Jul 13, 2012 2:27 pm
Send private message Reply with quote
TMC wrote:
James means "while(true)" instead of "switch(true)" of course. But the later would actually work if you replaced the 'if's with 'case's!


Hehe. You must have read my post in the first 30 seconds it was up, before I noticed and fixed that.

I am really fuzzy on how the existing expressions-in-cases support works. Even though it is going to be removed, it would be nice to know how it worked, out of curiosity.

And I agree about "else if" (or maybe a pythonish "elif"). That would be better than my somewhat clumsy single-pass-while hack
Metal Slime
Send private message
 
 PostSun Jul 15, 2012 1:03 pm
Send private message Reply with quote
Thanks, this (among a few other scripts I didn't list here) works now. I was also wondering how I could keep a script from continuing on to the next part, when the script is broken up into multiple scripts by a menu. Would the "break" command in one script stop the "while" loop in another?

EDIT: I should be more clear. I'm trying to make a level-up script, but the way I have it set up now, the script will skip to the last character defined in the script. I'm trying to figure out the best way to do so. Here is the script so far:
Code:
plotscript, levelling, begin

#Checks if Flynn leveled, and adjusts appropriate variables to reflect him
if (herolevelled (find hero (hero:Flynn))) then, begin

#stuff goes here, not relevant to the question

#Opens stat menus to start the upgrade process
show text box (376)
open menu (menu:Stat Up,false)
open menu (menu:LEVELUP STATS,false)
bring menu forward (bottom menu)
wait (1)
fade screen in
end


If I were to place a "while (true) do (" command here, wouldn't the script just endlessly repeat the "open menu" commands when the menu items in the menus that are opened by the script are selected? Here's an example of one:
Code:
plotscript, upgrade strength, begin
#does stuff, also not relevant to question

if (points == 0 && check tag (36)) then, begin
#blah blah stuff
show text box (379)
wait for text box

if (check tag (37)) then, begin
#opens up another menu like the first, with it's own set of menu items and scripts
open menu (menu:Skill Up,false)
open menu (menu:LEVELUP SKILLS,false)
bring menu forward (bottom menu)
show text box (376)
end,else,begin

#reopens the menu that started this mess
open menu (menu:Stat Up,false)
open menu (menu:LEVELUP STATS,false)
bring menu forward (bottom menu)
show text box (376)
end
end
end


So, as you can see, there's a lot of opening and reopening of menus. If i place the "while" command somewhere in here, it'll cause problems. Is there some simple way of preventing the script from continuing on to the next character?
Hey, I just met you, and this is crazy... So here's some lunchmeat... Sandwich, maybe?
Metal King Slime
Send private message
 
 PostWed Jul 18, 2012 7:21 pm
Send private message Reply with quote
No, you can't use 'break' in one script to affect a loop in another script.

Aside from that, I can't tell what you're asking. It's really hard to tell what going on, especially since menus are involved. Instead, here are a couple hints for ways to do flow control between multiple scripts:

Firstly, you can use a global variable to signal a condition. For example:
Code:
global variable (1, doing X)

script, do subtask, begin
  ...
  if (stopping condition) then (doing X := false)
  ...
end

script, ..., begin
  doing X := true
  ...
  do subtask
  ...
  # check whether to continue
  if (doing X) then (...)
  ...
end


Another, which I like for conceptual simplicity is to use script return values for signalling stuff like success, or having to continue:

Code:
script, try to do something, begin
  ...
  if (cant do it) then (exit returning (false))
  # do it...
  return (true)
end

script, ..., begin
  if (try to do something) then (
     # success
     ...
  ) else (
    if (try to do something else) then (
      ...
    ) else (
      # etc
    )
  )
end


Bob the Hamster wrote:
I am really fuzzy on how the existing expressions-in-cases support works. Even though it is going to be removed, it would be nice to know how it worked, out of curiosity.


I'll document it on the wiki, rather than corrupting minds around here :)
Metal Slime
Send private message
 
 PostSun Jul 22, 2012 1:32 pm
Send private message Reply with quote
TMC wrote:
No, you can't use 'break' in one script to affect a loop in another script.


Yeah, I kind of assumed this. Wishful thinking.

TMC wrote:
Aside from that, I can't tell what you're asking. It's really hard to tell what going on, especially since menus are involved.


Sorry, I'm very bad at explaining myself, especially when tired. All that I'm asking is for an easy way to make a script pause at certain parts of the script, while other scripts (such as menu-driven ones) run. Then after a certain condition is met in those scripts, the first script will continue.

I'll try one of the ways you suggested, though. Thanks.
Hey, I just met you, and this is crazy... So here's some lunchmeat... Sandwich, maybe?
Display posts from previous: