Jump to content


Photo

Backstab script


  • Please log in to reply
4 replies to this topic

#1 WizWom

WizWom
  • Member
  • 270 posts

Posted 10 February 2010 - 06:18 PM

IF
	!ActionListEmpty()
	!See(NearestEnemyOf(Myself))
THEN
	RESPONSE #100
END

IF
	HotKey(S)
	Global("GBStealth","LOCALS",0)
THEN
	RESPONSE #100
		DisplayStringHead(Myself,34120) // Hide In Shadows
		SetGlobal("GBStealth","LOCALS",1)
END

IF
	HotKey(S)
	!Global("GBStealth","LOCALS",0)
THEN
	RESPONSE #100
		DisplayStringHead(Myself,4188) // Leaving Shadows
		SetGlobal("GBStealth","LOCALS",0)
END

IF
	Global("GBUnseen","LOCALS",0)
	OR(2)
		StateCheck(Myself,STATE_INVISIBLE)
		StateCheck(Myself,STATE_IMPROVEDINVISIBILITY)
THEN
	RESPONSE #100
		SetGlobal("GBUnseen","LOCALS",1)
END

IF
		Global("GBUnseen","LOCALS",1)
	!StateCheck(Myself,STATE_INVISIBLE)
	!StateCheck(Myself,STATE_IMPROVEDINVISIBILITY)
THEN
	RESPONSE #100
		DisplayStringHead(Myself,75113) // You look familiar. Did I see you earlier?
		SetGlobal("GBUnseen","LOCALS",0)
		SetGlobal("GBBackStabbingNow","LOCALS",0)
END

IF
	Global("GBStealth","LOCALS",1)
	!Detect([EVILCUTOFF])
	Global("GBUnseen","LOCALS",0)
	!StateCheck(Myself,STATE_INVISIBLE)
	!StateCheck(Myself,STATE_IMPROVEDINVISIBILITY)
THEN
	RESPONSE #100
		EquipMostDamagingMelee()
		SetGlobal("GBUnseen","LOCALS",1)
		Hide()
END

IF
	HotKey(B)
	Global("GBBackStab","LOCALS",0)
THEN
	RESPONSE #100
		DisplayStringHead(Myself,17591) // The thief will attempt to hide in shadows when an enemy is not in sight.  As soon as the thief is hidden, he will attempt to backstab the closest enemy. (<script>)
		SetGlobal("GBBackStab","LOCALS",1)
		SetGlobal("GBStealth","LOCALS",1)
END

IF
	HotKey(B)
	!Global("GBBackStab","LOCALS",0)
THEN
	RESPONSE #100
		DisplayStringHead(Myself,3042) // The backstab seems to have failed.
		SetGlobal("GBBackStab","LOCALS",0)
END

IF
	Global("GBBackStab","LOCALS",1)
	See(NearestEnemyOf(Myself))
	Global("GBUnseen","LOCALS",1)
	!Range(LastSeenBy(Myself),3)
THEN
	RESPONSE #100
		FollowObjectFormation(LastSeenBy(Myself),11,1)
		MakeUnselectable(3)
END

IF
	Global("GBBackStab","LOCALS",1)
	Global("GBUnseen","LOCALS",1)
	!ActuallyInCombat()
	See(NearestEnemyOf(Myself))
	Range(LastSeenBy(Myself),3)
THEN
	RESPONSE #100
		Attack(NearestEnemyOf(Myself))
END

IF
	See(NearestEnemyOf(Myself))
	Range(LastSeenBy(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	Global("GBAmmoless","LOCALS",0)
	!HasItemSlot(Myself,SLOT_MISC19)
	HasItemSlot(Myself,SLOT_WEAPON)
	!InParty(LastSeenBy(Myself))
	!Class(LastSeenBy(Myself),INNOCENT)
	Allegiance(LastSeenBy(Myself),EVILCUTOFF)
THEN
	RESPONSE #100
		SelectWeaponAbility(SLOT_WEAPON,0)
		Attack(LastSeenBy(Myself))
END

IF
	See(NearestEnemyOf(Myself))
	Range(LastSeenBy(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	OR(3)
		!HasItemSlot(Myself,SLOT_WEAPON)
		HasItemSlot(Myself,SLOT_MISC19)
		Global("GBAmmoless","LOCALS",1)
	!InParty(LastSeenBy(Myself))
	!Class(LastSeenBy(Myself),INNOCENT)
	Allegiance(LastSeenBy(Myself),EVILCUTOFF)
THEN
	RESPONSE #100
		EquipMostDamagingMelee()
		Attack(LastSeenBy(Myself))
END

IF
	OR(3)
		See(NearestEnemyOf(Myself))
		See(TenthNearestEnemyOfType([0.0.0.CLERIC_ALL]))
		See(TenthNearestEnemyOfType([0.0.0.LONG_BOW]))
	!Range(LastSeenBy(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	!Range(LastAttackerOf(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	Global("GBAmmoless","LOCALS",0)
	!HasItemSlot(Myself,SLOT_MISC19)
	HasItemSlot(Myself,SLOT_WEAPON1)
	!InParty(LastSeenBy(Myself))
	!Class(LastSeenBy(Myself),INNOCENT)
	Allegiance(LastSeenBy(Myself),EVILCUTOFF)
THEN
	RESPONSE #100
		SelectWeaponAbility(SLOT_WEAPON1,0)
		Attack(LastSeenBy(Myself))
END

IF
	OR(3)
		See(NearestEnemyOf(Myself))
		See(TenthNearestEnemyOfType([0.0.0.CLERIC_ALL]))
		See(TenthNearestEnemyOfType([0.0.0.LONG_BOW]))
	!Range(LastSeenBy(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	!Range(LastAttackerOf(Myself),<img src='http://www.shsforums.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='8)' />
	OR(3)
		!HasItemSlot(Myself,SLOT_WEAPON1)
		HasItemSlot(Myself,SLOT_MISC19)
		Global("GBAmmoless","LOCALS",1)
	!GlobalTimerNotExpired("GBWizAlacrity","LOCALS")
	!InParty(LastSeenBy(Myself))
	!Class(LastSeenBy(Myself),INNOCENT)
	Allegiance(LastSeenBy(Myself),EVILCUTOFF)
THEN
	RESPONSE #100
		EquipRanged()
		Attack(LastSeenBy(Myself))
END

Issues:
  • sometimes when moving to the backstab position, it will prematurely attack
  • setting any variable takes you out of stealth, which makes doing anything complex problematical
  • hard to predict how long you'll have in stealth after the attack, you could become visible before you get in your swing (shortsword of backstabbing, anyone?)


#2 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 10 February 2010 - 09:29 PM

hard to predict how long you'll have in stealth after the attack, you could become visible before you get in your swing (shortsword of backstabbing, anyone?)

Stealth duration is fixed - http://forums.gibber...showtopic=18517
IIRC 300ticks=20sec

Retired from modding.


#3 WizWom

WizWom
  • Member
  • 270 posts

Posted 13 February 2010 - 06:44 PM

hard to predict how long you'll have in stealth after the attack, you could become visible before you get in your swing (shortsword of backstabbing, anyone?)

Stealth duration is fixed - http://forums.gibber...showtopic=18517
IIRC 300ticks=20sec


Ah, now, that is helpful. It's kindof a drag that setting a variable by script makes a character visible, but I can work around that, by assuming success and fixing the variable of failure.

#4 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 15 February 2010 - 11:37 PM

Your first block probably wants a NoAction(). Very nice for NPC AI if you get something like this working.

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#5 -Guest-

-Guest-
  • Guest

Posted 16 February 2010 - 01:09 AM

Different versions of the engine do different stupid things with empty action lists; I think it was some gosu nonsense back in the day for why you wanted to use it instead of NoAction(), but don't be surprised if something weird happens every thousand fights or so. ;-)

Also note that nthNearestEnemyOfType() simply returns NearestEnemyOfType() (bugz!). You can use TenthNearest([EVILCUTOFF.0.0.CLASS]) if you really want the tenth nearest of class.

ActuallyInCombat() is basically just !CombatCounter(0) and has no real purpose in that block.

I'm not sure where the premature attack comes from. It looks like maybe GBUnseen is set back to 0 earlier than you want and that first GBAmmoless,0 block is firing and causing the attack.