The New Pick-pocket Script

It Does What It Says on the Tin: Resolved Issues

Moderators: Moderator, Developer, DM

Swift
Posts: 20
Joined: Fri Aug 12, 2011 11:47 pm

Re: The New Pick-pocket Script

Unread post by Swift »

Noticed a bug today - I picked a player's character and succeeded but she yelled at me for trying to steal from her. After a few tells we determined that there was no way in the abyss I could steal from the character based on her spot and my SoH skills and I was actually detected but my stealth didn't break and I still received gold. If someone wants, screenshots, lemme know.
Opee
Honorshadow
Here comes the BOOM!
User avatar
Blackman D
Retired Staff
Posts: 4818
Joined: Sat Sep 12, 2009 5:43 am
Location: IL

Re: The New Pick-pocket Script

Unread post by Blackman D »

you can pm them to QC
everyone is evil till proven otherwise
Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

Re: The New Pick-pocket Script

Unread post by Dagesh »

I know y'all already have something but I put something together this afternoon. Feel free to use it if it's useful or borrow bits of it if they are useful alone.
Hidden: show

Code: Select all

//::///////////////////////////////////////////////
//:: FileName: s3_pockpocket
//:://////////////////////////////////////////////
/*

	This script controls PC pickpocketing
	using the sleight of hand skill.
	
	We check to make sure that the target is a valid creature (ex not an animal)
	and then we run spot checks for creatures around the target
	with the distance determined by SPOT_RADIUS (see const int below).
	
	If the PC has certain effects (ex. daze) then he cannot
	make the attempt. Also, if the target has the same effects
	the chance to spot is 0. If the PC is invisible,
	the target or others around the target must have the 
	proper spells to see the PC's attempt. Also, if the PC is in stealth mode,
	the code runs an opposed spot to see the PC as well before checking
	for the pickpocket attempt.
	
*/
//:://////////////////////////////////////////////
//:: Created By: Dagesh
//:: Created On: 3/2015
//:: Edited By:
//:: Edited On:
//:://////////////////////////////////////////////

#include "_inc_time"

// This sets the max that local
// spotters can assist in spotting pickpocketers
//const int CROWD_SPOT_SYNERGY_MAX = 5;

// How far around the target that will also run
// spot checks against the pickpocket attempt
const float SPOT_RADIUS = 7.5;

// This checks for acceptable races that can be
// pickpocketed
int GetAcceptableRace( object oTarget );

// Checks to see if PC has certain effects
int GetHasCertainEffects( object oPC = OBJECT_SELF );

// This runs the loop for people around the target
// who may spot the attempt
void RunRadiusCheck( object oMainTarget, object oPC = OBJECT_SELF );

void main()
{
	// This may be different 
	object oPC = OBJECT_SELF;

	int nSecondsPassed = GetTimeStampTotalSeconds( oPC, "PICKPOCKET_ELAPSED" );
	
	if( nSecondsPassed < 30 &&
		nSecondsPassed != 1 )
	{// Not enough time has passed and the stamp has been set
		string sMessage = IntToString( 30 - nSecondsPassed );
		string sMessage2 = " seconds.";
		if( nSecondsPassed == 1 )
		{// one second left, let's use proper English
			sMessage2 = " second.";
		}
		SendMessageToPC( oPC, "You may use this skill in " + sMessage + sMessage2 );
		return;
	}// Not enough time has passed and the stamp has been set
		
	// This will more than likely be different as well. I assume NWNX4 is involved
	object oTarget = GetSpellTargetObject(); 
	
	// ** Run some filters first **
	
	if( GetHasCertainEffects( oPC ) )
	{// Can't pickpocket with these effects
		SendMessageToPC( oPC, "You are currently unable to pick a pocket." );
		return;		
	}// Can't pickpocket with these effects
		
	if( !GetAcceptableRace( oTarget ) )
	{// Can only pickpocket humanoids
		SendMessageToPC( oPC, "That is not an acceptable target." );
		return;
	}// Can only pickpocket humanoids
			
	// ** Filters Done **
	
	// run a check for valid creatures in a certain radius to run spot checks
	
	AssignCommand( oPC, ActionMoveToObject( oTarget, FALSE, 0.5 ) );
	AssignCommand( oPC, ActionDoCommand( RunRadiusCheck( oTarget ) ) );
	
	
}

int GetHasEffect( int nEffectType, object oPC = OBJECT_SELF )
{
	effect eEffect = GetFirstEffect( oPC );
	
	int bReturn = 0;
	
	while( GetIsEffectValid( eEffect ) )
	{
		if( GetEffectType( eEffect ) == nEffectType )
		{
			bReturn = 1;
			break;
		}
		eEffect = GetNextEffect( oPC );
	}
	return bReturn;
}

int GetHasCertainEffects( object oPC = OBJECT_SELF )
{
	// Can't pickpocket with these effects
	if( GetHasEffect( EFFECT_TYPE_BLINDNESS ) || 
		GetHasEffect( EFFECT_TYPE_CONFUSED ) || 
		GetHasEffect( EFFECT_TYPE_CUTSCENE_PARALYZE ) || 
		GetHasEffect( EFFECT_TYPE_CUTSCENEIMMOBILIZE ) || 
		GetHasEffect( EFFECT_TYPE_DAZED ) || 
		GetHasEffect( EFFECT_TYPE_DOMINATED ) || 
		GetHasEffect( EFFECT_TYPE_ETHEREAL ) || 
		GetHasEffect( EFFECT_TYPE_FRIGHTENED ) || 
		GetHasEffect( EFFECT_TYPE_INSANE ) || 
		GetHasEffect( EFFECT_TYPE_PARALYZE ) || 
		GetHasEffect( EFFECT_TYPE_PETRIFY ) || 
		GetHasEffect( EFFECT_TYPE_SLEEP ) || 
		GetHasEffect( EFFECT_TYPE_STUNNED ) )
	{
		return TRUE;		
	}
	return FALSE;
}

int GetAcceptableRace( object oTarget )
{
	int nRacialType = GetRacialType( oTarget );

	switch( nRacialType )
	{// acceptable races to pickpocket from
		case RACIAL_TYPE_DWARF:
		case RACIAL_TYPE_ELF:
		case RACIAL_TYPE_GIANT:
		case RACIAL_TYPE_GNOME:
		case RACIAL_TYPE_GRAYORC:
		case RACIAL_TYPE_HALFELF:
		case RACIAL_TYPE_HALFLING:
		case RACIAL_TYPE_HALFORC:
		case RACIAL_TYPE_HUMAN:
		case RACIAL_TYPE_HUMANOID_GOBLINOID:
		case RACIAL_TYPE_HUMANOID_MONSTROUS:
		case RACIAL_TYPE_HUMANOID_ORC:
		case RACIAL_TYPE_HUMANOID_REPTILIAN:
		case RACIAL_TYPE_OUTSIDER:
		case RACIAL_TYPE_UNDEAD:
		{
			return TRUE;
		}
		
	}// acceptable races to pickpocket from
		
	return FALSE;
	
}

int RunSpotCheck( object oTarget, object oMainTarget, object oPC = OBJECT_SELF )
{
	
	// *** RUN MULTIPLE CHECKS FOR TARGET'S SPOT *** \\
	
	int nTargetSpot = GetSkillRank( SKILL_SPOT, oTarget );
	
	if( nTargetSpot < 0 )
		nTargetSpot = 0;
		
	nTargetSpot = nTargetSpot + d20();

	if( GetHasCertainEffects( oTarget ) )
	{// Target has certain effects preventing it from spotting
		nTargetSpot = 0;
	}// Target has certain effects preventing it from spotting

	if( GetHasSpellEffect( EFFECT_TYPE_INVISIBILITY ) )
	{// PC pickpocketer is invisible
		if( !GetHasSpellEffect( SPELL_BLINDSIGHT, oTarget ) &&
			!GetHasSpellEffect( SPELL_SEE_INVISIBILITY, oTarget ) )
		{// Target does not have means to see it
			nTargetSpot = 0;
		}// Target does not have means to see it
	}// PC pickpocketer is invisible
			
	if( GetStealthMode( oPC ) == STEALTH_MODE_ACTIVATED )
	{// PC is hiding while PPing
		int nHide = GetSkillRank( SKILL_HIDE ) + d20();
		if( nTargetSpot < nHide )
		{// if spot is less than hide,reduce spotting the pick pocket to 0
			nTargetSpot = 0;
		}// if spot is less than hide,reduce spotting the pick pocket to 0
	}// PC is hiding while PPing
	
	// *** DONE RUNNING MULTIPLE CHECKS FOR TARGET'S SPOT *** \\
	
	int nSleightOfHand = GetSkillRank( SKILL_SLEIGHT_OF_HAND ) + d20();
	
	if( nTargetSpot > nSleightOfHand )
	{// SPOTTED!
		if( GetIsPC( oTarget ) )
		{// spotter is a PC
			string sPickerName = GetName( oPC );	
			string sTargetName = GetName( oTarget ) + "'s";
			if( oTarget == oMainTarget )
			{
				sTargetName = "your";
			}
			SendMessageToPC( oTarget, "You have spotted " + sPickerName + 
									  "trying pick " + sTargetName + " pocket!" );
		}// spotter is a PC
		else
		{
			SpeakString( "THIEF!" );	
		}
	}// SPOTTED
	else if( oTarget == oMainTarget )
	{// PC passed spot check
		// I am only giving feedback on successful attempts otherwise PCs get
		// rewarded with information on an unsuccessful attempt
		FloatingTextStringOnCreature( "SUCCESSFUL ATTEMPT: " + IntToString( nSleightOfHand ), oPC, FALSE );
		
		// Gold recieved is roll + 20
		int nGoldAmount = nSleightOfHand + 20;
		
		GiveGoldToCreature( oPC, nGoldAmount, TRUE );
		
		if( GetIsPC( oTarget ) )
		{// report and log pickpocket		
		
			SendMessageToPC( oPC, "Your pickpocket has been sent to the DMs and logged." );
			
			string sReport = "****************************\n" +
							 "PICKPOCKET BY PC: " + GetName( oPC ) + "\n" +
							 "PICKPOCKET LOGIN NAME: " + GetPCPlayerName( oPC ) + "\n" +
							 "PICKPOCKET TARGET: " + GetName( oTarget ) + "\n" +
							 "PICKPOCKET TARGET LOGIN NAME: " + GetPCPlayerName( oTarget ) + "\n" + 
							 "GOLD RECEIVED: " + IntToString( nGoldAmount ) + "\n" +
							 "****************************";
			
			WriteTimestampedLogEntry( sReport );
			
			SendMessageToAllDMs( sReport );
			
			TakeGoldFromCreature( nGoldAmount, oTarget, TRUE, FALSE );			
			
		}// report and log pickpocket
		
		return TRUE;
	
	}// PC passed spot check
	
	return FALSE;
}

void RunRadiusCheck( object oMainTarget, object oPC = OBJECT_SELF )
{
	object oObject = GetFirstObjectInShape( SHAPE_SPHERE, SPOT_RADIUS, GetLocation( oMainTarget ), TRUE );
	
	while( GetIsObjectValid( oObject ) )
	{
		if( GetAcceptableRace( oObject ) && 
			oObject != oPC )
		{
			RunSpotCheck( oObject, oMainTarget );	
		}
				
		oObject = GetNextObjectInShape( SHAPE_SPHERE, SPOT_RADIUS, GetLocation( oMainTarget ), TRUE );
	}	
		
}
(note, _inc_time is a separate script I can send if desired)

(another note, it isn't tested in game)
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander
User avatar
Rasael
Retired Staff
Posts: 8096
Joined: Wed Jun 30, 2010 6:52 am
Location: Leiden, Netherlands

Re: The New Pick-pocket Script

Unread post by Rasael »

Its a very good sample script Dagash. You use comments well and the code is clearly written. In terms of what we have on the server its a fine approximation. It misses a number of the refinements, NWN2 fixes, and new features but those would be hard to incorporate without spending more time on it and NWN 2 development. What i mean are routines to deal with bugs and unexpected feedback, as well as code to make the guard npcs respond....Our community has been blessed recently with a good number of excelent programmers. :)
Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

Re: The New Pick-pocket Script

Unread post by Dagesh »

Awesome and thank you!

Most of my time is with NWN1 and NWNX2. I have a lot to learn about the stuff added to NWN2.
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander
Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

Re: The New Pick-pocket Script

Unread post by Dagesh »

I seem to have a problem w/ bystanders spotting the attempt. It seems their spot check is surprisingly high. Is there a spot buff for NPCs?
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander
User avatar
Rasael
Retired Staff
Posts: 8096
Joined: Wed Jun 30, 2010 6:52 am
Location: Leiden, Netherlands

Re: The New Pick-pocket Script

Unread post by Rasael »

Yes it scales on a falling curve with your level. You get less risk as you level but we didn't want the risk to disappear too quickly. The reward is partly based on the risk you run / difficulty. :)


https://www.youtube.com/watch?v=wcSXyyn7Ifw :lol:
Nihm
Posts: 63
Joined: Tue Apr 12, 2011 4:32 pm

Re: The New Pick-pocket Script

Unread post by Nihm »

That is awesome! Would it be hard to have the thief thrown in jail the same way the guards do when someone doesn't put a weapon away?
Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

Re: The New Pick-pocket Script

Unread post by Dagesh »

There's still a number of issues.

+If in stealth or invisible the pickpocket can still be spotted despite being completely unseen. No synergy love for the rogue? :cry: I find it hard to believe that a rogue w/ a million hide/ms can be seen by someone 10 meters away who can't see them anyways. Perhaps limit the spot check only to the target in this case. If this check is added, perhaps also break stealth/invis if attempt unsuccessful.
+If the target is stunned or has other similar effects it can still spot the attempt. Silly frozen target. Don't you know you're paralyzed?!
+Everything calls out for the guards or what not. Xvarts are optimistic I suppose.
+If the target is a non-humanoid it can still be pickpocketed. All those wyvern pockets? IKR?!

I know I'm a broken record and I'm sure you guys are getting to it :D. I'm going to recommend these next few chunks once again just in case. They're easily inserted into the right spot of code.


Check for Effects
Hidden: show

Code: Select all

int GetHasEffect( int nEffectType, object oPC = OBJECT_SELF )
{
   effect eEffect = GetFirstEffect( oPC );
   
   int bReturn = 0;
   
   while( GetIsEffectValid( eEffect ) )
   {
      if( GetEffectType( eEffect ) == nEffectType )
      {
         bReturn = 1;
         break;
      }
      eEffect = GetNextEffect( oPC );
   }
   return bReturn;
}

int GetHasCertainEffects( object oPC = OBJECT_SELF )
{
   // Can't pickpocket with these effects
   if( GetHasEffect( EFFECT_TYPE_BLINDNESS ) || 
      GetHasEffect( EFFECT_TYPE_CONFUSED ) || 
      GetHasEffect( EFFECT_TYPE_CUTSCENE_PARALYZE ) || 
      GetHasEffect( EFFECT_TYPE_CUTSCENEIMMOBILIZE ) || 
      GetHasEffect( EFFECT_TYPE_DAZED ) || 
      GetHasEffect( EFFECT_TYPE_DOMINATED ) || 
      GetHasEffect( EFFECT_TYPE_FRIGHTENED ) || 
      GetHasEffect( EFFECT_TYPE_INSANE ) || 
      GetHasEffect( EFFECT_TYPE_PARALYZE ) || 
      GetHasEffect( EFFECT_TYPE_PETRIFY ) || 
      GetHasEffect( EFFECT_TYPE_SLEEP ) || 
      GetHasEffect( EFFECT_TYPE_STUNNED ) )
   {
      return TRUE;      
   }
   return FALSE;
}
Check for Racial type (we're racist when it comes to pickpocketing)
Hidden: show

Code: Select all

int GetAcceptableRace( object oTarget )
{
   int nRacialType = GetRacialType( oTarget );

   switch( nRacialType )
   {// acceptable races to pickpocket from
      case RACIAL_TYPE_DWARF:
      case RACIAL_TYPE_ELF:
      case RACIAL_TYPE_GIANT:
      case RACIAL_TYPE_GNOME:
      case RACIAL_TYPE_GRAYORC:
      case RACIAL_TYPE_HALFELF:
      case RACIAL_TYPE_HALFLING:
      case RACIAL_TYPE_HALFORC:
      case RACIAL_TYPE_HUMAN:
      case RACIAL_TYPE_HUMANOID_GOBLINOID:
      case RACIAL_TYPE_HUMANOID_MONSTROUS:
      case RACIAL_TYPE_HUMANOID_ORC:
      case RACIAL_TYPE_HUMANOID_REPTILIAN:
      case RACIAL_TYPE_OUTSIDER:
      case RACIAL_TYPE_UNDEAD:
      {
         return TRUE;
      }
      
   }// acceptable races to pickpocket from
      
   return FALSE;
   
}
Pickpocketer is in stealth or invisible and target can't see invis
Hidden: show

Code: Select all

  if( GetHasSpellEffect( EFFECT_TYPE_INVISIBILITY ) )
   {// PC pickpocketer is invisible
      if( !GetHasSpellEffect( SPELL_BLINDSIGHT, oTarget ) &&
         !GetHasSpellEffect( SPELL_SEE_INVISIBILITY, oTarget ) )
      {// Target does not have means to see it
         nTargetSpot = 0;
      }// Target does not have means to see it
   }// PC pickpocketer is invisible
         
   if( GetStealthMode( oPC ) == STEALTH_MODE_ACTIVATED )
   {// PC is hiding while PPing
      int nHide = GetSkillRank( SKILL_HIDE ) + d20();
      if( nTargetSpot < nHide )
      {// if spot is less than hide,reduce spotting the pick pocket to 0
         nTargetSpot = 0;
      }// if spot is less than hide,reduce spotting the pick pocket to 0
   }// PC is hiding while PPing
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander
User avatar
Rasael
Retired Staff
Posts: 8096
Joined: Wed Jun 30, 2010 6:52 am
Location: Leiden, Netherlands

Re: The New Pick-pocket Script

Unread post by Rasael »

Hello Dagesh,

The issue with races is actually a stock NWN2 bug, its not related to scripting. Sometimes the function you use, GetRace or GetSubRace, will return 0. Normally this isn't an issue because 0 is treated as nothing or FALSE.... but with the race functions the dwarven race is actually entry 0. So every time the function returns an error it literally returns a dwarf in NWN2 script....

There is a way around it and I am not positive whether the latest version of the script is currently on the server eitherway. In any case, once the updating process is under way again I will incorporate it and send the amended version to Luna.
Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

Re: The New Pick-pocket Script

Unread post by Dagesh »

Rasael wrote:Hello Dagesh,

The issue with races is actually a stock NWN2 bug, its not related to scripting. Sometimes the function you use, GetRace or GetSubRace, will return 0. Normally this isn't an issue because 0 is treated as nothing or FALSE.... but with the race functions the dwarven race is actually entry 0. So every time the function returns an error it literally returns a dwarf in NWN2 script....

There is a way around it and I am not positive whether the latest version of the script is currently on the server eitherway. In any case, once the updating process is under way again I will incorporate it and send the amended version to Luna.
Oh the joys of 0. Good old' Acid Fog too if I remember correctly. Could there be a secondary if X == 0 && X != Dwarf Race follow up kind of thing or is it just the default function that's bugged. That would be horrible. Maybe GetAppearance would work? Gotta love bug squashing.
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander
User avatar
Theodore01
Recognized Donor
Posts: 2927
Joined: Wed Feb 16, 2011 5:32 pm

Re: The New Pick-pocket Script

Unread post by Theodore01 »

Have been in a party with an active thief recently, who always picked all monsters pockets.

My toon (with a spot skill of 4) got this message over and over.

Image

It is very annoying to have to click the dialog each time,
even more as the thief never stole from our party, (at least i assume ;) ).
User avatar
Blackman D
Retired Staff
Posts: 4818
Joined: Sat Sep 12, 2009 5:43 am
Location: IL

Re: The New Pick-pocket Script

Unread post by Blackman D »

do you know if his SoH is way higher than you should detect? either way i dont think any updates to this have gone in :?
everyone is evil till proven otherwise
User avatar
Theodore01
Recognized Donor
Posts: 2927
Joined: Wed Feb 16, 2011 5:32 pm

Re: The New Pick-pocket Script

Unread post by Theodore01 »

Blackman D wrote:do you know if his SoH is way higher than you should detect?
his SoH was 17.
Considerate_
Posts: 630
Joined: Tue May 11, 2010 5:51 am

Re: The New Pick-pocket Script

Unread post by Considerate_ »

Well, that means you do have a chance of catching him every now and then in the act, though you shouldn't get it every time!

Regardless... Are you supposed to be able to call the guards on him in the middle of a cave, surrounded by monsters? I know the Flaming Fists are good at upholding the law, buuuuuut! :P
Tamara - "I've seen colours you would never dream of"
Neschera - "Logic can bring you from one step to the next, creativity can bring you from anywhere to everywhere"
Post Reply

Return to “Solved Problems”