Creating Object Lists

Forgewright
13 Jan 2018, 22:03My thread went dead on this subject and I am back at it.
Trying to create game.Orcs list and goblins and humans as well.
Any ideas why this function wont work in start.
Orcs = NewObjectList()
Goblins = NewObjectList()
Humans = NewObjectList()
Listofnpcs = FilterByType(AllObjects(), "monster")
foreach (object, Listofnpcs) {
if (object.race = "Orc") {
list add (Orcs, object)
}
else if (object.race = "Goblin") {
list add (Goblins, object)
}
else if (race = "Human") {
list add (Humans, object)
}
}
game.Orcs = Orcs
game.Goblins = Goblins
game.Humans = Humans
Tried it with pre-made attributes and not. Either way the lists are always empty in debugger

K.V.
13 Jan 2018, 23:15That last else if
says race
when I think it should be object.race
.
Besides that, it seems to work for me.
Drop this into a new game and check the Log and Debugger out:
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Typewriter JS">
<gameid>cb4bf0de-4de3-4e95-bb06-d9c53a16528a</gameid>
<version>1.0</version>
<firstpublished>2018</firstpublished>
<start type="script">
Orcs = NewObjectList()
Goblins = NewObjectList()
Humans = NewObjectList()
Listofnpcs = FilterByType(AllObjects(), "monster")
foreach (object, Listofnpcs) {
if (object.race = "Orc") {
list add (Orcs, object)
// Debugging:
Log (object +" is an Orc.")
}
else if (object.race = "Goblin") {
list add (Goblins, object)
// Debugging:
Log (object +" is a Goblin.")
}
else if (object.race = "Human") {
list add (Humans, object)
// Debugging:
Log (object +" is a Human.")
}
else {
// Debugging:
Log (object + " is not Orc, Goblin, or Human.")
}
}
// Debugging:
foreach (obj, ListExclude(AllObjects(),Listofnpcs)) {
// Debugging:
Log (obj +" does not have the type: 'monster'.")
}
game.Orcs = Orcs
game.Goblins = Goblins
game.Humans = Humans
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<beforeenter type="script">
</beforeenter>
<enter type="script">
</enter>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="Morcrest">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Orc</race>
</object>
<object name="Vilhelm">
<inherit name="editor_object" />
<race>Human</race>
</object>
<object name="Schmeck">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Goblin</race>
</object>
<object name="Ralph">
<inherit name="editor_object" />
<inherit name="namedmale" />
</object>
<object name="Beetlejuice">
<inherit name="editor_object" />
<inherit name="monster" />
</object>
<object name="George">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Human</race>
</object>
</object>
<type name="monster" />
</asl>
1/13/2018 5:20:35 PM Object: Morcrest is an Orc.
1/13/2018 5:20:35 PM Object: Schmeck is a Goblin.
1/13/2018 5:20:35 PM Object: Beetlejuice is not Orc, Goblin, or Human.
1/13/2018 5:20:35 PM Object: George is a Human.
1/13/2018 5:20:35 PM Object: room does not have the type: 'monster'.
1/13/2018 5:20:35 PM Object: player does not have the type: 'monster'.
1/13/2018 5:20:35 PM Object: Vilhelm does not have the type: 'monster'.
1/13/2018 5:20:35 PM Object: Ralph does not have the type: 'monster'.
Edited code since first posting!

Forgewright
13 Jan 2018, 23:26I have the script as a function and call it in the start script. Wonder if that screws it up?
Orc is not a type it is a value of an attribute named race.

K.V.
13 Jan 2018, 23:29No, sir.
Just tested it.
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="NPC Races">
<gameid>cb4bf0de-4de3-4e95-bb06-d9c53a16528a</gameid>
<version>1.0</version>
<firstpublished>2018</firstpublished>
<start type="script">
FindRaces
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<beforeenter type="script">
</beforeenter>
<enter type="script">
</enter>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="Morcrest">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Orc</race>
</object>
<object name="Vilhelm">
<inherit name="editor_object" />
<race>Human</race>
</object>
<object name="Schmeck">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Goblin</race>
</object>
<object name="Ralph">
<inherit name="editor_object" />
<inherit name="namedmale" />
</object>
<object name="Beetlejuice">
<inherit name="editor_object" />
<inherit name="monster" />
</object>
<object name="George">
<inherit name="editor_object" />
<inherit name="monster" />
<race>Human</race>
</object>
</object>
<type name="monster" />
<function name="FindRaces">
Orcs = NewObjectList()
Goblins = NewObjectList()
Humans = NewObjectList()
Listofnpcs = FilterByType(AllObjects(), "monster")
foreach (object, Listofnpcs) {
if (object.race = "Orc") {
list add (Orcs, object)
// Debugging:
Log (object +" is an Orc.")
}
else if (object.race = "Goblin") {
list add (Goblins, object)
// Debugging:
Log (object +" is a Goblin.")
}
else if (object.race = "Human") {
list add (Humans, object)
// Debugging:
Log (object +" is a Human.")
}
else {
// Debugging:
Log (object + " is not Orc, Goblin, or Human.")
}
}
// Debugging:
foreach (obj, ListExclude(AllObjects(),Listofnpcs)) {
// Debugging:
Log (obj +" does not have the type: 'monster'.")
}
game.Orcs = Orcs
game.Goblins = Goblins
game.Humans = Humans
</function>
</asl>
1/13/2018 5:29:07 PM Object: Morcrest is an Orc.
1/13/2018 5:29:07 PM Object: Schmeck is a Goblin.
1/13/2018 5:29:07 PM Object: Beetlejuice is not Orc, Goblin, or Human.
1/13/2018 5:29:07 PM Object: George is a Human.
1/13/2018 5:29:07 PM Object: room does not have the type: 'monster'.
1/13/2018 5:29:07 PM Object: player does not have the type: 'monster'.
1/13/2018 5:29:07 PM Object: Vilhelm does not have the type: 'monster'.
1/13/2018 5:29:07 PM Object: Ralph does not have the type: 'monster'.

K.V.
13 Jan 2018, 23:32Try plugging my FindRaces() function into the game, then calling it from the start script, too.
Then check your Log and Debugger.
That function should work with what you've already got, and it should tell you why each object is or isn't added to a list.

Forgewright
13 Jan 2018, 23:33Orc is not a type it is a value of an attribute named race.

K.V.
13 Jan 2018, 23:36Orc is not a type it is a value of an attribute named race.
Precisely.
"monster" is the type.
the race
attribute has three possibilities: Orc, Goblin, or Human. (It is a string attribute.)

Forgewright
13 Jan 2018, 23:37Damn, I thought I was bored.

K.V.
13 Jan 2018, 23:40Nein!
When it comes to the boredom, you know nuzzink!
(Sorry. I've been watching Hogan's Heroes.)

Forgewright
13 Jan 2018, 23:45Shuuultz!

Forgewright
13 Jan 2018, 23:48The log shows your function working but none of the game.lists are there in the debugger

Forgewright
13 Jan 2018, 23:52It is not creating game.lists

K.V.
13 Jan 2018, 23:52Hmm...
Velly intelesting...
It vorks for me:

Forgewright
13 Jan 2018, 23:53Ok I'll investgate further. Ive didded something wrong

Forgewright
14 Jan 2018, 00:32OMG. Had added parameters to the function and call in start.
Working now

Forgewright
14 Jan 2018, 00:35Actually that was the old function. Yours was working when I called it. I was so used to seeing the attributes in a certain spot in game attributes because I manually added them before. The new ones were at the bottom after I removed the old ones. Duh

K.V.
14 Jan 2018, 00:55You should marvel at some of my mistakes along with me some time.
It will be fun.
(B.Y.O.B.)
The Pixie
14 Jan 2018, 09:00This should work too:
game.Orcs = FilterByAttribute(AllObjects(), "race", "Orc")

Forgewright
14 Jan 2018, 12:57Pixie, I saw that in another thread and used it early on. I kept changing my script over and over because I couldn't get it to work. I started to think that I could not save or add directly to a game.list. That I had to make a NewObjectList, add to that and then newObjectList = game.list to create it. I see that isn't so.
When your code is used and the next line is foreach (item, orcs), I learned that i, j ,k are customary letters to use as the iterator variable ,but can I use anyword or letters for it? As long as those same letters are used in the script from then on?
Anyway, on to my next head scratcher. I saved each type of monster in a list then save those lists in a list called NPC. When a monster is attacked I want to make all ors or goblin or whatever attack the player on sight. I used the "mean" and kind just for identifiers (which I may not need.) I tried changing the attack on sight on all orcs and tried do( object, "attack" , put them in attacker list, all to no avail. I have read many threads but have not found any code that worked for me. It may have been the way to do it but I was unable to reword my code using the given code. It is the last lines that are trouble here. Plus the object.mode = "Mean" never changes when looking in the debugger.
</function>
<function name="ChangeHostility">
foreach (object, game.NPC) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, "object")
list remove (game.attackers, "object")
}
if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = "True"
}
}
</function>

K.V.
14 Jan 2018, 15:07Are game.friends and game.attackers both object lists?
If yes, I think these two lines should be like this (sans quotation marks):
list add (game.friends, object)
list remove (game.attackers, object)
If they are string lists, I think they should be:
list add (game.friends, object.name)
list remove (game.attackers, object.name)
If you add "object" to a string list, that just adds the string "object" to said string list. (I believe it should throw an error when trying to add a string to an object list (and vice-versa), by the way.) You probably want the local variable object
.
I also think this line should not have quotation marks (making it a Boolean rather than a string):
object.attackonsight = true
Also, I don't see where you are modifying the game.attackers and game.friends lists when switching from "Kind" to "Mean".
EDIT
It also looks to me like you need that second if
to be an else if
.
Otherwise, I think it would change "Kind" to "Mean", no matter what.
...because, if it starts off as "Kind", the first if
ignores it. Then, the second if
changes "Kind" to "Mean".
If it starts off as "Mean", the first if
will change it to "Kind", but the second if
will change it right back to "Mean", because if(object.mode = "Kind")
will return true at that point in the script.
So, it would always end up setting the attribute to "Mean" the way you posted it, unless you change that second if
to else if
.
So, it seems like this would work:
<function name="ChangeHostility">
foreach (object, game.NPC) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, object)
list remove (game.attackers, object)
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
list add (game.attackers, object)
list remove (game.friends, object)
}
}
</function>

K.V.
14 Jan 2018, 15:46I learned that i, j ,k are customary letters to use as the iterator variable ,but can I use anyword or letters for it? As long as those same letters are used in the script from then on?
I believe this is true.
...just don't use e
or pi
. They exist already.
http://docs.textadventures.co.uk/quest/problems.html
‘e’ and ‘pi’
You will probably never need them in a text adventure, but e and pi are both mathematical constants. Quest will happily let you assign a value to them, but will ignore the assignment.

K.V.
14 Jan 2018, 16:10I started to think that I could not save or add directly to a game.list. That I had to make a NewObjectList, add to that and then newObjectList = game.list to create it. I see that isn't so.
There are instances where you have to 'reset' a list.
I.e.,
You want to add an ENTER verb to an object's verb list.
(This may seem off-topic at first, but stick with me.)
First off, you can't create an ENTER verb because it is already a command, so you'd need to create an ENTER command (either in a specific room or for the entire game):
Command
Name: enter_cmd
Pattern: enter #object#
if (not HasAttribute(this, "enterable")) {
msg ("You can't enter " + this.article + ".")
}
else {
if (not this.enterable) {
("You can't enter " + this.article + ".")
}
else {
MoveObject (game.pov, this)
}
}
Then, we would add a Boolean attribute on any object we want the player to be able to enter, and we'd set it to true
:
crate.enterable = true
Now that we've set all that up, let's add "Enter" to the crate's verb list to make things easier for the player.
(This assumes that we have NOT added any verbs at all to the crate object. That means crate.displayverbs has not been modified, and is an inherited list.)
This would NOT work:
list add (crate.displayverbs, "Enter")
Error running script: Cannot modify the contents of this list as it is defined by an inherited type. Clone it before attempting to modify.
This WOULD work, though:
crate.displayverbs = Split("Look at;Take;Enter", ";")
Alternatively, you could do this:
crate.displayverbs = NewStringList()
list add(crate.displayverbs, "Look at")
list add(crate.displayverbs, "Take")
list add(crate.displayverbs, "Enter")
Alternate 2:
// This first line creates a sort of clone of the list. The two lists will not effect each other this way.
crate.displayverbsbackup = ListExclude(crate.displayverbs, "zzzz")
crate.displayverbs = NewStringList()
crate.displayverbs = crate.displayverbs + crate.displayverbsbackup
crate.displayverbs = crate.displayverbs + "Enter"
// This last line deletes the clone of the original list, which is no longer needed.
crate.displayverbsbackup = null
I think this works the same for inventoryverbs
and generatedverbslist
.
hegemonkhan
14 Jan 2018, 19:37a String List holds String Values for its items:
(anything in double quotes is a String Value)
example_object.example_stringlist_attribute = NewStringList ()
list add (example_object.example_stringlist_attribute, "STRING_VALUE_1")
list add (example_object.example_stringlist_attribute, "STRING_VALUE_2")
list add (example_object.example_stringlist_attribute, "STRING_VALUE_3")
list add (example_object.example_stringlist_attribute, OBJECT_VALUE_1) // ERROR!!!!!
an Object List holds Object (reference/pointer) Values for its items:
(anything not in double quotes and not 'true/false', is an Object (reference/pointer) Value)
// create ("OBJECT_VALUE_1")
// create ("OBJECT_VALUE_2")
// create ("OBJECT_VALUE_3")
example_object.example_objectlist_attribute = NewObjectList ()
list add (example_object.example_objectlist_attribute, OBJECT_VALUE_1)
list add (example_object.example_objectlist_attribute, OBJECT_VALUE_2)
list add (example_object.example_objectlist_attribute, OBJECT_VALUE_3)
list add (example_object.example_objectlist_attribute, "STRING_VALUE_1") // ERROR!!!!!
foreach (NAME_OF_Variable, NAME_OF_OBJECT.NAME_OF_LIST_ATTRIBUTE) { /* scripting */ }
the 'NAME_OF_Variable' can be whatever you want, it's just a Variable
here's how 'foreach' works (conceptually):
create ("joe")
joe.run_laps => msg ("Joe runs laps")
create ("jim")
jim.run_laps => msg ("Jim runs laps")
create ("jeff")
jeff.run_laps => msg ("Jeff runs laps")
team_object.team_objectlist_attribute = NewObjectList ()
list add (team_object.team_objectlist_attribute, joe)
list add (team_object.team_objectlist_attribute, jim)
list add (team_object.team_objectlist_attribute, jeff)
foreach (team_member, team_object.team_objectlist_attribute) {
do (team_member, "run_laps")
//
// team_member = joe
// do (team_member, "run_laps")
// do (joe, "run_laps")
//
// team_member = jim
// do (team_member, "run_laps")
// do (jim, "run_laps")
//
// team_member = jeff
// do (team_member, "run_laps")
// do (jeff, "run_laps")
}
// output:
Joe runs laps
Jim runs laps
Jeff runs laps

Forgewright
14 Jan 2018, 21:21The problem is the actual list game.attacker does no make all orcs attack me. It is just for that parent room apparently. If I move to another room where another orc is, it does not attack. The attacker list only has the original orc I attacked. and "Kind" remains "Kind". The attackonsight remains False". The script may have no errors, but does nothing,
<function name="ChangeHostility">
foreach (object, game.NPC) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, object)
list remove (game.attackers, object)
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
list add (game.attackers, object)
list remove (game.friends, object)
}
}
</function>
The Pixie
14 Jan 2018, 21:23I learned that i, j ,k are customary letters to use as the iterator variable ,but can I use anyword or letters for it? As long as those same letters are used in the script from then on?
i, j and k are conventionally used if the iterator is an integer, i.e., for a for
loop, not for a foreach
loop. But you can use anything.
I saved each type of monster in a list then save those lists in a list called NPC.
So does game.NPC contain three eements, each one a list? Or is it the combination of the three lists?
There are instances where you have to 'reset' a list.
Specifically where the list belongs to the type, rather than the object. If your object uses the default verb list, then that verb list is on its type, not the object itself, and you cannot change it.
You can reset it, as you say, but anotherway is to add something to the list in the editor, and then remove it. This will ensure the object has ts own list.

Forgewright
14 Jan 2018, 21:30I got theses to lines from Monster.xml in combat.lib.
list add (game.friends, object)
list remove (game.attackers, object)
They sound like they would work but don't. I need the line that triggers a monster to attack on sight. I thought that would be
object.attackonsight = true
But attackonsight remains "false" using that line. It is inherited(grayed).
Changing it manually to true works. so that line in the script is not working.

Forgewright
14 Jan 2018, 21:37So does game.NPC contain three eements, each one a list? Or is it the combination of the three lists?
I used
list add (game.NPC, Humans; Goblins; Orcs)
And i just checked and it remains empty. oops!
Can I use "+" here?*
game.NPC = Humans + Goblins + Orcs
Tried it but does not add the lists to NPC
I will try list add on each one separately.
list add (game.NPC, Orcs)
list add (game.NPC, Goblins)
list add (game.NPC, Humans)
Nope
list add (game.NPC, game.Orcs)
list add (game.NPC, game.Goblins)
list add (game.NPC, game.Humans)
Nope
list add (game.NPC, game.Orcs)
list add (game.NPC, game.Goblins)
list add (game.NPC, game.Humans)
Nope

K.V.
14 Jan 2018, 22:08I saved each type of monster in a list then save those lists in a list called NPC. When a monster is attacked I want to make all ors or goblin or whatever attack the player on sight.
So, if one orc gets pissed off, you want all the orcs to be pissed off... (I need to slow down and read sometimes.)
It sounds like you want script something like:
<function name="ChangeHostility" parameters="race">
objectlist = FilterByAttribute(AllObjects(), "race", race)
foreach (object, objectlist) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, object)
list remove (game.attackers, object)
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
list add (game.attackers, object)
list remove (game.friends, object)
}
}
</function>
Then, I have this in the attack script on the NPC:
msg("You attack "+GetDisplayName(this)+".")
// Do whatever here - kill the NPC, add damage, or a miss
ChangeHostility (this.race)
So, when I attack an Orc, all the Orcs are "Mean" and their "attackonsight" attributes are all true
.

K.V.
14 Jan 2018, 22:16Before attacking Morcrest (an orc):
After attacking Morcrest:

Forgewright
14 Jan 2018, 22:19ooooh! Parameters....

K.V.
14 Jan 2018, 22:24Adding this to the end of FindRaces()
is one way you could make that game.NPC list work:
game.NPC = NewList()
list add(game.NPC, game.Orcs)
list add(game.NPC, game.Goblins)
list add(game.NPC, game.Humans)

K.V.
14 Jan 2018, 22:25Oops!
I posted that twice, somehow!

Forgewright
14 Jan 2018, 22:41I had added ChangeHostility to the attack script but in the GUI and put race as parameter not this.race. Had no parameters earlier
Used your script and ingame I attacked an orc...Went to another room and the orc there said "Sup"... no wait he attacked me..that Sum b.
Thanks so much!

K.V.
14 Jan 2018, 22:49How will you retrieve from game.NPC, though?
It would be like:
lc = ListCount(game.NPC)
for (i, 0, lc-1) {
foreach (obj, game.NPC[i]) {
// Do whatever, like:
msg (obj)
}
}
Which would output:
Object: Morcrest
Object: Scar
Object: Schmeck
Object: George
...but you wouldn't know who was what, just that they were all "monster" types, which is how the lists are derived...
What do you do with game.NPC, game.Orcs, game.Goblins, and game.Humans besides the ChangeHostility()
thing?
If you use those lists for other things, I recommend making game.NPC a dictionary.
<function name="FindRaces">
game.Orcs = FilterByAttribute(AllObjects(), "race", "Orc")
game.Goblins = FilterByAttribute(AllObjects(), "race", "Goblin")
game.Humans = FilterByAttribute(AllObjects(), "race", "Human")
game.NPC = NewDictionary()
dictionary add (game.NPC, "Orcs", game.Orcs)
dictionary add (game.NPC, "Goblins", game.Goblins)
dictionary add (game.NPC, "Humans", game.Humans)
</function>
Then, you could do ChangeHostility() like this:
<function name="ChangeHostility" parameters="race">
// race will be "Orc", "Goblin", or "Human", but we have it set up so that each list name (or dictionary key) ends in an "s" (making them plural)
// I left it this way in case your game has numerous scripts with this setup already
race_type = race + "s"
race_list = DictionaryItem(game.NPC,race_type)
foreach (object, race_list) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, object)
list remove (game.attackers, object)
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
list add (game.attackers, object)
list remove (game.friends, object)
}
}
</function>
If you don't use all those lists anywhere else, you could probably do away with some (if not most) of them.
EDIT
Yay!
You got it working while I was typing this!
Whoo-hoo!

Forgewright
14 Jan 2018, 23:07The script you gave me before did not require the NPC list. Which I had yet to get working.
This one will add the NPC for me. Again Thank you.
Nothing like being spoon fed...
I have a large game but am redoing it slowly, trying to get all the functions and basic scripts working before coping/pasting a lot of old content to the new code. So now is the time to figure it out.
Adding functions and different change scripts tend to screw thing up in a large game, when you don't know exactly what your doing. Sayin'

Forgewright
14 Jan 2018, 23:42I used the "Mean" and Kind" as a simple way to determine in other scripts if the monster is going to attack . I could use code to determine if the monster is in the attacker list.
Even with your new code, I noticed in debugger, the Mean and Kind are not changing in the original attacked monster or the other like race monsters.
Any thoughts on that.
Wait, let me get my spoon...

Forgewright
15 Jan 2018, 00:43Oh wait... I forgot to re-add the race list creation function to the start script...

Forgewright
15 Jan 2018, 01:04- I think the 'friends' is an attribute I added earlier to to work like 'mode'. It is not needed.
- I may not need to add the monster to the attackers list. Just the attackonsight attribute being set to "true" may do it.
- I wonder if Mode should be a type with a script that does what the ChangeHostility function does. Then add mode type to the Monster type...
- I may make it so the same/race attacks are only effective in a general area. It's not like they have a telegraph system to tell other orcs (miles/kilometers/several days travel) away that the player needs a woopin'.
I'll look into this tomorrow. Gotta leave for work shortly. Those Walmart shelves aren't gonna straighten themselves! 3rd shift rules!

K.V.
15 Jan 2018, 03:36Sorry, I nodded off. (I'm old.)
Adding functions and different change scripts tend to screw thing up in a large game
Change scripts?
Ooh, I hate it when change scripts throw errors!
It always takes me forever to even think of checking my change scripts.
I usually:
- change all sorts of other scripts
- change them back when that helps nothing
- curse the gods of programming
- curse myself
- curse whoever is in my vicinity
- rinse & repeat
- give up for a while
- THEN I think of checking out the change scripts!
I may make it so the same/race attacks are only effective in a general area.
[insert dramatic music here]
If you're just talking about the orcs in the same room, that would be very easy to implement.
Otherwise, do you have rooms inside of one room, the parent room being a "region"?
If yes, it probably wouldn't be that difficult. If not, we could probably come up with something (like iterating through the exits of the player's parent object and making an object list of each exit.to).
I wonder if Mode should be a type with a script that does what the ChangeHostility function does. Then add mode type to the Monster type...
What'chu talkin' 'bout, Willis?
(Seriously. Please expound upon this one. (I didn't nap long enough. Ha-ha!)
As far as all those attributes are concerned, I think you only need the one dictionary: game.NPC.
Here is my example game:
(NOTE: This has nothing to do with spoons. It's just easier for me when I can see the entire code, with all the scripts that work together. I assume everyone else is like me. (Right?))
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="example_game">
<gameid>d821c1d9-fa44-4d24-9658-627812651b61</gameid>
<version>1.0</version>
<firstpublished>2018</firstpublished>
<start type="script">
FindRaces
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<usedefaultprefix type="boolean">false</usedefaultprefix>
<feature_startscript />
<attr name="_initialise_" type="script">
game.pov.alias = "you"
</attr>
</object>
<object name="Morcrest">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
<mode>Kind</mode>
</object>
<object name="Vilhelm">
<inherit name="editor_object" />
<inherit name="namedmale" />
<race>Human</race>
</object>
<object name="Schmeck">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Goblin</race>
</object>
<object name="Ralph">
<inherit name="editor_object" />
<inherit name="namedmale" />
</object>
<object name="Beetlejuice">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
</object>
<object name="George">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Human</race>
</object>
<object name="Scar">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
</object>
</object>
<verb>
<property>attack</property>
<pattern>attack</pattern>
<defaultexpression>"You can't attack " + object.article + "."</defaultexpression>
</verb>
<turnscript name="monsters_attack_turnscript">
<enabled />
<script>
foreach (o, FilterByType(AllObjects(), "monster")) {
if (o.attackonsight) {
if (o.parent = game.pov.parent) {
DoAttack (o, game.pov)
}
}
}
</script>
</turnscript>
<type name="monster">
<attackonsight type="boolean">false</attackonsight>
<attackscript type="script">
DoAttack (this, game.pov)
</attackscript>
<attack type="script">
msg ("You attack "+GetDisplayName(this)+".")
// Do whatever here - kill or add damage - I'm just going to kill the NPC for simplicity's sake.
msg (CapFirst(GetDisplayName(this))+" falls dead then fades away, as if this were some sort of video game.")
RemoveObject (this)
// END OF "kill or add damage"
ChangeHostility (this.race)
</attack>
<feature_startscript />
<attr name="_initialise_" type="script">
this.displayverbs = Split("Look at;Speak to;Attack",";")
</attr>
</type>
<function name="FindRaces">
if (not HasAttribute(game, "NPC")) {
game.NPC = NewDictionary()
}
dictionary add (game.NPC, "Orc", FilterByAttribute(AllObjects(), "race", "Orc"))
dictionary add (game.NPC, "Goblin", FilterByAttribute(AllObjects(), "race", "Goblin"))
dictionary add (game.NPC, "Human", FilterByAttribute(AllObjects(), "race", "Human"))
</function>
<function name="ChangeHostility" parameters="race">
// I altered this so it only effects NPCs in the room when you attack.
foreach (object, DictionaryItem(game.NPC, race)) {
if(object.parent = game.pov.parent){
if (object.attackonsight) {
object.attackonsight = false
}
else {
object.attackonsight = true
msg (CapFirst(GetDisplayName(object))+" looks angry now!")
}
}
}
</function>
<function name="DoAttack" parameters="attacker, target">
msg (CapFirst(GetDisplayName(attacker))+" attacks "+GetDisplayName(target)+"!")
</function>
</asl>
First things last:
Even with your new code, I noticed in debugger, the Mean and Kind are not changing in the original attacked monster or the other like race monsters.
You got this working; right?

K.V.
15 Jan 2018, 03:39PS
You need to rotate stock and front those shelves, too, man!
You can't just straighten them...
(All K-Mart did was straighten, and look what happened to them!)
#InventoryJokes

Forgewright
15 Jan 2018, 08:34- Making the hostility change script part of the monster type would end having to add the function to attack command for each monster. Types can hold scripts too, so when the attack script is called, depending on the monster race different monsters can handle the attack differently. Maybe it will run away, maybe it will lead you to a bunch of his hidden buddies, maybe shat himself.
- First things last...Oh wait... I forgot to re-add the race list creation function to the start script...
- Entire scripts are just something I have to scroll past to get to the good stuff below it. Hey, I tell ya, I kid the feeble minded. That was Rodney Dangerfield. I do a great impression of him BTW. No Respect. I prefer the whole script too.
- Boot the other attributes. Agree
- I always have to rotate stock and front those shelves. we call it maize...no wait, zoning, we call it zoning.

Forgewright
15 Jan 2018, 12:50The general area I was talking about was certain regions in the game. Mountains, or grasslands and the such. No reason to piss off the whole nation of orcs.

K.V.
15 Jan 2018, 16:21Making the hostility change script part of the monster type would end having to add the function to attack command for each monster.
Mmm...
I think you'd still have to have at least one line which ran that ChangeHostility script, whether the script was a function, or a script attribute, or you just entered all the code directly into the script.
Types can hold scripts too, so when the attack script is called, depending on the monster race different monsters can handle the attack differently.
Sounds like you'd either:
A. need three new types to pull this off:
- Orc
- Goblin
- Human
B. need to modify the monster_turnscript after making a few other adjustments. Paste this in place of the full code of a new game and attack Vilhelm, George, Morcrest, or Scar:
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="example_game">
<gameid>d821c1d9-fa44-4d24-9658-627812651b61</gameid>
<version>1.0</version>
<firstpublished>2018</firstpublished>
<start type="script">
FindRaces
SetHostility
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<usedefaultprefix type="boolean">false</usedefaultprefix>
<feature_startscript />
<attr name="_initialise_" type="script">
game.pov.alias = "you"
</attr>
</object>
<object name="Morcrest">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
<mode>Kind</mode>
</object>
<object name="Vilhelm">
<inherit name="editor_object" />
<inherit name="namedmale" />
<inherit name="monster" />
<race>Human</race>
</object>
<object name="Schmeck">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Goblin</race>
</object>
<object name="Ralph">
<inherit name="editor_object" />
<inherit name="namedmale" />
<fleeonsight />
</object>
<object name="Beetlejuice">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
</object>
<object name="George">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Human</race>
</object>
<object name="Scar">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
</object>
<exit alias="north" to="another room">
<inherit name="northdirection" />
</exit>
</object>
<verb>
<property>attack</property>
<pattern>attack</pattern>
<defaultexpression>"You can't attack " + object.article + "."</defaultexpression>
</verb>
<turnscript name="monsters_turnscript">
<enabled />
<script>
foreach (o, FilterByType(AllObjects(), "monster")) {
if (o.parent = game.pov.parent) {
if (o.attackonsight) {
DoAttack (o, game.pov)
}
else if (o.fleeonsight) {
o.exit = PickOneUnlockedExit (game.pov.parent)
msg (CapFirst(GetDisplayName(o)) + " runs away to the {exit:"+o.exit.name+"}!")
MoveObject (o, o.exit.to)
o.exit = null
}
}
}
</script>
</turnscript>
<object name="another room">
<inherit name="editor_room" />
<exit alias="south" to="room">
<inherit name="southdirection" />
</exit>
</object>
<type name="monster">
<attackonsight type="boolean">false</attackonsight>
<feature_startscript />
<fleeonsight type="boolean">false</fleeonsight>
<attackscript type="script">
DoAttack (this, game.pov)
</attackscript>
<attack type="script">
msg ("You attack "+GetDisplayName(this)+".")
// Do whatever here - kill or add damage - I'm just going to kill the NPC for simplicity's sake.
msg (CapFirst(GetDisplayName(this))+" falls dead then fades away, as if this were some sort of video game.")
RemoveObject (this)
// END OF "kill or add damage"
ChangeHostility (this.race)
</attack>
<attr name="_initialise_" type="script">
this.displayverbs = Split("Look at;Speak to;Attack",";")
</attr>
<angers type="boolean">false</angers>
<flees type="boolean">false</flees>
</type>
<function name="FindRaces">
if (not HasAttribute(game, "NPC")) {
game.NPC = NewDictionary()
}
dictionary add (game.NPC, "Orc", FilterByAttribute(AllObjects(), "race", "Orc"))
dictionary add (game.NPC, "Goblin", FilterByAttribute(AllObjects(), "race", "Goblin"))
dictionary add (game.NPC, "Human", FilterByAttribute(AllObjects(), "race", "Human"))
</function>
<function name="ChangeHostility" parameters="race">
// I altered this so it only effects NPCs in the room when you attack.
foreach (object, DictionaryItem(game.NPC, race)) {
if (object.parent = game.pov.parent) {
if (object.angers) {
if (object.attackonsight) {
object.attackonsight = false
}
else {
object.attackonsight = true
msg (CapFirst(GetDisplayName(object))+" looks angry now!")
}
}
else if (object.flees) {
if (object.fleeonsight) {
object.fleeonsight = false
}
else {
object.fleeonsight = true
msg (CapFirst(GetDisplayName(object))+" looks frightened now!")
}
}
}
}
</function>
<function name="DoAttack" parameters="attacker, target">
msg (CapFirst(GetDisplayName(attacker))+" attacks "+GetDisplayName(target)+"!")
</function>
<function name="SetHostility">
foreach (orc, DictionaryItem(game.NPC,"Orc")) {
orc.angers = true
}
foreach (goblin, DictionaryItem(game.NPC,"Goblin")) {
goblin.angers = true
}
foreach (human, DictionaryItem(game.NPC,"Human")) {
human.flees = true
}
</function>
</asl>

K.V.
15 Jan 2018, 18:48Here it is with two regions.
The first two rooms are in one region, the third is in a region of its own.
So, attacking someone in room or another room will effect the NPCs in both of those rooms, but third room folks know nothing of the goings on anywhere besides in their room (unless an NPC is 'visiting' third room after fleeing there from the other region).
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="example_game">
<gameid>d821c1d9-fa44-4d24-9658-627812651b61</gameid>
<version>1.0</version>
<firstpublished>2018</firstpublished>
<start type="script">
FindRaces
SetHostility
</start>
</game>
<verb>
<property>attack</property>
<pattern>attack</pattern>
<defaultexpression>"You can't attack " + object.article + "."</defaultexpression>
</verb>
<turnscript name="monsters_turnscript">
<enabled />
<script>
foreach (o, FilterByType(AllObjects(), "monster")) {
if (o.parent = game.pov.parent) {
if (o.attackonsight) {
DoAttack (o, game.pov)
}
else if (o.fleeonsight) {
o.exit = PickOneUnlockedExit (o.parent)
msg (CapFirst(GetDisplayName(o)) + " runs away to the {exit:"+o.exit.name+"}!")
MoveObject (o, o.exit.to)
}
}
}
</script>
</turnscript>
<object name="northern_region">
<inherit name="editor_room" />
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<usedefaultprefix type="boolean">false</usedefaultprefix>
<feature_startscript />
<attr name="_initialise_" type="script">
game.pov.alias = "you"
</attr>
</object>
<object name="Morcrest">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
<mode>Kind</mode>
</object>
<object name="Vilhelm">
<inherit name="editor_object" />
<inherit name="namedmale" />
<inherit name="monster" />
<race>Human</race>
</object>
<object name="Schmeck">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Goblin</race>
</object>
<object name="Ralph">
<inherit name="editor_object" />
<inherit name="namedmale" />
<fleeonsight />
</object>
<object name="Beetlejuice">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
</object>
<object name="George">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Human</race>
</object>
<object name="Scar">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
</object>
<exit alias="north" to="another room">
<inherit name="northdirection" />
</exit>
</object>
<object name="another room">
<inherit name="editor_room" />
<usedefaultprefix type="boolean">false</usedefaultprefix>
<exit alias="south" to="room">
<inherit name="southdirection" />
</exit>
<exit alias="north" to="third room">
<inherit name="northdirection" />
</exit>
<object name="Wormface">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
</object>
<object name="Bill">
<inherit name="editor_object" />
<inherit name="namedmale" />
<inherit name="monster" />
<race>Human</race>
</object>
<object name="Knothead">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Goblin</race>
</object>
<object name="Tomas">
<inherit name="editor_object" />
<inherit name="namedmale" />
<fleeonsight />
</object>
<object name="Fordo">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
</object>
<object name="Joe">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Human</race>
</object>
</object>
</object>
<object name="southern_region">
<inherit name="editor_room" />
<object name="third room">
<inherit name="editor_room" />
<object name="Rott">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
<mode>Kind</mode>
</object>
<object name="William">
<inherit name="editor_object" />
<inherit name="namedmale" />
<inherit name="monster" />
<race>Human</race>
</object>
<object name="Schpleck">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Goblin</race>
</object>
<object name="Fred">
<inherit name="editor_object" />
<inherit name="namedmale" />
<fleeonsight />
</object>
<object name="Beetelgeuse">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
</object>
<object name="Jorge">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Human</race>
</object>
<object name="Gasher">
<inherit name="editor_object" />
<inherit name="monster" />
<inherit name="namedmale" />
<race>Orc</race>
</object>
<exit alias="south" to="another room">
<inherit name="southdirection" />
</exit>
</object>
</object>
<type name="monster">
<attackonsight type="boolean">false</attackonsight>
<feature_startscript />
<fleeonsight type="boolean">false</fleeonsight>
<angers type="boolean">false</angers>
<flees type="boolean">false</flees>
<attackscript type="script">
DoAttack (this, game.pov)
</attackscript>
<attack type="script">
msg ("You attack "+GetDisplayName(this)+".")
// Do whatever here - kill or add damage - I'm just going to kill the NPC for simplicity's sake.
msg (CapFirst(GetDisplayName(this))+" falls dead then fades away, as if this were some sort of video game.")
RemoveObject (this)
// END OF "kill or add damage"
ChangeHostility (this.race)
</attack>
<attr name="_initialise_" type="script">
this.displayverbs = Split("Look at;Speak to;Attack",";")
</attr>
</type>
<function name="FindRaces">
if (not HasAttribute(game, "NPC")) {
game.NPC = NewDictionary()
}
dictionary add (game.NPC, "Orc", FilterByAttribute(AllObjects(), "race", "Orc"))
dictionary add (game.NPC, "Goblin", FilterByAttribute(AllObjects(), "race", "Goblin"))
dictionary add (game.NPC, "Human", FilterByAttribute(AllObjects(), "race", "Human"))
</function>
<function name="ChangeHostility" parameters="race">
// I altered this so it only effects NPCs in the room when you attack.
foreach (object, DictionaryItem(game.NPC, race)) {
if (not object.parent = null) {
if (object.parent.parent = game.pov.parent.parent) {
if (object.angers) {
if (object.attackonsight) {
object.attackonsight = false
}
else {
object.attackonsight = true
if (object.parent = game.pov.parent) {
msg (CapFirst(GetDisplayName(object))+" looks angry now!")
}
}
}
else if (object.flees) {
if (object.fleeonsight) {
object.fleeonsight = false
}
else {
object.fleeonsight = true
if (object.parent = game.pov.parent) {
msg (CapFirst(GetDisplayName(object))+" looks frightened now!")
}
}
}
}
}
}
</function>
<function name="DoAttack" parameters="attacker, target">
msg (CapFirst(GetDisplayName(attacker))+" attacks "+GetDisplayName(target)+"!")
</function>
<function name="SetHostility">
foreach (orc, DictionaryItem(game.NPC,"Orc")) {
orc.angers = true
}
foreach (goblin, DictionaryItem(game.NPC,"Goblin")) {
goblin.angers = true
}
foreach (human, DictionaryItem(game.NPC,"Human")) {
human.flees = true
}
</function>
</asl>

K.V.
15 Jan 2018, 18:57This is fun.
What if, when an NPC flees, and they end up in a new region, you give the player a turn or two to run the NPC off, before he infects the NPCs of his race in the new region with his fears of you.
I figure the humans would be the ones to run. I also reckon the humans are the ones you need to speak to in order to gain information sometimes. So, if all of the humans run from you, you are screwed.
See where I'm going with that? Or do I have toys in the attic today? (Simply gone fishing.)
Holy crap!
I'm using some of this code in a fishing script!

Forgewright
16 Jan 2018, 01:14Humans are always scared of this player character. It is a mythical creature. The player will need to discover a way to transform into a human form if he wants to defeat another evil bastard (who controls you). For now if you enter an area with humans they will mostly run, but there always seems to be one or two that will want to take a stab at you. That's the last of them...
You play a gargoyle. The cause of many crying widows and soiled cotton under garments. You are actually a pretty nice fella since being summoned from hell, away from your torturous job involving the damned. Humans just won't give ya a chance.
Imagine flying up in the sky. You've learned to follow the lay of the forests and avoid roads and clearing. Suddenly, you can see some humans out hunting and they just happen to be in a small clearing.
They've seen you! At first they are puzzled as to what they are actually seeing, but after a moment they begin to run into the shelter of the trees.
You quickly veer off to get out of their sight but it is too late. One of them carefully aims a bow into the air and lets loose an arrow. It flies by, just missing your head .
You turn back toward the attacker and dive straight for them. "Well", you think to yourself, "I haven't had mid-day meal yet!"
It's the typical medieval romp through the 1500's. Set in Bristol, England.

K.V.
16 Jan 2018, 01:30That sounds cool!
Sign me up for beta-testing!

Forgewright
16 Jan 2018, 07:34Bug Alert (Edited)
The ChangeHostility function adds the original monster that the player attacks to the list of attackers every time the player attacks during battle, so there are multiples of that monster in the attackers list giving it more and more attacks each turn. Which is kinda funny but not what we're after here.
The monster starts getting more attacks on the third attack.
First attack adds him to the list of attackers.
Second attack adds him the second time, so you would think he would get 2 attacks, but doesn't.
This leads me to believe he is added to the list after he attacks.
Third attack on him he get 2 attacks.
Plus this bug is causing my fancy hitpoint gauge to not work. its there just not lowering and I seem to battle passed the point of what should have triggered my death.
I will see if I can ListExclude somehow or I could flag him after first attack and reference that flag. Burning the midnight oil tonight...good thing it's my night off

K.V.
16 Jan 2018, 07:47Are you using this one?
<function name="ChangeHostility" parameters="race">
// I altered this so it effects NPCs in the REGION when you attack.
foreach (object, DictionaryItem(game.NPC, race)) {
if (not object.parent = null) {
if (object.parent.parent = game.pov.parent.parent) {
if (object.angers) {
if (object.attackonsight) {
object.attackonsight = false
}
else {
object.attackonsight = true
if (object.parent = game.pov.parent) {
msg (CapFirst(GetDisplayName(object))+" looks angry now!")
}
}
}
else if (object.flees) {
if (object.fleeonsight) {
object.fleeonsight = false
}
else {
object.fleeonsight = true
if (object.parent = game.pov.parent) {
msg (CapFirst(GetDisplayName(object))+" looks frightened now!")
}
}
}
}
}
}
</function>

Forgewright
16 Jan 2018, 07:50No,
race_type = race + "s"
race_list = DictionaryItem(game.NPC,race_type)
foreach (object, race_list) {
if (object.mode = "Mean") {
object.mode = "Kind"
list add (game.friends, object)
list remove (game.attackers, object)
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
list add (game.attackers, object)
list remove (game.friends, object)
if (HasAttribute(object, "attacked")) {
}
}
}

Forgewright
16 Jan 2018, 07:55Was going to use a flag, but if I read the list of attackers each attack and exclude the ones there already, I should be good.

K.V.
16 Jan 2018, 07:57REVISED
race_type = race + "s"
race_list = DictionaryItem(game.NPC,race_type)
foreach (object, race_list) {
if (object.mode = "Mean") {
object.mode = "Kind"
if (not ListContains(game.friends, object){
list add (game.friends, object)
}
if (ListContains(game.attackers, object)){
list remove (game.attackers, object)
}
}
else if (object.mode = "Kind" ) {
object.mode = "Mean"
object.attackonsight = true
if (not ListContains(game.attackers, object){
list add (game.attackers, object)
}
if (ListContains(game.friends, object)){
list remove (game.friends, object)
}
if (HasAttribute(object, "attacked")) {
// You have no script here. (I'm watching you.)
}
}
}

Forgewright
16 Jan 2018, 08:16Don't need the 'attacked' attribute. You did just what I was doing! Just faster.
It's hard to win the race when you're laying on the bed watching the tube... been scripting all day, starting to get a little worn out.
Thanks KV.

K.V.
16 Jan 2018, 08:40I'm watching National Geographic: Wonders of the Universe Collection.
They are currently on Mars.
...well, the rovers are on Mars.
Just waiting for someone to post something while trying to keep from working on my own game up in here. (Know what I'm sprayin'?)

Forgewright
16 Jan 2018, 22:10Never tried this before, but
<command name="Stop this message">
<pattern>Stop this message</pattern>
<script>
DisableTurnScript (level_notice)
msg("This notice will no longer display until more points are distributed.")
game.notarealturn = true
</script>
</command>
I have at turnscript notice that pops up every turn, telling the player when they have attribute points to spend. This is a command shown at the bottom so the player can stop the message until they are ready(the notice is a bit annoying). I want it to not count as a turn, because they may be in battle at the time. However, the attacker still attacks when it is selected.
When using not a real turn should a line be used at some point to turn it back to false?

K.V.
17 Jan 2018, 02:25game.notarealturn usually only effects the turn script that adds a turn when game.notarealturn is not set to true
somewhere in a script.
You should have a turn script similar to this one:
if (not game.notarealturn) {
game.turns = game.turns + 1
}
game.notarealturn = false

K.V.
17 Jan 2018, 02:29You could check for that in the attack turn script (maybe):
<turnscript name="monsters_turnscript">
<enabled />
<script>
if (not game.notarealturn){
foreach (o, FilterByType(AllObjects(), "monster")) {
if (o.parent = game.pov.parent) {
if (o.attackonsight) {
DoAttack (o, game.pov)
}
else if (o.fleeonsight) {
o.exit = PickOneUnlockedExit (o.parent)
msg (CapFirst(GetDisplayName(o)) + " runs away to the {exit:"+o.exit.name+"}!")
MoveObject (o, o.exit.to)
}
}
}
}
</script>
</turnscript>

Forgewright
17 Jan 2018, 07:29EDITED
Added the notarealturn to the doattack script but the monster sill attacks.
I'm just home for lunch. I'll deal with this tomorrow!
if (this.noncorporeal and GetElement(game.pov.equipped) = null) {
if (game.pov.equipped.nonweapon) {
msg("You attack the " + GetDisplayAlias(this) + ", and pass straight through it!")
}
else {
msg("You {random:swing:stab with:thrust with} your " + GetDisplayAlias(game.pov.equipped) + " and it goes straight through the " + GetDisplayAlias(this) + "!")
}
}
else if (attackroll > 10) {
damage = GetDamage (game.pov.equipped, game.pov.strength / 2 + this.temp_damage + game.pov.damagebonus, this)
this.hitpoints = this.hitpoints - damage
if (this.hitpoints > 0) {
if (game.pov.equipped.nonweapon) {
msg ("You attack and hit, doing " + damage + " points of damage (" + this.hitpoints + " hits left). " + this.hurtbyweapon)
}
else {
msg (this.temp_desc + " " + GetDisplayAlias(game.pov.equipped) + " and hit, doing " + damage + " points of damage <br></br>(Foe has " + this.hitpoints + " hits left). " + this.hurtbyweapon)
}
if (HasScript(this, "onweaponhit")) do (this, "onweaponhit")
if (HasObject(game.pov.equipped, "venom")) {
if (this.poisonimmunity) {
if (HasString(this, "poisonimmunitymsg")) {
msg(this.poisonimmunitymsg)
}
else {
msg("The " + GetDisplayAlias(this) + " is immune to your blade venom.")
}
}
else {
game.pov.target = this
do(game.pov.equipped.venom, "effect")
}
game.pov.equipped.venom = null
}
}
else {
if (game.pov.equipped.nonweapon) {
msg ("You attack and hit, doing " + damage + " points of damage. " + this.death)
}
else {
msg (this.temp_desc + " " + GetDisplayAlias(game.pov.equipped) + " and hit, doing " + damage + " points of damage. " + this.death)
}
do (this, "makedead")
}
}
else {
if (game.pov.equipped.nonweapon) {
msg ("You attack and miss.")
}
else {
msg ("You {random:swing:stab with:thrust with} your " + GetDisplayAlias(game.pov.equipped) + " and miss.")
}
}
if (HasObject(game.pov, "secondary_attack")) {
do(this, "secondaryattack")
}
}
}
]]></doattack>

K.V.
17 Jan 2018, 07:35It doesn't display the details when I click on "Details". (It does that when I post sometimes, too. I usually just need to add an extra line-break after <details>.)

Forgewright
17 Jan 2018, 12:26Even with your explanation, I really have no idea where to put the notarealturn. I would think in the attack script it would have worked. I have it there and in doattack. But I still get whacked.

Forgewright
17 Jan 2018, 12:52Here's the link to game. If that helps.
Link removed for privacy....

K.V.
17 Jan 2018, 15:32where to put the notarealturn
If I didn't want to call DoAttack()
when game.notarealturn = True
, I would put it in the turn script that called DoAttack()
(assuming that's how DoAttack()
is being called).
if (not game.notarealturn){
DoAttack(f,your,parameters)
}

K.V.
17 Jan 2018, 15:45How do I get to a place where someone attacks me?
(Feel free to message me, if you'd rather not broadcast the information.)

K.V.
17 Jan 2018, 16:32I figured it out.
I added this turn script:
<turnscript name="TurnCountTurnScriptKV">
<enabled />
<script>
if (not HasAttribute(game,"turns")) {
game.turns = 0
}
if (not game.notarealturn) {
game.turns = game.turns + 1
}
game.notarealturn = false
</script>
</turnscript>
And I modified this turn script:
<turnscript name="attacktheplayerturnscript">
<enabled />
<script><![CDATA[
// In an ideal world, this would only fire if the player has actually done something.
// As it is, a mis-typed command will give monsters the opportunity to strike
// so we have thisL
//
// KV was here! I added the next if statement.
if (not game.notarealturn) {
if (game.command_successful) {
game.pov.turncount = game.pov.turncount + 1
// Anything added to this list will later get removed from the attackers list
game.forgetme = NewObjectList ()
// Any monsters here that need adding to the list of attacks because they attack on sight?
foreach (obj, GetDirectChildren (game.pov.parent)) {
if (DoesInherit(obj, "monster") and not ListContains(game.attackers, obj) and not ListContains(game.friends, obj)) {
do (obj, "initattack")
}
}
// Go through each monster
monsters = ListCombine(game.attackers, game.friends)
list remove (monsters, player)
foreach (attacker, monsters) {
if (GetBoolean(attacker, "stunned")) {
if (attacker.parent = game.pov.parent) {
msg (attacker.alias + " is stunned for a moment, and does not attack.")
}
attacker.stunned = false
}
else if (attacker.parent = game.pov.parent) {
do (attacker, "selecttarget")
if (HasObject(attacker, "target")) {
do (attacker, "attackplayer")
}
else {
msg (CapFirst(GetDisplayName(attacker)) + " has no target to attack.")
}
}
else {
do (attacker, "searchforplayer")
}
}
// These are no longer attackers or friends=
foreach (mon, game.forgetme) {
list remove (game.attackers, mon)
list remove (game.friends, mon)
}
// Check for spell/potion expiring
if (not HasInt(game.pov, "magiccountdown")) {
game.pov.magiccountdown = 0
}
if (game.pov.magiccountdown > 0) {
game.pov.magiccountdown = game.pov.magiccountdown - 1
if (game.pov.magiccountdown < 1) {
do (game.pov.currentspell, "endmagiceffect")
}
}
// Check sneaking
if (not HasInt(game.pov, "sneaklevel")) {
game.pov.sneaklevel = 0
}
game.pov.sneaklevel = game.pov.sneaklevel - 1
if (0 > game.pov.sneaklevel) {
game.pov.sneaklevel = 0
}
// Some attacks give a bonus to OB next round
game.pov.ob_bonus = game.pov.next_round_ob_bonus
game.pov.next_round_ob_bonus = 0
game.pov.db_bonus = 0
game.pov.currectattack = null
}
else {
game.command_successful = true
}
}
]]></script>
</turnscript>
Now game.notarealturn
gets set to false
after every turn, whether it's a real command or not (which is how it should be), and the monsters don't attack when game.notarealturn
is true
.

Forgewright
17 Jan 2018, 17:21I just had to add this to the command that stopped the "level notice" from popping up.
game.notarealturn = true
That was the issue. A notice will print every turn if the player has attribute points to spend. I'd hate to have the player forget they had them and miss out. But the notice is annoying. This gives them the option to shut it off especially if they are in battle. Everything works now KV.
I never would have figured this out, but now that I see it in action I understand the who, what, where of it.
Thanks again.
BTW, I edited the uploaded game. Now I just have a couple months of adding the old game contents a piece at a time to finish it. It has only been 2 years already...

K.V.
17 Jan 2018, 18:15Aha!
You were like Sherlock Holmes, and I was like Jiminy Cricket!

Forgewright
17 Jan 2018, 18:53Or Dumb and Dumber

Forgewright
17 Jan 2018, 22:17So I was thinking... I have been on the forum for years now. I should start a thread called " The Documentary of a Text Adventure" and it would show the steps involved, since I'm starting over. It would show the failures, successes, processes, and pitfalls involved in making a game. As well as the dedication it takes to create a truly crappy...wait, that's epic game.
And....I'm over it.
jmnevil54
18 Jan 2018, 01:25Ha.
I think this whole big forum is like one big tutorial. That's what it's there for, anyway.
"Oh hey, I have an idea, but I don't know how to do this?"
"I don't understand any of this..."
"Yay! I found useful code!"
"That didn't work, that didn't work, that didn't work..."
One day later.
"That didn't work, that didn't work, that didn't work..."
Three days later.
"Yes! It works now! Wait, now this is broken..."
Repeat the process for weeks, months, or years. Then publish the game, and then realize you have more bugs, and then spend one or two months getting those bugs out.
At least that's my experience.

Forgewright
18 Jan 2018, 07:12jmnevil54,
Exactly. Then there updates and newly learned code that you just have to have in your game causing you to start over or redo.
hegemonkhan
18 Jan 2018, 14:43gives you a lot of appreciation/respect for game makers (even if they're massive teams of big gaming companies), especially in the early days of gaming... where there wasn't massive teams, but only a few people, or even just one, making a game.
That's the problem with updating, unfortunately... I'm still using like quest 5.5.X, I've not even tried/downloaded/installed Pixie's quest versions... I'm just trying to learn how to code in things myself, even if Pixie has already coded such things in, I learn a lot by trying to do it myself, and I understand what I worked on and created, whereas it's not easy for me to learn other people's code and features, including the default/built-in quest's coding/features, laughs.
the worst is having a lot of code, and going back and changing your naming/labeling and/or coding structure system/convention, lol... I probably should learn to code in code, to do this for me (compiling/parsing/etc coding), laughs.
90% of coding, isn't coding... but trouble-shooting code and/or re-designing/re-coding (re-factoring/stream-lining) your code, lol.

Forgewright
18 Jan 2018, 22:47When using the hitpoint table indicator from
I have had an issue with it from day one. Everything thing works but the Hitpoints are not shown in the top until an attack occurs. The label is there but the integers are just ---. I'm sure this has to do with the ChangedHitpoints attribute. I would like the integers to show from the get go.
I have made some changes to the script concerning colors.
s = "<table width=\"100%\"><tr>"
s = s + " <td style=\"text-align:right;\" width=\"50%\">Hit points:</td>"
s = s + " <td style=\"text-align:left;\" width=\"50%\"><span id=\"hits-span\">---</span></td>"
s = s + " </tr>"
s = s + " <tr>"
s = s + " <td colspan=\"2\" style=\"border: thin solid;background:linen;text-align:left;\">"
s = s + " <span id=\"hits-indicator\" style=\"background-color:green;padding-right:200px;\"></span>"
s = s + " </td>"
s = s + " </tr>"
s = s + "</table>"
JS.setCustomStatus (s)
if (HasScript(player, "changedhitpoints")) {
do (player, "changedhitpoints")
}
I set the InitUserInterface in start as well as the hitpoints and max Hitpoints, which combatLib changes anyway.

K.V.
19 Jan 2018, 00:07I am making an RPG so I can be of more help to those of you who are doing the same.
This is what I've got on my player object.
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<feature_startscript />
<attr name="_initialise_" type="script"><![CDATA[
msg("Running player initialise script")
player.alias = "you"
//player.hitpoints = 35
player.damage = 3
player.attack = 0
player.defence = 0
player.armour = 0
player.changedhitpoints => {
if (player.hitpoints > 0) {
msg ("Hit points now: " + player.hitpoints)
}
else {
msg ("You have died!")
finish
}
JS.eval ("$('#hits-span').html('" + game.pov.hitpoints + "/" + game.pov.maxhitpoints + "');")
JS.eval ("$('#hits-indicator').css('padding-right', '" + (200 * game.pov.hitpoints / game.pov.maxhitpoints) + "px');")
}
player.maxhitpoints = 100
player.hitpoints = 100
]]></attr>
</object>
NOTE: You can set maxhitpoints and hitpoints to whatever you please and the thingy will still work.
My start script:
<start type="script"><![CDATA[
msg("Running start script")
// List of attackers
player.attackers = NewObjectList()
player.ammo = 35
// Status attributes
WeaponUpdate
player.statusattributes = NewStringDictionary()
dictionary add (player.statusattributes, "hitpoints", "Hit points: !")
dictionary add (player.statusattributes, "ammo", "Spare ammo: !")
dictionary add (player.statusattributes, "equippedname", "Weapon: !")
dictionary add (player.statusattributes, "ammonote", "Ammo: !")
SetTurnTimeout(1){
SetDate
}
s = "<table width=\"100%\"><tr>"
s = s + " <td style=\"text-align:right;\" width=\"50%\">Hit points:</td>"
s = s + " <td style=\"text-align:left;\" width=\"50%\"><span id=\"hits-span\">---</span></td>"
s = s + " </tr>"
s = s + " <tr>"
s = s + " <td colspan=\"2\" style=\"border: thin solid;background:linen;text-align:left;\">"
s = s + " <span id=\"hits-indicator\" style=\"background-color:green;padding-right:200px;\"></span>"
s = s + " </td>"
s = s + " </tr>"
s = s + "</table>"
JS.setCustomStatus (s)
if (HasScript(player, "changedhitpoints")) {
do (player, "changedhitpoints")
}
]]></start>
While we're here, want to see the order in which the start and initialisation script run?
Running user interface initialisation script
Running start script
Running player initialise script
Running junk pile initialise script
Running Cricket Bat initialise script
Running vomitattack initialise script
Running vomitreadying initialise script
Running kickattack initialise script
Running Spade initialise script
That is the order the objects are entered in full code view, by the way.

K.V.
19 Jan 2018, 00:13
Forgewright
19 Jan 2018, 02:44Somehow during changing things I was missing this in player Initializing script.
JS.eval ("$('#hits-span').html('" + game.pov.hitpoints + "/" + game.pov.maxhitpoints + "');")
JS.eval ("$('#hits-indicator').css('padding-right', '" + (200 * game.pov.hitpoints / game.pov.maxhitpoints) + "px');")

K.V.
19 Jan 2018, 02:45Tisk, tisk!