RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[RunUO 2.0 RC1] Courageous Random Encounter System

hughesdylan

Sorceror
Courageous, you are offically my hero.

I had a looksie at the code more in depth, seems like caves would be quite a bit of work, and i dont really want to trouble anyone for it.


this code here looks to be where i would need to add a check for cave tiles, in addition to adding a type "cave" to the current set of tile types.

Code:
        public static LandType DetermineLandTypeForMobile( Mobile m )
        {
            Tile        landTile        = m.Map.Tiles.GetLandTile( m.X, m.Y );

            int         landId          = landTile.ID & 0x3FFF;

            if ((TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == TileFlag.Wet) return LandType.Water;

            if( m_RoadTileHash.ContainsKey( landId ) ) return LandType.OnRoad;

            return LandType.OffRoad;
        }

<Edit>

This was in the engine for mining. Could this help?

Code:
		private static int[] m_MountainAndCaveTiles = new int[]
			{
				220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
				230, 231, 236, 237, 238, 239, 240, 241, 242, 243,
				244, 245, 246, 247, 252, 253, 254, 255, 256, 257,
				258, 259, 260, 261, 262, 263, 268, 269, 270, 271,
				272, 273, 274, 275, 276, 277, 278, 279, 286, 287,
				288, 289, 290, 291, 292, 293, 294, 296, 296, 297,
				321, 322, 323, 324, 467, 468, 469, 470, 471, 472,
				473, 474, 476, 477, 478, 479, 480, 481, 482, 483,
				484, 485, 486, 487, 492, 493, 494, 495, 543, 544,
				545, 546, 547, 548, 549, 550, 551, 552, 553, 554,
				555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
				565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
				575, 576, 577, 578, 579, 581, 582, 583, 584, 585,
				586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
				596, 597, 598, 599, 600, 601, 610, 611, 612, 613,

				1010, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749,
				1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1771, 1772,
				1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782,
				1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1801, 1802,
				1803, 1804, 1805, 1806, 1807, 1808, 1809, 1811, 1812, 1813,
				1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823,
				1824, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839,
				1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849,
				1850, 1851, 1852, 1853, 1854, 1861, 1862, 1863, 1864, 1865,
				1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875,
				1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1981,
				1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991,
				1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
				2002, 2003, 2004, 2028, 2029, 2030, 2031, 2032, 2033, 2100,
				2101, 2102, 2103, 2104, 2105,

				0x453B, 0x453C, 0x453D, 0x453E, 0x453F, 0x4540, 0x4541,
				0x4542, 0x4543, 0x4544,	0x4545, 0x4546, 0x4547, 0x4548,
				0x4549, 0x454A, 0x454B, 0x454C, 0x454D, 0x454E,	0x454F
			};


Im not asking you to do the work for me, just curious. If i were to do it myself i would need to use the hex data at the end correct?

Like this?

Code:
        private static int[] m_CaveTileIds = new int[]
        {
				0x453B, 0x453C, 0x453D, 0x453E, 0x453F, 0x4540, 0x4541,
				0x4542, 0x4543, 0x4544,	0x4545, 0x4546, 0x4547, 0x4548,
				0x4549, 0x454A, 0x454B, 0x454C, 0x454D, 0x454E,	0x454F
        };
        private static Hashtable GenerateCaveTileHash()
        {
            Hashtable caveTiles = new Hashtable();

            for (int i = 0; i < m_CaveTileIds.Length; i += 2)
            {
                for (int j = m_CaveTileIds[i]; j < m_CaveTileIds[i + 1]; j++)
                    caveTiles [j] = j;
            }

            return caveTiles;
        }
 

Courageous

Wanderer
Yes. Assuming you have the tile codes right, I think that is about right. You would then have to add something to the xml parser to recognize your attempt to tag cave regions, do something else to the records that keep the encounters for the regions, and then make sure that the random selector did the right work.

C//
 

Courageous

Wanderer
I can imagine why; there is this evil bit of code that does pairwise refinement: wilderness/road/night that would multiply out to a huge morass if you did caves too. Named regions would likely be better.

C//
 

hughesdylan

Sorceror
Yea, pretty much hit the nail on the head there. Thanks for your help anyway. Very nice system. Im currently using it to make fallout-esque random encounters ;)

I do have a suggestion for this though. Is it possible to send a message to the pc that generated the encounter? Like "You see some bandits hiding in the bushes" or whatever?


Also, How do you add more than 1 gold coin on a spawn? You can add several 1 gold piles of coins, but the min/max seems to alwase default to the number of coin piles you select
 

KillerBeeZ

Knight
I have 2 questions.

before I ask, I would like to say I love the idea of this script kudos for making it even if it turns out that I cannot use it.

ok now for the questions.

1) I know this is for 2.0, but how hard would it be (if even possible) to retro code it to work on 1.0?

2) on my shard my players have the ability to become immortal (blessed = true) is there a way to skip the encounters for blessed players and if so, where would I start looking?
 

Courageous

Wanderer
I believe that I originally prototyped it under 1.0. It should be mostly the same; perhaps the parts that walk over the regions are a bit different, it's been a long time since I ported it.

If you don't want an encounter for a player:

Look in the method EncounterEngine.GenerateEncounters() at the loop that looks like this:

foreach (PlayerMobile chosenMobile in chosenMobiles)
{
....

What you should do is check to see if the chosenMobile meets your skip criteria, and if it does, continue.

You will see an example of skipping the player with this line:

if ( possibileEncounters == null ) continue;

This is saying that if there are no encounters matching the region the player is in, suitable for the player "continue" the loop to the next player and try that player instead.

Your code will be something like this instead:

if ( chosenMobile.Blessed() ) continue;

Or something similar...

C//

p.s. to answer Hughes' question:

To send the player a message, look at both where GenerateEncounter() is called in GenerateEncounters(). Once GenerateEncounter() is called, an encounter is definitely occuring (unlike GenerateEncounters, which should be "MaybeGenerateEncounters()" :)

To answer your question about gold, look in GenerateEncounter and then at the section:

else if ( created is Item )
{
.....

It's possible that the code written is inufficient to get a pile of gold to have the right quantity.

C//
 

KillerBeeZ

Knight
thank you so much. I found the 1.0 version.

are there any bugs I should know about with that version?

and thank you again for your help
 

Courageous

Wanderer
It's been a long time. I don't recall lots of bugs, what I recall is lots of features added. What I might suggest you do, if you are up to it, is try the one for 2.0 on 1.0, and when problems occur, look to the 1.0 code for answers.

C//
 

KillerBeeZ

Knight
Courageous;786889 said:
It's been a long time. I don't recall lots of bugs, what I recall is lots of features added. What I might suggest you do, if you are up to it, is try the one for 2.0 on 1.0, and when problems occur, look to the 1.0 code for answers.

C//

yeah I did that in a whim and it had a lot of errors. Since I'm not familiar with 2.0 I found the errors daunting.

but being a man who loves to learn I will eventually work on it.

example of use: I am using the 1.0 version at the moment. I added a mob that sets a property of the player that tells the random encounter engine to work (if the player doesn't have this property then no encounters)

I loved the Wheel of Time by Robert Jordan, so I made the Dark One, if he hits a player, he marks the player, a marked player will have random encounters with Trollocs and Fades until he kills all the forsaken and drops their heads onto Rand Al'Thor who then takes the mark unto himself freeing the player from this curse.

just figured I'd share
 

Courageous

Wanderer
That's an interesting idea.

Right now, it's possible to limit player encounters to "class" and "level". RunUO has neither classes nor levels, so this works by looking at various skill levels, and deciding that they if they are high enough then a player is a level so and so this and that. In which case they qualify for certain types of encounters.

I toyed around with the idea of marking players who'd done particularly bad things with a historical record. For example, if a villain character killed a prominent good character, the encounter system might detect it and have them visited by bounty hunters or some such. This historical record might be extended in various ways, with encounters occurring according to the players history.

You might imagine this being combined with a messaging system. "Bounty hunters are attacking you: you are wanting having attacked the hero, Courageous."

:)

C//
 

greymeister

Wanderer
Courageous;787061 said:
I toyed around with the idea of marking players who'd done particularly bad things with a historical record. For example, if a villain character killed a prominent good character, the encounter system might detect it and have them visited by bounty hunters or some such. This historical record might be extended in various ways, with encounters occurring according to the players history.

Talon Company/Regulator Spawns here we go :cool:

Great idea btw. I'm going to merge this into my development machine's environment and see what's cookin'.
 

Courageous

Wanderer
A long while back, someone was running a shard who had thrown away all their point based spawners. Instead, they would create named regions in their shard, and then all encounters were controlled by random encounters. The beauty of this is that you can edit everything in a simple text file, it all makes sense, and nothing is predictable as far as the player is concerned. The downside is that you don't have resident mobs. Encounters occur randomly instead.

Thinking of this, I think a good variation of random encounters would be to create some sort of persistency record on regions, and let random make random resident mobs for a region ('resident mobs' meaning mobiles that are already spawned when you get there).

C//
 

kmekc

Wanderer
Some things i found out, when porting the code to RunUO1.0. Btw this was quite easy if you recompiled Core under .Net2.0. ;)

Ok but now some improvements:

The On- and OffRoad-Tiles are not complete and following ranges are missing:

0x3FF8, 0x3FFB,
0x3FF4, 0x3FF4

The function GenerateRoadHashTiles exists twice. Once in GenerateEncounters and once in Helpers but only the Helpers function is called. Also the last tile from the tile ranges doesn't get added you have to change following:
Code:
                for( int j = m_RoadTileIds[i]; j <[COLOR="Red"]=[/COLOR] m_RoadTileIds[i+1]; j++ )
					roadTiles[j]=j;

Then you have some localization problems in Record.cs. If someone is using another windows localization he gets some problems with float and double values in the xml-File.

So every float.Parse and double.Parse has to be checked if the language is given. Next thing is the RandomEncounter.Pick function. You create a new RandomEncounter and call it with the values converted to strings. Now every value is again printed out in localized values and the parse function is called with the given localization. So there is again a problem. Better is to add this constructor and call him in Pick():

Code:
        public RandomEncounter( 
            XmlNode node, 
            string facet, 
            string regionType, 
            string regionName, 
            float probability, 
            int shortest, 
            int farthest, 
            LandType landType,
            EncounterTime time,
            double level,
            LevelType levelType,
            bool scaleUp
            )
        {
            m_XmlNode       = node;
            m_Facet         = facet;
            m_RegionType    = regionType;
            m_RegionName    = regionName;
			m_Probability	= probability;
			if( m_Probability < 0 )
				m_Inclusive = true;
			else
				m_Inclusive = false;
            m_Shortest      = shortest;
            m_Farthest      = farthest;
            m_LandType      = landType;
            m_EncounterTime = time;
            m_Level         = level;
            m_LevelType     = levelType;
            m_ScaleUp       = scaleUp;
            m_Elements      = new ArrayList();
		}

This way no new parse of the values is needed and you have no localization problem.
 

kmekc

Wanderer
I figured out that the compiler takes a while longer now to compile with your Scripts. So i investigated where the problems come from and found out that your Tour delegates are heavy load for the compiler.

As you are using variables in the delegate from the defining function this seems to be the problem for the compiler. I rewrote your searches and random encounter script, so now only named delegates are used. Also all needed variables are now declared in the delegate function head.

Added the patched scripts
 

Attachments

  • RandomEncounter.rar
    61.4 KB · Views: 32

Kondor11

Wanderer
Encounters not working

Hello,
I have problem here... encounters system loads, but it says:
Code:
RandomEncounters: Facet "Felucca" at (14,3) had no elements. IGNORED.
and no encounter works then...

here are my regions and randomencounters.xml:

Regions.xml - Felucca facet
Code:
	<Facet name="Felucca">
		<region type="Wilderness" priority="50" name="Kea'man">
			<rect x="6692" y="3608" width="422" height="510" />
		</region>
	</Facet>

RandomEncounters.xml
Code:
<RandomEncounters
    skiphidden="true"
    delay="0.0"
    interval="10.0:10.0:10.0"
    cleanup="1800.0"
    cleanupGrace="0"
    debug="true"
    debugEffect="true"
    RTFM="true"
    >

	<ServerRegions>
	  <Facet name="Felucca">
	    <region regiontype="Wilderness" priority="1" name="Zakl.Ostrov">
		<rect x="6741" y="3736" width="434" height="190">
			<Encounter p="1" level="1" distance="15" landtype="AnyLand" time="AnyTime">
				<Mobile p="1" pick="BrownBear" n="1:2" effect="Smoke:96"/>
			</Encounter> 
		</rect>
	    </region>
	  </Facet>
	</ServerRegions>
</RandomEncounters>
Can anyone please tell me what did i mess up? :)

BTW: i have custom map on my shard

Thx for any awnsers
 

Courageous

Wanderer
Random encounters does not accept rect tags in the encounter description. It knows all regions by "name," not by rect.

So if you define a region named "EvilDungeon" in your regions file, all you have to do is identify the region by name in your RandomEncounters file.

Do not attempt to guess at the syntax for RandomEncounters. Its syntax is well-defined. Look at the examples, and do not stray, except to use combinations of elements in the examples, or other documentation. There are no hidden features.

C//
 

Gosmann

Sorceror
great system
but my players dont get encounters
i want savages just to show up at nights
i want many of them
how i got to configure my randomencounters.xml?
please help
 

Gosmann

Sorceror
excuse me my double post

these are my regions

<region priority="0" name="Wald 1">
<rect x="912" y="473" width="170" height="220" />
</region>
<region priority="0" name="Wald 2">
<rect x="221" y="561" width="335" height="354" />
</region>
<region priority="0" name="Wald 3">
<rect x="507" y="841" width="302" height="542" />

and these is my randomencounter

<RandomEncounters
picker="all"
skiphidden="true"
delay="0.0"
interval="5.0:5.0:5.0"
cleanup="1800.0"
cleanupGrace="0"
debug="true"
debugEffect="false"
RTFM="true"
>

<Facet name="Ilshenar">
<Region type="Wilderness" name="Wald 1, Wald 2, Wald 3">
<Encounter p="1.0" distance="5" time="Night" >
<Mobile pick="Savage" n="2:10" effect="Smoke:96"/>
</Encounter>
</Region>
</Facet>
</RandomEncounters>

I dont know what i messed up
please help
 
Top