• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Having an Edge do something only when a piece of gear is equiped.

Paragon

Well-known member
In my ongoing discovery of "things I borked up" in the Broken Earth file, I discovered I'd gotten confused about what the edge "Axe Fighter" did and had it add to attack when using an axe, rather than parry which is what its supposed to do.

However, it brought up an issue I thought I'd see if anyone had any feedback on before I did it: what's the best way to have something like this only apply when someone has an axe equipped?

I can see two possible ways off the top of my head, one I haven't tried, and one that's just a little annoying:

1. Brawler adds damage to unarmed attacks. I could try constructing code that does something similar but boosts the Parry value on the various axes after searching to see if they're there. I'm not entirely certain about the syntax of this since I'm presuming unlike Unarmed its not on the Hero.

2, I could replace all the axes with duplicates that look for the Edge and up their Parry if its present. I kind of hate to do that sort of thing because you always end up missing something that looks for the ID of the original object.

Is there a third option? If not, which of these would be the best way to go?
 
For option 2, as my initial testing shows that pre-requisites appear to work correctly(in at least the one place I tested them) when you input the original's Replaces Thing Id.

For example, if I create a "New Command"(did this as a test) edge and put "edgCommand" Replaces Thing Id, my new edge qualifies for "Command" when trying to take "Commanding Presence" edge for example.
 
Can you elaborate on what you're talking about here? Because I've certainly had problems with this in the past and I'm not sure what you're referring to as "Replaces Thing ID" above.
 
"Replaces Thing ID" is a GLOBAL replacement. It completely ignores source settings, so using it means you want that new thing to forever replace in ALL data files the original thing, so you should use it only in very specific situations. Normally when you want to do a replace for a specific source file you would need to put the original thing under the Preclude tab and if that original thing had other stuff that relied on it, you'd Preclude those things as well and create new versions that have the links you need to the newly created ones. Otherwise use of "Replaces Thing ID" could cause you major, major headaches down the road if you're not certain you want to use it globally for ever and ever and ever. That also means if you are creating a data file for other people to use then you should NEVER use it because it could potentially cause them major headaches if they have data files that your Replaces screws up in ways they don't like.

As to the original question there are a couple of things from the Common Code thread that might be of use for doing your #1:

CapedCrusader worked out the following code for me to apply a +1 bonus to damage for all Melee attacks on a character coming from a specific Edge. This is an example of stepping through just one set of things, in this case Melee Weapons, and applying to something just to those.

Pre-Traits/5000
Code:
Code:
foreach pick in hero from WeapMelee
   eachpick.field[wpDmgBonus].value += 1
nexteach
perform hero.child[wpUnarmed].setfocus
   focus.field[wpDmgBonus].value += 1
-----
This one is an example of narrowing down to a specific set of things (like above) but then checking for and changing a further subset of those things, in this case we're going to step through Ranged Weapons, then we'll look for the ones that have the tag for a Thrown weapon and then set what the range value is for those weapons, as taken from the Mighty Throw Edge from Weird Wars: Rome:

At Pre-Traits/5000
Code:
Code:
foreach pick in hero from WeapRange
   if (eachpick.tagis[Weapon.Thrown] <> 0) then
      eachpick.field[wpShort].value = 4
      eachpick.field[wpMedium].value = 8
      eachpick.field[wpLong].value = 16
   endif
nexteach

Would either of those help to get you on the right track?
 
Ah, that's what I thought he meant. Yeah, learned that one was bad practice early. The problem is when you end up missing a dependency (which I've done a couple times) when using Preclude replaces.

I saw those in the common code thread. The second is actually useful to me on a second problem, but the problem with the first is that it affects everything in the axes/maces category at least, where this just works on axes. I could go in and retag all the axes, but that gets back to the problems with things looking for the original ID.

It may just be that replacing the axe, battle axe and great axe, and doing some conditional code to modify their parry may be the simplest way.
I just wanted to make sure there was nothing better since that's a little annoying for one edge. But I suspect if it can be done on the edge it'd have to be structured kind of like that first example code, but with some kind of text search for the names or IDs that I'm not sure of the syntax for. I looked through the code thread to see if there was anything that did that kind of search looking for a name or ID and didn't see an example, and I couldn't find anything that would obviously do that in the standard edges (Trademark Weapon kind-of, sort-of does something like it but it lets you pick any weapon).
 
Last edited:
"Replaces Thing ID" is a GLOBAL replacement. It completely ignores source settings, so using it means you want that new thing to forever replace in ALL data files the original thing, so you should use it only in very specific situations. Normally when you want to do a replace for a specific source file you would need to put the original thing under the Preclude tab and if that original thing had other stuff that relied on it, you'd Preclude those things as well and create new versions that have the links you need to the newly created ones. Otherwise use of "Replaces Thing ID" could cause you major, major headaches down the road if you're not certain you want to use it globally for ever and ever and ever. That also means if you are creating a data file for other people to use then you should NEVER use it because it could potentially cause them major headaches if they have data files that your Replaces screws up in ways they don't like.

As to the original question there are a couple of things from the Common Code thread that might be of use for doing your #1:



Would either of those help to get you on the right track?


Ok.. so exactly how does that work?

Does it actually find all references to edgCommand(for example) in all other feats and whatever and physically replaces them in the source? If so, that's a rather odd thing to expect. So that even with your source turned off, it's still replaced? Either way, it seems a fairly odd to entirely re-implement loads of things to extend one or two things. I would think that if MY source which has a new copy of Axe which replaces the "core" Axe was turned OFF, but the Replace Thing ID still makes the system point to my axe, data load errors would happen.

For that matter, what is the purpose and use of Extend Thing for example which honestly sounds like it might be the correct method, because that seems to be the right way to do something like adding a new "property" of some kind to an existing object.

For the record, note that the the Gencon 2015 data set developer youtube video explicitly uses this Replace Thing Id mechanic which is where I got this idea from. The question is, was the speaker using to simplistic a solution for the problem presented or is it possible that the global thing was something which used to be true, but not is NOT(ie, a fixed defect or change in feature) or does it really only have consequences in our case since none of the data files are built by LW and instead hacked together by gobs of different users in the community?
 
Last edited:
Ah, that's what I thought he meant. Yeah, learned that one was bad practice early. The problem is when you end up missing a dependency (which I've done a couple times) when using Preclude replaces.

I saw those in the common code thread. The second is actually useful to me on a second problem, but the problem with the first is that it affects everything in the axes/maces category at least, where this just works on axes. I could go in and retag all the axes, but that gets back to the problems with things looking for the original ID.

It may just be that replacing the axe, battle axe and great axe, and doing some conditional code to modify their parry may be the simplest way.
I just wanted to make sure there was nothing better since that's a little annoying for one edge. But I suspect if it can be done on the edge it'd have to be structured kind of like that first example code, but with some kind of text search for the names or IDs that I'm not sure of the syntax for. I looked through the code thread to see if there was anything that did that kind of search looking for a name or ID and didn't see an example, and I couldn't find anything that would obviously do that in the standard edges (Trademark Weapon kind-of, sort-of does something like it but it lets you pick any weapon).


Could you not filter for WeaponType.MedAxes and then further filter by names containing "Axe", just like the filtering for specific knowledge skills is done)?

Since you know there are only 3(assuming), you have a limited list as long as others don't add any. Of course, the best solution was if there was something like substring or contains functions which would operate on the name itself.

is field[livename].text the "Name" of the item?

EDIT:

http://hlkitwiki.wolflair.com/index.php5?title=Language_Intrinsics shows the various functions available. It kind of sucks there is no contains function, but for the most part with some careful testing, using some careful and judicious use of uppercase or lowercase, along with pos could get you what you need. The ultimate solution would be if the documentation on the wiki were out of data AND there is now a regex function built in, but something tells me that's dreaming to big.
 
Last edited:
CC could answer better how that works behind the scenes, but my understanding is that if the system sees the original UniqueID being loaded up into memory on anything is simply replaces it with the new UniqueID on the fly. It know how to do that because it loads and compares ALL of your .user files on startup and checks them for errors and such, as far as I can tell, so presumably it just loads up all Replace ID's at that time.

I agree that I wouldn't have expect that to be the behavior that it was a global change even if I have a sourceID listed on that thing, but that's just they way they did it, I guess. It catches everybody at first, though (it certainly caught me!)

As for Extend Thing... honestly I don't remember seeing that before. I think that may be new? CC may have to jump in on what that's about.
 
CC could answer better how that works behind the scenes, but my understanding is that if the system sees the original UniqueID being loaded up into memory on anything is simply replaces it with the new UniqueID on the fly. It know how to do that because it loads and compares ALL of your .user files on startup and checks them for errors and such, as far as I can tell, so presumably it just loads up all Replace ID's at that time.

I agree that I wouldn't have expect that to be the behavior that it was a global change even if I have a sourceID listed on that thing, but that's just they way they did it, I guess. It catches everybody at first, though (it certainly caught me!)

As for Extend Thing... honestly I don't remember seeing that before. I think that may be new? CC may have to jump in on what that's about.

Well.. in theory for the Extend Thing, I would expect it to act just like adding a new property/tag/field to an existing thing without having to make a copy of it. Of course, I don't know exactly how it DOES work, but that's how I would hope it would work.

In that case, it would be easy to add a new tag to three axes(for example) using their ids, say for example tag AxeType.Great, AxeType.Hand,AxeType.Batle or whatever. Then he then has his filtering mechanisms without loads of extra work as in my previous post where I think it's possible to do what he wants(for all I know) with 2-3 more lines of code. To be fair, my solution, assuming it works would be VERY fragile since it could not determine the string WITHIN existins words(likely not a problem for Axe unless you use Axel in vehicles or some other really odd word, but could be a big issue with more common words. Of course, this could be mitigated quiet a lot by starting with the smaller context of WeaponType.MedAxes in the first place, so it might be safeish.
 
Could you not filter for WeaponType.MedAxes and then further filter by names containing "Axe", just like the filtering for specific knowledge skills is done)?

I'll give a look at the Knowledge skill filtering and see if its usable.

Of course I just realized I'd ended up doing a Preclude and replace with all the standard weapons a while back for some reason anyway for this .user file, so maybe I should just go in and do it the brute force way on those anyway.
 
CC could answer better how that works behind the scenes, but my understanding is that if the system sees the original UniqueID being loaded up into memory on anything is simply replaces it with the new UniqueID on the fly. It know how to do that because it loads and compares ALL of your .user files on startup and checks them for errors and such, as far as I can tell, so presumably it just loads up all Replace ID's at that time.

I agree that I wouldn't have expect that to be the behavior that it was a global change even if I have a sourceID listed on that thing, but that's just they way they did it, I guess. It catches everybody at first, though (it certainly caught me!)

Ok.. so the way I understand you, the order of operations is:

  1. Load all .users files, perform all replace one at a time(what if multiple files replace the same thing!?!?!?!? If this is the case, then the order of operations may be important.)
  2. Process Source information AFTER the character load/new screen kicks into the main program

So, by the time the sources are even presented to the end user, the replace has already been done. As I mentioned, if you don't then load that source AND someone has that pick selected, I assume that would then error out badly on an existing portfolio. To me, this seem like a bug.

Now, this really should not be any issue at all in a normal end user scenario in pretty much all cases, but for us since the community builds and trades data files much more frequently vs LW built sources, it could cause loads of issues<sigh>.
 
I honestly couldn't tell you the order of those things or even if my assumptions above are really correct! I'm absolutely no guru or have any REAL insight into how HL works beyond makeing a bunch of data files do what I wanted them to do (well, mostly) without messing things up for anyone else. I can make some assumptions but those assumptions could be totally wrong here. Really someone from Lone Wolf or maybe a thorough reading of the Wiki (out of date as it is) could be more insightful than I could be on the subject.
 
In fact, since I did replace those weapons, that, I think putting the code in them is the the easiest way to go here. It means anyone adding a new axe to the .user file will need to copy the eval script off one of the extent ones to work right with the Edge, but so be it.

Thanks for everyone's responses.
 
In fact, since I did replace those weapons, that, I think putting the code in them is the the easiest way to go here. It means anyone adding a new axe to the .user file will need to copy the eval script off one of the extent ones to work right with the Edge, but so be it.

Thanks for everyone's responses.

Question, why would you not use a new tag on your axes and your code to check for that tag? It seems end users who add a new type of axe would be much less intimidated by adding a tag vs messing with eval scripts. IMHO, adding new tags seems to be the more extensible solution. Granted, I am just wetting my feet with this stuff, so could be wrong on my assumptions.
 
I probably could have, but I'm not as experienced with messing with tags (and manipulating them in eval scrips) as I am with eval scripts themselves, and in this case, all they really need to do is the eval script over and change one thing (the id of the weapon).
 
Just for reference as to how I did this, in case anyone is interested:

Code:
<thing id="wpBEAxe" name="Axe" description="Rarity C" compset="Melee" summary="Rarity C">
    <fieldval field="grCost" value="200"/>
    <fieldval field="gearWeight" value="2"/>
    <usesource source="BrEarth"/>
    <tag group="WeaponType" tag="MedAxes"/>
    <tag group="WeaponDie" tag="3" name="d6" abbrev="d6"/>
    <eval phase="PreTraits" priority="5000" index="2"><![CDATA[if (hero.tagis[Edge.edgAxeFig] <> 0) then
perform hero.child[wpBEAxe].setfocus 
focus.field[wpParry].value += 1
endif]]></eval>
    </thing>
 
You could have it look at the names of weapons, too. So, if it has "axe" in the name it is valid. So, have it do an eachpick and then look at the name, maybe the shortname, and then if it has ?axe? (be sure to make what it finds be lower case so that you don't have to worry about it) and then if it is an axe, apply the benefit. Making all of those stupid eval scripts suck. Make one in a mechanic and be done with it. Duplicating crap -- and having to remember to add it elsewhere -- is a waste of time and memory.
 
That's what I was thinking about, but I'm really not terribly clear on the syntax there (I've seen eachpicks but not ever done one of my own) and wasn't sure if it'd only apply it if the axe was equiped, nor what the timing should be. What I ended up doing at least I was pretty sure would work.
 
Back
Top