Object Type and Object Not Recognizing THIS (Help Please) [Almost Solved]

So, I'm honestly not sure what's happening with my game's combat atm because all sorts of very strange things are happening. But that's another bag of apples we can get into after this...

I have an OBJECT TYPE

Monster

and another OBJECT TYPE that inherits it called

Female Zombie Type 

On the Monster Type I have an ATTRIBUTE
Distract (which runs a script on the Female Zombie Type called distractscript (script)

On the Female Zombie Type, distractscript --- I have several...

if (this.distraction<=9) {
yada yada ((and yes distraction is an integer))
}

But on the ENEMY OBJECTS, female_zombie, the creature's distraction isn't rising when the script is called and neither does the Player's (which is referred to as player so player.distraction etc). I even have a "+ this.distraction +" as an expression on the script. But no matter what the creature's distraction isn't rising.


I also have a weird problem where the player's health keeps getting fully recharged every turn and their distraction drops back down to zero instead of rising. But no where in ANY of the combat scripts or the turn-scripts do I have such a command/script prompting this.

I really, really need help with this cause I've been trying to fix these for about a week or two. Can anyone please help?

Anonynn.


Are there any error messages?

This is the kind of problem that's hard to approach without seeing the code. The first thing to check would be that the 'distract' script is definitely being called. Do 'distract' and 'distractscript' both output a message which lets you know they are running?


No error messages. They just aren't showing up or getting tallied. I feel like there is an underlying problem that is causing "this" and the "distract" not to get added or subtracted. It's like they don't exist in game.
Here's some of the code. Now the Monster Type recognizes "this" just fine.

MONSTER TYPE
ATTRIBUTE distract
ClearScreen
if (this.health > 0) {
  if (GetBoolean (this, "hasbeenattacked")) {
    msg ("<br/>After attacking this particular {if this.gender=male:guy}{if this.gender=female:girl}{if this.gender=other:creature} in self-defense or aggression, {if this.gender=male:he}{if this.gender=female:she}{if this.gender=other:it} can no longer be distracted.")
  }
  else {
        game.showmenuobject = this
        do (game.showmenuobject, "distractscript")
    }
	}
else {
  msg ("<br/>You cannot distract something dead... ")
}

^ this all works perfectly. But this script I've tried putting directly on the ENEMY OBJECT and on the FEMALE/MALE ZOMBIE TYPES as well but it's just not working at all. The scripts themselves work but anything regarding "this" referring to the ENEMY OBJECT does not.

FEMALE ZOMBIE TYPE
ATTRIBUTE distractscript
game.text_processor_this = this
if (this.distract<=9) {
if (RandomChance(50)) {
}
else if (RandomChance(33)) {
}
else if (RandomChance(25)) {
}
 else {
}
 msg ("<br/>{color:ivory:You've managed to increase her distraction!}")
    this.distraction= GetRandomInt (1,3)
    msg ("<br/>{color:ivory:The female zombie has gained "+ this.distraction +" distraction!}")
    switch (player.charmskill) {
      case (4,5,6, 7) {
        if (RandomChance(50)) {
             msg ("<br/>Yyour distraction has caused {if this.gender=female:her}{if this.gender=male:him} to falter...")
           this.distract= this.distract + 1
        }
      }
      case (8,9,10) {
        if (RandomChance(50)) {
             msg ("<br/>Yyour distraction has caused {if this.gender=female:her}{if this.gender=male:him} to falter even more...")
           this.distract= this.distract + 2
        }
      }
    }
    if (RandomChance(50)) {
      if (player.resist>=1) {
        msg ("<br/>{color:ivory:You've resisted getting distracted yourself. -1 Resist!}")
        player.resist = player.resist - 1
      }
      else {
        msg ("<br/>{color:ivory:Her reaction to all this has gotten you a little hot and bothered...}")
        player.lust = GetRandomInt (1,3)
        msg ("<br/>You've gained "+ player.distract +" distract!")
      }
    }
}
else {
  menulist = Split("Don't Attack;Attack Her", ";")
  ShowMenu ("", menulist, false) {
    if (result = "Don't Attack") {
      ClearScreen
      DontAttackEnemy
    }
    else if (result = "Attack Her") {
      ClearScreen
      if (player.equipped = null) {
        bonus = - this.defense
        damage = player.strength * 3
      }
      else {
        bonus = player.equipped.damagebonus - this.defense
        if (HasString(player.equipped, "damage")) {
          damage = DiceRoll(player.equipped.damage)
        }
        else {
          damage = player.equipped.damage * 2
        }
      }
      if (RandomChance(45 + 5 * bonus)) {
        this.health = this.health - damage
        if (this.health > 0) {
          PrintOrRun (this, "attackhit")
          msg ("[" + damage + " damage done, " + this.health + " health remaining]")
        }
        else {
          PrintOrRun (this, "attackkill")
          msg ("[" + damage + " damage done]")
          this.listalias = "<span style=\"color: red;\">" + this.alias + "</span>"
        }
      }
      else {
        PrintOrRun (this, "attackmissed")
      }
    }
  }
}
msg ("")

Like I said though, the Player's health is mysteriously regenerating instantly too. So I wonder if there is a more underlying problem.

Anonynn


I notice your distractscript treats both this.distraction and this.distract as numbers.
As this.distract appears to be a script, can I assume that you've renamed the attributes for the purpose of sharing here, and that you already double-checked you have it spelled consistently throughout?


So…

When run, the distractscript does the following:

  • If (this.distraction <= 9) {
    • Set this.distraction to a number between 1 and 3, and then increase it by 1 or 2 depending on the player's charmskill
  • else
    • this code will never run unless some other script raises this.distraction to 9

When your script outputs the message "The female zombie has gained 3 distraction.", it means that her distraction is now 3. This might be more than it was before, or it might be less.

If I understand the intended effect correctly, you want this script to increase this.distraction each time it is run, until it reaches 9, and then run the 'else' clause. Is that what you're after?

If so, you might want to change
this.distraction= GetRandomInt (1,3)
to
this.distraction = this.distraction + GetRandomInt (1,3)

Or if you want to display the number it was increased by,

    msg ("<br/>{color:ivory:You've managed to increase her distraction!}")
    increase = GetRandomInt (1,3)
    this.distraction = this.distraction + increase
    msg ("<br/>{color:ivory:The female zombie has gained "+ increase +" distraction!}")
    switch (player.charmskill) {

If I understand the intended effect correctly, you want this script to increase this.distraction each time it is run, until it reaches 9, and then run the 'else' clause. Is that what you're after?

Yup!

And the script fix worked perfectly on the expression portion but the game still isn't recognizing the rest of the "this" in the scripts, like, for example, {if this.gender=male:}{if this.gender=female:} (despite defining it) and in the Choice Menu with the ELSE.

Also yes, I've changed some of the variables because they are more adult in nature. I don't have a lot of adult elements in my game since it's mostly focused on RPG/Fantasy but there are some adult themes sprinkled far and between.

BTW thank you so much so far for all your help! I really appreciate your time.


The choice in the ELSE menu is throwing this error (see below) when choosing ATTACK (even though I'm using the exact attack scripts in regular combat with minor tweaks to the amount of damage done)...

Error running script: Error compiling expression '- this.defense': Unknown object or variable 'this'

and the Function called from the DONTATTACK choice is throwing this...

Error running script: No parameters passed to DistractEnemy function - expected 1 parameters

Parameter is target

Anonynn.


The choice in the ELSE menu is throwing this error (see below)

You're using this inside the script passed to ShowMenu. Remember, when the player clicks a menu choice it's now the next turn as far as the engine is concerned; all local variables and parameters have gone away.

But while you already saved it in an attribute, you could do:

  menulist = Split("Don't Attack;Attack Her", ";")
  ShowMenu ("", menulist, false) {
    this = game.text_processor_this
    if (result = "Don't Attack") {

for example, {if this.gender=male:}{if this.gender=female:} (despite defining it) and in the

That should work. (Aside from the "After attacking this particular {if …" line, which I think is called before you set text_processor_this).

I just checked your latest public version of the game. It looks like the gender attribute is a stringlist containing the single value female". So the condition on your {if statement boils down to if (ToString(Split("female")) = "female") in Quest code. I'm not sure if running ToString on a single element list would give a string that's equal to its element, but I wouldn't expect it to.

Maybe I'm wrong, in which case ignore me.

If this.gender is going to be a list, I think you probably want {either ListContains(this.gender,"male"):him:{either ListContains(this.gender,"female"):her:it}}. (Using either rather than if because it allows you to call functions in the condition).


and the Function called from the DONTATTACK choice is throwing this...

Error running script: No parameters passed to DistractEnemy function - expected 1 parameters

In the code you posted above, "Don't attack" calls the function DontAttackEnemy. Is that what you mean by "DistractEnemy function"?

I know you're editing the script to make it more family-friendly, but I can't tell if the problem here is that you've changed a nsfw function name to 2 different things; or if the error is coming from a part of the code you haven't shown.

If "DistractEnemy function" is the one that's DontAttackEnemy in your code sample, and it expects a target parameter, then maybe

    DontAttackEnemy

should be

    DontAttackEnemy (this)

Also, the male/female thing shows up a lot. That particular bit of text-processor code appears 704 times in your latest public release, so it could well be worth moving it into a function.

I'd suggest modifying the scriptdictionary game.textprocessorcommands to add an element with key "gender":

parts = Split (LTrim(Mid(section,7)), ":")
if (parts[0] = "") {
  if (HasObject (game, "text_processor_this)) {
    object = game.text_processor_this
  }
  else {
    object = game.pov
  }
}
else {
  object = ObjectForTextProcessor (parts[0])
}
gender = object.gender
if (TypeOf (gender) = "stringlist") {
  gender = gender[0]
}
else if (not TypeOf (gender) = "string") {
  gender = ToString (gender)
}
if (gender = "you" and HasString (object, "external_gender")) {
  // Not necessary for your game, but in case someone else decides to copy this code
  // makes the code work correctly for the player object
  gender = object.external_gender
}
switch (LCase(gender)) {
  case ("male", "him") {
    result = parts[1]
  }
  case ("female", "her") {
    result = parts[2]
  }
  default {
    result = parts[3]
  }
}
game.textprocessorcommandresult = ProcessTextSection (result, data)

It's a smallish chunk of code, which should mean you can write {gender this:he:she:it} or {gender enemy:guy:girl:creature}. Moving this into a dedicated text processor command would make your strings shorter and easier to read/debug, as well as reducing the size of your game file.

As your game includes a truly impressive amount of text, I think something like this might also ease the workload when adding new bits.


Sorry about the delay in the response --- busy couple of days >.<

    DontAttackEnemy

should be

    DontAttackEnemy (this)

Well, this was a simple fix that made me feel really dumb. I believe it worked perfectly. Thank you!

Also, I added that text processor code...

parts = Split (LTrim(Mid(section,7)), ":")
if (parts[0] = "") {
  object = game.text_processor_this
}
else {
  object = ObjectForTextProcessor (parts[0])
}
gender = object.gender
if (TypeOf (gender) = "stringlist") {
  gender = gender[0]
}
else if (not TypeOf (gender) = "string") {
  gender = ToString (gender)
}
switch (LCase(gender)) {
  case ("male", "him") {
    result = parts[1]
  }
  case ("female", "her") {
    result = parts[2]
  }
  default {
    result = parts[3]
  }
}
game.textprocessorcommandresult = ProcessTextSection (result, data)

To the text processor code in the GAME.OBJECT scripts and added this {gender this:he:she:it} to all of the "Distract" code but it's being printed like that in game. For example...

Blah blah blah {gender this:he:she:it} blah blah blah. So I'm not sure why that isn't working.


Also, a curious little quirk I found is that...your text processor command...

  this = game.text_processor_this

and this one that I use now and then...

game.text_processor_this = this

Don't seem to be interchangeable for some reason. I tried to use yours in replacement to the one I've been using and it was having trouble finding "this" but in the menu section, yours worked and the other one I normally use didn't. Weird, huh xD?


To the text processor code in the GAME.OBJECT scripts

Did you set it with the key "gender"?
That's the only issue I can think of off the top of my head.

I wrote that code in the forum without testing it, but I think if there was a mistake in it you'd see an error message.

If you changed the name "gender" to something else, note that the 7 in the first line is the length of the command including the following space.

Otherwise, might be worth temporarily adding debugging statements to that script to see what the value of parts and object are.


Don't seem to be interchangeable for some reason.

this is a local variable. It only exists until the end of the script it's used in.

game.text_processor_this is an attribute of the game object, so continues to have the same value until you change it to something else. It's used to tell the text processor functions what the value of this was in the script that generated the text.

I noticed that you already had game.text_processor_this before the call to ShowMenu. So after ShowMenu results in this becoming unavailable, you can reverse that and do this = game.text_processor_this to set this back to what it was before.


(Just to add: I've now tested the text processor script in my own game, and it works as intended. For games with a large volume of text, I'd say that making your own text processor commands is likely to be a saving in both memory and development time)


So I just went back through and re-added (because I guess it didn't save when I did the play-through) the text processor script and then changed all the scripting over again. I haven't test it out but I have a quick question before I change the last few lines.

In the command we have {gender:him:her:it} etc but how will the text processor recognize when I'm referring to a male or female gender of an enemy if I have something other than {if gender.this=male:him}{if gender.this=female:her}?

For example, {if gender.this=male:his big masculine body}{if gender.this=female:her slim feminine body}

Do I do this..?....

{gender this:his big masculine body:her slim feminine body:its strange body}

and if so, how will the game recognize the gender?


Do I do this..?....

Looks right to me. The syntax is:
{gender object:response if male:response if female:response if other}

The script compares the gender to "male" or "female" (as in your types), or "him" or "her" (in case of the default Quest types); and selects the parameters appropriately.

As you're likely to compare an object's gender to the same constants every time you use it, it makes sense for them to be specified once (in the script).
It's basically replacing 3 text-processor {ifs with a single Quest switch, which reduces both the amount of code and the time taken to run it.

I realised after posting that it might be a little neater if the same command could be used for the player (whose gender is stored differently in most games; Quest uses the 4th gender "you")


{gender object:response if male:response if female:response if other}

So the order doesn't matter? It just finds the 'he;him;his' pronouns and picks male?

I could have...{gender object:response if female:response if male:response if other} etc


The responses are male, female, and other, in that order.
Having them in the same order each time is a lot quicker to process than taking the string apart to work out which bit is the condition and which bit is the output.


Log in to post a reply.

Support

Forums