My 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
That 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!
I 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.
No, 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'.
The log shows your function working but none of the game.lists are there in the debugger
OMG. Had added parameters to the function and call in start.
Working now
Actually 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
This should work too:
game.Orcs = FilterByAttribute(AllObjects(), "race", "Orc")
Pixie, 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>
Are 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>
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?
I believe this is true.
...just don't use e
or pi
. They exist already.
http://docs.textadventures.co.uk/quest/problems.html
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.
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.
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
(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
.
a 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
The 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>
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?
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.
I 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.
So 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
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.
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
.
I 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!
How 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!
The 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'
I 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...
Oh wait... I forgot to re-add the race list creation function to the start script...
I'll look into this tomorrow. Gotta leave for work shortly. Those Walmart shelves aren't gonna straighten themselves! 3rd shift rules!
Sorry, 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:
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?
The 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.
Making 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:
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>
Here 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>
This 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!
Humans 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.
Bug 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
Are 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>
No,
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")) {
}
}
}
Was 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.
REVISED
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.)
}
}
}
Don'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.
Never 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?
game.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
You 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>
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>
Even 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.
Here's the link to game. If that helps.
Link removed for privacy....
I 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
.
I 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...
So 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.
Ha.
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.
jmnevil54,
Exactly. Then there updates and newly learned code that you just have to have in your game causing you to start over or redo.
gives 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.
When 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.
I 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.
Somehow 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');")