Aller au contenu

Photo

Question about area building...


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

#1
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

I have an old PW mod that has a number of city areas with many shops. Currently each shop is its own area. I'm wondering if it wouldn't be more efficient to condense those little internal shop areas into one not overly large area. Are there any pros and cons to doing this that I should be aware of?



#2
henesua

henesua
  • Members
  • 3 858 messages

AFAIK Its best to locate all of the actual stores in an area that players do not visit. By the actual store i mean the waypoint looking object rather than the NPC who provides access to the store.

 

If you do this, then combining those areas into one should work fine.



#3
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

AFAIK Its best to locate all of the actual stores in an area that players do not visit. By the actual store i mean the waypoint looking object rather than the NPC who provides access to the store.

 

If you do this, then combining those areas into one should work fine.

 

Why exactly is that better? As I mentioned before this mod is older (was last updated in 1.68) but it currently has the stores spawn in, much like npcs spawn in, with an on enter script. If the area is empty of players then npcs/shops/items left on the ground are cleaned up and removed. I'm all for improvements though. I'd just like to understand the benefits of doing the shops that way. The way I currently do it allows for shop inventories to be periodically reset so they never get overburdened with too many things being sold to the vendors yet still gives players an opportunity to buy the vendored items of others if a market area is particularly busy with players.



#4
Thayan

Thayan
  • Members
  • 244 messages

I recommend condensing things like generic shops and generic buildings into one physical area per city or general location. Then use the OnEnter script to hide the area every time someone enters so that if they've already visited other shops in that physical area, they don't show on the minimap.

 

Not only does this make it a little easier to manage these locations in the toolset, but it helps reduce the number of resources in the module since there is the known limitation of ~16K resources (.are, .git, .uti, .nss, etc, etc, etc) files that can be in the module before you start running into problems.


  • Nic Mercy aime ceci

#5
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

I recommend condensing things like generic shops and generic buildings into one physical area per city or general location. Then use the OnEnter script to hide the area every time someone enters so that if they've already visited other shops in that physical area, they don't show on the minimap.

 

Not only does this make it a little easier to manage these locations in the toolset, but it helps reduce the number of resources in the module since there is the known limitation of ~16K resources (.are, .git, .uti, .nss, etc, etc, etc) files that can be in the module before you start running into problems.

Oooh I like that "hide the map" on enter tip! That was a minor concern of mine that the map would look a bit silly. Do you happen to know the specific script command to do that?



#6
henesua

henesua
  • Members
  • 3 858 messages

I could be wrong but my understanding was that all the inventory of a store was cycled through when a player enters an area. Perhaps this is only on the first entry. In anycase, I have observed some delays on area entry when lots of stores are in the same area, and saw the problem go away when I located the stores elsewhere.



#7
Thayan

Thayan
  • Members
  • 244 messages

The ExploreAreaForPlayer function is where the magic happens. Something like this should do the trick if you put it in your Area OnEnter script, so long as the right-hand side of the name of any generic shops area is 'Shops':

 

object oPC = GetEnteringObject();

if (GetStringRight(GetName(OBJECT_SELF), 5) == "Shops")  ExploreAreaForPlayer(OBJECT_SELF, oPC, FALSE);


  • Nic Mercy aime ceci

#8
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

The ExploreAreaForPlayer function is where the magic happens. Something like this should do the trick if you put it in your Area OnEnter script, so long as the right-hand side of the name of any generic shops area is 'Shops':

 

object oPC = GetEnteringObject();

if (GetStringRight(GetName(OBJECT_SELF), 5) == "Shops")  ExploreAreaForPlayer(OBJECT_SELF, oPC, FALSE);

Much obliged!



#9
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

I could be wrong but my understanding was that all the inventory of a store was cycled through when a player enters an area. Perhaps this is only on the first entry. In anycase, I have observed some delays on area entry when lots of stores are in the same area, and saw the problem go away when I located the stores elsewhere.

My consolidated area would have about 8 shops in it... I may give your suggestion a try!



#10
kalbaern

kalbaern
  • Members
  • 824 messages

Henesua is correct, inventories of placeables and the inventories of merchants waypoints get loaded when a PC enters the map they are found on. This can add to an areas loading times. If this made stores load faster when you accessed them, any extra load time would likely be moot. It doesn't though. When you open a store, all the inventory info is resent anyhow. So in the end, having stores on a single map that is inaccessible to players works just fine and can help optimize a module when combined with other lag reducing practices.

 

To enable merchant waypoints to work anyplace in your module, just change

 

object oStore = GetNearestObjectByTag("Store_"+sStore);

 

to

 

object oStore = GetObjectByTag("Store_"+sStore);

 

in your open store scripts.


  • OldTimeRadio et Nic Mercy aiment ceci

#11
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

Henesua is correct, inventories of placeables and the inventories of merchants waypoints get loaded when a PC enters the map they are found on. This can add to an areas loading times. If this made stores load faster when you accessed them, any extra load time would likely be moot. It doesn't though. When you open a store, all the inventory info is resent anyhow. So in the end, having stores on a single map that is inaccessible to players works just fine and can help optimize a module when combined with other lag reducing practices.

 

To enable merchant waypoints to work anyplace in your module, just change

 

object oStore = GetNearestObjectByTag("Store_"+sStore);

 

to

 

object oStore = GetObjectByTag("Store_"+sStore);

 

in your open store scripts.

 

Thanks for that I'll give it a shot!

 

Also Thayan thank you! I put a bit of my own spin on the script but the fog of war works absolutely perfectly on my interior map! Only the shop the player is in has its map shown and the others remain black no matter where you enter from or how often!


  • Thayan aime ceci

#12
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

Would either of you guys know of a good way to reset the merchants in that inaccessible area to periodically clean them out of any sold goods so they don't get bogged down?



#13
kalbaern

kalbaern
  • Members
  • 824 messages

I clean my own stores instantly, using the module "OnUnAcquireItem" event. Here's what I use for it:

#include "x2_inc_switches"
void main()
{
     object oItem = GetModuleItemLost();
     if (GetObjectType(GetItemPossessor(oItem)) == OBJECT_TYPE_STORE) DestroyObject(oItem, 0.1f);
     if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS) == TRUE)
     {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_UNACQUIRE);
        int nRet =   ExecuteScriptAndReturnInt(GetUserDefinedItemEventScriptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
           return;
        }

     }

}

This cleans sold items as each is sold. Some might consider it a drawback as that means something "accidentally" sold is lost, but with my economy, the sell value rarely comes close to the buying price and most couldn't .. or wouldn't repurchase at the time anyhow. My players just take a screenie .. send me a PM .. then suffer a lecture .. before I replace the item. :D

 



#14
ehye_khandee

ehye_khandee
  • Members
  • 855 messages

Basic advice - script CLEANLY, efficiently and you need not worry about 'too many areas'.

 

My server is stable, does not lag, does not crash, is repleat with smooth-running features, and boasts 1337+ Areas. Emphasis on the "+". NWN is a robust game, well built and stable. More, it was built for machines we were running 14 years ago... today's machines are far superior. The bottom line is this, unless the user does something really not-well-thought-out, NWN will  run fine. If you start to see lag or running crash issues, look to the systems used first (rather than too many areas).


  • Nic Mercy aime ceci

#15
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

I clean my own stores instantly, using the module "OnUnAcquireItem" event. Here's what I use for it:

#include "x2_inc_switches"
void main()
{
     object oItem = GetModuleItemLost();
     if (GetObjectType(GetItemPossessor(oItem)) == OBJECT_TYPE_STORE) DestroyObject(oItem, 0.1f);
     if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS) == TRUE)
     {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_UNACQUIRE);
        int nRet =   ExecuteScriptAndReturnInt(GetUserDefinedItemEventScriptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
           return;
        }

     }

}

This cleans sold items as each is sold. Some might consider it a drawback as that means something "accidentally" sold is lost, but with my economy, the sell value rarely comes close to the buying price and most couldn't .. or wouldn't repurchase at the time anyhow. My players just take a screenie .. send me a PM .. then suffer a lecture .. before I replace the item. :D

 

 

I'd prefer not to go this route. Ideally items would be "cleaned" out from vendors every few hours. I don't actually have any lag issues but I'm looking to optimize my mod and make things more efficient without giving up too much (I'd like the ability to buy back items if sold accidentally or to have other players have a chance to buy something sold to a vendor at least for a 2 hours).



#16
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

Basic advice - script CLEANLY, efficiently and you need not worry about 'too many areas'.

 

My server is stable, does not lag, does not crash, is repleat with smooth-running features, and boasts 1337+ Areas. Emphasis on the "+". NWN is a robust game, well built and stable. More, it was built for machines we were running 14 years ago... today's machines are far superior. The bottom line is this, unless the user does something really not-well-thought-out, NWN will  run fine. If you start to see lag or running crash issues, look to the systems used first (rather than too many areas).

 

I'm not too concerned about hitting the resource limit. But it just seems silly for me to tie up my mod with multiple single room areas for this or that shop when many that reside in the same general area (like a city) can be consolidated into a single area and a little fog of war trickery to give the illusion of being in that one shop. It just makes managing the mod in the toolset less of a hassle for me when I'm working instead of scrolling through a list of hundreds of areas.



#17
an ominous cow herd

an ominous cow herd
  • Members
  • 12 messages

The builders for Thain have, in recent history, consolidated many of the city interiors into one area (for each city). It's worked well for us, and certainly makes browsing the area list in the toolset easier.

 

For merchants, we have a script set to OnOpenStore that destroys duplicate items; this keeps the inventory somewhat tidy(er) but still allows other people to buy things other players have sold. We also have one particular shop that saves part of it's inventory over restarts since it's pretty much just a dump for loot and doesn't sell anything by default.

 

Here is the code (DISCLAIMER: I don't know if this is optimal. It's probably not! I didn't do it, I swear!)

// file name: merch_trim_inv
// Trim duplicate items from the merchant object if over the duplicate threshold
void main()
{
    // Bill Jones  20-Jun-2006; Reduced allowable duplicates from 5 to 3
    int iNumAllowedDupes = 3;
    int iItemCount;
    string sItemTag;

    object oCurrentItem = GetFirstItemInInventory();
    while (oCurrentItem != OBJECT_INVALID)
    {
        sItemTag = GetTag(oCurrentItem);
        iItemCount = GetLocalInt(OBJECT_SELF, "count_"+sItemTag);

        if (iItemCount >= iNumAllowedDupes)
        {
            DestroyObject(oCurrentItem);
        }
        // Bill Jones  24-Mar-2008; Don't count items with the tag "aly_throwweapons"
        else if (sItemTag != "aly_throwweapons")
        {
            iItemCount++;
            SetLocalInt(OBJECT_SELF, "count_"+sItemTag, iItemCount);
        }
        oCurrentItem = GetNextItemInInventory();
    }


    // Reset all the counts in preparation for the next store opening
    oCurrentItem = GetFirstItemInInventory();
    while (oCurrentItem != OBJECT_INVALID)
    {
        SetLocalInt(OBJECT_SELF, "count_"+GetTag(oCurrentItem), 0);
        oCurrentItem = GetNextItemInInventory();
    }
}

  • CaveGnome et Nic Mercy aiment ceci

#18
Nic Mercy

Nic Mercy
  • Members
  • 181 messages

 

The builders for Thain have, in recent history, consolidated many of the city interiors into one area (for each city). It's worked well for us, and certainly makes browsing the area list in the toolset easier.

 

For merchants, we have a script set to OnOpenStore that destroys duplicate items; this keeps the inventory somewhat tidy(er) but still allows other people to buy things other players have sold. We also have one particular shop that saves part of it's inventory over restarts since it's pretty much just a dump for loot and doesn't sell anything by default.

 

Here is the code (DISCLAIMER: I don't know if this is optimal. It's probably not! I didn't do it, I swear!)

// file name: merch_trim_inv
// Trim duplicate items from the merchant object if over the duplicate threshold
void main()
{
    // Bill Jones  20-Jun-2006; Reduced allowable duplicates from 5 to 3
    int iNumAllowedDupes = 3;
    int iItemCount;
    string sItemTag;

    object oCurrentItem = GetFirstItemInInventory();
    while (oCurrentItem != OBJECT_INVALID)
    {
        sItemTag = GetTag(oCurrentItem);
        iItemCount = GetLocalInt(OBJECT_SELF, "count_"+sItemTag);

        if (iItemCount >= iNumAllowedDupes)
        {
            DestroyObject(oCurrentItem);
        }
        // Bill Jones  24-Mar-2008; Don't count items with the tag "aly_throwweapons"
        else if (sItemTag != "aly_throwweapons")
        {
            iItemCount++;
            SetLocalInt(OBJECT_SELF, "count_"+sItemTag, iItemCount);
        }
        oCurrentItem = GetNextItemInInventory();
    }


    // Reset all the counts in preparation for the next store opening
    oCurrentItem = GetFirstItemInInventory();
    while (oCurrentItem != OBJECT_INVALID)
    {
        SetLocalInt(OBJECT_SELF, "count_"+GetTag(oCurrentItem), 0);
        oCurrentItem = GetNextItemInInventory();
    }
}

 

Much appreciated! I'll give this a looksee!