I’m trying to make a universal combat mod, but I’m having a bit of trouble with multiple enemies. What I think I need to do is create a table of current enemies in the room in sequence so I can keep track of them. I think I nearly have it, but it doesn’t quite work. This is my script so far:
[code]Definition: a person is AttackingFoe if they are hostile and their health is at least 1 and they are not the player.
AttackerOrder is a number that varies. AttackerOrder is 1. [This is to keep track of the table’s rows]
Table of IntFoes
Recorded Initiative CAttacker
0 Person
with 30 blank rows.
To record (Number - Person) in (target table - Table of IntFoes):
choose a row AttackerOrder in the target table;
Let TTX be a random AttackingFoe who is IntSorting;
now the Recorded Initiative entry is Initiative of TTX;
now the CAttacker entry is TTX;
Now TTX is attack-ready;
To list the AttackMenu: [This is the way I am checking if it all works]
Now AttackerOrder is 1;
repeat through the Table of IntFoes:
Choose row AttackerOrder in the Table of IntFoes;
say " [AttackerOrder]: [CAttacker entry][line break]"; [say “[o]Attack [CAttacker entry][x] | [line break]”;]
Increment AttackerOrder;
[/code]
And this is what I am using to create the list:
[code]
To RoleCall:
Now AttackerOrder is 1;
Now every person is IntSorting;
blank out the whole of the Table of IntFoes;
repeat through the Table of IntFoes:
Record a random AttackingFoe in Table of IntFoes;
increment AttackerOrder;
Sort Table of IntFoes in reverse Recorded Initiative order; [This is to rank them by speed so they attack in that order][/code]
Without the line “blank out the whole of the Table of IntFoes;” the script appears to work, except that the listing script will only ever list one item. I don’t know if this even makes sense, but I’m hoping someone can help! If I missed out any info, please tell me!
It seems to me as though you don’t want to be repeating through the Table of IntFoes. You definitely don’t want to blank out the table and then repeat through it–there’s nothing to repeat through! And modifying a table while you’re repeating through it seems like a way to make bad things happen.
(To be clear, “repeat through the table of foo” sets up a loop which looks at the first row of the table of foo, does something, looks at the second row, does something, and so on. If you mess with the table while you’re repeating through it then I’d expect unpredictable results.)
Also, your phrase
To record (Number - Person) in (target table - Table of IntFoes):
is not going to work the way you want. This creates a temporary value called “number,” which stores whatever you used as the first argument when you called it, and another called “target table,” which stores the second argument–but that has to be the Table of IntFoes! So when you write “Record a random AttackingFoe in Table of IntFoes,” it calls your phrase with a random AttackingFoe stored in “number” and the Table of IntFoes stored in "target table’–but you aren’t doing anything with that.
I think what you want may be something more like this:
[code]To record (TTX - Person) in (target table - table): [note that I called the variable TTX]
choose a blank row in the target table; [you don’t need to manually keep track of the number of the row you’re writing to–this phrase will find the first blank row]
now the Recorded Initiative entry is Initiative of TTX;
now the CAttacker entry is TTX;
Now TTX is attack-ready;
To RoleCall:
blank out the whole of the Table of IntFoes;
repeat with attacker running through AttackingFoe people in the location: [this is important! it collects every AttackingFoe in the location and runs the following loop on it; so we don’t need to pick them out at random, and we don’t need to use IntSorting to see whether we’ve already recorded them]
Record attacker in Table of IntFoes; [and now the “attacker” will get copied to the “TTX” variable in our “to record” phase]
Sort Table of IntFoes in reverse Recorded Initiative order; [This is to rank them by speed so they attack in that order]
To list the AttackMenu: [This is the way I am checking if it all works]
Now AttackerOrder is 1;
repeat through the Table of IntFoes:
say " [AttackerOrder]: [CAttacker entry][line break]"; [say “[o]Attack [CAttacker entry][x] | [line break]”;] [you don’t need to choose row AttackerOrder–the “repeat through the table” loop is choosing each row one by one anyway]
Increment AttackerOrder; […but you still do want to keep track of AttackerOrder so you can print out the row number][/code]
See if that works–hope it’s helpful. (I haven’t tested it.)
Thanks! That’s a lot neater, but for some reason it still only lists one attacker and then stops, even though my test group is two. I’ve tried a few different things, like turning hyperlinks off, but I keep getting the same result. In order to get it to compile, I did have to change one line to:
To record (TTX - Person) in (target table - Table of IntFoes):
But that’s all. Unfortunately I don’t know much about tables so I can’t honestly guess why it does this, but I get the impression it is only listing or recording the first row then stopping. I tried changing ‘attacker’ to different things, but it didn’t do anything, so I’m guessing it’s just a temporary variable.
Whoops, I think the fully general version of what I wrote is:
To record (TTX - Person) in (target table - table name):
When you’re using a table as a variable you have to call it “table name” for some reason. If the table of IntFoes is the only table you’ll ever use, which it seems like it is, your version should work fine.
As for why it’s behaving the way it is… I’m afraid you need to see if you can cut your source down to a complete compilable game that reproduces the error. Without looking at all the rest of the code you’re using, I can’t tell whether the error is somewhere in the code we’re looking at here or in something else that’s happening. And trying to cut down the code may help you find the error! Anyway, it’s possible that I messed up. Also, are you sure that both members of your test group are in the same room as the player?
After attacking when the noun (called foe) is defeated: [or whatever the trigger is]
choose a row with a CAttacker of the foe in the Table of IntFoes;
blank out the whole row.
This method of choosing a row follows the syntax from §16.5 of Writing with Inform… in general it’s a great idea to try to work through chapter 16 if you’re doing a lot with tables.