Aller au contenu

Photo

Simply Stealing


  • Veuillez vous connecter pour répondre
10 réponses à ce sujet

#1
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages
:unsure: So I really tried finding a simple thieving script I could throw on a chest or what-have-you, but everything I dug up wanted me to put in whole honkin' system of functions... download .rar files and import a bunch of stuff. This doesn't suit my minimalist attitude. So I tried writing one and I haven't a clue why it won't compile. Of course, I never used a loop or an n'th variable before, either. Here it is...

//

#include "nw_i0_2q4luskan"
void main()
{
object oPC=GetLastOpenedBy();
object oWitness=GetNearestCreature();
int iWitness=1;
while (GetIsObjectValid(oWitness))
{
  if (GetCanSeePC(oWitness))
  {
  AssignCommand(oWitness, ActionSpeakString("''Thief!''"));
  AdjustReputation(oPC, oWitness, -100);
  SetIsTemporaryEnemy(oPC, oWitness);
  AssignCommand(oWitness, DetermineCombatRound(oPC));
  }
  oWitness=GetNearestCreature(iWitness++);
}
}

//

The ''AssignCommand(oWitness, DetermineCombatRound(oPC));'' Is giving me the error.

Will this even do what I want? Loop through the creatures and, if they can see the PC, set to killin'? If an n'th variable is being set, will it even work multiple times?

#2
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
There are a few reasons why this won't compile correctly. The error you specified is due to the fact that you also need to include "nw_i0_generic" to DetermineCombatRound. After that there are other problems though. You got some of the right ideas but you may want to specify exactly what you are looking for first as there are quite a few ways you can do this. You can use the GetNearestCreature but how many creatures do you want to loop through..just the 3 nearest? 4 nearest? etc.. You could also use the GetFirst/GetNextObject functions to loop through all of the objects in the area and then filter NPCs. I would recommend using the GetFirst/GetNextObjectInShape as this does less searching. You wouldn't have to search all the objects in the area, just the objects in a specified perimeter from the chest. Maybe just give that some thought and we can go from there?

Hope that helps ya somewhat.

Modifié par GhostOfGod, 23 juillet 2010 - 08:09 .


#3
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages
That helps a lot, actually. I don't really know what I'm doing, so I didn't know you could specify the number of creatures. Most of the anti-thieving scripts are gonna be placed in small areas like shops and homes. So I don't see there being numerous creatures around.



Basically, I just want a script that fires in the OnUnlock or OnOpen event which grabs, say, the nearest 5 creatures... if they can see the PC, they go hostile (fleeing if cowardly or attacking if not). I'd love to use the listening patterns too, but... one step at a time.

#4
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
Ok so here's my version of what I think you are looking for. Tested and working so far:

//Put script in the OnOpened or OnUnlocked event of object.
#include "nw_i0_generic"
void main()
{
//object oThief = GetLastUnlocked();
object oThief = GetLastOpenedBy();
int iWitness = 1;

while (iWitness <= 5)//Up to 5 NPCs who saw the theft will react. Can change.
    {
    object oWitness = GetNearestCreature(CREATURE_TYPE_PERCEPTION,
                                         PERCEPTION_SEEN, oThief, iWitness,
                                         CREATURE_TYPE_IS_ALIVE, TRUE);
    if (oWitness != OBJECT_INVALID)
        {
        AssignCommand(oWitness, ActionSpeakString("Stop thief!"));
        DelayCommand(1.0, AssignCommand(oWitness, DetermineCombatRound(oThief)));
        }
    else return;
    iWitness++;
    }
}


"oWitness" will most likely have to be further defined. If there is a nearby chicken that sees you it will react. Perhaps you don't want NPCs with evil alignments to attack. Maybe if the nearby NPC is a rogue they won't attack, etc..

Hope this helps. Good Luck.

Modifié par GhostOfGod, 23 juillet 2010 - 10:18 .


#5
TSMDude

TSMDude
  • Members
  • 865 messages
Dont know if this will help but we use a bit of a changed versin of the BioWare one.

On the Heart beat of the Mod we do a simple check and include.
#include "theft_functions"
void main()
//Paste below the void main in your own module heartbeat script 
object oFem;
if(oPC!=OBJECT_INVALID && GetIsPC(oPC) && !GetIsDM(oPC))
    {
    if(GetCurrentAction(oPC)==ACTION_OPENLOCK)
        {
        //Theft_SpotThief(oPC,FALSE,oPC);
        }
    else if (GetCurrentAction(oPC)==ACTION_PICKPOCKET)
        {
       //Good chance the victom is closest
       //If anybody knows a better way to do this let me know
       object oVictom = GetNearestObject(OBJECT_TYPE_CREATURE,oPC);
       //Theft_SpotThief(oPC,FALSE,oVictom);
        }
    else if((oFem = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC))!= OBJECT_INVALID)
        {//v1.1 Familiar Check
        if(GetCurrentAction(oFem)==ACTION_OPENLOCK)
            {
            //Theft_SpotThief(oFem,FALSE,oFem);
            }
        }
    else if((oFem = GetHenchman(oPC))!= OBJECT_INVALID)
        { //v1.1 Henchmen Check
        if(GetCurrentAction(oFem)==ACTION_OPENLOCK)
            {
            //Theft_SpotThief(oFem,FALSE,oFem);
            }
        }

On some spawned in NPCs that are NOT Guards

#include "theft_functions"
void main()
{
    int nEvent = GetUserDefinedEventNumber();
    if(nEvent == EVENT_HEARTBEAT)
    {
        if(GetLocalInt(OBJECT_SELF,"SPOTTED_THIEF"))
         {
            SetLocalInt(OBJECT_SELF,"SPOTTED_THIEF",0);
            SpeakString("Thief!! GUARDS!!!");
            Theft_AlertGuards(GetLocalObject(OBJECT_SELF,"THIEF"));
        }


On Some that are Guards in case they are in the vincinity

//*************** THEFT CODE ***********************
    int thief_alert = GetLocalInt(OBJECT_SELF,"SPOTTED_THIEF");
    if(thief_alert)
    {
        SetLocalInt(OBJECT_SELF,"SPOTTED_THIEF",0);
        object oThief = GetLocalObject(OBJECT_SELF,"THIEF");
        if(oThief != OBJECT_INVALID)
        {
            SetLocalInt(OBJECT_SELF,"SPOTTED_THIEF",0);
            ActionAttack(oThief);
            DetermineCombatRound(oThief);
            SpeakString("Thief!!!");//React to theft
            //I saw the crime, Call for help.
            if(thief_alert == SPOTTED_THIEF)
                Theft_AlertGuards(oThief);
        }


And then added this
#include "theft_functions"
to the same scripts listed above. I know it sounds complicated but it has allowed us to do some things for rogues and allow them some more functionality. If I explained it horrible I apologize as I always suck at explaining things.Posted Image

#6
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages

GhostOfGod wrote...

Ok so here's my version of what I think you are looking for. Tested and working so far:

...

"oWitness" will most likely have to be further defined. If there is a nearby chicken that sees you it will react. Perhaps you don't want NPCs with evil alignments to attack. Maybe if the nearby NPC is a rogue they won't attack, etc..

Hope this helps. Good Luck.


Glorious! I wouldn't have figured that out. Still, the more I see it done right, the more I learn. You're right about those chickens, though. How would we put an intelligence test in there, so anything with an intelligence score less than 4 doesn't respond. 3 is considered animal intelligence, right? *checks* Right.

My module takes place in a rigid tyranny, so thieves are likely just killed, and any evil NPCs are happy for the opportunity to legally stab someone and call themselves civic minded.

Also, the PC's own henchmen won't react to this, will they?

#7
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages

TSMDude wrote...

Dont know if this will help but we use a bit of a changed versin of the BioWare one.

...
 If I explained it horrible I apologize as I always suck at explaining things.Posted Image


Wow. No, you explained well. I think I could use it but it looks like I would wanna tweak it and it's a bit complex for me to start pulling on strings to see what they do. Like, I recognize very few of those variables... the thief function ones. Thank you, though. I might have my buddy use it in his module, actually. I'll let you know.

#8
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
Same as above with added int check:

//Put script in the OnOpened or OnUnlocked event of object.
#include "nw_i0_generic"
void main()
{
//object oThief = GetLastUnlocked();
object oThief = GetLastOpenedBy();
int iWitness = 1;

while (iWitness <= 5)//Up to 5 NPCs who saw the theft will react. Can change.
    {
    object oWitness = GetNearestCreature(CREATURE_TYPE_PERCEPTION,
                                         PERCEPTION_SEEN, oThief, iWitness,
                                         CREATURE_TYPE_IS_ALIVE, TRUE);
    int iIntel = GetAbilityScore(oWitness, ABILITY_INTELLIGENCE, TRUE);
    if (oWitness != OBJECT_INVALID && iIntel > 3)
        {
        AssignCommand(oWitness, ActionSpeakString("Stop thief!"));
        DelayCommand(1.0, AssignCommand(oWitness, DetermineCombatRound(oThief)));
        }
    else return;
    iWitness++;
    }
}


And in testing i know a familiar will not attack you. I don't think your own henchmen/followers can attack you. Though I could be mistaken on that one.:D

Modifié par GhostOfGod, 23 juillet 2010 - 08:08 .


#9
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages
Ha! THAT's the simplicity I was after. I couldn't find anything like that for the life of me! Awesome. I can make progress once again! Thank you for your time, good ghost!

#10
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

One Thousand Talons Mao Ra wrote...

 
Basically, I just want a script that fires in the OnUnlock or OnOpen event which grabs, say, the nearest 5 creatures... if they can see the PC, they go hostile (fleeing if cowardly or attacking if not). I'd love to use the listening patterns too, but... one step at a time.


If you ever do start messing with the listening pattern.  Here is a brief decription of how you would do it.  


 The only thing the chest would have to do is shout something wen it is opened. Now having the chest shout does not mean the PC would hear it.  But all the NPC that could see it would.   For the shout you would use something like this in the on opened. 



SpeakString("THIEF_I_WAS_LOOTED", TALKVOLUME_SILENT_TALK);

or if the thief is good at what he is doing:


SpeakString("THIEF_I_WAS_LOOTED", TALKVOLUME_SILENT_WISPER);

You can look at the  Default On Attacked script: NW_C2_DEFAULT5  to see how bioware used this to make an NPC Shout if he was attacked.

Now that you have the Chest shouting something You just need to make sure that the NPC are listening for it.
You do this by setting a listening pattern on the NPC's.   Bioware  sets there    Listening Patterns in the OnSpawn script for the NPC.  They call the single function SetListeningPatterns(); that calls SetListeningPattern(); several times for a given NPC depending on how they want him to react.  If you wanted to see the code for  the SetListeningPatterns(); function that bioware uses. it is buryed deep in the includes so can be hard to find.  I is in
x0_i0_spawncond down around line 161. you will note this is where ihe NPC are set to listen for that  NW_I_WAS_ATTACKED That NPC silently shout when they are attacked. 

So for your system you would need to set something like :

SetListenPattern(OBJECT_SELF, "THIEF_I_WAS_LOOTED", 156 ); in the onspawn scripts for your NPC's

The 156 is just a unique number not used any of the other things the NPC may be listening for .( Hoppfully.) 


The Third and last part is to setup what the NPC's do if they hear the cry of looting.  This is done in the OnConversation event for the NPC's   the default one bioware uses is  NW_C2_DEFAULT4.  You can see a few of the shouts listed there that the NPC's are listening for.  But most of them are handled by the function: RespondToShout(oShouter, nMatch, oIntruder);  called twords the bottom of that script.  If you want to see what is in that function it is in  nw_i0_generic down around line 1086. 

So to have your NPC respond when the hear the shout and following the pattern boiware did you would have something like this added to the onConversation script. 


 if (nMatch == 156)
{
// the command you want the NPC to do.
// You can even chech for other stuff on the npc here to have different ons do different things. 
}

This has the advantage that if you set it up on all your NPC's anytime you a chest in any area that shouts.  The Defualt NPC will react.  you could have defenders that would always take note when the noticed and comoners that could randomly do anything thing from run away to attack.  Or even shout for help from a defender.  

Hope this was explained good enough.  

Good luck.  
 
      

#11
One Thousand Talons Mao Ra

One Thousand Talons Mao Ra
  • Members
  • 40 messages
That is outstanding info for me, Lightfoot. That actually solves other issues for me. I have a couple crates where goblins keep their babies, if you kill them through a conversation, I wanted them to shout that they had been killed. Now I know how.