Author Topic: Need some verification  (Read 375 times)

Legacy_zero-feeling

  • Sr. Member
  • ****
  • Posts: 287
  • Karma: +0/-0
Need some verification
« on: May 24, 2014, 10:18:09 am »


               

been about a year since i've dabbled in building, so..... been working on finishing an old mod and wanted to make sure a script i have will do what i think it will (or what it's supposed to do at least)


 


the script is supposed to spawn in enemies when a player rests and are spotted.


this will interrupt the players rest so any and all spells and such will not be reset (need full rest for this)


it's supposed to be a random chance based on an integer. (can't remember where i'm supposed to put these anymore)


so... can someone verify that the script is right and maybe help me remember where the integers go again?


 


void main()

{

ExecuteScript("horse_delete",OBJECT_SELF);

object oPC = GetLastPCRested();

ExecuteScript("sh_res",oPC);

object oMount;

object oArea = GetArea(oPC);

location lPCLoc = GetLocation(oPC);

if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)

    {

    int nChanceOfEncounter = GetLocalInt(oArea,"chance_encounter");

    if (d100() <= nChanceOfEncounter)

        {

        int nNumMonsterTypes = GetLocalInt(oArea,"num_monster_types");

        int nMaxAmountMonsters = GetLocalInt(oArea, "max_amount_monsters");

        int nRandMonsterType = Random(nNumMonsterTypes) + 1;

        int nMonsters = Random(nMaxAmountMonsters) + 1;

        string sMonsterType = GetLocalString(oArea, "monster_num" + IntToString(nRandMonsterType));

        for (nMonsters; nMonsters > 0; nMonsters--)

            {

            object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sMonsterType, lPCLoc, FALSE);

            AssignCommand(oEnemy, ActionAttack(oPC));

            }

        AssignCommand(oPC, ActionSpeakString("Wake Up!!!  We're under attack!!!", TALKVOLUME_TALK));

        }

    }

    object oItem, oArea2;

    vector v;

    float fFacing;

    switch(GetLastRestEventType())

    {

    case REST_EVENTTYPE_REST_STARTED:

      oItem = GetItemPossessedBy(oPC,"memorybox");

      oArea2 = GetArea(oPC);

      v = GetPosition(oPC);

      fFacing = GetFacing(oPC);

        SetLocalString(oItem,"LOC_A",GetTag(oArea));

        SetLocalFloat(oItem,"LOC_X",v.x);

        SetLocalFloat(oItem,"LOC_Y",v.y);

        SetLocalFloat(oItem,"LOC_Z",v.z);

        SetLocalFloat(oItem,"LOC_F",fFacing);

    break;

    case REST_EVENTTYPE_REST_CANCELLED:

    case REST_EVENTTYPE_REST_FINISHED:

      ExportSingleCharacter(oPC);

      FloatingTextStringOnCreature("** Character Saved **",oPC,FALSE);

    break;

    }

}

 

thanks


               
               

               
            

Legacy_BelowTheBelt

  • Hero Member
  • *****
  • Posts: 699
  • Karma: +0/-0
Need some verification
« Reply #1 on: May 24, 2014, 01:37:27 pm »


               The way this script is set up, you are supposed to put the Local Variables (integers and the strings) on the Area.  So, right-click on each area in your area list, select Properties, then select the Advanced tab, then click the Variables button.  You can input the list of variables there.


This script requires that you put the resrefs of each monster type onto each area (for each sMonsterType). This seems like a cumbersome way to hold this data, especially if you have areas with the same list, since it has to be repeated for each area.  That's a pain for you to have to manually set up and maintain.


I'd recommend creating a custom function using an integer variable to denote your random creature list.  This would add a new integer to be added to the area


Int iList = GetLocalInt(oArea,"iList");


But, it removes the need for nMonsterNum and sMonsterType in the script above.


It could be something like

 string GetRandomCreature (int iList)

{

String sResref;

Switch (iList}

  {

  Case 1:  

     {

      Switch (Random(6))

        {

        Case 0:  sResref= "nw_rat"; break;

        Case 1 and so on and so on

        Break;

        }

  Case 2:

  Case 3:

  And so on

  }

return Resref;

}


This way, areas only have to carry the int variable iList, which tells the script what wandering monster table to reference, rather than a huge list of resrefs. And, similar areas don't have to have duplicate lists.


You can more easily construct robust wandering monster tables without worrying about having to update each and every area when there is a change.  


Hope that helps. I didn't check your script to see if yours compiles.


Lastly, the spawning location is the PC's location.  You may want to pick a random location somewhere near the PC, rather then right on him/her.
               
               

               
            

Legacy_zero-feeling

  • Sr. Member
  • ****
  • Posts: 287
  • Karma: +0/-0
Need some verification
« Reply #2 on: May 24, 2014, 07:27:01 pm »


               

thanks for the info. i don't think i even implemented this script in to my mod yet, i just happened to stumble upon it. 


 


so keeping in mind i'm not a an expert, would i just need to remove this section


 


 {

        int nNumMonsterTypes = GetLocalInt(oArea,"num_monster_types");

        int nMaxAmountMonsters = GetLocalInt(oArea, "max_amount_monsters");

        int nRandMonsterType = Random(nNumMonsterTypes) + 1;

        int nMonsters = Random(nMaxAmountMonsters) + 1;

        string sMonsterType = GetLocalString(oArea, "monster_num" + IntToString(nRandMonsterType));

        for (nMonsters; nMonsters > 0; nMonsters--)

            {

            object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sMonsterType, lPCLoc, FALSE);

            AssignCommand(oEnemy, ActionAttack(oPC));

            }

 


then add in what was suggested in it's place? i'm sure there's more, but am i on the right track?


 


thanks



               
               

               
            

Legacy_Ed Venture

  • Full Member
  • ***
  • Posts: 200
  • Karma: +0/-0
Need some verification
« Reply #3 on: May 26, 2014, 03:46:09 am »


               

 object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sMonsterType, lPCLoc, FALSE);


            AssignCommand(oEnemy, ActionAttack(oPC));

___________________________________________________________________________________________________________

Is it just me ? It has been my experience that Assigning Commands to spawns dosen't work. If they are hostles they will attack, but for friendlies I have had to SetInts and execute the script again.

Just a noob, trying to learn,

Ed


               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Need some verification
« Reply #4 on: May 26, 2014, 09:54:50 am »


               I've been looking at this recently. Bear in mind is that CreateObject causes the OnSpawn script to run after the current script finishes. So, if OnSpawn issues ClearAllActions(), which the unmodified Bioware scripts do via WalkWayPoints, any actions in your script will be cancelled.

The workarounds are either to issue the actions with a very brief DelayCommand, or change the spawn script.
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Need some verification
« Reply #5 on: May 26, 2014, 05:30:16 pm »


               

I'm not sure on that Proleric.  It would take ClearAllActions(TRUE); to get rid of combat actions like ActionAttack()



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Need some verification
« Reply #6 on: May 26, 2014, 10:57:00 pm »


               I'll recheck when I'm back at my desk, but IIRC WalkWayPoints has ClearAllActions with a debug flag, which is logically true.
               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Need some verification
« Reply #7 on: May 27, 2014, 07:33:33 am »


               Apologies, I was wrong about that. WalkWayPoints only clears actions if there are waypoints to walk, and doesn't clear combat actions.
               
               

               
            

Legacy_zero-feeling

  • Sr. Member
  • ****
  • Posts: 287
  • Karma: +0/-0
Need some verification
« Reply #8 on: May 28, 2014, 10:04:56 am »


               

so... not to be rude... but to get back to my question...


 


from what i get out of what belowthebelt says i need to do something like this:


 


string GetRandomCreature (int iList)

    {

    String sResref;

    Switch (iList}

        {

        Case 1:

            {

            Switch (Random(3))

                {

                Case 0: sResref= "rst_sytar"; break;

                Break;

              Case 1: sResref= "rst_sytar2"; break;

                Break;

              Case 2: sResref= "rst_sytar3"; break;

                Break;

                }

            return Resref;

            }

        Case 2:

            {

            Switch (Random(3))

                {

                Case 0: sResref= "rst_blackhand"; break;

                Break;

                Case 1: sResref= "rst_blackhand2"; break;

                Break;

                Case 2: sResref= "rst_blackhand3"; break;

                Break;

                }

            return Resref;

            }

        Case 3:

            {

            Switch (Random(3))

                {

                Case 0: sResref= "rst_ork"; break;

                Break;

                Case 1: sResref= "rst_ork2"; break;

                Break;

                Case 2: sResref= "rst_ork3"; break;

                Break;

                }

            return Resref;

            }

        Case 4:

            {

            Switch (Random(3))

                {

                Case 0: sResref= "rst_brood"; break;

                Break;

                Case 1: sResref= "rst_brood2"; break;

                Break;

                Case 2: sResref= "rst_brood3"; break;

                Break;

                }

            return Resref;

            }

        }

    }

 

 

and incorporate it in to this:

 

 

void main()

{

ExecuteScript("horse_delete",OBJECT_SELF);

object oPC = GetLastPCRested();

ExecuteScript("sh_res",oPC);

object oMount;

object oArea = GetArea(oPC);

location lPCLoc = GetLocation(oPC);

if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)

    {

    int nChanceOfEncounter = GetLocalInt(oArea,"chance_encounter");

    if (d100() <= nChanceOfEncounter)

        {

        int nNumMonsterTypes = GetLocalInt(oArea,"num_monster_types");

        int nMaxAmountMonsters = GetLocalInt(oArea, "max_amount_monsters");

        int nRandMonsterType = Random(nNumMonsterTypes) + 1;

        int nMonsters = Random(nMaxAmountMonsters) + 1;

        string sMonsterType = GetLocalString(oArea, "monster_num" + IntToString(nRandMonsterType));

        for (nMonsters; nMonsters > 0; nMonsters--)

            {

            object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sMonsterType, lPCLoc, FALSE);

            AssignCommand(oEnemy, ActionAttack(oPC));

            }

        AssignCommand(oPC, ActionSpeakString("Wake Up!!!  We're under attack!!!", TALKVOLUME_TALK));

        }

    }

    object oItem, oArea2;

    vector v;

    float fFacing;

    switch(GetLastRestEventType())

    {

    case REST_EVENTTYPE_REST_STARTED:

      oItem = GetItemPossessedBy(oPC,"memorybox");

      oArea2 = GetArea(oPC);

      v = GetPosition(oPC);

      fFacing = GetFacing(oPC);

        SetLocalString(oItem,"LOC_A",GetTag(oArea));

        SetLocalFloat(oItem,"LOC_X",v.x);

        SetLocalFloat(oItem,"LOC_Y",v.y);

        SetLocalFloat(oItem,"LOC_Z",v.z);

        SetLocalFloat(oItem,"LOC_F",fFacing);

    break;

    case REST_EVENTTYPE_REST_CANCELLED:

    case REST_EVENTTYPE_REST_FINISHED:

      ExportSingleCharacter(oPC);

      FloatingTextStringOnCreature("** Character Saved **",oPC,FALSE);

    break;

    }

}

 

 

is this right? if so, and keeping in mind i'm only a novice scripter, where and how would this be done?

 

thanks again


               
               

               
            

Legacy_BelowTheBelt

  • Hero Member
  • *****
  • Posts: 699
  • Karma: +0/-0
Need some verification
« Reply #9 on: May 28, 2014, 02:06:48 pm »


               

Try this on for size.  Compare it to your version to see the edits.  As far as the wandering monsters are concerned, you need the following area integers:

 

"chance_encounter"

"max_amount_monsters"

"RandomMonsterTable"


 


You can see the call to the custom script within the 'for' loop.  We create the resref of the creature through it and then the creature is created using that found resref.

 

I also cleaned up the code and incorporated the second switch statement into the first (I didn't see a specific reason why you should be looping through the rest types a second time, so I moved the effects of the second rest check into the first).  This saves the engine from having to spend some resources recalculating the rest type.  


 


As an aside, the benefit of how you have it set up now, is that each area can hold individual chance of encounter and max amounts, which gives you great flexibility to make wildly different chances per area of wandering monsters.  However, if you find that you are using similar values across areas with the same tables, it is possible to incorporate those values into the custom script, so that each Table has its own chance of encounter/max amounts.   In that way, you wouldn't have to set 3 variables per area, just the RandomMonster Table.  It would make all areas using the same table have the same chance and max monsters, but could simplify things a bit more if you found that you're re-using the same values whenever you reference each table.  Just a thought.



string GetRandomCreature (int iList)
    {
    string sResref;
    switch (iList)
        {
        case 1:
            {
            switch (Random(3))
                {
                case 0: sResref= "rst_sytar"; break;
                case 1: sResref= "rst_sytar2"; break;
                case 2: sResref= "rst_sytar3"; break;
                }
            break;
            }
        case 2:
            {
            switch (Random(3))
                {
                case 0: sResref= "rst_blackhand"; break;
                case 1: sResref= "rst_blackhand2"; break;
                case 2: sResref= "rst_blackhand3"; break;
                }
            break;
            }
        case 3:
            {
            switch (Random(3))
                {
                case 0: sResref= "rst_ork"; break;
                case 1: sResref= "rst_ork2"; break;
                case 2: sResref= "rst_ork3"; break;
                }
            break;
            }
        case 4:
            {
            switch (Random(3))
                {
                case 0: sResref= "rst_brood"; break;
                case 1: sResref= "rst_brood2"; break;
                case 2: sResref= "rst_brood3"; break;
                }
            break;
            }
        }
    return sResref;
    }
 
 
void main()
{
ExecuteScript("horse_delete",OBJECT_SELF);
object oPC = GetLastPCRested();
ExecuteScript("sh_res",oPC);
 
switch (GetLastRestEventType())
    {
    case REST_EVENTTYPE_REST_STARTED:
        {
        object oArea = GetArea(oPC);
        location lPCLoc = GetLocation(oPC);
        if (d100() <= GetLocalInt(oArea,"chance_encounter"))
            {
            int nMonsters = Random(GetLocalInt(oArea, "max_amount_monsters")) + 1;
            string sResref;
            for (nMonsters; nMonsters > 0; nMonsters--)
                {
                sResref = GetRandomCreature (GetLocalInt(oArea, "RandomMonsterTable"));
                object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sResref, lPCLoc, FALSE);
                AssignCommand(oEnemy, ActionAttack(oPC));
                }
            AssignCommand(oPC, ActionSpeakString("Wake Up!!!  We're under attack!!!", TALKVOLUME_TALK));
            }
        object oItem = GetItemPossessedBy(oPC,"memorybox");
        vector v = GetPosition(oPC);
        SetLocalString(oItem,"LOC_A",GetTag(oArea));
        SetLocalFloat(oItem,"LOC_X",v.x);
        SetLocalFloat(oItem,"LOC_Y",v.y);
        SetLocalFloat(oItem,"LOC_Z",v.z);
        SetLocalFloat(oItem,"LOC_F",GetFacing(oPC));
        }
    break;
    case REST_EVENTTYPE_REST_CANCELLED: break;
    case REST_EVENTTYPE_REST_FINISHED:
        {
        ExportSingleCharacter(oPC);
        FloatingTextStringOnCreature("** Character Saved **",oPC,FALSE);
        }
    break;
    }
}