WizWom Posted December 31, 2007 Share Posted December 31, 2007 I made up this script to automatically backstab, and it seems sweet... except that every time the character sees an enemy, it somehow causes him to leave shadows. I can't even honestly debug what part is doing it, because it seems PauseGame() ALSO causes the character to leave shadows. IF HotKey(S) Global("WXNoSneak","LOCALS",0) THEN RESPONSE #100 SetGlobal("WXNoSneak","LOCALS",1) END IF HotKey(S) !Global("WXNoSneak","LOCALS",0) THEN RESPONSE #100 SetGlobal("WXNoSneak","LOCALS",0) StartTimer(5,1) END IF See(NearestEnemyOf(Myself)) Range(NearestEnemyOf(Myself),8) THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",1) EquipMostDamagingMelee() Continue() END IF !ModalState(STEALTH) !See(NearestEnemyOf(Myself)) CombatCounter(0) Global("WXNoSneak","LOCALS",0) TimerExpired(5) ActionListEmpty() THEN RESPONSE #100 StartTimer(5,6) Hide() END IF CombatCounter(0) !See(NearestEnemyOf(Myself)) Global("WxMelee","LOCALS",0) ActionListEmpty() THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",1) EquipMostDamagingMelee() Continue() END IF !See(NearestEnemyOf(Myself)) OR(7) Heard([ANYONE],99) Heard([ANYONE],ALERT) Heard([ANYONE],ASSIST) Heard([ANYONE],1) Heard([ANYONE],2) Heard([ANYONE],2727) Heard([ANYONE],50) THEN RESPONSE #100 MoveToObject(LastHeardBy(Myself)) END IF CombatCounter(0) !See(NearestEnemyOf(Myself)) !See([0.0.0.0.WXJON_TARGET]) !Detect([ENEMY]) THEN RESPONSE #100 END IF OR(2) See(NearestEnemyOf(Myself)) See([0.0.0.0.WXJON_TARGET]) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) THEN RESPONSE #100 Shout(ALERT) Continue() END IF CombatCounter(0) !See(NearestEnemyOf(Myself)) Detect([ENEMY]) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) THEN RESPONSE #100 Hide() MoveToObject(NearestEnemyOf(Myself)) END IF CombatCounter(0) !See(NearestEnemyOf(Myself)) ActionListEmpty() InMyArea(NearestEnemyOf(Myself)) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) THEN RESPONSE #100 Hide() END IF CombatCounter(0) OR(2) See(NearestEnemyOfType([EVILCUTOFF])) See([0.0.0.0.WXJON_TARGET]) HPGT([EVILCUTOFF],1) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) THEN RESPONSE #100 StartCombatCounter() Shout(ALERT) SetGlobalTimer("WXHalfAttack","LOCALS",1) Continue() END IF CombatCounter(0) OR(2) Detect([EVILCUTOFF]) Detect([0.0.0.0.WXJON_TARGET]) HPGT([EVILCUTOFF],1) ModalState(STEALTH) THEN RESPONSE #100 StartCombatCounter() SetGlobalTimer("WXHalfAttack","LOCALS",1) Continue() END IF OR(2) See(NearestEnemyOf(Myself)) See(Nearest([0.0.0.0.WXJON_TARGET])) !Range(LastSeenBy(Myself),8) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",0) EquipRanged() Continue() END IF See(NearestEnemyOf(Myself)) OR(6) See(Nearest([0.0.0.0.WXJON_TARGET])) See(NearestEnemyOfType([ENEMY.0.0.CLERIC_ALL])) See(NearestEnemyOfType([ENEMY.0.0.BARD_ALL])) See(NearestEnemyOfType([ENEMY.0.0.DRUID_ALL])) See(NearestEnemyOfType([ENEMY.0.0.LONG_BOW])) See(NearestEnemyOf(Myself)) OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) !TargetUnreachable(LastSeenBy(Myself)) THEN RESPONSE #100 ActionOverride(LastSeenBy(Myself),DisplayStringHead(Myself,10070)) // Target ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET) EquipMostDamagingMelee() Continue() END IF OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) See(Nearest([0.0.0.0.WXJON_TARGET])) Class(LastSeenBy(Myself),INNOCENT) THEN RESPONSE #100 ChangeSpecifics(LastSeenBy(Myself),0) Continue() END IF OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) See(Nearest([0.0.0.0.WXJON_TARGET])) !Range(LastSeenBy(Myself),2) THEN RESPONSE #100 DisplayStringHead(LastSeenBy(Myself),12128) // Backstab Damage FollowObjectFormation(LastSeenBy(Myself),11,1) END IF OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) See(Nearest([0.0.0.0.WXJON_TARGET])) THEN RESPONSE #100 AttackNoSound(LastSeenBy(Myself)) END IF GlobalTimerNotExpired("WXHalfAttack","LOCALS") See(NearestEnemyOf(Myself)) !Class(NearestEnemyOf(Myself),INNOCENT) Allegiance(NearestEnemyOf(Myself),EVILCUTOFF) THEN RESPONSE #100 Attack(NearestEnemyOf(Myself)) END IF See(NearestEnemyOf(Myself)) !Class(LastSeenBy(Myself),INNOCENT) Allegiance(LastSeenBy(Myself),EVILCUTOFF) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END Link to comment
Razfallow Posted December 31, 2007 Share Posted December 31, 2007 IF See(NearestEnemyOf(Myself)) OR(6) See(Nearest([0.0.0.0.WXJON_TARGET])) See(NearestEnemyOfType([ENEMY.0.0.CLERIC_ALL])) See(NearestEnemyOfType([ENEMY.0.0.BARD_ALL])) See(NearestEnemyOfType([ENEMY.0.0.DRUID_ALL])) See(NearestEnemyOfType([ENEMY.0.0.LONG_BOW])) See(NearestEnemyOf(Myself)) OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) !TargetUnreachable(LastSeenBy(Myself)) THEN RESPONSE #100 ActionOverride(LastSeenBy(Myself),DisplayStringHead(Myself,10070)) // Target ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET) EquipMostDamagingMelee() Continue() END Actions EquipMostDamagingMelee() and Continue() break stealth action, as well as ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET), but you can change it to ActionOverride(LastSeenBy(Myself),ChangeSpecifics(Myself,WXJON_TARGET)). IF !ModalState(STEALTH) !See(NearestEnemyOf(Myself)) CombatCounter(0) Global("WXNoSneak","LOCALS",0) TimerExpired(5) ActionListEmpty() THEN RESPONSE #100 StartTimer(5,6) Hide() END I would change !ModalState(STEALTH) to !StateCheck(Myself,STATE_INVISIBLE) and !See(NearestEnemyOf(Myself)) to !Detect(NearestEnemyOf(Myself)). Your character will still try to hide with !ModalState(STEALTH), even if he drinks potion of invisibility. With !See you will try to hide when invisible enemy is near to you. StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) returns true only when you are partially invisible (it means, that enemy can see you). Replace OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) with StateCheck(Myself,STATE_INVISIBLE) and !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) with !StateCheck(Myself,STATE_INVISIBLE) Link to comment
WizWom Posted December 31, 2007 Author Share Posted December 31, 2007 Actions EquipMostDamagingMelee() and Continue() break stealth action, as well as ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET), but you can change it to ActionOverride(LastSeenBy(Myself),ChangeSpecifics(Myself,WXJON_TARGET)).[/code] Continue()? Tested it, you are correct. Weird. Also, it seems... IF CombatCounter(0) OR(2) Detect([EVILCUTOFF]) Detect([0.0.0.0.WXJON_TARGET]) HPGT([EVILCUTOFF],1) OR(2) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 StartCombatCounter() ActionOverride(NearestEnemyOf(Myself),DisplayStringHead(Myself,52333)) // Beware! More enemies approach! SetGlobalTimer("WXHalfAttack","LOCALS",1) END breaks stealth... must be the StartCombatCounter() StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) returns true only when you are partially invisible (it means, that enemy can see you).Replace OR(3) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) StateCheck(Myself,STATE_IMPROVEDINVISIBILITY) with StateCheck(Myself,STATE_INVISIBLE) and Tried that, doesn't work at all when I'm in Stealth. Link to comment
Yovaneth Posted December 31, 2007 Share Posted December 31, 2007 If this is for IWD2 (as it appears to be) then dump ModalState(STEALTH) and stick to invisibility checks. There's something funny going on with it in IWD2 and neither I nor Cirerrek have ever been able to run it down. -Y- Link to comment
WizWom Posted December 31, 2007 Author Share Posted December 31, 2007 No, this is the ToB engine I'm working with. For Tutu, but it should be useful for any thief type under that engine. Well, after working with the code a bit I and up with this functioning code: IF Global("WXSneakTime","LOCALS",0) THEN RESPONSE #100 SetGlobalTimer("WXSneakTime","LOCALS",1) END IF HotKey(S) Global("WXNoSneak","LOCALS",0) THEN RESPONSE #100 SetGlobal("WXNoSneak","LOCALS",1) END IF HotKey(S) !Global("WXNoSneak","LOCALS",0) THEN RESPONSE #100 SetGlobal("WXNoSneak","LOCALS",0) END IF !ModalState(STEALTH) See(NearestEnemyOf(Myself)) Range(NearestEnemyOf(Myself),8) THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",1) EquipMostDamagingMelee() Continue() END IF !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) !LOS(NearestEnemyOf(Myself),14) CombatCounter(0) Global("WXNoSneak","LOCALS",0) GlobalTimerExpired("WXSneakTime","LOCALS") ActionListEmpty() THEN RESPONSE #100 SetGlobalTimer("WXSneakTime","LOCALS",ONE_ROUND) Hide() END IF CombatCounter(0) !Detect(NearestEnemyOf(Myself)) Global("WxMelee","LOCALS",0) ActionListEmpty() THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",1) EquipMostDamagingMelee() Continue() END IF !See(NearestEnemyOf(Myself)) OR(7) Heard([ANYONE],99) Heard([ANYONE],ALERT) Heard([ANYONE],ASSIST) Heard([ANYONE],1) Heard([ANYONE],2) Heard([ANYONE],2727) Heard([ANYONE],50) THEN RESPONSE #100 MoveToObject(LastHeardBy(Myself)) END IF CombatCounter(0) !Detect([0.0.0.0.WXJON_TARGET]) !Detect([ENEMY]) THEN RESPONSE #100 END IF OR(2) See(NearestEnemyOf(Myself)) See([0.0.0.0.WXJON_TARGET]) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 DisplayStringHead(Myself,52333) // Beware! More enemies approach! Shout(ALERT) Continue() END IF CombatCounter(0) Detect([ENEMY]) LOS(NearestEnemyOf(Myself),14) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 Hide() MoveToObject(NearestEnemyOf(Myself)) END IF CombatCounter(0) !LOS(NearestEnemyOf(Myself),14) ActionListEmpty() InMyArea(NearestEnemyOf(Myself)) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 Hide() END IF CombatCounter(0) OR(2) See(NearestEnemyOfType([EVILCUTOFF])) See(NearestMyGroupOfType([0.0.0.0.WXJON_TARGET])) HPGT([EVILCUTOFF],1) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 StartCombatCounter() DisplayStringHead(Myself,52333) // Beware! More enemies approach! Shout(ALERT) SetGlobalTimer("WXHalfAttack","LOCALS",1) Continue() END IF OR(2) See(NearestEnemyOf(Myself)) See(NearestMyGroupOfType([0.0.0.0.WXJON_TARGET])) !Range(LastSeenBy(Myself),8) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 SetGlobal("WxMelee","LOCALS",0) EquipRanged() Continue() END IF OR(5) See(NearestEnemyOfType([ENEMY.0.0.CLERIC_ALL])) See(NearestEnemyOfType([ENEMY.0.0.BARD_ALL])) See(NearestEnemyOfType([ENEMY.0.0.DRUID_ALL])) See(NearestEnemyOfType([ENEMY.0.0.LONG_BOW])) See(NearestEnemyOf(Myself)) OR(2) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) !TargetUnreachable(LastSeenBy(Myself)) !Specifics(LastSeenBy(Myself),WXJON_TARGET) THEN RESPONSE #100 ActionOverride(LastSeenBy(Myself),DisplayStringHead(Myself,10070)) // Target ActionOverride(LastSeenBy(Myself),ChangeSpecifics(Myself,WXJON_TARGET)) END IF See([0.0.0.0.WXJON_TARGET]) Class(LastSeenBy(Myself),INNOCENT) THEN RESPONSE #100 ChangeSpecifics(LastSeenBy(Myself),0) END IF OR(2) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) See([0.0.0.0.WXJON_TARGET]) !Range(LastSeenBy(Myself),2) THEN RESPONSE #100 ActionOverride(LastSeenBy(Myself),DisplayStringHead(Myself,12128)) // Backstab Damage FollowObjectFormation(LastSeenBy(Myself),11,1) END IF OR(2) ModalState(STEALTH) StateCheck(Myself,STATE_INVISIBLE) See([0.0.0.0.WXJON_TARGET]) Range(LastSeenBy(Myself),2) THEN RESPONSE #100 EquipMostDamagingMelee() AttackNoSound(LastSeenBy(Myself)) END IF GlobalTimerNotExpired("WXHalfAttack","LOCALS") See(NearestEnemyOf(Myself)) !Class(NearestEnemyOf(Myself),INNOCENT) Allegiance(NearestEnemyOf(Myself),EVILCUTOFF) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 Attack(NearestEnemyOf(Myself)) END IF See(NearestEnemyOf(Myself)) !Class(LastSeenBy(Myself),INNOCENT) Allegiance(LastSeenBy(Myself),EVILCUTOFF) !ModalState(STEALTH) !StateCheck(Myself,STATE_INVISIBLE) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END See(Nearest([0.0.0.0.WXJON_TARGET])) did not work where I have See([0.0.0.0.WXJON_TARGET]); it seems Nearest() is broken. One of the reasons I want to arget net just NearestEnemyOfType() is because I use Specific WXJON_TARGET for NPC battles, it's a tweak, since it's set by Ajantis in my fix to allow Jonathan to join in his attacks on Evil party members he attacks. But this use of specifics to track my backstab target without making a big nasty block is nice and sweet. The only bug right now is if the character hits the range 2 check on the way to getting behind the target, then it won't end up backstabbing. I can't see any way to avoid that, though. And I suppose the DisplayStringHeads are not needed anymore - but I like knowing what my characters are doing. Link to comment
SimDing0 Posted December 31, 2007 Share Posted December 31, 2007 I have vague recollections of Horred mentioning that the IDS mask on Nearest() gets ignored. Link to comment
devSin Posted December 31, 2007 Share Posted December 31, 2007 I have vague recollections of Horred mentioning that the IDS mask on Nearest() gets ignored.Nearest() itself just doesn't work, but it's identical to just (O:Object) so doesn't matter much. EA isn't checked by the engine for NearestEnemy* and NearestMyGroup* (even though the latter doesn't have anything to do with EA). In general, it won't make a difference, but NearestEnemyOfType([EA]) is bad (See([EA]) will give you what you want). NearestMyGroupOfType() can detect only creatures with the same group (specifics) as the caller. I wouldn't bother using LOS(); it's not guaranteed to do anything more useful than See() (if even that). InMyArea() could just as easily be Exists() (NearestEnemyOf() doesn't exist unless there's a living enemy within visual range that's visible to the caller). Detect(NearestEnemyOf()) is similarly useless (again, nearest living visible enemy). TargetUnreachable() does nothing. Link to comment
aVENGER_(RR) Posted December 31, 2007 Share Posted December 31, 2007 I'd be wary of using ChangeSpecifics() on opponents. Several characters in BG2 already have a predetermined SPECIFIC value and some mods also assign custom values to their creatures. Link to comment
WizWom Posted January 2, 2008 Author Share Posted January 2, 2008 I was under the impression that detect() would work out the the full VisualRange distance, See() just to the area cleared of Fog Of War by the active character. Also Detect() is supposed to continue to sense a creature you can hear but not see... such as one around a corner, or in darkness (not that the game uses Darkness) So, all things being equal, if it might do a little more than See() it's worth using instead. Re: ChangeSpecifics()... hrm, I'm going to have to survey the install and see what I can see. I suppose I could use SetToken() but that seemed more arcane. I did want to figure out some way to tag the most dangerous opponent, then have the entire party attack it. I'm going to have to look at cierrek's Party AI scripts and see what he's doing. Link to comment
Fyorl Posted January 2, 2008 Share Posted January 2, 2008 It's difficult to define 'most dangerous' with just stats and classes and such. What's most dangerous for one party might be a breeze with another party. Link to comment
devSin Posted January 2, 2008 Share Posted January 2, 2008 I'm not sure what you're suggesting. LOS() is unused and I don't think we ever figured out anything about it. Detect() works only on a creature that would be visible were it not invisibile (i.e., you still have to be able to see it). Detect() won't do anything more than See() for dynamic object types -- these objects are determined separately as needed, and for the engine to consider an actor a valid NearestEnemyOf(), it has to be alive, within visual range of the caller, and actually visible to the caller. Outside a creature with the SEEINVISIBLE stat, NearestEnemyOf() will *never* be an invisible object (so Detect() will either pick up the nearest visible enemy or will return false (Detect(null))). Specifics is group, and although it's used without much purpose in the game (usually as a way to determine a specific creature in targeting), it's best to avoid setting it generically to targets everywhere since it invalidates NearestMyGroup* and InMyGroup checks. Objects See()n are retained by LastSeenBy(), so you could adopt a more advanced targeting block using False() triggers to funnel through the targeting sequence and wind up with an equivalent target to the current specifics shuffling. Link to comment
WizWom Posted January 2, 2008 Author Share Posted January 2, 2008 Objects See()n are retained by LastSeenBy(), so you could adopt a more advanced targeting block using False() triggers to funnel through the targeting sequence and wind up with an equivalent target to the current specifics shuffling. For this application, perhaps. Like I mentioned, the ultimate goal is to have some sort of party cohesion under AI rather than a lot of independent attacking. I've run into a small trouble with this scripting: sometimes, the character will be involved in a discussion with an NPC, who then goes hostile. If the PC is stealthed, such a dialog kills stealth, which means I can't backstab the ne'er-de-well as he properly deserves - the scipt thinks he's not ModalState(STEALTH) anymore, even though he still is not visible. And I already mentioned StateCheck(Myself,STATE_INVISIBLE) doesn't apply to a stealthed character, didn't I? Link to comment
Yovaneth Posted January 5, 2008 Share Posted January 5, 2008 For this application, perhaps. Like I mentioned, the ultimate goal is to have some sort of party cohesion under AI rather than a lot of independent attacking. Umm.... see my sig? If the Party Co-operation Scripts don't do what you're after, feel free to rip them apart and use any code chunks that might help you. The targeting needs an overhaul (I might even do it one day!) but in general they 'll probably do what you're after. Alternatively, just ask and I'll email you the snippets that are used to construct the final scripts. -Y- Link to comment
WizWom Posted January 22, 2008 Author Share Posted January 22, 2008 OK, I packaged my Mage-Thief Tutu script with working Backstabs into a little mod of it's own http://wizwom.is-a-geek.net/BGMods/WizWomBackstab.rar Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.