ID:151099
 
Hello,
I'm trying to group verbs for combat by attack type, but have been having no luck... Is there any way that I can filter verbs based on the item that a player has equiped at the time. I've tried hidden and invisable but both methods had side effects that made them un-useable.

currently they are as such...
mob/monster/verb
/*HtH*/
Punch()
set src in oview()
...
Kick()
set src in oview()
...
...
/*Slashing*/
Slash()
set src in oview()
...
...

all mobs have an attack_type var, witch is based off the equiped item's attack_type(HtH if no item), I put the verbs in the monster definition so direct PvP would not be an option in the begining. I couldn't get if statements to work while in the verb definitions but byond wouldn't take it. I'm thinking the solution would be the ussage of runtime verbs but I have no idea how to do that and keep the verbs on the monsters...

Thanks,
Salarn
Hi Salarn,

[skip to *** part if you want a working solution-- the first part is just some discussion on the topic as I thought about it myself]

You can accomplish "verb groups" in a couple different fashions. The cleanest way is probably to use OO syntax, by assigning the desired verbs to the different object types, eg:

obj/weapon
blunt
// some different blunt weapons
hammer
club
...

// blunt verbs
verb/bash(mob/M as mob)
set src = usr.loc
...

sharp
// some different sharp weapons
knife
sword
...

// sharp verbs
verb/slash(mob/M as mob)
set src = usr.loc
...

and so on.

The idea here is to only give players access to these different verbs when they are in his possession. The 'set src = usr.loc' line ensures this condition (you can read about the meaning of the '=' tag vs. the 'in' tag in the guide). So when a player has a knife, he'll have a "slash" verb.

The problem is that a player might have a knife _and_ a club, but only have the knife equipped. Currently DM only allows you to set the src based on a few categories, and this doesn't include user-defined ones like "equipped". So if you go with this method you'll probably need to have a separate list that indicates which items a user owns, and use the 'contents' list to refer to equipped items. That's kind of hacky so I don't imagine you'll want to use this.
But I hope you follow this line of thought because this OO style will be useful in other aspects of DM coding.

*** --> fun starts here!

So the functional alternative is, as you suggested, to use runtime verbs. Probably the easiest way to do this is to make a few global "dummy" objects that contain the various verbs, eg:

obj/blunt_prototype
verb
bash(mob/M as mob)
...

obj/sharp_prototype
verb
slash(mob/M as mob)
...
slice(mob/M as mob)
...

mob/var/obj/instance // whatever I am currently weilding

obj/weapon
var/prototype // will point to the category you want
sword
prototype = /obj/sharp_prototype
club
prototype = /obj/blunt_prototype
...

verb/weild()
// first, remove whatever I am currently weilding
// that is stored in usr.instance.
if(usr.instance)
// loop through the verbs of this instance and
// remove them from our verbs
for(var/my_verb in usr.instance.verbs)
usr.verbs -= my_verb // remove it from my verbs

// next, change it so that I weild this guy
// (point usr.instance to an instance of this prototype)
// we've got to find the right instance first
usr.instance = locate(prototype)
if(!usr.instance) // doesn't exist yet
usr.instance = new prototype

// at this point, my_instance has all the verbs we want
// so give them to the mob
for(var/my_verb in usr.instance.verbs)
usr.verbs += my_verb // add it in to my verbs

Sorry for the barrage of code! It occurs to me that this may be much more complicated than you were hoping, but if you can follow it I think you'll find success with this method. The mob.instance var effectively replaces the category names you were using, since it distinguishes between the different types.
In response to Tom
On 4/25/01 11:25 am Tom wrote:
Hi Salarn,

[skip to *** part if you want a working solution-- the first part is just some discussion on the topic as I thought about it myself]

You can accomplish "verb groups" in a couple different fashions. The cleanest way is probably to use OO syntax, by assigning the desired verbs to the different object types, eg:

obj/weapon
blunt
// some different blunt weapons
hammer
club
...

// blunt verbs
verb/bash(mob/M as mob)
set src = usr.loc
...

sharp
// some different sharp weapons
knife
sword
...

// sharp verbs
verb/slash(mob/M as mob)
set src = usr.loc
...

and so on.

The idea here is to only give players access to these different verbs when they are in his possession. The 'set src = usr.loc' line ensures this condition (you can read about the meaning of the '=' tag vs. the 'in' tag in the guide). So when a player has a knife, he'll have a "slash" verb.

The problem is that a player might have a knife _and_ a club, but only have the knife equipped. Currently DM only allows you to set the src based on a few categories, and this doesn't include user-defined ones like "equipped". So if you go with this method you'll probably need to have a separate list that indicates which items a user owns, and use the 'contents' list to refer to equipped items. That's kind of hacky so I don't imagine you'll want to use this.
But I hope you follow this line of thought because this OO style will be useful in other aspects of DM coding.

*** --> fun starts here!

So the functional alternative is, as you suggested, to use runtime verbs. Probably the easiest way to do this is to make a few global "dummy" objects that contain the various verbs, eg:

obj/blunt_prototype
verb
bash(mob/M as mob)
...

obj/sharp_prototype
verb
slash(mob/M as mob)
...
slice(mob/M as mob)
...

mob/var/obj/instance // whatever I am currently weilding

obj/weapon
var/prototype // will point to the category you want
sword
prototype = /obj/sharp_prototype
club
prototype = /obj/blunt_prototype
...

verb/weild()
// first, remove whatever I am currently weilding
// that is stored in usr.instance.
if(usr.instance)
// loop through the verbs of this instance and
// remove them from our verbs
for(var/my_verb in usr.instance.verbs)
usr.verbs -= my_verb // remove it from my verbs

// next, change it so that I weild this guy
// (point usr.instance to an instance of this prototype)
// we've got to find the right instance first
usr.instance = locate(prototype)
if(!usr.instance) // doesn't exist yet
usr.instance = new prototype

// at this point, my_instance has all the verbs we want
// so give them to the mob
for(var/my_verb in usr.instance.verbs)
usr.verbs += my_verb // add it in to my verbs

Sorry for the barrage of code! It occurs to me that this may be much more complicated than you were hoping, but if you can follow it I think you'll find success with this method. The mob.instance var effectively replaces the category names you were using, since it distinguishes between the different types.



Yeah, I knew that I would have to re-write a huge block of code...Kida hoped there would be a tricky work around that the the high vizars would only know....

my first attemp at this was to have multiple set commands i.e.(from memory)

mob/monster/verb
/*HtH*/
Punch()
set src in oview()

if (usr.attack_type != "Hand to Hand")
set category = "Unaviliable"
else
set categroy = "Physical Attacks"

...yadda...


the problem with that is that byond goes "Hey stupid, you can't declare category twice" (wich makes me cry on the inside) and won't run.

so then I tried

mob/monster/verb
/*HtH*/
Punch()
set src in oview()

if (usr.attack_type != "Hand to Hand")
set visibility = 1 //no visable
else
set categroy = "Physical Attacks"

...yadda...

the problem with that is that byond then goes "Great, I'll hide it from the statpanel, but just to anoy ya, I'll keep it in the right click menu" and this makes it real hard to do anything in that menu.

Salarn
In response to Salarn
oops....I forgot to add the point to all that...

I though my reasoning behind thouse to methods was sound, or would a new feature need to be added to sport that crazyness....or how can I exil things from the right click menu, or even better, how can I have menus within menus on the right click menu.


Salarn
In response to Tom

// blunt verbs
verb/bash(mob/M as mob)
set src = usr.loc
...

I think you mean <code>set src = usr.contents</code>, which means pick a src object (without asking the user to choose one) from the user's contents. Having it as <code>set src = usr.loc</code> makes it pick a src object from the user's location.

I think we may need to consider the addition of an "equipped" flag that could be used as a condition for the accessibility of a verb like so:

obj/verb/myverb()
set equipped = 1

It seems a fairly common requirement.

--Dan
In response to Dan

I think we may need to consider the addition of an "equipped" flag that could be used as a condition for the accessibility of a verb like so:

obj/verb/myverb()
set equipped = 1

I should add to this discussion that there is currently a more general solution, but I think this case may be common enough to warrant special treatment.

The general solution (short of adding/subtracting verbs, which is rather arcane) is to create an invisible companion object when your main object gets activated (by equipping in this case). You can make the verbs of an invisible object visible like this:

obj
   equipped_weapon
      visibility = 0
      verb/hit(mob/M)
         set visibility = 1 //override object visibility

   weapon
      var/equip_obj

      verb/wield()
         //add the "equipped" verbs to the user
         equip_obj = new/obj/equipped_weapon(loc)
      verb/remove()
         del equip_obj

      Move()
         //when we get dropped, clean up
         del equip_obj
         return ..()
      Del()
         del equip_obj
         return ..()


The use of invisible objects to carry verbs is fairly powerful, but a little awkward--especially if you were planning to allow some players to see invisible things.

--Dan
In response to Dan
On 4/26/01 9:26 am Dan wrote:
I think we may need to consider the addition of an "equipped" flag that could be used as a condition for the accessibility of a verb like so:

obj/verb/myverb()
set equipped = 1

Perhaps an 'active' setting would be more general and clear?

Then you could turn a verb on or off.

The current system of adding/removing verbs is quite flexible, but does seem to be confusing to some people. So a setting like this would probably reduce some confusion.
In response to Deadron
Perhaps an 'active' setting would be more general and clear?

Then you could turn a verb on or off.

But wouldn't this (or Dan's suggestion, for that matter) toggle the verb for all objects of that type? And if not, how would it be handled when you added the verb to something at runtime?
In response to Gughunter
On 4/26/01 11:45 am Gughunter wrote:

But wouldn't this (or Dan's suggestion, for that matter) toggle the verb for all objects of that type? And if not, how would it be handled when you added the verb to something at runtime?

I think the idea is to have an atom var that could be used (at runtime) to toggle a verb. Eg:

obj/weapon
active = 0
verb
equip()
active = 1
unequip()
active = 0
slash()
set active = 1 // really means: set src in world "when active==1"
usr << "You slash [src]"

This would give a limited form of control over the src accessibility. In an ideal world, the 'set src' setting could be applied to any general expression (eg: set src in my_custom_proc()), but this is a difficult problem since this information has to be realized client-side in order for the verb-lists and context-menus to be updated on-the-fly (without doing an expensive server lookup).