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!

Poisonous swamps

Alari

Wanderer
Poisonous swamps

Update: 02-14-2006: Added two more null checks, in the testing for swampboots and GetItemsInRange. Please post if you experience any crashes with this! Script in post and attached file have both been updated. Documentation also updated.

Update: 02-13-2006: Updated to include an internal map check. If the character is on the internal map, the swamp check ends. Updated included code and attached file.

Update: 01-30-2006: Updated for an apparently rare problem where the playermobile is or becomes null. Updated attached files and included code, as well as the file on my script archive site. I put the null check in two places, both before calling SwampCheck and as the first sanity check inside SwampCheck.

Update: 07-26-2005: Updated to verify the player height. (Players walking in structures in Papua will no longer be poisoned) Download and code attached updated.

Update: 07-25-2005: Detects Land/Terrain (ie: swamp east of Britain) Static (ie: 'static' dungeon decoration) and Added (ie: Pandora's Box or '[add static ####') swamps! Yay!



How this script works:


This script runs each time a character moves, examining the ground beneath them for 'swampy' tiles. Light swamp tiles (generally light green, such as found on the edges of swamps or in small islands around trees and such) have a 0.05% chance of giving the character a Lesser poisoning, while Deep swamp tiles (darker green, sometimes bubbling) have a 0.15% chance of giving the character a Regular poisoning.

I tested the values carefully, although they may seem low, from my experience a player has a reasonable chance of 'dashing across' a small patch of light swampy ground without becoming poisoned, while even short forays into deeper swamp areas will almost certainly poison the character after a few steps. Of course you can adjust the chance of poisoning to your own taste.


This script was inspired by the original Ultima series, where swampy ground would poison the characters.


Currently three forms of tile data are examined:

Land Terrain - These tiles are actual ground tiles, such as the kind of ground that can slope up or downhill. They are written to the map file as 'ground level' data, though of course objects can exist below ground level. (Not necessarily located at 0z, most of the default Britannia is above 0z.)

Static Terrain - These tiles are 'ground tile' pieces that have been added and frozen, or are included in the existing map, such as certain types of ground inside dungeons. These tiles cannot slope, they are objects that look like ground and have been frozen to the map.

Added Terrain - These tiles are 'added' by GMs using tools such as Pandora's Box, or by directly adding a static. They are also the type of tiles that make up character houses. Yes, this means that if you use this script and don't disable that check, swamp tiles in houses can poison characters.



Installation:

This script modifies PlayerMobile.cs! Please please PLEASE make a FULL backup of your shard and a spare copy of your PlayerMobile.cs before installing this. Though there are no changes to serialization/deserialization (which, when done incorrectly, could cause the loss of all characters on the shard) - it's better to be safe than sorry. ^.^;

In this post you will find two forms of the code necessary to modify your PlayerMobile.cs.
The easiest way to install this: (Only if you have not modified your PlayerMobile.cs!) In the zip file attached to this post is a distro PlayerMobile.cs modified appropriately. Rename your PlayerMobile.cs to PlayerMobile.cs.bak, and extract the PlayerMobile.cs to wherever you like in your Scripts directory.

If you have modified your PlayerMobile.cs, you can use either the code in the quote box below, or from the archive attached to this post there is a file called
"Poisonous Swamps - Modification to PlayerMobile.txt"
Both include the same code.

The code begins with the full Move override, to show you where to add the call to SwampCheck. Please note that only two lines actually need to be added to the Move override, they are clearly marked. Add those lines to the appropriate place in the Move override. Now from the point where it says "// begin poisonous swamps" to the end of the code box or file, select that code and place it below the closing brace of your Move override.

(Conversely, if you have not modified the Move override, you can select ALL the text from the code box or modification file, and replace the entire PlayerMobile.cs Move override with that.)



Things you should know: (and some things that you can change, by editing the code. =)


Staff members WILL be poisoned. There is a section of code commented out at the beginning of SwampCheck which will keep staff from being poisoned. Remove the comment marks and adjust the access level to your taste. (Or have staff wear swamp boots. =)

This script ONLY affects characters. Mounts and pets will not be poisoned. Mounted characters will be poisoned regardless of wearing Swamp Boots. (The mount walking through the swamp stirs up poisonous gasses, or some such like that. =)

ALL swamps will be poisonous after this is installed, including homes with swamp tiles.

Proximity to swamps doesn't matter, only the tile directly below the character is checked.


Please report any new slowdowns or crashes that this script may cause. So far I haven't found any in my testing, but it has been rather limited. If you encounter a crash and you can repeat it, a crash report from the server running in debug mode would be exteremly helpful.


And thank you to everyone. ^.^


-----------------------------

PlayerMobile.cs modifications:
Code:
// for poisonous swamps.

// code given is for Move override in PlayerMobile. Code changes start at the "SwampCheck( this )" line.
// Please note that the code given closes the move override, just selecting all the code and pasting it
// at the given line will not work. You need to select the entire Move override to be replaced, or selectively
// replace the code starting at that point.

		public override bool Move( Direction d )
		{
			NetState ns = this.NetState;

			if ( ns != null )
			{
				GumpCollection gumps = ns.Gumps;

				for ( int i = 0; i < gumps.Count; ++i )
				{
					if ( gumps[i] is ResurrectGump )
					{
						if ( Alive )
						{
							CloseGump( typeof( ResurrectGump ) );
						}
						else
						{
							SendLocalizedMessage( 500111 ); // You are frozen and cannot move.
							return false;
						}
					}
				}
			}

			TimeSpan speed = ComputeMovementSpeed( d );

			if ( !base.Move( d ) )
				return false;

			m_NextMovementTime += speed;


			///////////////////////  begin playermobile Move addition


			// 'Move( Direction d )' seems to be called when the player moves.

			if ( this != null )
				SwampCheck( this );   // for poisonous swamps


			///////////////////////  end playermobile Move addition


			return true;
		}


// begin poisonous swamps


		private static void SwampCheck( PlayerMobile from )
		{

// poisonous swamps...  Mostly.

		// basic sanity checks

			if ( from == null )
				return;  // wtf? O.o;

			// don't poison staff
	//		if ( from.AccessLevel >= AccessLevel.GameMaster )
	//			return;

			// if the player is dead, don't poison them. Thanks GrayStar! :>
			if ( !from.Alive )
				return;

			// don't poison a poisoned player.
			if ( from.Poisoned )
				return;

			// no swamps on the internal map.
			if ( from.Map == Map.Internal )
				return;

			// is the player wearing swamp boots and not mounted?
			Item shoes = from.FindItemOnLayer( Layer.Shoes );
			if ( shoes != null && shoes is SwampBoots && !( from.Mounted ) )
				return;

		// find out if the player is moving over a land/terrain (ground), static/frozen (dungeon) swamp, or static/unfrozen/added swamp.

			// initialize common variables.
			Map map = from.Map;



			// is it a land/terrain swamp?
			
			Tile lt = map.Tiles.GetLandTile( from.X, from.Y );
			
			if ( IsDeepLandSwamp( lt.ID ) && lt.Z == from.Z )
			{
				if ( Utility.RandomDouble() < 0.15 )
				{
					// poison player
					from.Poison = Poison.Regular;
						
					from.SendMessage( "You were poisoned by the swamp!" );

					return;
				}
			}
			else if ( IsLightLandSwamp( lt.ID ) && lt.Z == from.Z )
			{
				if ( Utility.RandomDouble() < 0.05 )
				{
					// poison player
					from.Poison = Poison.Lesser;

					from.SendMessage( "You were poisoned by the swamp!" );

					return;
				}
			}


			// is it a static swamp?

			Tile[] tiles = map.Tiles.GetStaticTiles( from.X, from.Y );

			for ( int i = 0; i < tiles.Length; ++i )
			{
				Tile t = tiles[i];
				ItemData id = TileData.ItemTable[t.ID & 0x3FFF];
				
				int tand = t.ID & 0x3FFF;
				
				if ( t.Z != from.Z )
				{
					continue;
				}
				else if ( IsDeepStaticSwamp( tand ) )
				{
					if ( Utility.RandomDouble() < 0.15 ) // 0.15% chance
					{
						// poison player
						from.Poison = Poison.Regular;
							
						from.SendMessage( "You were poisoned by the swamp!" );

						return;
					}
				}
				else if ( IsLightStaticSwamp( tand ) )
				{
					if ( Utility.RandomDouble() < 0.05 ) // 0.05% chance
					{
						// poison player
						from.Poison = Poison.Lesser;
							
						from.SendMessage( "You were poisoned by the swamp!" );

						return;
					}
				}
			}


			// is it an added swamp?

			IPooledEnumerable eable = map.GetItemsInRange( new Point3D( from.X, from.Y, from.Z ), 0 );

			foreach ( Item item in eable )
			{
				if ( item == null || item.Z != from.Z )
				{
					continue;
				}
				else if ( IsDeepStaticSwamp( item.ItemID ) )
				{
					if ( Utility.RandomDouble() < 0.15 ) // 0.15% chance
					{
						// poison player
						from.Poison = Poison.Regular;
							
						from.SendMessage( "You were poisoned by the swamp!" );

						return;
					}
				}
				else if ( IsLightStaticSwamp( item.ItemID ) )
				{
					if ( Utility.RandomDouble() < 0.05 ) // 0.05% chance
					{
						// poison player
						from.Poison = Poison.Lesser;
							
						from.SendMessage( "You were poisoned by the swamp!" );

						return;
					}
				}
			}

			eable.Free();
		}

		private static bool IsLightLandSwamp( int itemID )
		{
			if ( itemID >= 15808 && itemID <= 15833 )
				return true;

			if ( itemID >= 15835 && itemID <= 15836 )
				return true;

			if ( itemID >= 15838 && itemID <= 15848 )
				return true;

			if ( itemID >= 15853 && itemID <= 15857 )
				return true;

			return false;
		}

		private static bool IsDeepLandSwamp( int itemID )
		{
			if ( itemID >= 15849 && itemID <= 15852 )
				return true;

			return false;
		}

		private static bool IsLightStaticSwamp( int itemID )
		{
			if ( itemID >= 12809 && itemID <= 12810 )
				return true;

			if ( itemID >= 12882 && itemID <= 12905 )
				return true;

			if ( itemID >= 12912 && itemID <= 12933 )
				return true;

			return false;
		}

		private static bool IsDeepStaticSwamp( int itemID )
		{
			if ( itemID >= 12813 && itemID <= 12881 )
				return true;

			if ( itemID >= 12906 && itemID <= 12911 )
				return true;

			return false;
		}


// end poisonous swamps
Oh yeah you might need these. ;)

Code:
namespace Server.Items
{
	public class SwampBoots : ThighBoots
	{
		[Constructable]
		public SwampBoots() : base()
		{
			Name = "swamp boots";
			Hue = Utility.RandomGreenHue();
		}

		public SwampBoots(Serial serial) : base(serial)
		{
		}

		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);

			writer.Write((int) 0);
		}

		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);

			int version = reader.ReadInt();
		}
	}
}
I suggest you sell the swamp boots on vendors and make them craftable by players.
 

Attachments

  • PoisonousSwamps.zip
    23.7 KB · Views: 135
hmmm :) what about staffies? They shouldn't get poisoned imo except you got Counselors, who play.
Besides: What about Pets? Like mounted horses, cats, dogs, rats dragons. *lol*
 

Alari

Wanderer
Kamuflaro said:
hmmm :) what about staffies? They shouldn't get poisoned imo except you got Counselors, who play.
Besides: What about Pets? Like mounted horses, cats, dogs, rats dragons. *lol*

Staff members can '[add swampboots' and wear them. Or you could put in an accesslevel check.

I've intentionally excluded pets and mounts from this.

But for pets it'd be basically the same code, in BaseCreature, with a IsControlled check. For mounts it'd be a check to see if the player is mounted and if mount != null (Dunno how it handles ethereals...) then poison the mount if so.

And of course tameable swamp-dwelling creatures should probably be immune to poison of up to regular levels, so they don't suddenly get poisoned by the swamps they live in once you tame them.
 

Greystar

Wanderer
Alari said:
Staff members can '[add swampboots' and wear them. Or you could put in an accesslevel check.

I've intentionally excluded pets and mounts from this.

But for pets it'd be basically the same code, in BaseCreature, with a IsControlled check. For mounts it'd be a check to see if the player is mounted and if mount != null (Dunno how it handles ethereals...) then poison the mount if so.

And of course tameable swamp-dwelling creatures should probably be immune to poison of up to regular levels, so they don't suddenly get poisoned by the swamps they live in once you tame them.


Noticed a small bug, nothing serious mind you but I figured you might want to know. If a dead person walks through a swamp they get poisoned.
 

Alari

Wanderer
Greystar said:
Noticed a small bug, nothing serious mind you but I figured you might want to know. If a dead person walks through a swamp they get poisoned.
Doh. ^.^;

Thank you very much. =)


I'm still working on cleaning the code up and optimizing it, I'll post an update to the original. For now it should be easy enough with an "|| !(this.Alive)" added to the checks for swamp boots.


I still have no idea how to detect swamp tiles placed by Pandora's Box or such like that. (Basically any swamp tiles that aren't terrain or dungeon statics)
 

Alis

Wanderer
Well Alari you as i told you before that you had the potential to this script modification by your own as you can see you did it :) thanks for sharing with us this kind of role play'
stic thing an thoe we will wait and see what other things can be done on the land core
 

Alari

Wanderer
Alis said:
Well Alari you as i told you before that you had the potential to this script modification by your own as you can see you did it :) thanks for sharing with us this kind of role play'
stic thing an thoe we will wait and see what other things can be done on the land core

Unfortunately I couldn't do all of it (Still no 'added' swamp detection) and it came at a terrible cost. (Ow my head ow ow ow. =)
 

Alis

Wanderer
Ehuehuhe yeah well for a girl i havent slept about 84 hours now dont complain :) what actually do you want in the release of poison range > something like that ?
 

Alari

Wanderer
Alis said:
Ehuehuhe yeah well for a girl i havent slept about 84 hours now dont complain :) what actually do you want in the release of poison range > something like that ?

Ouch. Insomnia sucks.


I want it to detect swamps that aren't landscaped like the swamp east of Britain or static decorations like the swamps found as 'decoration' in dungeons. That is, swamp tiles you add with '[add static ###' or whatever. I don't know how to do that. The things I've seen will work with a targetted item, but I don't know how to detect an item at a certain location.

I still need to check the decoration script, what I'm looking for is probably in there somewhere.
 

Alis

Wanderer
well use pandoras pox and create all the tiles look at their item codes or in another way use Insideuo and look over the tile numbers something like this 0x1241c something like this then implement them to the playermobile.cs
 

Greystar

Wanderer
since i decided to delete my original post cause personally I thought it was kinda rude when I posted it. You might want to consider looking at the Harvest System that was written by David and Edited by someone to include a garden and see how they detect "placed" tiles of x type using the tile ID that may also help. I do realize you said you found code you where looking for in the deco stuff. But I wanted to give you another option of what code to look at for ideas and examples

http://www.runuo.com/forum/showthread.php?t=37594

that system may ore may not help you. But It was what I was going to use as an example when I was going to do the very same thing you did. Like I had mentioned in Alis's thread for the save mod thing.

Edit oops I was a little slow in posting this I guess. if you want me to delete this (Alari being the you I was talking about) I will just pm me.
 

Alari

Wanderer
Alis said:
well use pandoras pox and create all the tiles look at their item codes or in another way use Insideuo and look over the tile numbers something like this 0x1241c something like this then implement them to the playermobile.cs

I updated the script, it detects added swamps now.


Alis the problem I was having was actually *detecting* the objects (Use: 'GetItemsInRange') - the statics use the same ItemIDs as the added ones, since they're not land tiles, and were very easy to add once I figured out how to detect them. (Though I have to '& 0x3FFF' to get the RIGHT itemIDs. I still have no idea why or what that really does. =)
 

Pr-nce

Wanderer
Nice :)

Very nice little addition, Alari :)

I've been debating whether or not to script certain swamp areas as poisonous with your method or a regions way of doing it.

Your way is very nice; It's a pretty quick and easy modification. But I'm just reluctant to use it because it would involve calling a moderately long function (with possibly performing enumerations, etc..) every time every player moves.
Scripting the regions would be a bitch, but I think you would have more control with that. Like, maybe you don't want a certain portion of swamp to be poisonous for whatever reason (the swamps south of Destard come to mind--I don't think they were poisonous). And at least with the region method, you'd avoid that small performance inhibition.

Anyways, thanks for sharing :) I've definitely missed being poisoned by swamps. For.. some.. odd reason..
 
Hey could you add an attachment with the edits in the distros? It sure would make adding this nicer. Anyhow just asking as a favor really but I think others would really find it nicer too.
 

Alari

Wanderer
Pr-nce said:
Very nice little addition, Alari :)

I've been debating whether or not to script certain swamp areas as poisonous with your method or a regions way of doing it.

Your way is very nice; It's a pretty quick and easy modification. But I'm just reluctant to use it because it would involve calling a moderately long function (with possibly performing enumerations, etc..) every time every player moves.
Scripting the regions would be a bitch, but I think you would have more control with that. Like, maybe you don't want a certain portion of swamp to be poisonous for whatever reason (the swamps south of Destard come to mind--I don't think they were poisonous). And at least with the region method, you'd avoid that small performance inhibition.

Anyways, thanks for sharing :) I've definitely missed being poisoned by swamps. For.. some.. odd reason..
Like I said I didn't notice any slowdowns when testing (at least, when running the server on a seperate computer and not having any of the debug messages in there) but I need people to give this an actual real test with multiple players. (I have faith in RunUO but I'd like to test it in a real environment too. =) I did optimize the code a little, it breaks off as soon as it possibly can, returning immediately if they're wearing swamp boots, already poisoned, dead, or staff members (commented out but easy to include) Also it returns now as soon as a player has been successfully poisoned by the swamp.

The problem with regions was that they didn't match the irregular shape of most swamps very easily. The swamps I've found have been irregular in shape, very much not "boxy" like regions.

As far as I know, *all* swamps in the original series were poisonous, and that's what I'm shooting for here. :> Yes, if you wanted some to not be poisonous, you'd have to include specific 'region' or coordinate checks in the beginning and return if the player is inside that area.


evil lord kirby said:
Hey could you add an attachment with the edits in the distros? It sure would make adding this nicer. Anyhow just asking as a favor really but I think others would really find it nicer too.
I could. My PlayerMobile is rather heavily edited, so I didn't want to post the whole thing. But I have an unedited original distro one I could apply the modifications to and post. I'll work on that. =) Edit: OK, done. There's a zip file attached to the first post with the modified distro playermobile and the swamp boots. =)
 

Greystar

Wanderer
Thanks for the zip although I already put it in using the forum post but it is easier to use winmerge to see differences.
 

Alari

Wanderer
I've noticed a few problems, and could use some suggestions. :confused:;

If someone builds a bridge over a land-tile based swamp, that looks like it will still trigger poisoning. I need a way to detect the Z height of the land and verify that's the Z height of the player. Same thing for static tiled swamps.
 
Top