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
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Fri Dec 31, 2010 5:54 pm   

Affected By _ checker & caster
 
Hi everyone,... I've spent the last couple of days pouring through posts trying to find a workable solution to what I am trying to do, but as of yet, am unable...

What I want to do is check my "Affected By" list to see what it is that I am affected by... I created a new class called "Affected By Spells" then created integer variables of some of the basic spells, so that they could be set to a simple 0 or 1, for off or on, e.g.:

@dragonwit
@ogremight
@elvenbeauty
@slink
@sagacity
@trollishvigor

Then I created a trigger to check the "Affected By" list to see which spells I in fact am affected by, then set those variables to either on or off... Since Cmud apparently does not have an "else" command built into it, I was forced to first set all of the variables to off and then check to see whether or not they are on and change them to on, if in fact they are on...:

#VAR @sagacity 0
#VAR @dragonwit 0
#VAR @ogremight 0
#VAR @trollishvigor 0
#VAR @slink 0
#VAR @elvenbeauty 0
#SEND af
#IF (Affected: ~"sagacity") {@sagacity 1}
#IF (Affected: ~"dragon wit") {@dragonwit 1}
#IF (Affected: ~"ogre might") {@ogremight 1}
#IF (Affected: ~"trollish vigor") {@trollishvigor 1}
#IF (Affected: ~"slink") {@slink 1}
#IF (Affected: ~"elven beauty") {@elvenbeauty 1}

Unfortunately when I test this above code, it does not change the variable value, but outputs this on the screen instead:

0 1
0 1
0 1
0 1
0 1
0 1

The next step will be of course to check all of the variables inside of the "Affected by Spells" class to see which ones are set to 0, then cast the ones that are off...

Can anyone help me on this, what am I doing wrong in setting these variable values?
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Fri Dec 31, 2010 6:55 pm   
 
You are doing a lot of things wrong here:

1)#VAR @sagacity 0

When referencing variables in #command syntax, you do not use the @ unless the variable you are referencing is the value of the variable, ahem, referenced. Since there's probably nothing in @Sagacity yet, you were actually trying to assign 0 to a variable with a blank name instead of to the Sagacity variable.

2)#IF (Affected: ~"sagacity") {@sagacity 1}

Everything in red in the above code needs to follow the rules of expressions and mathematical operators (=, >, >=, etc). Your attempt doesn't at all do so, so effectively it evaluates to non-zero. Since non-zero equates to true, your code produces the 0 1 you see.

3)#IF (Affected: ~"sagacity") {@sagacity 1}

CMud allows for the use of a=b syntax. Like with #1, you do not use the @ but you do need to include the =.

4)#IF (Affected: ~"sagacity") {@sagacity 1} {}

The part is red is the else codeblock for the #IF command. Alternatively, you can skip the entire #IF command in favor of the logical NOT operator: #variable Sagacity !@Sagacity

You demonstrated an interesting result of initiative in trying to figure this out, but you DO need to spend more time with the helpfile. It's what it's there for.
_________________
EDIT: I didn't like my old signature
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Fri Dec 31, 2010 7:12 pm   
 
Thank you, will read the help files and report back my success and/or failure, post trial and error...
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Fri Dec 31, 2010 7:38 pm   
 
Ok, so I read what you said and certainly see how I was not properly assigning variables and I think that I have that understood and properly syntaxed... the problem I'm having now is pattern recognition of the aforementioned...

Here's what I go thus far... (note: I changed the variable names to end with the word "spell", so there wouldn't be any potential violations...)

#SEND af;
#IF (^~"Affected:" %s ~"bless") {blessspell = 1} {blessspell = 0};
#IF (^~"Affected:" %s ~"armor") {armorspell = 1} {armorspell = 0};

and tried this as well as many many other variations...

#SEND af;
#IF (^Affected: %s bless) {blessspell = 1} {blessspell = 0};
#IF (^Affected: %s sagacity) {sagacityspell = 1} {sagacityspell = 0};

From this it is setting all variables to 1, even when the spell is not currently on, giving false positives...

The "af" output looks like this...

<87/87hp 106/118m 250/250mv> af

Affected: bless
Affected: bless
Affected: armor
Reply with quote
mikeC130
Apprentice


Joined: 03 Jul 2006
Posts: 110

PostPosted: Fri Dec 31, 2010 8:40 pm   
 
Your if statements aren't doing anything. IF checks a statement, as in @af = "bless", but you aren't asking it to evaluate anything. Rather, you are looking for a trigger.

To use it as a trigger, you would have #TR {^Affected: &affect} {processing commands here}

You now have a variable (@affect) with the name of the specific affect. You can then use #if to evaluate against your list of spells and set as appropriate. Alternatively, you could set a specific trigger for each possibility.
(for example, #TR {^Affected: bless} {blessspell = 1}

You won't have any "false" command here, since there is no "command if the trigger doesn't fire"

As a note, if you use a single trigger it will trigger multiple times if you get a list of affects, such as your example. Using the If statements you have would end up resetting every spell value except the last one to zero.
It would probably be best to NOT set non-affects to zero within this specific trigger, since you'll lose previous entries. You should have a separate trigger or command to reset them, perhaps as part of an alias that sets the values to zero, enables the triggers, and then calls for the list.

Mike
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Fri Dec 31, 2010 8:53 pm   
 
I guess I was assuming that the IF statement had a built in CONTAINS for pattern matching, thus giving a true or false... because that is really what I am trying to do, is check a line to see if it contains a matching pattern and if so, set a variable to 1 and if not, set it to 0

Like:
#IF (CONTAINS((^) Affected: (%s) sagacity)) {sagacityspell = 1} {sagacityspell = 0}
or
#IF (PATTERN((^) Affected: (%s) sagacity)) {sagacityspell = 1} {sagacityspell = 0}

I guess from what I am seeing though, is that there is no syntax for CONTAINS for pattern matching recognition... just a very basic IF , that has to match or not...

Sorry, I'm used to programming in HTML, Javascript, PHP, .NET... this scripting language is very foreign to me...
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Fri Dec 31, 2010 10:05 pm   
 
It does have a pattern matching operator, but you need to actually tell it what you are matching. It does not automatically try to match against the text captured by the trigger--for one thing, #IF can be used in lots of things besides triggers. You need do an operation or a function which evaluates to TRUE or FALSE within the #IF statement:
#IF (@A = "Affected: sagacity") {whatever}
#IF (@A =~ "^Affected:%ssagacity") {whatever}
#IF (%match(@a,"^Affected:%ssagacity")) {whatever}
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sat Jan 01, 2011 1:05 am   
 
What is this variable "a"?
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Sat Jan 01, 2011 4:41 pm   
 
A variable that you need to create and set the value of. I was just using the @A as an example--you could use any variable name, or use %1 or anything else which carries a value that you want to compare. The point is that you need to actually specify what value you are trying to compare. Which means you need to store that value in a variable, or generate it from a function.
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sat Jan 01, 2011 5:33 pm   
 
This is getting very confusing, there has got to be a way to make this work and I have a feeling that I'm getting way off track...

All I want to do is check my Affected By spells, then recast the ones that aren't there, from say a list or something... That way the spells are always on, and if the spell fails during casting, it would do another check, post casting...

So I'm thinking on the lines of (Pseudo):
A list type variable or perhaps a database with a collection of these spells...
Then a trigger, any trigger, to activate the "Affected By" spells script... and at the end of the script run it again until all of the spells are in the "Affected By"

Obviously of course there are going to be obstacles that I'll have to overcome once this part of the script is functioning, e.g.:
Running out of mana and having to sleep... Setting a timer to check to see if my mana is maxed during my sleep, to then wake me up when it is maxed and then call upon the "Affected By" script again...
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sat Jan 01, 2011 6:23 pm   
 
So I've tried more variations of trying to use the %match than I can even count... Here's some of my latest...

This one always sends a false positive...

#IF (%match("Affected: bless","Affected: bless")) {#SEND test}
as well as this one
#IF ("Affected: bless" = "Affected: bless") {#SEND test}

This one I thought would send a 1 if it was positive and a 0 if not, why would I think that? Because the help file said it would... apparently it just always sends a 1, not sure what that is good for...

#VAR armorspell (%match("Affected: armor","Affected: armor"))
Reply with quote
Fizgar
Magician


Joined: 07 Feb 2002
Posts: 333
Location: Central Virginia

PostPosted: Sat Jan 01, 2011 7:22 pm   
 
This is a crude example that should give you a starting point.

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <class name="SpellupScript" copy="yes">
    <alias name="CheckSpells" copy="yes">
      <value>#loopdb @spells {#addkey spells %key 0}

#send af

//Add a pattern that will match your prompt inbetween the brackets of the #waitfor below.
#waitfor {}

#loopdb @spells {#if (%val = 0) {#send cast %key;#wait 1500}}</value>
    </alias>
    <var name="spells" type="Record" copy="yes">
      <value>armor=0|shield=0|bless=0</value>
      <json>{"armor":0,"shield":0,"bless":0}</json>
    </var>
    <trigger priority="30" copy="yes">
      <pattern>^Affected:%s(*)</pattern>
      <value>#addkey spells %1 1</value>
    </trigger>
  </class>
</cmud>


Cast all the spells you wish to check for and type af. This should populate the @spells database record with the name of the spell as the key and a value of 1.
Open the package editor and click on the CheckSpells alias. On line 8 of the CheckSpells alias there is a #waitfor command followed by empty brackets. Here you will need to supply a pattern that will match your prompt.

If you follow the above steps correctly each time you type checkspells the value of each spell in your @spells Database record will be set to 0, then your affects command will be sent to the MUD. At this time the supplied trigger will set each spell's value in the @spells Database record that you are affected by to 1. Once your prompt is received from the MUD, CMUD will loop through your @spells Database record and for each spell that has a value of 0 (was not on the affects list), CMUD will send cast <spellname> where <spellname> is the key in the @spells Database record that has a value of 0.

Hope that is of some help, and my directions are clear because my head definitely isn't today. :(

*edit*
Correction to alias name, I'm still a bit foggy upstairs. Also simplified the script a bit. I didn't test this much but it should give you a starting place.
_________________
Windows Vista Home Premium SP2 32-bit
AMD Athlon Dual Core 4400+ 2.31 GHz
3 GB RAM
CMUD 3.34

Last edited by Fizgar on Sat Jan 01, 2011 8:23 pm; edited 2 times in total
Reply with quote
Fizgar
Magician


Joined: 07 Feb 2002
Posts: 333
Location: Central Virginia

PostPosted: Sat Jan 01, 2011 7:40 pm   
 
webwired wrote:
This one always sends a false positive...

#IF (%match("Affected: bless","Affected: bless")) {#SEND test}
as well as this one
#IF ("Affected: bless" = "Affected: bless") {#SEND test}

This one I thought would send a 1 if it was positive and a 0 if not, why would I think that? Because the help file said it would... apparently it just always sends a 1, not sure what that is good for...


The correct way to do what you are trying above would be in a trigger similar to one of the two below.

Code:
#tr {^(*)} {#IF (%match(%1,"Affected: bless$")) {#SEND test}}

or
Code:
#tr {^(*)} {#IF (%1 = "Affected: bless") {#SEND test}}


You need to tell CMUD where to look for the text you are trying to match. The above two triggers will check every line that comes from the MUD to see if it starts with Affected: bless. Generally you would want to try to use a pattern that was less greedy. Something similar to the examples below would be better.

Code:
#tr {^Affected: (*)} {#IF (%match(%1,"bless$")) {#SEND test}}

or
Code:
#tr {^Affected: (*)} {#IF (%1 = "bless") {#SEND test}}
_________________
Windows Vista Home Premium SP2 32-bit
AMD Athlon Dual Core 4400+ 2.31 GHz
3 GB RAM
CMUD 3.34
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sat Jan 01, 2011 11:11 pm   
 
Fizgar wrote:
This is a crude example that should give you a starting point.

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <class name="SpellupScript" copy="yes">
    <alias name="CheckSpells" copy="yes">
      <value>#loopdb @spells {#addkey spells %key 0}

#send af

//Add a pattern that will match your prompt inbetween the brackets of the #waitfor below.
#waitfor {}

#loopdb @spells {#if (%val = 0) {#send cast %key;#wait 1500}}</value>
    </alias>
    <var name="spells" type="Record" copy="yes">
      <value>armor=0|shield=0|bless=0</value>
      <json>{"armor":0,"shield":0,"bless":0}</json>
    </var>
    <trigger priority="30" copy="yes">
      <pattern>^Affected:%s(*)</pattern>
      <value>#addkey spells %1 1</value>
    </trigger>
  </class>
</cmud>



First of all I would just like to thank you very much for your tremendous help...

As instructed, I added my prompt in the #waitfor and it works ...
#waitfor {<(*)/(*)hp (*)/(*)m (*)/(*)mv>}

I had to change this line...
#loopdb @spells {#if (%val = 0) {#send cast %key;#wait 1500}}
to this... to have the proper syntax...
#loopdb @spells {#if (%val = 0) {#send cast '%key' self;#wait 1500}}

The only problem now that is preventing it from working properly is spaces... The spells are being saved in the database with spaces and when they are called upon, they are called with their spaces as well and the game isn't recognizing the name of the spells ... here's an example...

<152/118hp 171/173m 290/290mv> cast 'detect invis ' self
You can't do that.

<152/118hp 171/173m 290/290mv> cast 'detect evil ' self
You can't do that.

<152/118hp 171/173m 290/290mv> cast 'detect hidden ' self
You can't do that.

<152/118hp 171/173m 290/290mv> cast 'protection ' self
You can't do that.

<152/118hp 171/173m 290/290mv> cast 'armor ' self
You can't do that.

If there was a way to record the spell into the database by trimming off all the spaces from the end of the spell name, it would work perfectly, because if I manually go into the database variables and delete the spacing from the end, the spell casts perfectly, example...

<152/118hp 173/173m 290/290mv> cast 'detect hidden' self
Your senses are heightened to those of an animal.

Edit: Just so you know, there are many, many more spaces at the end of the spells than what are showing up in here, but they are being trimmed off...
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Sat Jan 01, 2011 11:19 pm   
 
As I said, you need to tell Cmud what string you are trying to match.
Code:
#IF (%match("Affected: bless","Affected: bless")) {#SEND test}

This #IF will always evaluate to TRUE because %match() require TWO arguments. The first argument is the string to check, and the second argument is what you want to test whether it matches.
Code:
#IF ("Affected: bless" = "Affected: bless") {#SEND test}

This #IF always evaluates to true because "Affected: bless" is always equal to "Affected: bless"". The #IF statement tests whether the equation is true, and this one is always true.

Fizgar has given some examples of how to capture a string from the trigger, which you can then test in an #IF statement. #IF can't guess what you are trying to test--you have to tell it. This is true in all those other scripting languages you know, as well.
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sat Jan 01, 2011 11:51 pm   
 
Its going to have to be the following line that changes... I'm going to have to figure out how to trim off the spaces from the end of the spell name before I cast them in order for this to work... because when I manually remove the spaces from the spell variables, it then doesn't recognize them when it goes to check them... So it is going to store them with spaces and its going to check them with spaces... so the only way I see around this hiccup is to cast them without the spaces...

#loopdb @spells {#if (%val = 0) {#send cast '%key' self;#wait 1500}}

to something equivalent to this...

#loopdb @spells {#if (%val = 0) {#send cast '%trim(%key)' self;#wait 1500}}
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sun Jan 02, 2011 12:37 am   
 
Ok, adding the %trim fixed the whole spacing issue, the only thing that I'm trying to deal with now, is how to make the script keep running until all of the spells are cast, because sometimes I fail at casting them...

Also, how to exclude certain spells, because some spells are cast on me from other people...
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sun Jan 02, 2011 1:11 am   
 
To exclude trying to cast spells, that I can't cast, on myself, I tried this bit of code in the trigger...

#if (%trim(%1) != loopdb %trim(@dontcastspells)) {
#addkey spells %trim(%1) 1
}

I added a new database variable called "dontcastspells", which has the spells from the database variable "spells", that I don't want to try to cast on myself... I then removed them from the "spells" database variable... and tried the above trigger, it didn't work... My logic was that it would check to see if the spell that it was seeing was in the dontcastspells variable, if it wasn't then it could continue, if not, then don't add it to the spells variable...

Any ideas?
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sun Jan 02, 2011 2:29 am   
 
Quote:

Any ideas?


Read the manual, starting with the beginning topic. You seem to be ignoring the basics, which is why your logic is failing you here. Your #IF condtion is always true because %1 is always going to be not-equal to "loopdb".

Once you are familiar with the basic stuff, check out the helpfile for %ismember().
_________________
EDIT: I didn't like my old signature
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Sun Jan 02, 2011 10:13 pm   
 
Ok, so I have read and read and read... and read some more... Here's what I got, it works great for adding a 0 if the spell isn't on and 1 if it is...

#loopdb @spells {#if (%trim(%key) = %trim(%1)) {#addkey spells %trim(%1) 1}}
#loopdb @spells {#if (%trim(%key) != %trim(%1)) {#addkey spells %trim(%1) 0}}

The only problem with this is, is that it adds new spells... after reading through all of the documentation, I could not find any type of command or function that will edit a database variable's key's value, e.g. editkey or editval ... Or another option would be if I could lock the database variable from allowing new entries, but I did not see any way to do that either...
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Mon Jan 03, 2011 1:40 am   
 
Simply doing #ADDKEY with the new value will replace the existing value for the key.
Reply with quote
webwired
Beginner


Joined: 22 Dec 2010
Posts: 18

PostPosted: Mon Jan 03, 2011 1:54 am   
 
Rahab wrote:
Simply doing #ADDKEY with the new value will replace the existing value for the key.


Yes, but it will also add new entries that aren't currently in there, that's the part that I need to stop... a way to either update/edit the existing database variable value key or lock the database variable from adding new entries...

I really don't understand... there's an ADDKEY, a DELKEY, but no UPDATEKEY/EDITKEY ...
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4774
Location: Pensacola, FL, USA

PostPosted: Mon Jan 03, 2011 3:15 am   
 
That's because updating a variable is simply giving it a new value.
As far as editing, you can store the value into a local value, edit away with various functions like %trim, and then assign the new value.

Functionally speaking there are only three things you can do to a variable, access the value, change the value, or delete it entirely.
The term used to describe the process is irrelevant, there are several ways to do each.

You can test to see if a suspect key exists though:

$key=suspect key string
#IF (%ismember($key, @spells)) {#SAY this key exists already} {#SAY insert code to check if i want to keep this new key, here}
_________________
Discord: Shalimarwildcat
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Mon Jan 03, 2011 3:00 pm   
 
As Shalimar said. If you don't want to add new keys under certain circumstances, you need to test for those circumstances before using #ADDKEY.
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