Picky creatures
chimeric
Member Posts: 1,163
This could go to troubleshooting, I think. Anyway, if you script a creature - like a creature you are about to make an invisible servant out of, for all sorts of menial tasks - if you script a servant, I say, to look around for Nearest, SecondNearest and so forth so it can, for example, cast a spell on them, he will totally ignore and snub Specifics values and Spell State values that you may have wanted to distinguish the target with. This goes for both custom and basic entries in those IDS files. For example, if you tell him to look for
Specifics(Nearest,NORMAL)
and so on for everyone up to TenthNearest, the servant will just turn his nose and not notice any of them. He will react to Race, Class, Alignment and Gender that you can set through opcode 72, Set IDS State, but not Specifics. This makes Specifics a lot less useful for doing what it's supposed to do, marking things. I'm less certain about Spell States, but I wasn't able to get the servant to notice those either. I don't know if switching someone's class through 72 is an actual game change or only a formal change, the same for gender-swapping and so on. I haven't tried. If this opcode only changes the IDS value, it can be used as a marker, but turning someone's class to ANKHEG is an awfully theatrical way to get noticed.
Specifics(Nearest,NORMAL)
and so on for everyone up to TenthNearest, the servant will just turn his nose and not notice any of them. He will react to Race, Class, Alignment and Gender that you can set through opcode 72, Set IDS State, but not Specifics. This makes Specifics a lot less useful for doing what it's supposed to do, marking things. I'm less certain about Spell States, but I wasn't able to get the servant to notice those either. I don't know if switching someone's class through 72 is an actual game change or only a formal change, the same for gender-swapping and so on. I haven't tried. If this opcode only changes the IDS value, it can be used as a marker, but turning someone's class to ANKHEG is an awfully theatrical way to get noticed.
0
Comments
See(Nearest([0.0.0.0.SPECIFICS]))
It's not really meant to be used outside of AI and InMyGroup() trigger.
You certainly can use it for other purpose, but that may cause AI to malfunction sometimes, especially in SoD.
Regarding spell states (or any other way to mark the target, really, like local variable), it's more likely to be an error in your script somewhere.
IF True() THEN RESPONSE #100 Wait(2) Continue() END IF Class(Nearest,DOG_WILD) RandomNumLT(20,10) THEN RESPONSE #100 Wait(2) ReallyForceSpellRES("SPWI105",Nearest) // Color Spray DestroySelf() END IF Class(Nearest,DOG_WILD) RandomNumGT(20,9) THEN RESPONSE #100 DestroySelf() END
IF True() THEN RESPONSE #100 ReallyForceSpellRES("VISION_#",Myself) // Not important Wait(2) Continue() END IF Detect(Nearest) THEN RESPONSE #100 ReallyForceSpellRES("SPWI003",LastSeenBy()) // Magic Missile END
It casts MM on itself. Plus, it's weird but I keep putting
Detect(Nearest([0.0.0.0.0.0.NONE]))
there in Near Infinity, save, and when I come back in the window, it has been converted to just
Detect(Nearest)
Oh, I almost forgot about this :facepalm:
There's a problem (or was it a feature, lol?) with Nearest() in that it includes myself in the range of available objects. So, if you use Nearest() without additional specifications, it will return the script owner themselves, not an actor that is nearest in the common human sense. SecondNearest() and so forth work fine.
Regarding NI auto converting the script, in ALIGN.IDS the value of 0 is labeled as NONE, which results in [0.0.0.0.0.0.0] object and is basically the same as just Nearest(), so I think NI is simply trying to not display data it deems irrelevant.
So, you gonna need a non-zero value to match in at least one of these ids EA.GENERAL.RACE.CLASS.SPECIFIC.GENDER.ALIGN (I actually misspelled two of them as SPECIFICS and ALIGNMENT in my earlier post). Not that I recommend setting object fields to custom IDS values anyway...
Assuming we're still talking about charm, and you still set it to GOODBUTBLUE, then you should be able to match it with Nearest([GOODBUTBLUE]). If you expect other GOODBUTBLUEs to be present in the area, then additionally set a custom spell state (opcode 328) on the target and iterate through Nearest([GOODBUTBLUE])-TenthNearest([GOODBUTBLUE]) to check if any of them have the spell state set. Note that it may sometimes fail in SoD, due to large numbers of allied soldiers all flagged as GOODBUTBLUE.
And another thing: that ANYONE object. Just what is it useful for? Only for reactions to seeing or detecting someone so the creature fires off a spell or such? I mean, you can't put that object in regular triggers, right? ForceSpellOn(ANYONE... and so on. It would be nice. It would work as EVERYONE, if I could just issue a command or cast a spell on a whole bunch of creatures at once. I wouldn't have to go through SecondNearest and so on. But then, I already can with an Everyone-targeted effect, which I can further filter through a specific or something... That only works for effects, though. Not for script actions or ActionOverride in particular.
If the creature doing the search for nearests takes itself to be the first Nearest, then there is no point to using that object at all, is there? I can just start with SecondNearest.
No direct way, I'm afraid... LastSummonerOf(Myself) can be used to reliably detect one's summoner, but there can only be one such a thing, so if you want the caster and their target, you're still out of luck.
For when you don't care about some particular ids value.
See([ENEMY.0.HUMAN.FIGHTER.0.MALE.NEUTRAL_GOOD]) will match hostile neutral good human male fighters. But if you only want enemy fighters in general, then you need a wildcard for other parameters, which is what ANY/ANYONE/0 is, making the trigger look like See([ENEMY.0.0.FIGHTER]).
Not sure if I understood correctly... [0.0.0.FIGHTER], Player1, "custom_script_name", NearestEnemyOf(LastSummonerOf(Myself)) are all valid object types, so as long as the action/trigger allow an object as an argument, you can use any. The catch, of course, is that the existing types are not always enough, i.e. you can't include a variable check or a spell state this way, it'd have to be checked in a separate scripting line.
What you mean by everyone doesn't exist unfortunately, a scripting object in Infinity Engine is always a singular entity. So it's either iterating through SecondNearest() etc. or using an AoE projectile.
Problem is that you'll miss an actual nearest this way, which may or may not be the one you really need. If you search for a particular ids value (e.g. [0.0.0.FIGHTER]), then you can set the script owner's class to e.g. MAGE. Since myself will not return true, it will search for the next nearest fighter, and do it correctly this time.
It won't work as nice if you want anyone but myself, though, since there can be no negatives (IIRC only ea.ids has a NOTEVIL entry, that sounds remotely close). Even though you can check manually later whether someone's class is fighter or not, it's not possible to automatically See() any non-fighters.
Another easy way is when you don't care about neutrals, then you can rely on NearestEnemyOf(), NearestEnemyOfType() and NearestAllyOf(), which automatically omit myself from a list of valid targets.