Author Topic: All encompassing Door handler script  (Read 355 times)

Legacy_Birdman076

  • Sr. Member
  • ****
  • Posts: 320
  • Karma: +0/-0
All encompassing Door handler script
« on: August 29, 2011, 03:39:50 am »


               This is what I currently have which works wonderful for closing and locking doors.

void main()
{
  object oDoor = OBJECT_SELF;
  float fClose;
  string sClose = GetLocalString( OBJECT_SELF, "sClose" );

  if( sClose == "" )
  {
    fClose = 15.0;
  }
  else if( sClose == "-1" )
  {
    return;
  }
  else
  {
    fClose = StringToFloat( sClose );
  }

  DelayCommand( fClose, ActionCloseDoor(oDoor) );

  if ( GetLockLockable( oDoor ) )
  {
    SetLocked( oDoor, TRUE );
  }
}

Ideally i'd like to have a script that would handle via variables set on the door things such as day/night locked or locked for x amount of time, xp for unlocking (if door is unlocked, door would remain unlocked for set amount of time again variable driven and then relocked with a higher DC to simulate a better lock the NPC bought as not to be broken into again), racial locks, class locks, locked based on feat req, skill req, attribute req, spell req, etc. Pretty much the full gamut of options in one script so we don't need multiple scripts to handle multiple door events only variables set on the door for what we wish to happen. Anyone care to tackle this or know of a solution already in place?
               
               

               


                     Modifié par Birdman076, 29 août 2011 - 02:41 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
All encompassing Door handler script
« Reply #1 on: August 29, 2011, 04:48:00 am »


               You can't really do this with one script since many of the things you want are triggered with different door events. OnUnLock, OnOpened. You could probably get away with 2 "all encompassing" scripts unless you want things to also happen in the OnFailToOpen, OnLock, etc..

You'd probably also need a specific list of what you want since "all encompassing" to one person does not mean the same thing to another.
               
               

               
            

Legacy_Birdman076

  • Sr. Member
  • ****
  • Posts: 320
  • Karma: +0/-0
All encompassing Door handler script
« Reply #2 on: August 29, 2011, 01:57:39 pm »


               Well, as far as a list of features:

OnClosed:

Day/Night locked/unlocked variable driven
Locked/Unlocked for xx.xx amount of time variable driven
Locked/Unlocked based on skill variable driven
Locked/Unlocked based on class variable driven
Locked/Unlocked based on race variable driven
Locked/Unlocked based on sex variable driven
Locked/Unlocked based on feat variable driven
Locked/Unlocked based on spell variable driven
Locked/Unlocked based on subrace variable driven
Locked/Unlocked based on deity variable driven
Locked/Unlocked based on item variable driven

OnUnlock

Xp for unlocking based on dc of lock, skill level, and player level (a penalty against multi-class rogues who's last level taken was not a rogue. My opinion on this is that they have slacked off on their rogueish duties and do not have the concentration, knowledge, and commitment of a pure rogue who has devoted his/her life to the arts of stealth & thievery and as such should suffer a slight skill penalty because of that. Let the pure rogues be rogues, let the power builders be power builders.)

A chance to "break" the lock thereby making it unpickable for xx.xx amount of time till it is "fixed" or replaced.

Set the DC of the lock higher to simulate a better lock once successfully picked variable driven for having the feature and for the DC increment.

Place an "alarm" variable on the door that spawns in creatures based on a string stored on the door for the creatures resref

Do a level check against the unlocker, if they are too high of a level (configured with a variable on the door) they are penalized xp rather then gain xp. This would give the lower level rogues a chance to pick lower level locks and make some $$ and keep the DC to a sane level for low level rogues if the door is featured with a DC adjustment on successful unlocking.

I'm sure there is more, but thats all that comes to mind right now.
               
               

               


                     Modifié par Birdman076, 29 août 2011 - 12:59 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
All encompassing Door handler script
« Reply #3 on: August 29, 2011, 06:30:18 pm »


               

GhostOfGod wrote...

You can't really do this with one script since many of the things you want are triggered with different door events. OnUnLock, OnOpened. You could probably get away with 2 "all encompassing" scripts unless you want things to also happen in the OnFailToOpen, OnLock, etc..

You'd probably also need a specific list of what you want since "all encompassing" to one person does not mean the same thing to another.

Actually, you CAN mix n' match events with scripts. You have to be careful, though, as you can get some very hard-to-debug results and erratic behavior, if you don't get it right. Here, by way of example, is our script for handing out task objective objects, called by a number of different objects and events:


#include "hg_inc"
#include "tsk_inc"

void main()
{
    CheckGivePCsTaskObjective();
}

And the included function:

void CheckGivePCsTaskObjective() {
    object oPC, oArea, oItem;
    int nTaskGiver, nTask, nType = GetObjectType(OBJECT_SELF);
    string sTask, sObjTag, sConRes = "";
    struct IntList list;
    location lLoc;

    if (nType == OBJECT_TYPE_PLACEABLE) {
        if (!GetIsPC(oPC = GetLastUsedBy()))
            return;
        sTask = GetLocalString(OBJECT_SELF, "tsk_objective");

    } else if (GetIsPC(OBJECT_SELF)) {//SIMTools search command
        oPC = OBJECT_SELF;
        lLoc = GetLocalLocation(oPC, "tsk_click");
        DeleteLocalLocation(oPC, "tsk_click");

        if (!GetIsObjectValid(GetAreaFromLocation(lLoc)))
            return;

        object oWay = GetNearestObjectOfTagToLocation("tsk_search", lLoc);

        if (GetDistanceBetweenLocations(lLoc, GetLocation(oPC)) > 4.0) {
            FloatingTextStringOnCreature("You must be closer to the spot you are attempting to search.", oPC, FALSE);
            return;
        }
        float fDis = GetLocalFloat(oWay, "tsk_dist");
        if (!GetIsObjectValid(oWay) || (GetDistanceBetweenLocations(GetLocation(oWay), lLoc) > fDis)) {
            FloatingTextStringOnCreature("You search, but find nothing.", oPC, FALSE);
            return;
        }

        sTask = GetLocalString(oWay, "tsk_objective");

    } else if (nType == OBJECT_TYPE_CREATURE) {
        oPC = GetIsPC(GetLastKiller()) ? GetLastKiller() : GetMaster(GetLastKiller());
        if (!GetIsPC(oPC))
            return;
        sTask = GetLocalString(OBJECT_SELF, "tsk_objective");

    } else if (GetIsObjectValid(oItem = GetItemActivated())) {//quest container item
        oPC = GetItemActivator();
        lLoc = GetItemActivatedTargetLocation();

        if (!GetIsObjectValid(GetAreaFromLocation(lLoc)))
            return;

        if (GetDistanceBetweenLocations(lLoc, GetLocation(oPC)) > 4.0) {
            FloatingTextStringOnCreature("You must be closer to the spot you are attempting to use the container on.", oPC, FALSE);
            return;
        }

        string sNoFind = GetLocalString(oItem, "tsk_nofind");
        if (sNoFind == "")
            sNoFind = "You don't find anything to put in the container.";
        string sFind = GetLocalString(oItem, "tsk_find");
        if (sNoFind == "")
            sNoFind = "You fill the container.";

        object oWay = GetNearestObjectOfTagToLocation("tsk_container", lLoc);

        sTask = GetLocalString(oWay, "tsk_objective");
        list = GetIntList(sTask);
        sConRes = GetTaskObjectiveItemResRef(list.i0, list.i1)+"_c";

        float fDis = GetLocalFloat(oWay, "tsk_dist");
        if (!GetIsObjectValid(oWay) || GetResRef(oItem) != sConRes || (GetDistanceBetweenLocations(GetLocation(oWay), lLoc) > fDis)) {
            FloatingTextStringOnCreature(sNoFind, oPC, FALSE);
            return;
        }

        FloatingTextStringOnCreature(sFind, oPC, FALSE);

    }


    if (sTask == "")
        return;

    list = GetIntList(sTask);
    nTaskGiver = list.i0;
    nTask = list.i1;

    oArea = GetArea(oPC);
    if (GetLocalInt(oArea, "DespawnTime")) {
        FloatingTextStringOnCreature("You cannot find task objectives in a despawned area.", oPC, FALSE);
        return;
    }

    sObjTag = GetTaskObjectiveItemResRef(nTaskGiver, nTask);

    int nPCHD = GetHitDiceIncludingLLs(oPC);
    object oCon, oMember = GetFirstFactionMember(oPC);
    while (GetIsObjectValid(oMember)) {

        if (!GetPCHasTaskActive(oMember, nTaskGiver)             ||
            (GetTaskCompleted(oMember, nTaskGiver) != (nTask-1)) ||
            (abs(GetHitDiceIncludingLLs(oMember)-nPCHD) > 6)) {//no more than 6 level spread
            oMember = GetNextFactionMember(oPC);
        } else {

            if (!GetLocalInt(oMember, sObjTag)) {
                SetLocalInt(oMember, sObjTag, 1);//mark it fresh - doubles as a DoOnce

                if (!GetIsObjectValid(GetItemPossessedByResRef(oMember, sObjTag))) {
                    oItem = CreateItemOnObject(sObjTag, oMember);
                    SetPickpocketableFlag(oItem, FALSE);
                } else
                    FloatingTextStringOnCreature("You already acquired this.", oMember, FALSE);

                if (sConRes != "" && GetIsObjectValid(oCon = GetItemPossessedByResRef(oMember, sConRes)))
                    DestroyObject(oCon);
            } else
                FloatingTextStringOnCreature("You already acquired this.", oMember, FALSE);

            oMember = GetNextFactionMember(oPC);
        }
    }
}


Again, I'm not necessarily advocating that you do this, just noting that it is possible, and sometimes convenient. It can also generate serious debugging headaches. When you call event-related functions in different events, it can yeild very unpredictable results. Even after writing the above in a way that seemed logically safe to me, I had to shuffle the if/else order around, and alter the way I did some things, in order to stop some quixotic bugs.

Funky
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
All encompassing Door handler script
« Reply #4 on: August 29, 2011, 08:14:49 pm »


               o.O

Wow, that's gonna be a doozy script, whoosh!
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
All encompassing Door handler script
« Reply #5 on: August 29, 2011, 11:45:00 pm »


               @Funky. So which door event would you use to include all that the OP wants for both locked and unlocked doors?