Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
loopy
Newbie


Joined: 23 Oct 2007
Posts: 4

PostPosted: Tue Oct 23, 2007 10:19 am   

Unusual Database Scripting
 
Hi, I have been trying to capture a multi line output of a "lore scroll" used on my mud. However, because of the unusual formatting of the output, I am having setting up the script properly. The result is that records in the database suddenly change to 0 and the data has to be re-entered manually. An example would be as follows:

Object 'robe blood stained robes'
Item Type: WORN
Mat Class: cloth Material: wool
Weight : 2 Value : 300

Affects : SAVING_SPELL by -1
Affects : STR by -1
Item is : MAGIC ANTI_GOOD

There are inherently several problems capturing this output. Firstly there is a break in the middle of the information causing my {$} trigger to fire prematurely. Secondly, Affects and by are listed twice so I am unsure on how to parse the data into thier own fields. The current script I am attempting to use is the following:

<!-----------------------------------Start Alias Definition--------------------->
#ALIAS identify {
#t+ identify
recite lore %1
}
<!----------------------------------End Alias Definition------------------------>

<!----------------------------------Start Class Definition---------------------->
#CLASS {identify}
<!---------------------------------End Class Definition------------------------>

<!---------------------------Main Trigger Definitions-------------------------->
#TRIGGER Object '(&item.name)' {}
#TRIGGER Item Type: (&item.type) {}
#TRIGGER Mat Class: (&item.matclass) Material: (&item.material) {} <------Two values on same line
#TRIGGER Weight : (&item.weight) Value : (&item.value) {}
#TRIGGER Affects : (&item.affects) by (&item.by) {}
#TRIGGER Item is : (&item.is) {}
#TRIGGER Restricts: (&item.restricts) {}
#TRIGGER Apply : (&item.apply) {}
<!-----------------End Main Trigger Definitions------------------------------->

<!-----------------Final Trigger Fires-------------------------------------------->
#TRIGGER {$} {
#if (%find( @item.name) = "") {#new "" @item}
#t- identify
}
#CLASS 0
<!-----------------End Final Trigger---------------------------------------------->

There is also an instance where multiple peices of data are on the same line. I tried putting both values on the same line seperating them with a # but that had little effect. I was also thinking of trying to define them as variables. i.e. %1 and %2 but I thought it best to check the forums first to gain input from more experienced scripters. Thank you for any suggestions and/or corrections that you may have.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Tue Oct 23, 2007 11:40 am   
 
The %nn variables probably won't help you here. I personally never use the &variable syntax - I like using specific wildcards - but this is one situation where that won't help.

Firstly, the newline problem, because that's simple enough. Use a multistate trigger:

#TRIGGER {$} {}
#COND {$} {
#if (%find( @item.name) = "") {#new "" @item}
#t- identify
}

This'll only fire after you've received two blank lines instead of one.

Your main problem obviously stems from the fact that your first affect is getting overwritten by the second. If you always have two affects and two affects only and the lines always follow each other, just create another field for the second affect and use another multistate trigger and another database field:

#TRIGGER {Affects : (&item.affects) by (&item.by)} {}
#COND {Affects : (&item.affects2) by (&item.by2)} {} {within|param=1}

If your items can have a variable number of affects, it's going to be more complex.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
loopy
Newbie


Joined: 23 Oct 2007
Posts: 4

PostPosted: Tue Oct 23, 2007 5:07 pm   
 
These are excellent answers and I think they will work well. I am still a little confused about two items on the same line though. For example:

#TRIGGER Mat Class: (&item.matclass) Material: (&item.material) {}
---------------^-------------------------------^-----------------------------------

What my crudely drawn arrows are trying to show is that sometimes I have to capture two entries from a line. Is there a delimiter necessary for CMUD to understand that two different entries on a single line go to two independent fields? Thus far, my trigger has been capturing both entries and dupkicating them in the fields

matclass metal gold
material metal gold

instead of

matclass metal
material gold
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Tue Oct 23, 2007 5:59 pm   
 
There's not much I can say except that it shouldn't be doing that. Perhaps it's a new bug?

You could try something like

#trig {Mat Class: (%w) Material: (%w)} {item.matclass = %1;item.material - %2}

instead.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
loopy
Newbie


Joined: 23 Oct 2007
Posts: 4

PostPosted: Tue Oct 23, 2007 8:06 pm   
 
I believe you are right. It is most likely due to syntax which I will review line by line. CMUD has ran pretty well on Vista so far. I am really impressed with how many features it has and the CMUD forum moderators are very smart and helpful as well. Thank you for all of your help I will repost if I find anything new. Mr. Green
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: Tue Oct 23, 2007 10:19 pm   
 
I have similar output from the 'identify <object>' command on my MUD. It doesn't have the issue of internal blank lines, so my script terminates capture on a blank line or a prompt (line starting with '<'). The adaptations shown above would work fine.

As for the multiple AFFECTs, try storing them as a db variable, as shown below. Works for any number of lines. (Actually, my script stores SOME properties in specific named variables, and stores anything else it finds into a catchall db of name-value pairs).

Sample output from my MUD:
Code:

You feel informed.
Object "dusty-worn-arm-bands", Item type: Armor
Item is: Invisible Secured
Weight: 5, Volume: 50, Value: 40000 [Rare]
Durability and Armor Rating is 14.
Can affect you as:
Affects Damroll by 2.
Affects Strength by 12.
Affects Armor by -5.
Affects Saving Paralyzation by -3.
Affects Necromancy by 5.

You feel informed.
Object "evasion-stave", Item type: Staff
Item is: Glow Magic Bless Donated
Weight: 4, Volume: 688, Value: 0 [Rare]
Has 0 charges, with 9 charges left.
Level 99 spell of Doppelganger
Can affect you as:
Affects Hit-N-Dam by 1
Affects Armor by -25
Affects Dodge by 10
Affects Lose by 25

You feel informed.
Object "sorcery axe", Item type: Throwable Axe
Item is: Anti-Thief Anti-Warrior
Weight: 14, Volume: 275, Value: 5000
Damage Dice is 3d9
Can affect you as:
Affects Mana by -100


My (still in zMUD, but soon to be adapted to CMUD) script:
Code:
#CLASS {QLib|Ident} {setdef}
#TR idtrig {^You feel informed.$} {
  #say Capturing object information - QLib
  #var obj {%null} {} {QLib|Ident}
  #t+ {QLib|Ident|Capture}
}
#AL eqstore {
  #var force {%1} {}
  #var idx {%2} {}
  #dboffline
  #dbload eq
  #if (@force) {
    #if (@force = "add") {
      #say Forcing add of @lastident.Name
      #new All @lastident
    }
    #if (@force = "over") {
      #dbget @idx
      #if (@lastident.Name = &Name) {
   #say Overwriting @idx
        #dbput @idx @lastident
      } {
        #say Last object name doesn't match that ID!
   #sayp "Last: "
   eqshowshort @lastident
   #sayp @idx": "
   eqshowshort %rec
      }
    }
  } {
    #var matches {%find(@obj.Canon,"All")} {}
    #if (@matches) {
      #var lastident {@obj} {}
      #say Item @obj.name already in DB:
      #forall @matches {
        #dbget %i
   #sayp %i": "
   eqshowshort %rec
      }
      #say Use 'eqstore over <id>' to overwrite or 'eqstore add' to force a new record.
    } {
      #say Storing item @obj.Name
      #new All @obj
      #dbsave
    }
  }
  #dbonline
  #say
}
#CLASS {QLib|Ident|Capture} {disable}
#TR {^Object "(%*)", Item type: (%*)$} {
  obj.Name=%replace(%1," ","-")
  obj.Canon=%replace(%sort(%replace(@obj.Name,"-","|")),"|","-")
  #if (%word(%2,1)="Throwable") {
    obj.Type=%word(%2,2)
    obj.Throwable="Y"
  } {
    obj.Type=%2
    obj.Throwable="N"
  }
}
#TR {^Item is: (%*)~.$} {
  obj.Flags=%replace(%1," ","|")
  #delitem obj.Flags Donated
  #delitem obj.Flags Secured
  #delitem obj.Flags None
}
#TR {^Weight: &%n{obj.Weight}, Volume: &%n{obj.Volume}, Value: &%n{obj.Value}(%*)$} {
  #if (%literal(%4)=%literal([Rare])) {#additem obj.Flags Rare}
  #if (%literal(%4)=%literal([Unrentable])) {#additem obj.Flags Norent}
}
#TR {^Durability} {}
#COND {^Durability is &%n{obj.Durability}.} {} {reparse}
#COND {Damage Dice is &%x{obj.Damage}~.$} {} {reparse}
#COND {^Durability and Armor Rating is (%n).$} {
  obj.Durability=%1
  obj.Armor=%1
} {reparse}
#TR {^Has &%n{obj.Charges} charges, with (%*) charges left.} {}
#TR {^Level &%n{obj.CSL} spell* of (%*).$} {
  obj.CS=%replace(%replace("%2",", ","|",)" ","-")
}
#TR AffectTrig {Affects (%*) by (%*).$} {#var oa 1 {}}
#COND {Affects Hit Points by &%n{obj.HP}.$} {oa=0} {reparse}
#COND {Affects Mana by &%n{obj.Mana}.$} {oa=0} {reparse}
#COND {Affects Movement by &%n{obj.Move}.$} {oa=0} {reparse}
#COND {Affects Hitroll by &%n{obj.Hitroll}.$} {oa=0} {reparse}
#COND {Affects Damroll by &%n{obj.Damroll}.$} {oa=0} {reparse}
#COND {Affects Hit-N-Dam by (%n).$} {
  obj.Hitroll=%1
  obj.Damroll=%1
  oa=0
} {reparse}
#COND {Affects Weapon Spell by (%*) at Level &%n{obj.WSL}.$} {
  #additem obj.WS %replace(%1," ","-")
  oa=0
} {reparse}
#COND {Affects Weapon Spell by (%*) at Character Level.$} {
  #additem obj.WS %replace(%1," ","-")
  obj.WSL=0
  oa=0
} {reparse}
#COND {Affects Spell Affect by (%*).$} {
  #additem obj.SA %replace(%1," ","-")
  oa=0
} {reparse}
#COND {Affects Eat Spell by (%*).$} {
  #additem obj.CS %replace(%1," ","-")
  oa=0
} {reparse}
#COND {Affects Weapon Spell Chance by &%n{obj.WSC}~%.$} {oa=0} {reparse}
#COND {Affects Armor by &%n{obj.AC}.$} {oa=0} {reparse}
#COND {Affects Strength by &%n{obj.Str}.$} {oa=0} {reparse}
#COND {Affects Intelligence by &%n{obj.Int}.$} {oa=0} {reparse}
#COND {Affects Wisdom by &%n{obj.Wis}.$} {oa=0} {reparse}
#COND {Affects Dexterity by &%n{obj.Dex}.$} {oa=0} {reparse}
#COND {Affects Constitution by &%n{obj.Con}.$} {oa=0} {reparse}
#COND {Affects Immunity by (%*).$} {
  #additem obj.Imm %1
  oa=0
} {reparse}
#COND {Affects Resistance by (%*).$} {
  #additem obj.Res %1
  oa=0
} {reparse}
#COND {Affects Susceptibility by (%*).$} {
  #additem obj.Sus %1
  oa=0
} {reparse}
#COND {Affects (%*) by (%*).$} {
  #if (@oa) {
    #var oadb {@obj.OA} {}
    #if (%2 > 0) {
      #addkey oadb %replace(%1," ","-") "+"%2
    } {
      #addkey oadb %replace(%1," ","-") %2
    }
    obj.OA=@oadb
  }
} {reparse}
#TR idendtrig1 {^$} {idend}
#TR idendtrig2 {^<} {idend}
#AL idend {
  #t- {QLib|Ident|Capture}
  #var lastident {@obj} {} ./QLib/Ident
  eqstore
}
#CLASS 0
#t- {QLib|Ident|Capture}


BTW, the reason that I create the canonical name of the object (obj.Canon) is for lookup purposes, so that I can find an object with only parts of the object name (those aliases not shown). Also note that the 'eqstore' alias checks for conflicts before it stuffs all the data into my database.

Anyway, as noted it's still a zMUD script, but it should give you a good idea of how something like this can be put together. I can't speak to the possible bugs with captures of more than one item per line....but you can see that the triggers are capturing multiple values as you expected. Hopefully this will continue to work in CMUD. And I'll be porting it over to CMUD soon (probably in 2.x).
_________________
Come visit Mozart Mud...and tell an imm that Aerith sent you!
Reply with quote
loopy
Newbie


Joined: 23 Oct 2007
Posts: 4

PostPosted: Tue Oct 30, 2007 8:33 am   
 
You know that long a** code was kinda what I was looking for. It poses as a great reference to study and adapt. The way the code is set up now it seems to capture some of the information and then send it to a variable instead of to the database itself. I am not entirely sure why it does this so I am still playing with the script. It might be nice if you could post your script after you convert it over to cmud. Maybe it will help give more ideas on top of the already great ones we had so far :-)
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: Tue Oct 30, 2007 11:36 pm   
 
loopy wrote:
You know that long a** code was kinda what I was looking for. It poses as a great reference to study and adapt. The way the code is set up now it seems to capture some of the information and then send it to a variable instead of to the database itself. I am not entirely sure why it does this so I am still playing with the script. It might be nice if you could post your script after you convert it over to cmud. Maybe it will help give more ideas on top of the already great ones we had so far :-)


Well, that's pretty much why I posted it. I'll be happy to post the new one when I get it converted (but no promises about timeframe yet). I'll probably publish my whole set of scripts as one or two packages for MozartMUD eventually.

To address your question about the variable: The script has a medium-sized pile of triggers that each catch a handful of useful bits of info and stick them into a variable. Specifically into a db-record variable (named 'obj'), which is correctly formatted to be sent to the db functions. (So it's not really capturing 'some of the information' to a variable, it's capturing ALL of the information to a variable.) Then there are a pair of triggers that catch the end-of-object-info condition (either a blank line or my prompt), and call 'idend', which takes that 'obj' variable and actually crams it into the DB using 'eqstore'.

Also note that you can throw away most or all of the #COND statements that deal with Affects lines if you don't care about keeping specific Affects in named columns in the DB. In my case, for instance, I want to be able to filter my DB to show, say, only weapons with Damroll > +2 and a non-empty weapon-spell, so those specific Affects are stuck into named fields in the 'obj' variable, and thus into named columns in the DB. If you don't care, just use the single trigger for Affects lines, and they will ALL wind up in a big list variable.

One more side note: in a number of places, I go through and replace all spaces with dashes. That's a bit of candy for my MUD (which likes to deal with spell names such as "fire-wind", but prints them in the ID output as "fire wind"). The replacement may not be required, or even appropriate, for your MUD.
_________________
Come visit Mozart Mud...and tell an imm that Aerith sent you!
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net