Statuses

How would one go about making statuses? Like bleeding and poison? Like in my game my hero is bleeding and they have to find a way to patch up before their pain reaches max... How would I go about doing that? Like how would I create the multiple conditions like 1- doing fine to 5- about to die? Also how would I create the bleeding effect? Thanks for any help. (Also I changed games I'm working on I didn't want an only adult game so I'm toning down my content for teens and the like.)


Io

There is a METRIC TON of ways to do this.

There is, built into Quest, a 'Health' mechanic. I don't use that, though - generating your own systems to do things is both good programming practice, and lets you know better what you can and can't do.

So for 'how close are you to dead', you can create a custom Health attribute for the player, of Double (Decimal numbers) type. Pardon my psuedocode, but it could look like this:

Player.Health=56

Even have a Max Health, if you have healing mechanics and don't want to go over the max:

Player.MaxHealth=100
#Which then leads into, whenever you heal the player:
if Player.Health>Player.MaxHealth:
Player.Health=Player.MaxHealth

As for making statuses, there's a lot of ways to do this. One way like before is to give the player an attribute for every possible status.

Player.PoisonStrength=0
Player.BleedingStrength=5

And you can do stuff like:

Player.Health=Player.Health-Player.PoisonStrength-Player.BleedingStrength
if Player.Health<=0:
print("You died!")

to damage the player.

This isn't a VERY flexible method, because you have to go back and add a new attribute to the player every time you think of a new attribute - "Oh, I also want the player to be able to get cold! Oh, or get too hot! Also... etc". There is, again, a lot of ways to do this, but I've solved this problem in my current indev game and here's my solution:

The way I'd THAT problem is, in a hidden DebugRoom, I create an Invisible Object called EffectBase. EffectBase has lots of attributes itself. An alias, to call it "Cold" "Broken Bone" etc. EffectStrength, so the bleed you get from a papercut can be EffectStrength of 1 but from being stabbed with a sword EffectStrength of 10. Duration, Permanent (Duration only ticks down if Permanent is false) etc etc.

The use of this is, whenever I need to make a new effect, I simply set EffectBase's attributes to whatever I want, then clone a copy and move it to the player. I don't need to know every status ahead of time, I can make them up on the fly. It's invisible, too, so the player doesn't see. So for example, if I walk out into a floor and step on shattered glass, psuedocode might look like this:

EffectBase.alias="Bleeding"
EffectBase.Permanent=True
EffectBase.EffectStrength=10
Clone EffectBase and move to Player
print("Ouch! You're bleeding! Better get some bandages fast!")

And any time a 'turn' passes, you can search for all the EffectBase clones the player currently has with ForEach, with an If to look for the right status:

foreach (Status, FilterByAttribute(GetDirectChildren(Player), "prototype", EffectBase)){
if (Status.alias="Bleeding){
Player.Health=Player.Health-Status.EffectStrength
msg("Blood drips from your wound!")
}
}

Hope this helps.


the "simple" concepts are...


if you only want/need a single status at a time, use a String Attribute:

player.condition = "normal" // you're normal
player.condition = "poisoned" // you're no longer normal, and now you're poisoned
player.condition = "normal" // you're no longer poisoned, and back to normal
player.condition = "bleeding" // you're no longer normal, and now you're bleeding
player.condition = "dead" // you're no longer bleeding, and now you're dead

and then a simple example of handling it:

using either:

  1. a 'Turnscript' Element
  2. a 'Timer' Element
  3. the special 'changed' Script Attribute
  4. a specific action, such as via a Verb or Command

and for the scripting within:

if (player.condition = "normal") {
  // scripting
} else if (player.condition = "poisoned") {
  // scripting
} else if (player.condition = "bleeding") {
  // scripting
} else if (player.condition = "dead") {
  // scripting
} else if (player.condition = "confused") {
  // scripting
}
// etc etc etc 'else ifs' of more or less statuses

if you want/need to have multiple statuses at the same time, then use a List/Dictionary Attribute:

player.condition_list = NewStringList () // creates a new (and blank/empty) Stringlist Attribute

list add (player.condition_list, "normal") // you're normal

list remove (player.condition_list, "normal") // you're no longer normal
list add (player.condition_list, "poisoned") // you're now poisoned

list remove (player.condition_list, "poisoned") // you're no longer poisoned
list add (player.condition_list, "normal") // you're now normal

list remove (player.condition_list, "normal") // you're no longer normal
list add (player.condition_list, "poisoned") // you're now poisoned
list add (player.condition_list, "bleeding") // you're now bleeding too (you're poisoned and bleeding)

and then a simple example of handling it:

using either:

  1. a 'Turnscript' Element
  2. a 'Timer' Element
  3. the special 'changed' Script Attribute
  4. a specific action, such as via a Verb or Command

and for the scripting within:

if (ListContains (player.condition_list, "normal")) {
  // scripting
} else if (ListContains (player.condition_list, "dead")) {
  // scripting
} else {
  if (ListContains (player.condition_list, "poisoned")) {
    // scripting
  }
  if (ListContains (player.condition_list, "confused")) {
    // scripting
  }
  if (ListContains (player.condition_list, "bleeding")) {
    // scripting
  }
}

if you want/need to have multiple statuses at the same time, then alternatively (if using Lists/Dictionaries is too complicated/confusing), you can use Boolean Attributes:

player.normal = true
player.poisoned = false
player.bleeding = false
player.dead = false
player.confused = false
// you're normal

player.normal = false
player.poisoned = false
player.bleeding = false
player.dead = true
player.confused = false
// you're dead

player.normal = false
player.poisoned = true
player.bleeding = true
player.dead = false
player.confused = false
// you're poisoned and bleeding

player.normal = false
player.poisoned = true
player.bleeding = true
player.dead = true
player.confused = true
// you're dead, poisoned, bleeding, and confused (despite being dead, you still also have the statuses of poisoned, bleeding, and confused, so for example, if you got revived back to life, you'd still suffer from poisoning, bleeding, and confusion)

and then a simple example of handling it:

using either:

  1. a 'Turnscript' Element
  2. a 'Timer' Element
  3. the special 'changed' Script Attribute
  4. a specific action, such as via a Verb or Command

and for the scripting within:

(using a design structure for if you don't allow being dead and having another status)
(same as with the List/Dictionary example above)

if (player.normal) {
  // scripting
} else if (player.dead) {
  // scripting
} else {
  if (player.poisoned) {
  // scripting
  }
  if (player.confused) {
  // scripting
  }
  if (player.bleeding) {
  // scripting
  }
}

if any of your statuses cause/do an equation/formula or whatever else that needs to be undone to return to normal, for its action, then you got to have another instance/action that does the reverse, to be able to return it back to normal (the "cancel" effect):

see pixie's libraries, such as reading about the "cancel effects / secondary actions"

https://github.com/ThePix/quest/wiki/CombatLib-Part-08:-Lasting-Spells
https://github.com/ThePix/quest/wiki/CombatLib-Part-09:-Instant-Spells
(and probably more sections as well)

here's pixie's home page: https://github.com/ThePix/quest/wiki


and for any statuses with a scale, simply also have an Integer Attribute for it (and possibly you'd also want/need a String Attribute too), here's an simple example:

player.condition = "radiation"

player.radiation_integer_attribute = 0

player.radiation_string_attribute = "zero radiation"

// if you want/need max/min bounds (for this example: 0 to 100):

if (player.radiation_integer_attribute > 100) {
  player.radiation_integer_attribute = 100
} else if (player.radiation_integer_attribute < 0) {
  player.radiation_integer_attribute = 0
} 

------------

// not the best design (redundant code), but I think/hope it'll be easier for you to understand:

// (also, I'm skipping some scale amounts, as I don't want to do that much work, lol)

if (player.radiation_integer_attribute = 100) {
  msg ("You're dead, killed from your radiation sickness")
  msg ("GAME OVER")
  finish
} else if (player.radiation_integer_attribute > 90) {
  player.radiation_string_attribute = "You're on the verge of death from radiation sickness"
  foreach (stat_string_attribute, stat_object.stat_list) {
    if (player.stat_string_attribute >= player.radiation_integer_attribute) {
      player.stat_string_attribute = player.stat_string_attribute - player.radiation_integer_attribute
      //
      // example:
      //
      // player.strength_integer_attribute = 100
      // player.radiation_integer_attribute = 93
      // player.strength_integer_attribute = player.strength_integer_attribute - player.radiation_integer_attribute
      // player.strength_integer_attribute = [100] - [93]
      // player.strength_integer_attribute = 7
      //
      // player.endurance_integer_attribute = 99
      // player.radiation_integer_attribute = 95
      // player.endurance_integer_attribute = player.endurance_integer_attribute - player.radiation_integer_attribute
      // player.endurance_integer_attribute = [99] - [95]
      // player.endurance_integer_attribute = 4
      //
      // etc etc etc (all/every stat = for*EACH*)
      //
    } else {
      player.stat_string_attribute = 0
      //
      // example:
      //
      // player.strength_integer_attribute = 30
      // player.radiation_integer_attribute = 93
      // player.strength_integer_attribute = 0
      //
    }
  }
} else if (player.radiation_integer_attribute > 70) {
  player.radiation_string_attribute = "You're severly suffering from your radiation sickness"
  foreach (stat_string_attribute, stat_object.stat_list) {
    if (player.stat_string_attribute >= player.radiation_integer_attribute) {
      player.stat_string_attribute = player.stat_string_attribute - player.radiation_integer_attribute
    } else {
      player.stat_string_attribute = 0
    }
  }
} else if (player.radiation_integer_attribute > 10) {
  player.radiation_string_attribute = "You're just starting to feel the symptoms of radiation sickness"
  foreach (stat_string_attribute, stat_object.stat_list) {
    if (player.stat_string_attribute >= player.radiation_integer_attribute) {
      player.stat_string_attribute = player.stat_string_attribute - player.radiation_integer_attribute
    } else {
      player.stat_string_attribute = 0
    }
  }
} else {
  player.radiation_string_attribute = "You're clean (zero radiation count)"
}

msg (player.radiation_string_attribute)

a more simple example:

alignment:

0-33: evil
34-66: neutral
67-100: good

// initial/starting Attributes:
player.alignment_integer_attribute = 50
player.alignment_string_attribute = "neutral"

<object name="player">

  <attr name="alignment_string_attribute" type="string">neutral</attr>

  <attr name="alignment_integer_attribute" type="int">50</attr>

  <attr name="changedalignment_integer_attribute" type="script">

    <![CDATA[

      if (this.alignment_integer_attribute > 66) {
        this.alignment_string_attribute = "good"
      } else if (this.alignment_integer_attribute > 33) {
        this.alignment_string_attribute = "neutral"
      } else {
        this.alignment_string_attribute = "evil"
      }

    ]]>

  </attr>

</object>

// high to low example:

if (test.score >= 90) {
  test.grade = "A"
} else if (test.score >= 80) {
  test.grade = "B"
} else if (test.score >= 70) {
  test.grade = "C"
} else if (test.score >= 60) {
  test.grade = "D"
} else {
  test.grade = "F"
}

----------------

// high to low alternative (fewer operations, more efficient) example:

if (test.score > 89) {
  test.grade = "A"
} else if (test.score > 79) {
  test.grade = "B"
} else if (test.score > 69) {
  test.grade = "C"
} else if (test.score > 59) {
  test.grade = "D"
} else {
  test.grade = "F"
}

-----------------

// low to high example:

if (test.score < 60) {
  test.grade = "F"
} else if (test.score < 70) {
  test.grade = "D"
} else if (test.score < 80) {
  test.grade = "C"
} else if (test.score < 90) {
  test.grade = "B"
} else {
  test.grade = "A"
}

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums