Author Topic: Looping Through Areas/Dynamic Conversation Options  (Read 1408 times)

Legacy_BelowTheBelt

  • Hero Member
  • *****
  • Posts: 699
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« on: July 21, 2010, 09:47:00 pm »


               Banging my head on trying to get a custom system in place for my faction leaders.  The purpose of this is so that faction leaders can identify areas within the world for their faction members to attack. 

I have an area int variable set on a number of areas on the module -  "Attack" set to 1. 

2 Questions:
1)  How can I loop through all the module areas looking for variables?
2)  How do I in a conversation, identify those areas and dynamically represent them into the conversation. 

I realize the second part would involve custom tokens, but have very limited experience with using them.  I also considered using a waypoint in the selected areas rather than an area variable, but I'm still stuck at creating a "list" of areas that have the waypoint.

Any help is much appreciated.
               
               

               
            

Legacy_ChaosInTwilight

  • Full Member
  • ***
  • Posts: 126
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #1 on: July 21, 2010, 10:06:10 pm »


               #1:   You really can't cycle through area's, so... The best method(AFAIK, the only method) for doing this is to slap down a waypoint in each and every area.    You can then cycle through those and get the area from that.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #2 on: July 22, 2010, 04:49:00 am »


               Will need more information on how you want to display the areas to give much help on formatting your custom tokens.

As far as the areas go. Placing an object in the area, sounds like the way to go.

The function below compiled but is untested.

// //::///////////////////////////////////////////////
//:: Name L8_Inc_Area
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
- In order to use the functions you must have
- placed a object in each Area with the tag 'Area'.
- This will include the area in the iterator list.
-
- GetFirstArea and GetNextArea functions are iterators
- and there for can not be nested.
-
- Warning: If there are two objects with the tag 'Area'
- in the an area. It will cause the area to show up twice
- in the iterator.
*/
//:://////////////////////////////////////////////
//:: Created By:LightFoot8
//:: Created On: 7-21-10
//:://////////////////////////////////////////////

 
const string AREA_COUNT = "L8_AREA_COUNT";
const string AREA = "L8_AREA_";
const string WAYPOINT_TAG = "Area_";
int CURRENT_AREA;
 
///returns the area of the first object with a tag of 'Area'
object GetFirstArea ();
 
///returns the area of the next object with a tag of 'Area'
object GetNextArea();
 
///function Definitions
void CacheAreaList()
{
int iCount;
object oArea;
object oMod = GetModule();
do
{
oArea = GetArea(GetObjectByTag(WAYPOINT_TAG,iCount));
SetLocalObject(oMod, AREA+IntToString(iCount), oArea);
iCount++;
}
while (GetIsObjectValid(oArea));
SetLocalInt(oMod,AREA_COUNT,iCount);
[/list]}
 
object GetFirstArea ()
{
object oMod = GetModule();
if (!GetLocalInt(oMod, AREA_COUNT)) CacheAreaList();
CURRENT_AREA = 0;
return GetLocalObject( oMod , AREA + IntToString(CURRENT_AREA));
}
 
object GetNextArea()
{
CURRENT_AREA++;
return GetLocalObject (GetModule() ,AREA+IntToString(CURRENT_AREA));
}
               
               

               


                     Modifié par Lightfoot8, 23 juillet 2010 - 04:57 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #3 on: July 22, 2010, 01:59:00 pm »


               yeah that will work, however Im using the same and got strange issue with some areas appeared twice or thrice (yes waypoint there is only once), I fixed it by using string patter where I store each area resref, if its there already, it skips that area to be added into "pseudo-list" now not so sure

EDIT: yet error in your script, in initializing process, you store waypoint, you should store GetArea(oArea)
               
               

               


                     Modifié par ShaDoOoW, 22 juillet 2010 - 01:11 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #4 on: July 23, 2010, 05:59:24 am »


               Thanks for the error report ShaDoOoW.   I edited the corection into the above post.
               
               

               
            

Legacy__Knightmare_

  • Full Member
  • ***
  • Posts: 191
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #5 on: July 23, 2010, 12:36:27 pm »


               @ Lightfoot - just wondering how you had your script display with the colors there. Is there some meta-tag for that or did you manually go through and use the <color> tag?
               
               

               
            

Legacy_TSMDude

  • Hero Member
  • *****
  • Posts: 1515
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #6 on: July 23, 2010, 02:48:27 pm »


               

_Knightmare_ wrote...

@ Lightfoot - just wondering how you had your script display with the colors there. Is there some meta-tag for that or did you manually go through and use the tag?

]

Sorry for the hijack but I too would love to know that.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #7 on: July 23, 2010, 05:09:56 pm »


               simi-manually went through and added the BBC code.  



I say simi-manually because i opened it in a text editor and used the find/replace function.  



for example I did a search for int and replaced it with (color=lightseagreen)int(/color)



useing square braces in place of the () of course.  



I plan on making a app to do the converting for me at some point just don't have the time yet.

It Could be a good segestion for the Devlopers board.
               
               

               
            

Legacy_BelowTheBelt

  • Hero Member
  • *****
  • Posts: 699
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #8 on: July 23, 2010, 08:57:35 pm »


               thanks for the reply. Here's what I did, which also includes use of custom tokens.

Essentially, I'm trying to create a list of selected areas in the module so that faction and guild leaders can target to launch "long range" attacks using siege engine placeables. Through a conversation, they can choose the type of siege engine (trebuchet, catapault, ballista, etc...) with each type having various quantity of ammunition, qualities of ammunition (damage), accuracy, and cost. The leader also gets to determine what portion of the target area to launch at (upper left, upper middle, upper right, middle left, middle middle, middle right, lower left, lower middle, lower right) Once launched, the system determines if, given the accuracy of the seige engine, whether the shot was "on target" or not. It then creates effects in a random spot within the spot that was hit and does the appropriate damage.

The area list will be static (i.e. the number of areas "shouldn't" change during the game, though it would be cool for DMs to have the flexibility to place down temporary banners that the system would recognize...), so I'm toying with the idea of writing the list to the module on the first use of the placeable so as to reduce system resource needs to do the loop every time the placeable is used.

So in the below code, I figure I'll use less than 100 waypoints in the module as being targettable (the areas are selected based on their proximity to all the faction headquarters).

My area tagging referenced in the code is based on the following convention: AX100Y100, where "A" or some other letter designates the type of map it is (A is for outdoor, B is for indoor) and then the X/Y coordinates on my map.

I'd be interested to hear how the above code might be better than what I've cobbled together, though I think we largely went in the same direction. I'm not sure that it would be appropriate to set the custom tokens here or set them in a different script. I was thinking of changing the SetCustomToken to SetLocalString and write it to the mod.

What do you think?


void main()
{
object oPC = GetPCSpeaker();
object oWP;
object oWPArea;

string sWPAreaName;
string sWPAreaTag;
string sWPAreaTagLeft1;

int iModSet = GetLocalInt (GetModule(), "SiegeListSet");
int iN;
int iWPCustomToken;

//if the loop has been done before, no need to do it again
if (iModSet !=0)
{
//Loop to look for waypoints
for (iN =0; iN
{
oWP = GetObjectByTag("WP_Siege, iN");
oWPArea = GetArea (oWP);
sWPAreaName = GetName (oWPArea);
sWPAreaTag = GetTag (oWPArea);
sWPAreaTagLeft1 = GetStringLeft (sWPAreaTag, 1);

int iAreaRace = GetLocalInt (oWPArea, "SeigeRace");

//Use area tag classification to determine if the area is outdoor, indoor, or underdark. Skip random dungeon areas. Others possible.
if (sWPAreaTagLeft1 == "A") //Outdoor
{
//Separate Feylands from non-fey. 1 = Fey, 2=Bastion/Human/Halfelf, 3 = Dwarf, 4 = Gnome, 5 = Monster, 6= halfling
if (iAreaRace ==1)
{
SetCustomToken (410000 + iN, sWPAreaName);
SetCustomToken (510000 + iN, sWPAreaTag);
}
else if (iAreaRace ==2)
{
SetCustomToken (442000 + iN, sWPAreaName);
SetCustomToken (542000 + iN, sWPAreaTag);
}
else if (iAreaRace ==3)
{
SetCustomToken (443000 + iN, sWPAreaName);
SetCustomToken (543000 + iN, sWPAreaTag);
}
else if (iAreaRace ==4)
{
SetCustomToken (444000 + iN, sWPAreaName);
SetCustomToken (544000 + iN, sWPAreaTag);
}
else if (iAreaRace ==5)
{
SetCustomToken (445000 + iN, sWPAreaName);
SetCustomToken (545000 + iN, sWPAreaTag);
}
else if (iAreaRace ==6)
{
SetCustomToken (446000 + iN, sWPAreaName);
SetCustomToken (546000 + iN, sWPAreaTag);
}
//Nonclaimed lands
else
{
SetCustomToken (470000 + iN, sWPAreaName);
SetCustomToken (570000 + iN, sWPAreaTag);
}
}
else if (sWPAreaTagLeft1 == "B")//indoor
{
//Separate Feylands from non-fey. 1 = Fey, 2=Bastion/Human/Halfelf, 3 = Dwarf, 4 = Gnome, 5 = Monster, 6= halfling
if (iAreaRace ==1)
{
SetCustomToken (420000 + iN, sWPAreaName);
SetCustomToken (520000 + iN, sWPAreaTag);
}
else if (iAreaRace ==2)
{
SetCustomToken (452000 + iN, sWPAreaName);
SetCustomToken (552000 + iN, sWPAreaTag);
}
else if (iAreaRace ==3)
{
SetCustomToken (453000 + iN, sWPAreaName);
SetCustomToken (553000 + iN, sWPAreaTag);
}
else if (iAreaRace ==4)
{
SetCustomToken (454000 + iN, sWPAreaName);
SetCustomToken (554000 + iN, sWPAreaTag);
}
else if (iAreaRace ==5)
{
SetCustomToken (455000 + iN, sWPAreaName);
SetCustomToken (555000 + iN, sWPAreaTag);
}
else if (iAreaRace ==6)
{
SetCustomToken (456000 + iN, sWPAreaName);
SetCustomToken (556000 + iN, sWPAreaTag);
}
//Nonclaimed lands
else
{
SetCustomToken (480000 + iN, sWPAreaName);
SetCustomToken (580000 + iN, sWPAreaTag);
}
}
else if (sWPAreaTagLeft1 == "U") //Underdark
{
//Separate Feylands from non-fey. 1 = Fey, 2=Bastion/Human/Halfelf, 3 = Dwarf, 4 = Gnome, 5 = Monster, 6= halfling
if (iAreaRace ==1)
{
SetCustomToken (430000 + iN, sWPAreaName);
SetCustomToken (530000 + iN, sWPAreaTag);
}
else if (iAreaRace ==2)
{
SetCustomToken (452000 + iN, sWPAreaName);
SetCustomToken (552000 + iN, sWPAreaTag);
}
else if (iAreaRace ==3)
{
SetCustomToken (463000 + iN, sWPAreaName);
SetCustomToken (563000 + iN, sWPAreaTag);
}
else if (iAreaRace ==4)
{
SetCustomToken (464000 + iN, sWPAreaName);
SetCustomToken (564000 + iN, sWPAreaTag);
}
else if (iAreaRace ==5)
{
SetCustomToken (465000 + iN, sWPAreaName);
SetCustomToken (565000 + iN, sWPAreaTag);
}
else if (iAreaRace ==6)
{
SetCustomToken (466000 + iN, sWPAreaName);
SetCustomToken (566000 + iN, sWPAreaTag);
}
//Nonclaimed lands
else
{
SetCustomToken (490000 + iN, sWPAreaName);
SetCustomToken (590000 + iN, sWPAreaTag);
}
}
}
}
SetLocalInt (GetModule(), "SiegeListSet",1);
}
               
               

               


                     Modifié par BelowTheBelt, 23 juillet 2010 - 08:00 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #9 on: July 23, 2010, 10:51:25 pm »


               

I'd be interested to hear how the above code might be better than what I've cobbled together, though I think we largely went in the same direction. I'm not sure that it would be appropriate to set the custom tokens here or set them in a different script. I was thinking of changing the SetCustomToken to SetLocalString and write it to the mod.



It is better because:

It already does what you stated you plan on adding.

so I'm toying with the idea of writing the list to the module on the first use of the placeable so as to reduce system resource needs to do the loop every time the placeable is used.



The First time the GetFirstArea function above is called it caches the areas to the module. It will never do that again. After that first call it just looks at the list already made.

Basicly it is set up to be used as an #include file. 
Then you will be able to use:
GetFirstArea();
GetNextArea();

Just like you would use:
GetFirstPC();
GetNextPC();

There will be High overhead the first time GetFirstArea(); Is called after a server reset.  After the first call the over head is minute.  It will not even have to search for the area just grab the next one out of the list.

Since you already have your waypoints in place.  To use the script above, If you chose to,  Change the const at the top to your waypoint tag.

const string  WAYPOINT_TAG = "Area_";
               
               

               


                     Modifié par Lightfoot8, 23 juillet 2010 - 10:00 .
                     
                  


            

Legacy_BelowTheBelt

  • Hero Member
  • *****
  • Posts: 699
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #10 on: July 26, 2010, 09:02:20 pm »


               Thanks.  



Now that there's a cached list of areas and custom tokens set, how would I create a conversation node that would display all the areas (this could be 30-40+ areas) from the list as different PC covo options?  The size of the list is the main reason I subdivided the areas into categories (by racial faction, then by location - outdoor, indoor, underdark, etc...).  I was imagining a loop of all token numbers in a certain classification (that way the options are more like 10-15 per type).



I know how to set and display a single token in a conversation, but not multiple where there may be different numbers of tokens to display.



Thanks!
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #11 on: July 27, 2010, 12:48:05 am »


               Pardon me for saying this,

But you have scripted a disaster.

How may I ask do you plan on retrieving your custom tokens?

I mean  which tokens are set?

Does Custom token 410000 have a value set to it ?

By what I see there is no way to tell.

if (iAreaRace ==1) the first time through the loop it is set. If it was not equal to one the first time through the loop it is not set. How do we know what tokens are set and what tokens are not set. They are at this point just set in random spots decided by the loop iteration and the race.

Please don't take what I said Above the wrong way. We have all had our share of scripting disasters. Many times I have thought I had a great Idea that turned out like that.

How you set up the tokens really needs to be decided by how you are going to display them.
If you just wanted a list of areas to be displayed in the conversation that is really not a problem. You can just add the entire list of areas to the one token and add it to your text.

If you wanted each area to be selectable through this conversation that is a totally different matter altogether. for that you would need to build a conversation that dynamically changed a token that displayed the text for that node.

I know of no  way to dynamically place a different tokens or different number of tokens into a conversation node.

The first thing you most likely need to do is get the area's listed in some kind of linier order. At least where they are cached at. Or you will find yourself having to search for the areas over and over again. Even if they are stored by Tags. The tag would still have to be searched for in order to find the object. It is best if you store them by object this way they are already found and the engine does not have to search for the area again.

second is to decide how to pull off the conversation and the setting of the tokens.

For simplicity I would suggest just a list of the hostile areas in the conversation. This way you will not have to build a complex Text appears / Text Displayed/ Action Taken dynamic conversation tree.

for firing the artillery I would go with Siege Engineers (NPC) set to listening.

Have Pc walk within say 5’ of the one to fire and says “fire at the Eleven Hold northeast.” Or what ever area / cord system you want to use. If he fires at a friendly area. well that is on him. Or you could put controls in place for it. “Sir are you sure you want me to fire on our friends? “
               
               

               


                     Modifié par Lightfoot8, 26 juillet 2010 - 11:50 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #12 on: July 27, 2010, 01:06:19 am »


               I didnt read LightFoot's post, too long man ':whistle:', but easiest way is make 10 custom tokens and allow Previous/Next browsing.
If player uses Next it will increase local int by 10, Previous decrease by 10 etc...

I know this been done already, try to look for Dynamic Conversation at vault.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looping Through Areas/Dynamic Conversation Options
« Reply #13 on: July 27, 2010, 01:34:28 am »


               I'll ParaPhrase for you shadow.  

1) Tokens currently set in non- liner order with no way to find where they are set at. He need to rewrite what he has.  



2) suggestion: Forget about the headach of dynamic conversations and just list all the area in the conversation. Then set Seige engeneers to listening  to take verbal commands for the target.