[Solved] Problems running custom commands with other scripts

Hi bit of a beginner here and I'm stuck trying to get custom commands running with other scripts. For example I have a custom command fight with the command pattern fight #object# which initiates the very basic combat system I have made. This works fine when I have the player input "fight orc" for example, but I would like to have combat initiated at other times, eg the player enters a room and a script starts the fight process automatically.

I have tried using the do script so that when a player enters the room the script runs (do (orc, "fight") for example) but that produces an "Object reference not set to an instance of an object" error. Is there a way to replicate the player typing "fight orc" using a script?

Many thanks for your help.


(filler for getting my edited post, updated/posted)


HK edit: changed the 'do (XXX)' to 'rundelegate (XXX)' for the 2nd code sample, which uses Objects+Script_Attribute+Delegate, as I forgot to switch it over until just now (sorry about that).


there's probably a way to do/call/use/activate a Command, but I'm not sure how it's done... others may be able to help you with it... you can try this...

(replace my upper-case with your coding's labeling/naming)

do (NAME_OF_COMMAND, "script")
// or:
do (NAME_OF_COMMAND, "script", NAME_OF_MONSTER)


alternative methods would be to have your 'fight' Command's scripting be within either: a Function or an Object+Script_Attribute+(optional: Delegate):

simple example (using a Function):

<object name="room">
</object>

<object name="player">
  <inherit name="editor_object" />
  <inherit name="editor_player" />
  <attr name="parent" type="object">room</attr>
</object>

<object name="orc">
  <inherit name="monster_type" />
  <attr name="parent" type="object">room</attr>
</object>

<object name="ogre">
  <inherit name="monster_type" />
  <attr name="parent" type="object">room</attr>
</object>

<type name="monster_type">
  <attr name="fight" type="script">
    fight_function (this)
  </attr>
</type>

<command name="fight_command">
  <pattern>fight #object#</pattern>
  <script>
    fight_function (object)
  </script>
  <unresolved>Error: Object not found within the current room</unresolved>
</command>

<function name="fight_function" parameters="enemy_object_parameter">
  // your fight function's scripting using 'enemy_object_parameter'
</function>

<verb>
  <property>fight</property>
  <pattern>fight</pattern>
  <defaultexpression>You can't fight that!</defaultexpression>
</verb>

simple example (using an: Object + Script Attribute + Delegate):

<delegate name="fight_delegate" parameters="enemy_object_parameter" />

<game name="example_game">
</game>

<object name="room">
</object>

<object name="player">
  <inherit name="editor_object" />
  <inherit name="editor_player" />
  <attr name="parent" type="object">room</attr>
</object>

<object name="orc">
  <inherit name="monster_type" />
  <attr name="parent" type="object">room</attr>
</object>

<object name="ogre">
  <inherit name="monster_type" />
  <attr name="parent" type="object">room</attr>
</object>

<object name="fight_object">
  <attr name="fight_script_attribute" type="fight_delegate">
    // your fight scripting using 'enemy_object_parameter'
  </attr>
</object>

<type name="monster_type">
  <attr name="fight" type="script">
    rundelegate (fight_object, "fight_script_attribute", this)
  </attr>
</type>

<command name="fight_command">
  <pattern>fight #object#</pattern>
  <script>
    rundelegate (fight_object, "fight_script_attribute", object)
  </script>
  <unresolved>Error: Object not found within the current room</unresolved>
</command>

<verb>
  <property>fight</property>
  <pattern>fight</pattern>
  <defaultexpression>You can't fight that!</defaultexpression>
</verb>

K.V.

It's not a clone of an orc, is it?


Thank you for your quick reply. I tried the variations of thedo (NAME_OF_COMMAND, "script") you suggested but no luck. I think the idea of putting the fight scripting into a function is probably the way to go (I've not had any experience with Object+Script_Attribute+(optional: Delegate)).

Thanks again, I'll post back if I get the function version working.


Hi K.V, no it's unique orc (eg orc1). I've tried with other objects as well and still have the same problem.


K.V.

See if this example game helps you.

I am cloning an orc, but the script will work on the original orc as well. (So, it doesn't matter if you're using clones or not.)

<!--Saved by Quest 5.8.6590.33649-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Orc Fight">
    <gameid>c92ed3ee-24d4-4aac-ba77-e3de5d58a7ff</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <beforeenter type="script">
      clone = CloneObjectAndMoveHere(orc)
      clone.proto = orc
      clone.alias = "orc clone"
    </beforeenter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="orc">
      <inherit name="editor_object" />
      <look type="script">
        if (HasAttribute(this,"fallen") and GetBoolean(this,"fallen")) {
          msg ("The orc is out cold.")
        }
        else {
          msg ("The orc looks like it wants to {command:fight orc:fight}!")
        }
      </look>
      <fight type="script"><![CDATA[
        if (HasAttribute(this,"fallen") and GetBoolean(this,"fallen")) {
          msg ("The orc is already down.")
        }
        else {
          msg ("You attack the orc.")
          if (RandomChance(75)) {
            msg ("<br/>The orc falls.")
            this.alias = "fallen orc"
            this.fallen = true
          }
        }
      ]]></fight>
    </object>
  </object>
  <command name="fight_cmd">
    <pattern>fight #object#</pattern>
    <unresolved>You can't fight something that isn't here.</unresolved>
    <script>
      if (HasAttribute(object,"fight")) {
        do (object, "fight")
      }
      else {
        msg ("You can't fight "+object.article+".")
      }
    </script>
  </command>
</asl>

Thank you for everyone's help, I managed to get it working (as hegemonkhan suggested) by moving my fight script from the custom command fight to a function, and then calling the function whenever I needed to initiate combat. Thank you both for you sample game codes, I've learned lots from going through them!


Thank you for your quick reply. I tried the variations of the do (NAME_OF_COMMAND, "script") you suggested but no luck. I think the idea of putting the fight scripting into a function is probably the way to go (I've not had any experience with Object+Script_Attribute+(optional: Delegate)).

The problem with do (NAME_OF_COMMAND, "script") is that the object variable has not been set. Commands do this behind the scenes, from the command pattern #object#.

However, you can do that by sending a dictionary.

d = NewDictionary()
dictionary add (d, "object", orc)
do (NAME_OF_COMMAND, "script", d)

All that said, doing it as a function is probably easier!


ah, so you use a Dictionary for the Object's setting, for using a Command, thank you Pixie! (need to save/bookmark/favorite this post, lol)


K.V.

I've been following Pixie's Zombie Apocalypse guide*, and I wish I'd have read these last two posts before I fooled with it today.

I just fought that battle with do, and trying to pass the object variable to it did not work out. So, like Pix suggested here, I ended up using a function.

  <command name="reload_command">
    <pattern>reload</pattern>
    <script>
      if (HasAttribute(game.pov,"equipped")) {
        if (HasAttribute(game.pov.equipped,"ammo")) {
          object = game.pov.equipped
          if (game.debugging) {
            DbgMsg ("reload script: setting object to "+object)
          }
          ReloadIt (object)
        }
        else {
          msg ("You don't have that sort of a weapon equipped.")
        }
      }
      else {
        msg ("You haven't equipped a weapon.")
      }
    </script>
  </command>
  <command name="reload_object_cmd">
    <pattern>reload #object#</pattern>
    <script>
      ReloadIt (object)
    </script>
  </command>
  <type name="region_type" />
  <type name="room_type" />
  <function name="ReloadIt" parameters="object"><![CDATA[
    if (game.debugging) {
      DbgMsg ("ReloadIt: object = "+object)
    }
    if (not HasInt(object, "ammo")) {
      msg ("You can't reload a " + GetDisplayAlias(player.equipped) + ".")
    }
    else if (player.ammo < 1) {
      msg ("You have no ammo.")
    }
    else {
      bullets = object.ammomax - object.ammo
      if (bullets > player.ammo) {
        bullets = player.ammo
      }
      player.ammo = player.ammo - bullets
      object.ammo = object.ammo + bullets

      if (bullets > 0){
        msg ("You put " + bullets + " bullets in it.")
      }
      else {
        msg("You can't fit any more bullets in it.")
      }
    }
    WeaponUpdate
  ]]></function>

* Scripts from Pixie's guide are slightly modified.


REVISED SCRIPTS (just for archival purposes):

<command name="reload_cmd">
    <pattern>reload #object#;load #object#;reload;reload</pattern>
    <script>
      if (not IsDefined("object")) {
        if (HasAttribute(game.pov,"equipped")) {
          if (HasAttribute(game.pov.equipped,"ammo")) {
            object = game.pov.equipped
            if (game.debugging) {
              DbgMsg ("reload script: setting object to "+object)
            }
            ReloadWeapon (object)
          }
          else {
            msg ("You don't have that sort of a weapon equipped.")
          }
        }
        else {
          msg ("You have no weapon equipped.")
        }
      }
      else {
        if (HasAttribute(object,"ammo")) {
          ReloadWeapon (object)
        }
        else {
          msg ("You can't reload "+object.article+".")
        }
      }
    </script>
  </command>
<function name="ReloadWeapon" parameters="object"><![CDATA[
    if (game.debugging) {
      DbgMsg ("ReloadWeapon: object = "+object)
    }
    if (not HasInt(object, "ammo")) {
      msg ("You can't reload a " + GetDisplayAlias(player.equipped) + ".")
    }
    else if (player.ammo < 1) {
      msg ("You have no ammo.")
    }
    else {
      cartridges = object.ammomax - object.ammo
      if (cartridges > player.ammo) {
        cartridges = player.ammo
      }
      player.ammo = player.ammo - cartridges
      object.ammo = object.ammo + cartridges
      if (cartridges = 1) {
        msg (cartridges + " cartridge:  Loaded.")
      }
      if (cartridges > 1) {
        msg (cartridges + " cartridges:  Loaded.")
      }
      else {
        msg (object.article+" is fully loaded.")
      }
    }
    WeaponUpdate
  ]]></function>

K.V.

Today MrAngel taught me how to use IsDefined() properly, and I devised a dirty way to use do() to invoke a script with the local variable object in it.

You can enter SLAP or SLAP #object#.

Example game:

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="SLAP">
    <gameid>f187b2c5-6dad-48ee-991c-7c5d401a782b</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <defaultwebfont type="string"></defaultwebfont>
    <start type="script">
      SetWebFontName ("Patrick Hand")
      SetWebFontName (game.defaultfont)
    </start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <object name="nametag">
        <inherit name="editor_object" />
        <ondrop type="script">
        </ondrop>
        <take />
        <look type="script"><![CDATA[
          msg ("It reads:<br/><center><br/><div style=';border:1px solid black'><span style='font-weight:bold;font-size:110%'>Hello!  My name is:<span style='font-family:\"Patrick Hand\";font-size:135%;'><hr style='border-top:1px solid black' />XanMag</span></span></div></center>")
        ]]></look>
        <feature_usegive />
        <giveto type="scriptdictionary">
          <item key="XanMag">
            MoveObject (this, XanMag)
            msg ("\"Thanks!\"  says XM.  \"I've been looking for that!\"")
            this.alias = "nametag (worn)"
            this.take = false
            this.takemsg = "\"Leave my nametag alone, please,\" says XM."
          </item>
        </giveto>
        <alt type="stringlist">
          <value>tag</value>
        </alt>
        <inventoryverbs type="stringlist">
          <value>Look at</value>
          <value>Wear</value>
          <value>Drop</value>
        </inventoryverbs>
      </object>
    </object>
    <object name="XanMag">
      <inherit name="editor_object" />
      <inherit name="namedmale" />
      <inherit name="surface" />
      <look>He's drinking a beer.</look>
      <feature_container />
      <listchildren />
      <contentsprefix>who is carrying</contentsprefix>
      <addscript type="script">
        msg ("\"Get that off me!\" booms XanMag.{once:  He slaps you.}")
      </addscript>
      <listchildrenprefix>He is carrying</listchildrenprefix>
      <take />
      <alt type="stringlist">
        <value>xm</value>
      </alt>
      <speak>{random:"Hello," grumbles Xan.:"I like fish tacos," he says.:"Beer is good," says XM.}</speak>
    </object>
  </object>
  <command name="slap_cmd">
    <pattern>slap</pattern>
    <script>
      if (XanMag.parent = game.pov.parent) {
        do (slap_it_cmd, "script")
      }
      else {
        msg ("XanMag's not here, man!")
      }
    </script>
  </command>
  <command name="slap_it_cmd">
    <pattern>slap #object#</pattern>
    <script><![CDATA[
      if (not IsDefined("object")) {
        object = XanMag
      }
      if (object = XanMag) {
        msg ("You slap XanMag.<br/><br/>He takes a drink of his beer, laughs, then says, \"thank you, sir!  May I have another?\"")
      }
      else {
        msg ("You can't slap "+object.article+".")
      }
    ]]></script>
  </command>
  <command name="wear_cmd">
    <pattern>wear #object#</pattern>
    <script>
      if (object = nametag) {
        msg ("That appears to belong to XanMag.")
      }
      else {
        msg ("You can't wear "+object.article+".")
      }
    </script>
  </command>
</asl>

not quite however, as you can't dynamically get/pass/insert a value for the 'object' variable from the 'do' function call.

looks like the only way is via using a Dictionary as the argument's/parameter's value


K.V.

not quite however

I said it was dirty...

...but I am using do() to call a script which uses the object variable without passing it.

  <command name="slap_cmd">
    <pattern>slap</pattern>
    <script>
      if (XanMag.parent = game.pov.parent) {
        do (slap_it_cmd, "script")
      }
      else {
        msg ("XanMag's not here, man!")
      }
    </script>
  </command>
  <command name="slap_it_cmd">
    <pattern>slap #object#</pattern>
    <script><![CDATA[
      if (not IsDefined("object")) {
        object = XanMag
      }
      if (object = XanMag) {
        msg ("You slap XanMag.<br/><br/>He takes a drink of his beer, laughs, then says, \"thank you, sir!  May I have another?\"")
      }
      else {
        msg ("You can't slap "+object.article+".")
      }
    ]]></script>
  </command>

K.V.

How about creating a temporary attribute?

(Yes. I'm bored.)

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Do things">
    <gameid>c4a82a07-95b9-4641-9e1e-4975aa275c51</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="puddle">
      <inherit name="editor_object" />
      <displayverbs type="stringlist">
        <value>Look at</value>
      </displayverbs>
      <jumpable />
    </object>
  </object>
  <command name="jump_over_it_cmd">
    <pattern>jump over #object#</pattern>
    <script>
      if (not IsDefined("object")) {
        if (TypeOf(game.tempobject)="object") {
          object = game.tempobject
        }
        else {
          msg ("You can't do that.")
          return (false)
        }
      }
      if (HasBoolean(object,"jumpable")) {
        if (object.jumpable) {
          msg ("You jump over "+object.article+".")
        }
        else {
          msg ("You can't jump over "+object.article+".")
        }
      }
      else {
        msg ("You can't do that.")
      }
    </script>
  </command>
  <command name="jump_over_cmd">
    <pattern>jump over</pattern>
    <script><![CDATA[
      thingstojump = NewObjectList()
      foreach (o, ScopeVisibleNotHeld()) {
        if (HasBoolean(o,"jumpable")) {
          if (o.jumpable) {
            list add (thingstojump, o)
          }
        }
      }
      if (ListCount(thingstojump)>0) {
        game.tempobject = PickOneObject(thingstojump)
        do (jump_over_it_cmd, "script")
        SetTurnTimeout (1) {
          game.tempobject = null
        }
        return (true)
      }
      msg ("There is nothing to jump over.")
    ]]></script>
  </command>
</asl>

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

Support

Forums