First things first, let's just go ahead and make a variable for every item. Yeah, it's going to be a long list, but it's pretty straightforward to do (and we're not going to add any new items during the game). That's going to be a bunch of variables, so I'm going to make a new Passage “Initialize” to dump it all in. That will be the starting Passage (for this test, and would be in the game too) from which we'll go to the "Inventory Tracker" we were starting at. Here's the “Initialize” code...
::Initialize
This is just a starting point for our story, the blahblahblah place where we can set all our variables.
[[Check your inventory->Inventory Tracker]]
/* Belt Pouch slot, max 50 */
<<set $Gold = 0>>
/* Head slot, max 1 */
<<set $Helmet = 0>>
/* Body slot, max 1 */
<<set $Armor = 0>>
/* Hand slot, max 2 */
<<set $Daggers = 0>>
<<set $Spears = 0>>
<<set $Maces = 0>>
<<set $ShortSwords = 0>>
<<set $Warhammers = 0>>
<<set $Swords = 0>>
<<set $Axes = 0>>
<<set $Quarterstaffs = 0>>
<<set $Broadswords = 0>>
/* Backpack slot, max 8 */
<<set $Meals = 0>>
<<set $HealthPotions = 0>>
<<set $MealOfLaumspur = 0>>
<<set $StrengthPotion = 0>>
This is just a starting point for our story, the blahblahblah place where we can set all our variables.
[[Check your inventory->Inventory Tracker]]
/* Belt Pouch slot, max 50 */
<<set $Gold = 0>>
/* Head slot, max 1 */
<<set $Helmet = 0>>
/* Body slot, max 1 */
<<set $Armor = 0>>
/* Hand slot, max 2 */
<<set $Daggers = 0>>
<<set $Spears = 0>>
<<set $Maces = 0>>
<<set $ShortSwords = 0>>
<<set $Warhammers = 0>>
<<set $Swords = 0>>
<<set $Axes = 0>>
<<set $Quarterstaffs = 0>>
<<set $Broadswords = 0>>
/* Backpack slot, max 8 */
<<set $Meals = 0>>
<<set $HealthPotions = 0>>
<<set $MealOfLaumspur = 0>>
<<set $StrengthPotion = 0>>
Doesn't look like much, since everything is happening behind the scenes. Speaking of which, if you look in the code you'll notice I put some HTML comments to remind me about how the items are grouped and the max numbers...
/* Belt Pouch slot, max 50 */
<<set $Gold = 0>>
/* Head slot, max 1 */
<<set $Helmet = 0>>
/* Body slot, max 1 */
<<set $Armor = 0>>
Comments are good. What makes perfect sense today could become a blur in a week, or after a bunch of code revisions. So it's not a bad idea to make notes for yourself, or others if you want to share your work (which I'm going to with this when I'm done).
Looking at it, I also have 16 items, counting “gold” as one item - which isn't too bad. The code for handling gold is pretty much done I think, so I'm part-way there. There are some additional items (maybe another 6-8) but they are ‘special items’ that don't take up any inventory space - so not going to worry about them right now.
Okay, so let's move on to the Inventory Tracker and show the player what they are carrying around.
Makes a pretty ugly list when you print it all, doesn't it? :) Let's make that a bit neater... (come to think of it, you do start with an item or two)
::Inventory Tracker
<<nobr>>Your Belt Pouch has $Gold Gold Crowns.
<br><br>You are wearing-
<br>The green tunic and cloak of a Kai initiate.
<<if $Helmet > 0>><br>A Helmet.<</if>>
<<if $Armor > 0>><br>A Chainmail Waistcoat.<</if>>
<br><br>You are carrying-
<<if $Daggers > 0>><br>A Dagger<</if>>
<<if $Spears > 0>><br>A Spear<</if>>
<<if $Maces > 0>><br>A Mace<</if>>
<<if $ShortSwords > 0>><br>A Short Sword<</if>>
<<if $Warhammers > 0>><br>A Warhammer<</if>>
<<if $Swords > 0>><br>A Sword<</if>>
<<if $Axes > 0>><br>An Axe<</if>>
<<if $Quarterstaffs > 0>><br>A Quarterstaff<</if>>
<<if $Broadswords > 0>><br>A Broadsword<</if>>
<br><br>Your Backpack has-
<<if $Meals > 0>><br>$Meals Meals<</if>>
<<if $HealthPotions > 0>><br>$HealthPotions Health Potions<</if>>
<<if $MealOfLaumspur > 0>><br>$MealOfLaumspur Meals Of Laumspur<</if>>
<<if $StrengthPotion > 0>><br>$StrengthPotion Strength Potions<</if>>
<</nobr>>
Let's go [[Find Stuff]]
<<nobr>>Your Belt Pouch has $Gold Gold Crowns.
<br><br>You are wearing-
<br>The green tunic and cloak of a Kai initiate.
<<if $Helmet > 0>><br>A Helmet.<</if>>
<<if $Armor > 0>><br>A Chainmail Waistcoat.<</if>>
<br><br>You are carrying-
<<if $Daggers > 0>><br>A Dagger<</if>>
<<if $Spears > 0>><br>A Spear<</if>>
<<if $Maces > 0>><br>A Mace<</if>>
<<if $ShortSwords > 0>><br>A Short Sword<</if>>
<<if $Warhammers > 0>><br>A Warhammer<</if>>
<<if $Swords > 0>><br>A Sword<</if>>
<<if $Axes > 0>><br>An Axe<</if>>
<<if $Quarterstaffs > 0>><br>A Quarterstaff<</if>>
<<if $Broadswords > 0>><br>A Broadsword<</if>>
<br><br>Your Backpack has-
<<if $Meals > 0>><br>$Meals Meals<</if>>
<<if $HealthPotions > 0>><br>$HealthPotions Health Potions<</if>>
<<if $MealOfLaumspur > 0>><br>$MealOfLaumspur Meals Of Laumspur<</if>>
<<if $StrengthPotion > 0>><br>$StrengthPotion Strength Potions<</if>>
<</nobr>>
Let's go [[Find Stuff]]
A bunch of
<<if>>
s to see what you have, a general <<nobr>>
with each item having it's own <br>
to get the spacing looking good, and we have a decent inventory list. Let's move on to actually picking up stuff.According to the book, you went out to chop wood when your monastery was attacked. After you rush back you search and find one item, chosen at random. So let's generate a random item and figure out how to equip it while staying within our limits.
After a lot of playing around with things, here's where I am...
Okay, so I added the random item picker to this page, and left the gold that was there. Here's the code...
::Find Stuff
Your home has been destroyed and your friends killed. You will need supplies to get your revenge.
Searching the wreckage-
<<set $newgold = random (0,9)>><<include [[Change Gold]]>>
And a buried item...
<<nobr>><<set $burieditem = random (0, 9)>>
<<if $burieditem == 0>><<set $founditem = ["Broadsword", 1]>><<print "A Broadsword">><</if>>
<<if $burieditem == 1>><<set $founditem = ["Sword", 1]>><<print "A Sword">><</if>>
<<if $burieditem == 2>><<set $founditem = ["Helmet", 1]>><<print "A Helmet">><</if>>
<<if $burieditem == 3>><<set $founditem = ["Meals", 2]>><<print "2 Meals">><</if>>
<<if $burieditem == 4>><<set $founditem = ["Armor", 1]>><<print "A Chainmail Waistcoat">><</if>>
<<if $burieditem == 5>><<set $founditem = ["Mace", 1]>><<print "A Mace">><</if>>
<<if $burieditem == 6>><<set $founditem = ["Health Potion", 1]>><<print "A Healing Potion">><</if>>
<<if $burieditem == 7>><<set $founditem = ["Quarterstaff", 1]>><<print "A Quarterstaff">><</if>>
<<if $burieditem == 8>><<set $founditem = ["Spear", 1]>><<print "A Spear">><</if>>
<<if $burieditem == 9>><<set $founditem = ["Gold", 12]>><<print "12 Gold Crowns">><</if>><</nobr>>
[[Pick up the item->Change Item]]
Now that you have some money, let's [[Go to the Store->Store]]
Your home has been destroyed and your friends killed. You will need supplies to get your revenge.
Searching the wreckage-
<<set $newgold = random (0,9)>><<include [[Change Gold]]>>
And a buried item...
<<nobr>><<set $burieditem = random (0, 9)>>
<<if $burieditem == 0>><<set $founditem = ["Broadsword", 1]>><<print "A Broadsword">><</if>>
<<if $burieditem == 1>><<set $founditem = ["Sword", 1]>><<print "A Sword">><</if>>
<<if $burieditem == 2>><<set $founditem = ["Helmet", 1]>><<print "A Helmet">><</if>>
<<if $burieditem == 3>><<set $founditem = ["Meals", 2]>><<print "2 Meals">><</if>>
<<if $burieditem == 4>><<set $founditem = ["Armor", 1]>><<print "A Chainmail Waistcoat">><</if>>
<<if $burieditem == 5>><<set $founditem = ["Mace", 1]>><<print "A Mace">><</if>>
<<if $burieditem == 6>><<set $founditem = ["Health Potion", 1]>><<print "A Healing Potion">><</if>>
<<if $burieditem == 7>><<set $founditem = ["Quarterstaff", 1]>><<print "A Quarterstaff">><</if>>
<<if $burieditem == 8>><<set $founditem = ["Spear", 1]>><<print "A Spear">><</if>>
<<if $burieditem == 9>><<set $founditem = ["Gold", 12]>><<print "12 Gold Crowns">><</if>><</nobr>>
[[Pick up the item->Change Item]]
Now that you have some money, let's [[Go to the Store->Store]]
Like I did with the “Change Gold” Passage (also on this page) I want to make one external Passage that I can call from anywhere to equip an item (this is a lot of code after all, really don't want to have to re-type for each Passage it appears in). So I did a simple
<<random>>
to get the found item. Then, since you can find more than 1 of an item, I put the item name and quantity into an array <<set $founditem = ["Sword", 1]>>
so I would know how many I was dealing with. Which makes $founditem[0] “Sword” and $founditem[1] “1”, because arrays start at 0. For weapons and armor that doesn't matter, you only need 1 so I actually ignore if you try to pick up more than 1 at a time (which works for this story, but might not work for other types of games).Now, I want to make this an
<<include>>
so that “Change Gold” and “Change Item” both exist within the Passage that calls them - but for now I left it as a separate Passage so that I could bounce back-and-forth between them, picking up more and more items and making sure everything worked (code and test). Which it eventually did - I had a ton of names and spaces and plural-or-not-plural variable names to correct. Also, I copied the code to increase gold from the “Change Gold” Passage, that way I have two ways to get gold if I need (a small duplication). Also, some items took Hand or Backpack slots, which are shared across different items (all weapons go in Hands, potions and meals share Backpack) - so I decided to just make two new variables, $CountHands
and $CountBackpack
, so I know how many of each the player has (and was easier than trying to iterate through all the types of items to add them up).Here's the code for the “Change Item” Passage...
<<switch $founditem[0]>>
<<case "Gold">>
You pick up $founditem[1] Gold Crowns,
<<set $Gold = $Gold + $founditem[1]>>
<<if $Gold > 50>>
<<set $Gold = 50>>
but your Belt Pouch only holds 50 Gold Crowns,
<</if>>
you now have $Gold Gold Crowns.
<<case "Helmet">>
<<if $Helmet > 0>>You are already wearing a helmet!
<<else>>
<<set $Helmet = 1>>You put on the Helmet.
<</if>>
<<case "Armor">>
<<if $Armor > 0>>You are already wearing armor!
<<else>>
<<set $Armor = 1>>You put on the Chainmail Waistcoat.
<</if>>
<<case "Dagger">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Daggers > 0>>You already have a Dagger!
<<else>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<</if>>
<<case "Spear">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Spears > 0>>You already have a Spear!
<<else>>
<<set $Spears = 1>>You pick up the Spear.<<set $CountHands++>>
<</if>>
<<case "Mace">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Maces > 0>>You already have a Mace!
<<else>>
<<set $Maces = 1>>You pick up the Mace.<<set $CountHands++>>
<</if>>
<<case "Short Sword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $ShortSwords > 0>>You already have a Short Sword!
<<else>>
<<set $ShortSwords = 1>>You pick up the Short Sword.<<set $CountHands++>>
<</if>>
<<case "Warhammer">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Warhammers > 0>>You already have a Warhammer!
<<else>>
<<set $Warhammers = 1>>You pick up the Warhammer.<<set $CountHands++>>
<</if>>
<<case "Sword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Swords > 0>>You already have a Sword!
<<else>>
<<set $Swords = 1>>You pick up the Sword.<<set $CountHands++>>
<</if>>
<<case "Axe">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Axes > 0>>You already have an Axe!
<<else>>
<<set $Axes = 1>>You pick up the Axe.<<set $CountHands++>>
<</if>>
<<case "Quarterstaff">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Quarterstaffs > 0>>You already have a Quarterstaff!
<<else>>
<<set $Quarterstaffs = 1>>You pick up the Quarterstaff.<<set $CountHands++>>
<</if>>
<<case "Broadsword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Broadswords > 0>>You already have a Broadsword!
<<else>>
<<set $Broadswords = 1>>You pick up the Broadsword.<<set $CountHands++>>
<</if>>
<<case "Meals">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $Meals = $Meals + $founditem[1]>>You now have $Meals Meals.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Health Potion">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $HealthPotions = $HealthPotions + $founditem[1]>>You now have $HealthPotions Health Potions.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Meal Of Laumspur">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $MealOfLaumspur = $MealOfLaumspur + $founditem[1]>>You now have $MealOfLaumspur Meals Of Laumspur.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Strength Potion">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $StrengthPotion = $StrengthPotion + $founditem[1]>>You now have $StrengthPotion Strength Potions.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<</switch>>
<<return "Go Back">>
Debug Code- Inventory Dump
<<nobr>>Your Belt Pouch has $Gold Gold Crowns.
<br><br>You are wearing-
<br>The green tunic and cloak of a Kai initiate.
<<if $Helmet > 0>><br>A Helmet.<</if>>
<<if $Armor > 0>><br>A Chainmail Waistcoat.<</if>>
<br><br>You are carrying-
<<if $Daggers > 0>><br>A Dagger<</if>>
<<if $Spears > 0>><br>A Spear<</if>>
<<if $Maces > 0>><br>A Mace<</if>>
<<if $ShortSwords > 0>><br>A Short Sword<</if>>
<<if $Warhammers > 0>><br>A Warhammer<</if>>
<<if $Swords > 0>><br>A Sword<</if>>
<<if $Axes > 0>><br>An Axe<</if>>
<<if $Quarterstaffs > 0>><br>A Quarterstaff<</if>>
<<if $Broadswords > 0>><br>A Broadsword<</if>>
<br><br>Your Backpack has-
<<if $Meals > 0>><br>$Meals Meals<</if>>
<<if $HealthPotions > 0>><br>$HealthPotions Health Potions<</if>>
<<if $MealOfLaumspur > 0>><br>$MealOfLaumspur Meals Of Laumspur<</if>>
<<if $StrengthPotion > 0>><br>$StrengthPotion Strength Potions<</if>>
<</nobr>>
<<case "Gold">>
You pick up $founditem[1] Gold Crowns,
<<set $Gold = $Gold + $founditem[1]>>
<<if $Gold > 50>>
<<set $Gold = 50>>
but your Belt Pouch only holds 50 Gold Crowns,
<</if>>
you now have $Gold Gold Crowns.
<<case "Helmet">>
<<if $Helmet > 0>>You are already wearing a helmet!
<<else>>
<<set $Helmet = 1>>You put on the Helmet.
<</if>>
<<case "Armor">>
<<if $Armor > 0>>You are already wearing armor!
<<else>>
<<set $Armor = 1>>You put on the Chainmail Waistcoat.
<</if>>
<<case "Dagger">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Daggers > 0>>You already have a Dagger!
<<else>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<</if>>
<<case "Spear">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Spears > 0>>You already have a Spear!
<<else>>
<<set $Spears = 1>>You pick up the Spear.<<set $CountHands++>>
<</if>>
<<case "Mace">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Maces > 0>>You already have a Mace!
<<else>>
<<set $Maces = 1>>You pick up the Mace.<<set $CountHands++>>
<</if>>
<<case "Short Sword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $ShortSwords > 0>>You already have a Short Sword!
<<else>>
<<set $ShortSwords = 1>>You pick up the Short Sword.<<set $CountHands++>>
<</if>>
<<case "Warhammer">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Warhammers > 0>>You already have a Warhammer!
<<else>>
<<set $Warhammers = 1>>You pick up the Warhammer.<<set $CountHands++>>
<</if>>
<<case "Sword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Swords > 0>>You already have a Sword!
<<else>>
<<set $Swords = 1>>You pick up the Sword.<<set $CountHands++>>
<</if>>
<<case "Axe">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Axes > 0>>You already have an Axe!
<<else>>
<<set $Axes = 1>>You pick up the Axe.<<set $CountHands++>>
<</if>>
<<case "Quarterstaff">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Quarterstaffs > 0>>You already have a Quarterstaff!
<<else>>
<<set $Quarterstaffs = 1>>You pick up the Quarterstaff.<<set $CountHands++>>
<</if>>
<<case "Broadsword">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Broadswords > 0>>You already have a Broadsword!
<<else>>
<<set $Broadswords = 1>>You pick up the Broadsword.<<set $CountHands++>>
<</if>>
<<case "Meals">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $Meals = $Meals + $founditem[1]>>You now have $Meals Meals.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Health Potion">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $HealthPotions = $HealthPotions + $founditem[1]>>You now have $HealthPotions Health Potions.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Meal Of Laumspur">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $MealOfLaumspur = $MealOfLaumspur + $founditem[1]>>You now have $MealOfLaumspur Meals Of Laumspur.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<<case "Strength Potion">>
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
<<else>>
<<set $StrengthPotion = $StrengthPotion + $founditem[1]>>You now have $StrengthPotion Strength Potions.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
<</if>>
<</switch>>
<<return "Go Back">>
Debug Code- Inventory Dump
<<nobr>>Your Belt Pouch has $Gold Gold Crowns.
<br><br>You are wearing-
<br>The green tunic and cloak of a Kai initiate.
<<if $Helmet > 0>><br>A Helmet.<</if>>
<<if $Armor > 0>><br>A Chainmail Waistcoat.<</if>>
<br><br>You are carrying-
<<if $Daggers > 0>><br>A Dagger<</if>>
<<if $Spears > 0>><br>A Spear<</if>>
<<if $Maces > 0>><br>A Mace<</if>>
<<if $ShortSwords > 0>><br>A Short Sword<</if>>
<<if $Warhammers > 0>><br>A Warhammer<</if>>
<<if $Swords > 0>><br>A Sword<</if>>
<<if $Axes > 0>><br>An Axe<</if>>
<<if $Quarterstaffs > 0>><br>A Quarterstaff<</if>>
<<if $Broadswords > 0>><br>A Broadsword<</if>>
<br><br>Your Backpack has-
<<if $Meals > 0>><br>$Meals Meals<</if>>
<<if $HealthPotions > 0>><br>$HealthPotions Health Potions<</if>>
<<if $MealOfLaumspur > 0>><br>$MealOfLaumspur Meals Of Laumspur<</if>>
<<if $StrengthPotion > 0>><br>$StrengthPotion Strength Potions<</if>>
<</nobr>>
Oh yeah, you'll also notice I copied the code to list the player's inventory so that I could check for errors...
So one of the primary things I needed to do with this Passage was make sure the player didn't try to equip too many of the same items...
Which I did in a few steps.
The Gold already had it's check in the code I copied from “Change Gold”, easy.
Helmets and Armor were easy, if you had one you didn't need another one, so I just checked to see if you had any in your inventory
<<if $Helmet > 0>>You are already wearing a helmet!
Weapons you could have 2 of, so I needed to check how many you already had:
<<if $CountHands >= 2>>Your hands are full!
You already have two weapons, you don't have room for any more...
<<elseif $Daggers > 0>>You already have a Dagger!
Even if you had room for a weapon, if you already have a dagger you don't need another one...
<<else>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
So if you've got room and don't already have one, then you pick it up, and increase the counter for your hands/weapons total.
Backpack items worked the same way, check for how many free spaces you have...
<<if $CountBackpack >= 8>>Your Backpack is full!
<<elseif ($founditem[1] + $CountBackpack) > 8>>You don't have room for that many items!
And if you have room put them in your backpack and increase the ‘container counter’ by the number you picked up.
<<else>>
<<set $Meals = $Meals + $founditem[1]>>You now have $Meals Meals.<<set $CountBackpack = ($CountBackpack + $founditem[1])>>
Now, one thing wrong with this: if you find 2 Meals but only have room for one, it won't let you pick up just one - so I'll have to fix that. Also, some items do something when you pick them up/ have them - like weapons, if you have one it increases your Combat Skill. I need to set those effects here, when the item is picked up, or I need to check for it every time it's necessary. So I could put the code in the Combat section I'm working on next? Which sounds good to me actually, I could total up all the factors related to combat just before it starts. The only problem is that the player won't see the effect an item has on his stats except for Combat, so he couldn't just pull up the sheet and check it out... hmmm... I have to think about this. Most other items will just sit in the inventory until they get used by a Passage, so I don't need to worry about them. I do need to be able to drop or swap out items though... So no rest for the wicked, time to work on some more code before I can call the Inventory section done.
Dropping items is easy, just subtract from their count. Swapping items is trickier, so that was the first thing I decided to tackle. Let me show you what I came up with...
<<case "Dagger">>
<<if $CountHands >= 2>>
<<if $Daggers == 0>>Your hands are full!
<<elseif $Daggers == 2>>You already have two Daggers, your hands are full!
<<elseif $Daggers == 1>>You already have a Dagger! Do you want to drop your other weapon and have 2 Daggers instead?
<<linkreplace " Yes">><<set $Daggers = 2>><<if $Spears == 1>><<set $Spears = 0>><<elseif $Maces == 1>><<set $Maces = 0>>
<<elseif $ShortSwords == 1>><<set $ShortSwords = 0>><<elseif $Warhammers == 1>><<set $Warhammers = 0>><<elseif $Swords == 1>><<set $Swords = 0>><<elseif $Axes === 1>><<set $Axes = 0>><<elseif $Quarterstaffs == 1>><<set $Quarterstaffs = 0>>
<<elseif $Broadswords == 1>><<set $Broadswords = 0>><</if>> You now have 2 Daggers.<</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>><</if>>
<<elseif $CountHands == 1>>
<<if $Daggers == 1>>You already have a Dagger, do you want to pick up a spare?
<<linkreplace " Yes">><<set $Daggers = 2>>You now have 2 Daggers.<<set $CountHands++>><</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>><</if>>
<<else>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<</if>>
So this was about an hour, maybe hour-and-half, of writing, testing, fixing, testing, fixing, changing the testing, removing a section, testing, fixing, testing, fixing, moving one section to another spot, testing, fixing, removing a section, testing, testing, realizing I should have left that last section alone, testing, fixing, it finally seems toactually work, thank the good spirits!
Let me walk you through what I should have done instead.
Difficulty really seems to come down to 2 parts: difficulty in understanding and difficulty in tracking. Learning this HTML/ CSS/ JavaScript/ Twine/ SugarCube stuff is “difficult to understand.” It's not like casual writing, thinking or speaking. You need a new language and new ways of thinking. "Difficult to track" is like trying to memorize a phone book, all the names and numbers and address are everyday English, but there are so many of them to remember. Coding a project like this also has a lot of “difficult to track” associated with it, but that kind of difficulty is at least a little easier to deal with by it's nature. What am I talking about? Something I remembered (too late) I had heard of called “pseudocode.”
The idea behind “pseudocode” is to organize your thoughts by writing what you need to happen in plain English, but English that kind of reflects the code you'll need to write. It tackles the “difficult to track” first by getting your thoughts organized, then you fill in the blanks with real code and deal with the “difficult to understand” part one step at a time, while now seeing how each step has to fit together to make the whole.
One more thing and I'll explain - “Occam's Razor” is an idea that, generally speaking, the simplest potential answer is the right one. It says to look for simple answers before complicated ones. I think if there was an “Occam's Programming Theory” it would be start with the easiest thing to check for and then get more complicated.
Okay, I jumped in to trying to program the difficulties of the situation instead of thinking through what I needed to happen. I'm trying to write code to let you swap out one item for another, and I'm adding it to the code for picking up items (since for the most part my inventory isn't going to change very often, there are only a relative few Passages that have items to pick up). So I'm going to use a technique from before and write some HTML comments, but structure them along with what I'm trying to do - and use spaces to organize the smaller steps within the big steps. Something like this...
/* pick up new item */
I'm assuming the player wants the item, they had to click on the link to pick it up, so I'm not asking if they want to pick it up or not
/* check what kind of container it goes in */
/* check space in that container */
/* check if you already have item */
/* ask to swap items */
Yes //swap items
No //exit
That's a pretty basic outline, I'm going to need some details to refine it. Going from the top down my existing code, my Gold, Helmet and Armor don't need to swap. The first place the player might need to swap items in with the Hands/ Weapons, and the first weapon is the Dagger - so I'm going to start thinking/ coding with that...
/* pick up new item */
I'm assuming the player wants the item, they had to click on the link to pick it up, so I'm not asking if they want to pick it up or not
/* check what kind of container it goes in */
Weapons go in the Hands container, max 2
/* check space in that container */
How many hands are free?
/* Do you have 2 hands free */
Pick up the item (no swapping or thinking required)
/* Do you have 1 hand free */
/* check if you already have item */
/* if not */
Pick up the item
/* if you do */
Ask if you want an extra
Yes //pick up items
No //exit
/* Do you have 0 free hands */
/* check if you already have 2 of the item */
If you do, you're already full //exit
/* check if you already have 1 of the item */
/* ask to swap items */
Yes //swap items
No //exit
/* check if you already have 0 of the item */
/* ask to swap items */
Yes
/* what items do you have? */
/* which item do you want to drop/swap? */
No //exit
It makes for a moderately-sized flowchart, sometimes simple things are more complicated than they look :) Let me walk through this and point out my thinking:
/* pick up new item */
/* check what kind of container it goes in */
/* check space in that container */
So you want an item, what is it and where does it go? I've got the ‘what is it’ and ‘where’ parts already written in my code to pick the item up (in the variable that gets passed and then the big <<switch>> sorting by items).
/* Do you have 2 hands free */
/* Do you have 1 hand free */
/* Do you have 0 free hands */
How many hands you have open says weather you'll need to swap anything or not (since you don't need to swap if you have free space, you just pick up, which is the code I already have written).
/* Do you have 2 hands free */
Pick up the item (no swapping or thinking required)
This is the easiest, you don't currently have anything so you pick the item up.
/* Do you have 1 hand free */
Okay, so you do have something already, is it the same item you want to pick up or not?
/* check if you already have item */
/* if not */
Pick up the item
No, well then you have space, so pick up the item.
/* if you do */
Ask if you want an extra
Yes //pick up item
No //exit
If yes, well, you don't get much benefit from having 2 of the same weapon in this game (another game might be a different story), so do you want to pick it up? Now, looking over the story again while working on this stuff I reminded myself that there are a few Passages where you can lose some or all of your Weapons and/or Backpack items - so it might, in a few cases, be helpful to have 2 of the same weapon that you're proficient in using (if you took the Weaponskill to begin with). Should I mention that to the player? Well, the book doesn't, so no, but if this was my own game I'd debate saying that. (also if there were stores to sell stuff (which you can't in this game) there would be another reason having spare items could be useful)
/* Do you have 0 free hands */
Okay, so you're holding all the items you can, so you'll have to swap something, right?
/* check if you already have 2 of the item */
If you do, you're already full //exit
Thinking about it, well, no - if you have 2 of the same item you have the item and a spare and no room for yet another, so there's noting to do here
/* check if you already have 1 of the item */
/* ask to swap items */
Yes //swap items
No //exit
Here we need to ask, like above, if you really want to drop your other item to have a spare of the one you're picking up
/* check if you already have 0 of the item */
/* ask to swap items */
Yes
/* what items do you have? */
/* which item do you want to drop/swap? */
No //exit
And finally, if you're full but don't have any of the item you're picking up, then we need to ask what existing item you want to drop to make room for the new one.
It's a modestly-sized ‘flowchart’ and it did take a little while to think through and write out - but I can tell you that I would have avoided several errors from last night if I had done this first (and if you look at the code I posted, you'll notice I completely missed the last thing- if you had 2 weapons, but none of the one you want, so which to drop/swap). Being new to all this I kind of want to just jump in and start doing something, and while that does teach - it teaches painfully. All the re-writes, error-tracking, and research add up. There have been a few points where I felt like giving up on the whole project. Thinking things through like this helps me stay organized, should help me do fewer re-writes, and makes the whole thing feel a little easier to understand. Now that I have my flowchart, I just have to start writing code one line at a time until it's filled in.
Mind you, I don't want to flowchart too big - if I tried to outline the whole game/ mechanics this way I'd likely have something so big it would be more confusing than helpful; once things have been broken into semi-manageable chunks this really helps.
Okay, so now that I have an outline, let's start adding coding this thing...
<<case "Dagger">>
<<nobr>>
<<if $CountHands == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $CountHands == 1>>
<<if $Daggers == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $Daggers == 1>>You already have a Dagger, do you want to pick up a spare?
<<linkreplace " Yes">><<set $Daggers = 2>>You now have 2 Daggers.<<set $CountHands++>><</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<</if>>
<<elseif $CountHands >= 2>>
<<if $Daggers == 2>>You already have two Daggers, your hands are full!
<<elseif $Daggers == 1>>
You already have a Dagger! Do you want to drop your other weapon and have 2 Daggers instead?
<<linkreplace " Yes">>
<<set $Daggers = 2>>
<<if $Spears == 1>><<set $Spears = 0>>
<<elseif $Maces == 1>><<set $Maces = 0>>
<<elseif $ShortSwords == 1>><<set $ShortSwords = 0>>
<<elseif $Warhammers == 1>><<set $Warhammers = 0>>
<<elseif $Swords == 1>><<set $Swords = 0>>
<<elseif $Axes == 1>><<set $Axes = 0>>
<<elseif $Quarterstaffs == 1>><<set $Quarterstaffs = 0>>
<<elseif $Broadswords == 1>><<set $Broadswords = 0>>
<</if>>
You now have 2 Daggers.<</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<<elseif $Daggers == 0>>
What item do you want to drop to make room for the Dagger?
<<if $Spears == 1>>
<<linkreplace " the Spear">><<set $Spears = 0>><<set $Daggers = 1>>You drop your Spear and gain a Dagger.<</linkreplace>><</if>>
<<if $Maces == 1>>
<<linkreplace " the Mace">><<set $Maces = 0>><<set $Daggers = 1>>You drop your Mace and gain a Dagger.<</linkreplace>><</if>>
<<if $ShortSwords == 1>>
<<linkreplace " the Short Sword">><<set $ShortSwords = 0>><<set $Daggers = 1>>You drop your Short Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Warhammers == 1>>
<<linkreplace " the Warhammer">><<set $Warhammers = 0>><<set $Daggers = 1>>You drop your Warhammer and gain a Dagger.<</linkreplace>><</if>>
<<if $Swords == 1>>
<<linkreplace " the Sword">><<set $Swords = 0>><<set $Daggers = 1>>You drop your Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Axes == 1>>
<<linkreplace " the Axe">><<set $Axes = 0>><<set $Daggers = 1>>You drop your Axe and gain a Dagger.<</linkreplace>><</if>>
<<if $Quarterstaffs == 1>>
<<linkreplace " the Quarterstaff">><<set $Quarterstaffs = 0>><<set $Daggers = 1>>You drop your Quarterstaff and gain a Dagger.<</linkreplace>><</if>>
<<if $Broadswords == 1>>
<<linkreplace " the Broadsword">><<set $Broadswords = 0>><<set $Daggers = 1>>You drop your Broadsword and gain a Dagger.<</linkreplace>><</if>>
<<linkreplace " None">>You leave your items unchanged.<</linkreplace>>
<</if>>
<</if>><</nobr>>
<<nobr>>
<<if $CountHands == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $CountHands == 1>>
<<if $Daggers == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $Daggers == 1>>You already have a Dagger, do you want to pick up a spare?
<<linkreplace " Yes">><<set $Daggers = 2>>You now have 2 Daggers.<<set $CountHands++>><</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<</if>>
<<elseif $CountHands >= 2>>
<<if $Daggers == 2>>You already have two Daggers, your hands are full!
<<elseif $Daggers == 1>>
You already have a Dagger! Do you want to drop your other weapon and have 2 Daggers instead?
<<linkreplace " Yes">>
<<set $Daggers = 2>>
<<if $Spears == 1>><<set $Spears = 0>>
<<elseif $Maces == 1>><<set $Maces = 0>>
<<elseif $ShortSwords == 1>><<set $ShortSwords = 0>>
<<elseif $Warhammers == 1>><<set $Warhammers = 0>>
<<elseif $Swords == 1>><<set $Swords = 0>>
<<elseif $Axes == 1>><<set $Axes = 0>>
<<elseif $Quarterstaffs == 1>><<set $Quarterstaffs = 0>>
<<elseif $Broadswords == 1>><<set $Broadswords = 0>>
<</if>>
You now have 2 Daggers.<</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<<elseif $Daggers == 0>>
What item do you want to drop to make room for the Dagger?
<<if $Spears == 1>>
<<linkreplace " the Spear">><<set $Spears = 0>><<set $Daggers = 1>>You drop your Spear and gain a Dagger.<</linkreplace>><</if>>
<<if $Maces == 1>>
<<linkreplace " the Mace">><<set $Maces = 0>><<set $Daggers = 1>>You drop your Mace and gain a Dagger.<</linkreplace>><</if>>
<<if $ShortSwords == 1>>
<<linkreplace " the Short Sword">><<set $ShortSwords = 0>><<set $Daggers = 1>>You drop your Short Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Warhammers == 1>>
<<linkreplace " the Warhammer">><<set $Warhammers = 0>><<set $Daggers = 1>>You drop your Warhammer and gain a Dagger.<</linkreplace>><</if>>
<<if $Swords == 1>>
<<linkreplace " the Sword">><<set $Swords = 0>><<set $Daggers = 1>>You drop your Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Axes == 1>>
<<linkreplace " the Axe">><<set $Axes = 0>><<set $Daggers = 1>>You drop your Axe and gain a Dagger.<</linkreplace>><</if>>
<<if $Quarterstaffs == 1>>
<<linkreplace " the Quarterstaff">><<set $Quarterstaffs = 0>><<set $Daggers = 1>>You drop your Quarterstaff and gain a Dagger.<</linkreplace>><</if>>
<<if $Broadswords == 1>>
<<linkreplace " the Broadsword">><<set $Broadswords = 0>><<set $Daggers = 1>>You drop your Broadsword and gain a Dagger.<</linkreplace>><</if>>
<<linkreplace " None">>You leave your items unchanged.<</linkreplace>>
<</if>>
<</if>><</nobr>>
Okay, I removed all the comments once I had the code that went to that section (there was enough code that the comments started making it hard to read everything). I really should have coded a section, tested it, moved on to the next section - but of course I didn't. I just wrote the whole thing and made some extra Passages to test it. That did work, but the less code to debug at once the better.
<<case "Dagger">>
<<nobr>>
<<if $CountHands == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $CountHands == 1>>
<<if $Daggers == 0>>
<<set $Daggers = 1>>You pick up the Dagger.<<set $CountHands++>>
<<elseif $Daggers == 1>>You already have a Dagger, do you want to pick up a spare?
<<linkreplace " Yes">><<set $Daggers = 2>>You now have 2 Daggers.<<set $CountHands++>><</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<</if>>
So the above section is the easy stuff, you just pick up the Dagger, you get asked once if you want the spare. Notice that I have to remember the <<set $CountHands++>>, I'm adding a weapon so I need to remember to increase that tracker.
Also, when comparing something with <<if>> you use TWO equals signs “==”, (two letters in “if”, two “==”) boy did I have to fix that a lot. (still do, someday I'll remember :)
<<elseif $CountHands >= 2>>
<<if $Daggers == 2>>You already have two Daggers, your hands are full!
Again, easy
<<elseif $Daggers == 1>>
You already have a Dagger! Do you want to drop your other weapon and have 2 Daggers instead?
<<linkreplace " Yes">>
<<set $Daggers = 2>>
<<if $Spears == 1>><<set $Spears = 0>>
<<elseif $Maces == 1>><<set $Maces = 0>>
<<elseif $ShortSwords == 1>><<set $ShortSwords = 0>>
<<elseif $Warhammers == 1>><<set $Warhammers = 0>>
<<elseif $Swords == 1>><<set $Swords = 0>>
<<elseif $Axes == 1>><<set $Axes = 0>>
<<elseif $Quarterstaffs == 1>><<set $Quarterstaffs = 0>>
<<elseif $Broadswords == 1>><<set $Broadswords = 0>>
<</if>>
You now have 2 Daggers.<</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
Okay, here you have one Dagger and one other item, you're picking up a dagger. You decide you must have it, so I go through and set every other item's count to 0 with an <<if / elseif>> series. I DON'T increase $CountHands because here I am swapping items, not taking up a new ‘hand.’
<<elseif $Daggers == 0>>
What item do you want to drop to make room for the Dagger?
<<if $Spears == 1>><<linkreplace " the Spear">><<set $Spears = 0>><<set $Daggers = 1>>You drop your Spear and gain a Dagger.<</linkreplace>><</if>>
<<if $Maces == 1>><<linkreplace " the Mace">><<set $Maces = 0>><<set $Daggers = 1>>You drop your Mace and gain a Dagger.<</linkreplace>><</if>>
<<if $ShortSwords == 1>><<linkreplace " the Short Sword">><<set $ShortSwords = 0>><<set $Daggers = 1>>You drop your Short Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Warhammers == 1>><<linkreplace " the Warhammer">><<set $Warhammers = 0>><<set $Daggers = 1>>You drop your Warhammer and gain a Dagger.<</linkreplace>><</if>>
<<if $Swords == 1>><<linkreplace " the Sword">><<set $Swords = 0>><<set $Daggers = 1>>You drop your Sword and gain a Dagger.<</linkreplace>><</if>>
<<if $Axes == 1>><<linkreplace " the Axe">><<set $Axes = 0>><<set $Daggers = 1>>You drop your Axe and gain a Dagger.<</linkreplace>><</if>>
<<if $Quarterstaffs == 1>><<linkreplace " the Quarterstaff">><<set $Quarterstaffs = 0>><<set $Daggers = 1>>You drop your Quarterstaff and gain a Dagger.<</linkreplace>><</if>>
<<if $Broadswords == 1>><<linkreplace " the Broadsword">><<set $Broadswords = 0>><<set $Daggers = 1>>You drop your Broadsword and gain a Dagger.<</linkreplace>><</if>>
Here comes the really fun part, you currently have 2 other weapons and you want to swap one for a dagger. So I need a bunch of <<if>>s to check what that other weapon is, then set it's count to 0 and the dagger to 1. First time I wrote this, I copied the code from above to do the weapon check - which was a mistake. Above I did an<<if - elseif>> series, but that whole series exits at the first true condition. Here I need to return 2 values/ changes, so each <<if>> has to be it's own thing. Again, I'm swapping items so I don't increase $CountHands.
It looks so simple, it gave me so many headaches :(
Okay, so now I can pick up and swap a dagger. Just a dagger. Now, I need to copy-and-paste this for each weapon and change all the variables to be the correct ones. Not really hard, but going to be tedious. Still, I've got some time. And I'm going to have to find a better way to do this, eventually...
After the great-copying-and-pasting I need to do basically the same thing for Backpack Items, though the code is going to be completely different of course.
Two quick side-notes...
I love how the code I started with (6 lines):
<<case "Mace">>
<<if $CountHands >= 2>>Your hands are full!
<<elseif $Maces > 0>>You already have a Mace!
<<else>>
<<set $Maces = 1>>You pick up the Mace.<<set $CountHands++>>
<</if>>
Has turned into (57 lines):
<<case "Mace">>
<<nobr>>
<<if $CountHands == 0>>
<<set $Maces = 1>>You pick up the Mace.<<set $CountHands++>>
<<elseif $CountHands == 1>>
<<if $Maces == 0>>
<<set $Maces = 1>>You pick up the Mace.<<set $CountHands++>>
<<elseif $Maces == 1>>You already have a Mace, do you want to pick up a spare?
<<linkreplace " Yes">><<set $Maces = 2>>You now have 2 Maces.<<set $CountHands++>><</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<</if>>
<<elseif $CountHands >= 2>>
<<if $Maces == 2>>You already have two Maces, your hands are full!
<<elseif $Maces == 1>>
You already have a Mace! Do you want to drop your other weapon and have 2 Maces instead?
<<linkreplace " Yes">>
<<set $Maces = 2>>
<<if $Daggers == 1>><<set $Daggers = 0>>
<<elseif $Spears == 1>><<set $Spears = 0>>
<<elseif $ShortSwords == 1>><<set $ShortSwords = 0>>
<<elseif $Warhammers == 1>><<set $Warhammers = 0>>
<<elseif $Swords == 1>><<set $Swords = 0>>
<<elseif $Axes == 1>><<set $Axes = 0>>
<<elseif $Quarterstaffs == 1>><<set $Quarterstaffs = 0>>
<<elseif $Broadswords == 1>><<set $Broadswords = 0>>
<</if>>
You now have 2 Maces.<</linkreplace>>
<<linkreplace " No">>You leave the item.<</linkreplace>>
<<elseif $Maces == 0>>
What item do you want to drop to make room for the Mace?
<<if $Daggers == 1>>
<<linkreplace " the Dagger">><<set $Daggers = 0>><<set $Maces = 1>>You drop your Dagger and gain a Mace.<</linkreplace>><</if>>
<<if $Spears == 1>>
<<linkreplace " the Spear">><<set $Spears = 0>><<set $Maces = 1>>You drop your Spear and gain a Mace.<</linkreplace>><</if>>
<<if $ShortSwords == 1>>
<<linkreplace " the Short Sword">><<set $ShortSwords = 0>><<set $Maces = 1>>You drop your Short Sword and gain a Mace.<</linkreplace>><</if>>
<<if $Warhammers == 1>>
<<linkreplace " the Warhammer">><<set $Warhammers = 0>><<set $Maces = 1>>You drop your Warhammer and gain a Mace.<</linkreplace>><</if>>
<<if $Swords == 1>>
<<linkreplace " the Sword">><<set $Swords = 0>><<set $Maces = 1>>You drop your Sword and gain a Mace.<</linkreplace>><</if>>
<<if $Axes == 1>>
<<linkreplace " the Axe">><<set $Axes = 0>><<set $Maces = 1>>You drop your Axe and gain a Mace.<</linkreplace>><</if>>
<<if $Quarterstaffs == 1>>
<<linkreplace " the Quarterstaff">><<set $Quarterstaffs = 0>><<set $Maces = 1>>You drop your Quarterstaff and gain a Mace.<</linkreplace>><</if>>
<<if $Broadswords == 1>>
<<linkreplace " the Broadsword">><<set $Broadswords = 0>><<set $Maces = 1>>You drop your Broadsword and gain a Mace.<</linkreplace>><</if>>
<<linkreplace " None">>You leave your items unchanged.<</linkreplace>>
<</if>>
<</if>><</nobr>>
Second, the great-copying-and-pasting is going a lot easier by using a program called Notepad++. The 'find and replace' feature is making it a lot easier to convert the Dagger code into the other weapons.
Notepad++ is a text editor designed for writing code. You can open multiple files in the same program, good for tracking scattered code, it does "syntax highlighting" when it colors key words, which can help you see where you're missing or mis-spelling something, and it has a ton of other features. I had been working in Twine itself to write all my code, but these last sections have gotten so big it's been a lot easier to work in Notepad++ instead. Here's a screenshot...
This is such a great resource that you are providing and you give it away for free. I love seeing websites that understand the value of providing a quality resource for free. It is the old what goes around comes around routine.
ReplyDeleteBelt pouch