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!

Capture the Flag and Double Domination games (Updated)

Zippy

Razor Creator
Capture the Flag and Double Domination games (Updated)

Update on 8/11/04:
This is a small clean up & update for the CTF and DD games. If you already have CTF/DD on your shard you will NOT need to resetup your games to use the new version of the scripts. The only thing you must do after unextracting is re-add all of your signup stones (and relink them to the game stone). Please delete DDJoin.cs, CTFJoin.cs, and CTFJoinGump.cs from previous isntallations.

What changed? The game no longer infinitely restarts itself. The game now runs once for it's set length and then stops. If someone reaches the maxscore before the game time is over, it will end early. You can use [startgame and [stopgame (see below) to control the game as you see fit. When the game is not running, players will be unable to fight (or heal) each other, and none of the flags/waypoints will work.
Also, Notoriety.cs is now much less cluttered with CTF stuff. There are only 2 places, (both are clearly marked) where CTF stuff is in there. There is a comment in CTFGame.cs where you can add code to give prizes to members of the winning team.

**** Installation ****
Unextract to your scripts folder. Then make SURE you delete your "Scripts/Misc/Notoriety.cs" file. This is very important....
Follow the instructions below to setup your game.

**** Setup Instuctions ****
Okay, this is a fairly large system.. there's a lot of little thigns and you'll want to play around with it before dropping it right on to your shard... Here is a "crash" course in how to set it up.

Before setting up the script on the shard, you may want to change the Coords in the "GameRegion.cs" script. The coords in there now are some nice places me & alkiser found a while ago on the default map... but you might want to use something else.

Capture the Flag:
1) [add CTFGame put it someplace out of the way.. this is used for controling game options only, players dont need to see it.
2) [props or double click the game stone and setup the properties of the game (like how many teams, etc).
3) [add CTFFlag, this is the flag so it should go someplace in your "arena"
4) Double click or do [props on the Flag, you will get a props menu... FIRST Set the TeamID to the Team Number (0, 1, 2, 3) etc you want the team to have. (This should never be >= the number of teams in the game)
5) Next set the Flag's Game property to the game stone you added in step 1.
6) Set all the other properties how you want, Note:set the flag's Hue to the color you want the team to wear (a blue flag means everyone on the team will wear a blue robe).

*) Repeat steps 3-6 for each team

Now you may [add gamejoinstone all around your shard to allow players to join the game. These must also be linked via props to the game stone from step 1.
You may also [add ctfscoreboard all over your shard (and dont forget to link them to the gamestone) so your players can see the scores. You might also want to add one in the arena.

Double Donimation:
First off, what is double domination?
This is a game I originally saw in Unreal on the Xbox. Basically 2 teams fight to control 2 way points at the same time, to control the point they must stand on it for 10 seconds without the other team touching it. Once they control both points at the same time for 30 seconds, they "score" and then the game resets.
It's very fast paced, but if teams are too large it can get out of hand.

The setup for double domination is pretty similar to CTF, with a few exceptions:

1) For each team you need to add a DDTeamControl (similar to the gamestone this will not be used by players) to control the DDTeams since they dont have flags. Otherwise, it acts the same as a ctfflag (including hue...).
2) You must add 2 DDWayPoints in your arena. DO NOT FORGET TO DO [inc z 5 on them so you can see the whole thing (its rather large). And you of course have to link them to your CTFGame (yes its still a CTFGame even though is DoubleDom)... These points must also be linked to each other. Your DD Game can have as many teams as you want, but it can only have 2 way points.

You should also be able to use the CTFScoreBoard for DD games.

Also included in this package is an "AutoSupply Stone" which when double clicked gives a player items based on their skills, its designed to make it so when a player dies he/she can re-equip very quickly.

Commands:
[endgame : (target ganestone) will end the current game
[startgame <reset> : will start the game, or if the game is already running, will restart it. The paramemter reset should be true (or yes) if you want everyoen to reselect their teams, or false (or no) to keep the current teams. [startgame true to reset/rebalance teams.
[t and [team : These commands allow players to talk to the entire team ( no matter where they are )

New to this package is the LeaveGameGate. [add leavegamegate Do not forget to [props and set the target location & map for the gate to take players. When stepped on the gate will remove the player for any/all games they are currently in, remove their game robe, and teleport them to the desired location.

When you die in a CTF or DD Game you are resurrected automatically and taken back to your team's "home." A good strategy for this is to make the home a place somewhere outside of the battle area where the player can re-equip in peace, and then go through a gate to enter the game. This also prevents people from restocking on the stones when they didn't die.

Also this is provided AS IS, I am usually too busy to provide support for it. Please don't try to contact about it. Use this thread for support.

Thanks, enjoy.
 

Attachments

  • games.zip
    21.6 KB · Views: 2,139

bean56

Wanderer
Dang zippy. I just downloaded the old one yesturday and added it into server this morning. I've played ctf before and had it on the old server a while back and decided to re add it now. Looks like I'll be reediting my noriety.cs again .. Good job once again zippy and thanks.
 

Cole

Wanderer
Added this to my shard, and successfully set the settings. But now every time someone picks up a flag of an opposing team they are killed... Anyone know how to fix this?
 

bean56

Wanderer
Oh reeeaally. I might have to look at that. I havent' done anything yet until I decide exactly where I want it. Is your avatar a picture of a guard from ff8? Kinda looks like it.
 

Cole

Wanderer
If you figure it out let me know.. I'm still working on it :) Actually I don't know where I got this avatar, just found it on the web somewhere..

I also found a problem in the scripts... The following code in the file CTFGame.cs

Code:
Server.Commands.Register( "endgame", AccessLevel.GameMaster, new CommandEventHandler( EndGame_Command ) );
   Server.Commands.Register( "startgame", AccessLevel.GameMaster, new CommandEventHandler( EndGame_Command ) );

Should Be:
Code:
Server.Commands.Register( "endgame", AccessLevel.GameMaster, new CommandEventHandler( EndGame_Command ) );
   Server.Commands.Register( "startgame", AccessLevel.GameMaster, new CommandEventHandler( StartGame_Command ) );
 

Zippy

Razor Creator
Fixed the problems Cole mentioned and updated the .zip

The fix for people dying right after d-click is in CTFFlag.cs... the other is exactly how he described. :)

ty for the bug report
 

Saxum

Wanderer
Hi there Zippy! Credits for you to re-post it! Thanks a lot man!

However though I have two questions concerning your script.

1. How do I make so all items get deleted when they join and leave the game?

2. Is it possible to make so the characters don't die when they enter/leave?

Thanks a lot in advance!
 

milkman_dan

Wanderer
Major Problem

Ok problem Im running into is this.

Ive made my arena, got the Game Stone in place. i added my gamestone by saying [add ctfgame 2, for Two teams of Course.

Then I made two seperate CTF Flags, each at their corresponding place. I set their TeamID to 1 and 2. Once again corresponding their teams and their bases. I then Linked them to the gamestone

Then I added Scoreboards out the butt everywhere and each and everyone of them are linked to the gamestone as well

Now hears where i get problems. I do the [add gamejoinstone

Heres the error:
Usage:
GameJoinStone String GameName

So then I tried [add gamejoinstone ctf and that worked. But the problem is when I linked it to the Main CTF Stone, My players are killed then takin to the middle of the ocean!!!!!! I also edited the Gameregion, to point exactly to my arena but to no aveil. Can anyone help me get this last step working please o please :)


On a side note, when they hit the Join Stone, it just shows ~unnamed team~ for team names. anyway to fix that as well?
 

Cole

Wanderer
Sounds like you have set all the settings on the flags.. Just [prop the flags and enter the Names of the Teams and the Coords where the flag is and where your players should start.

Hope this helps!
 

Saxum

Wanderer
milkman_dan said:
Ok problem Im running into is this.

Ive made my arena, got the Game Stone in place. i added my gamestone by saying [add ctfgame 2, for Two teams of Course.

Then I made two seperate CTF Flags, each at their corresponding place. I set their TeamID to 1 and 2. Once again corresponding their teams and their bases. I then Linked them to the gamestone

Then I added Scoreboards out the butt everywhere and each and everyone of them are linked to the gamestone as well

Now hears where i get problems. I do the [add gamejoinstone

Heres the error:
Usage:
GameJoinStone String GameName

So then I tried [add gamejoinstone ctf and that worked. But the problem is when I linked it to the Main CTF Stone, My players are killed then takin to the middle of the ocean!!!!!! I also edited the Gameregion, to point exactly to my arena but to no aveil. Can anyone help me get this last step working please o please :)


On a side note, when they hit the Join Stone, it just shows ~unnamed team~ for team names. anyway to fix that as well?

Well, you haven't read his instructions properly as he clearly said the first team should have the TeamID as 0. So if you have two teams the two teams should have TeamID's 0 & 1. I had the same problem, but noticed I didn't read through his documentation :)
 

rugzo

Wanderer
Accessory

I am sorry for my reply. But I think to be useful.

It is used for players sending to the over location that CTFflag shows by the system when [gameend command executed.

I edited CTFGame.cs and CTFTeam.cs for game over location.

CTFGame.cs
Code:
		public void EndGame()
		{
			if ( !m_Running )
				return;

			CTFTeam Winner = null;
			
			if ( m_GameTimer != null )
			{
				m_GameTimer.Stop();
				m_GameTimer = null;
			}

			if ( m_ScoreTimer != null )
			{
				m_ScoreTimer.Stop();
				m_ScoreTimer = null;
			}

			for (int i=0;i<m_Teams.Count;i++)
			{
				CTFTeam team = (CTFTeam)m_Teams[i];
				if ( team.Flag != null )
					team.Flag.ReturnToHome();

				if ( Winner == null || team.Points > Winner.Points )
					Winner = team;
			}

			if ( Winner != null )
			{
				PlayerMessage( "The game is over.  The winner is {0} with {1} points!", Winner.Name, Winner.Points );
//game over location begin
				for (int i=0;i<m_Teams.Count;i++)
				{
					CTFTeam team = (CTFTeam)m_Teams[i];

					team.Points = 0;
					if ( team.Flag != null )
						team.Flag.ReturnToHome();

					for(int j=0;j<team.Members.Count;j++)
					{
						Mobile m = (Mobile)team.Members[j];

						m.Kill();
						if ( m.Corpse != null && !m.Corpse.Deleted )
							m.Corpse.Delete();

						m.LogoutLocation = team.Over;
						m.Location = team.Over;
						m.Location = team.Over;
						m.Map = team.Map;
					
						m.Resurrect();
		
						m.Hits = m.HitsMax;
						m.Mana = m.ManaMax;
						m.Stam = m.StamMax;
					}
				}
//game over location end
				/*
				// Uncomment this and mofiy as nessessary to give prize(s) to the winning team members.
				for (int j=0;j<Winner.Members.Count;j++)
				{
					Mobile m = (Mobile)Winner.Members[j];

					m.BankBox.AddItem( ... );
				}
				*/
			}
			else
			{
				PlayerMessage( "The game is over." );
//game over location begin
				for (int i=0;i<m_Teams.Count;i++)
				{
					CTFTeam team = (CTFTeam)m_Teams[i];

					team.Points = 0;
					if ( team.Flag != null )
						team.Flag.ReturnToHome();

					for(int j=0;j<team.Members.Count;j++)
					{
						Mobile m = (Mobile)team.Members[j];

						m.Kill();
						if ( m.Corpse != null && !m.Corpse.Deleted )
							m.Corpse.Delete();

						m.LogoutLocation = team.Over;
						m.Location = team.Over;
						m.Location = team.Over;
						m.Map = team.Map;
					
						m.Resurrect();

						m.Hits = m.HitsMax;
						m.Mana = m.ManaMax;
						m.Stam = m.StamMax;
					}
				}
//game over location end
			}
			
			m_Running = false;
		}

CTFTeam.cs
Code:
using System;
using System.Collections;

namespace Server.Items
{
	public class CTFTeam
	{
		private ArrayList m_Members;
		private Point3D m_Home;
//game over location begin
		private Point3D m_Over;
//game over location end
		private Point3D m_FlagHome;
		private Map m_Map;
		private int m_Points;
		private string m_Name;
		private int m_Hue;
		private IGameFlag m_Flag;

		private int m_UId;
		private CTFGame m_Game;

		public CTFTeam( CTFGame game, int uid )
		{
			m_UId = uid;
			m_Game = game;

			m_Points = 0;
			m_Home = Point3D.Zero;
//game over location begin
			m_Over = Point3D.Zero;
//game over location end
			m_Map = Map.Felucca;
			m_Members = new ArrayList();
		}

		public CTFTeam( GenericReader reader )
		{
			Deserialize( reader );
		}

		public void Serialize( GenericWriter writer )
		{
			writer.Write( (int)1 );//version

			writer.Write( (Item)m_Flag );

			writer.WriteMobileList( m_Members );
			writer.Write( m_Home );
//game over location begin
			writer.Write( m_Over );
//game over location end
			writer.Write( m_FlagHome );
			writer.Write( m_Map );
			writer.Write( m_Points );
			writer.Write( m_Name );
			writer.Write( m_Hue );
			writer.Write( m_UId );
			writer.Write( m_Game );
		}

		public void Deserialize( GenericReader reader )
		{
			int version = reader.ReadInt();

			switch ( version )
			{
				case 1:
				{
					m_Flag = reader.ReadItem() as IGameFlag;
					goto case 0;
				}
				case 0:
				{
					m_Members = reader.ReadMobileList();
					m_Home = reader.ReadPoint3D();
//game over location begin
					m_Over = reader.ReadPoint3D();
//game over location end
					m_FlagHome = reader.ReadPoint3D();
					m_Map = reader.ReadMap();
					m_Points = reader.ReadInt();
					m_Name = reader.ReadString();
					m_Hue = reader.ReadInt();
					m_UId = reader.ReadInt();
					m_Game = reader.ReadItem() as CTFGame;
					break;
				}
			}
		}

		public IGameFlag Flag{ get{ return m_Flag; } set {m_Flag = value; } }
		
		[CommandProperty( AccessLevel.Seer )]
		public Point3D Home{ get{ return m_Home; } set{ m_Home = value; } }

//game over location begin
		[CommandProperty( AccessLevel.Seer )]
		public Point3D Over{ get{ return m_Over; } set{ m_Over = value; } }
//game over location end

		[CommandProperty( AccessLevel.Seer )]
		public Point3D FlagHome{ get{ return m_FlagHome; } set{ m_FlagHome = value; } }

		[CommandProperty( AccessLevel.Seer )]
		public Map Map{ get{ return m_Map; } set{ m_Map = value; } }

		[CommandProperty( AccessLevel.Seer )]
		public int Points
		{ 
			get{ return m_Points; } 
			set
			{ 
				m_Points = value; 
				if ( m_Points >= m_Game.MaxScore )
					m_Game.EndGame();
			} 
		}

		[CommandProperty( AccessLevel.Seer )]
		public string Name
		{ 
			get
			{ 
				if ( m_Name == null || m_Name == "" )
					return "-unnamed-";
				else
					return m_Name; 
			} 
			set { m_Name = value; } 
		}

		[CommandProperty( AccessLevel.Seer )]
		public int Hue
		{
			get{ return m_Hue; } 
			set
			{ 
				m_Hue = value; 
				if ( m_Flag is CTFFlag )
					((CTFFlag)m_Flag).Hue = m_Hue;
			} 
		}

		[CommandProperty( AccessLevel.Counselor )]
		public int ActiveMemberCount
		{
			get
			{
				int count = 0;
				for (int i=0;i<m_Members.Count;i++)
				{
					if ( ((Mobile)m_Members[i]).NetState != null )
						++count;
				}

				return count;
			}
		}

		public ArrayList Members { get{ return m_Members; } }
		public int UId { get{ return m_UId; } }
		public CTFGame Game { get{ return m_Game; } }

		public bool IsMember( Mobile m )
		{
			return m_Members.Contains( m );
		}

		public void AddMember( Mobile m )
		{
			m_Members.Add( m );
		}

		public void RemoveMember( Mobile m )
		{
			m_Members.Remove( m );
		}
	}
}

I used my server.
Thanks for games package.
 

Attachments

  • CTFGame.cs
    17.1 KB · Views: 135
  • CTFTeam.cs
    3.5 KB · Views: 115

DarkJustin

Wanderer
How would one disable insured items here... i've found that my players are smart--they insured items to use during capture the flag. Is there anyone to send all there stuff to the bank ... or just disable iteminsurance--and they loose all there crap when they enter?

((ideally I'd LOVE to see the set items put in da' bank and then... when they exit the game via the gate or when game is over... that they'd get all their stuff returned to them...)) I've seen this concept used before... how would one implement it here? ANY thoughts?
 

bean56

Wanderer
Thx for the fixes zippy. I would have fixed them, but I had to go out of town for the weekend. I'm surprised to find that people are killed in order to make sure they don't keep their stuff(was this changed from the last version to be more efficient?). This is not acceptable for me and I'll be changing that and posting fixes for people hopefully sometime in the near future for people that want to do it differently if that's ok with zippy. I'm guessing that people lose fame and karma when they die in ctf too. This I also don't like if it's the case and will probably be making changes, if not then of course I'll leave it how it is. Good job with everything zippy.

On a side note. At least with the last zip file you didn't have them unzip into a folder. Of course this is in no way a big deal, but it would be a little more convient I think.

One last thing. I'll probably just move everything from the players backpack and possibly body into a bag and put it in their bank as I've seen done before. I've had the thought though, I know your backpack in game can get too full, but I can't remember if other bags do or not. Does anyone think items may be lost because the bag is too full?
Thank you everyone, especially zippy.
 

DarkJustin

Wanderer
Definatly post those fixes when you get them... the not loosing fame and karma thing--and the moving items into a bag in bank. ;) SWEET
 

bean56

Wanderer
Change the onresponse method in gameteamselector so it looks like this
Code:
public override void OnResponse( NetState state, RelayInfo info )
		{
			Mobile from = state.Mobile;
			from.CloseGump( typeof( GameTeamSelector ) );
			
			if ( m_Game.Deleted )
				return;
			
			CTFTeam team = m_Game.GetTeam( info.ButtonID - 1 );
			if ( team != null && team.ActiveMemberCount < m_TeamSize )
			{
				bool freeze = from.Frozen;

				if ( from.Backpack != null )
				{
					if( from.FindItemOnLayer( Layer.TwoHanded) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.TwoHanded) );
					if( from.FindItemOnLayer( Layer.Shoes) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Shoes) );
					if( from.FindItemOnLayer( Layer.Pants) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Pants) );
					if( from.FindItemOnLayer( Layer.Shirt) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Shirt) );
					if( from.FindItemOnLayer( Layer.Helm) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Helm) );
					if( from.FindItemOnLayer( Layer.Gloves) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Gloves) );
					if( from.FindItemOnLayer( Layer.Ring) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Ring) );
					if( from.FindItemOnLayer( Layer.Neck) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Neck) );
					if( from.FindItemOnLayer( Layer.OneHanded) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.OneHanded) );
					if( from.FindItemOnLayer( Layer.Waist) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Waist) );
					if( from.FindItemOnLayer( Layer.InnerTorso) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.InnerTorso) );
					if( from.FindItemOnLayer( Layer.Bracelet) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Bracelet) );
					if( from.FindItemOnLayer( Layer.MiddleTorso) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.MiddleTorso) );
					if( from.FindItemOnLayer( Layer.Earrings) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Earrings) );
					if( from.FindItemOnLayer( Layer.Arms) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Arms) );
					if( from.FindItemOnLayer( Layer.Cloak) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.Cloak) );
					if( from.FindItemOnLayer( Layer.OuterTorso) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.OuterTorso) );
					if( from.FindItemOnLayer( Layer.OuterLegs) != null )
						from.Backpack.DropItem( from.FindItemOnLayer( Layer.OuterLegs) );

					from.Backpack.Movable = true;
					from.BankBox.AddItem( from.Backpack );

					Backpack pack = new Backpack();
					pack.Movable = false;

					from.AddItem( pack );
				}
				//check if they are mounted and dismount them
				IMount mount = from.Mount;
				if ( mount != null )
					mount.Rider = null;

				from.Location = team.Home;
				from.Map = team.Map;

				from.Frozen = freeze;
				
				m_Game.SwitchTeams( from, team );

				from.SendMessage( "You have joined team {0}!", team.Name );
			}
			else
			{
				from.SendMessage( "That team is full, please try again." );
				from.SendGump( new GameTeamSelector( m_Game ) );
			}
		}
	}
Notice I added a check to see if they were mounted. You can take that out if you want, but I don't want some players with a mount and some w/o. If you want that then it's very important that you add
Code:
using Server.Mobiles;
to the top. I also changed the leavegame function in CTFgame.cs to make sure people can't leave with full spellbooks. So it looks something like this
Code:
public void LeaveGame( Mobile m )
		{
			CTFTeam t = GetTeam( m );
			if ( t != null )
				t.RemoveMember( m );

			if ( m.AccessLevel == AccessLevel.Player && !m.Blessed )
			{
				if ( m.Alive )
				{
					m.Kill();
					if ( m.Corpse != null && !m.Corpse.Deleted )
						m.Corpse.Delete();
				}
				m.Resurrect();
				m.Hits = m.HitsMax;
				m.Mana = m.ManaMax;
				m.Stam = m.StamMax;
			}
			
			Item robe = m.FindItemOnLayer( Layer.OuterTorso );
			if ( robe is CTFRobe )
				robe.Delete();
			if ( m.Backpack != null )
			{
				//Spell books are blessed so must check for them.
				//check to make sure spell book isn't equiped
				if( m.FindItemOnLayer( Layer.OneHanded) != null )
					m.FindItemOnLayer( Layer.OneHanded).Delete();//delete it if it's equiped
				Item[] book = m.Backpack.FindItemsByType( typeof( Spellbook) );//find any spellbooks in backpack
				for(int i=0;i<book.Length;i++)
					book[i].Delete();//delete them

				Item[] robes = m.Backpack.FindItemsByType( typeof( CTFRobe ) );
				for(int i=0;i<robes.Length;i++)
					robes[i].Delete();
			}

			m.Delta( MobileDelta.Noto );
		}
That is all for now. Fame and karma seem to pretty much be taken care of so this is all i'll probably do. I'm pretty sure people weren't intended to be able to join with a mount and they probably shouldn't be allowed to leave with full spellbooks so you may want to add those to the distro. Thx zippy.
 

Saxum

Wanderer
Thanks a lot for your help bean56.

Is anyone aware of how you can change the script so random teams exist only? And with teambalance so one team wont have 5 players and one 1.
 

DarkJustin

Wanderer
Sweet. Any idea why it takes so long to res? Is there a timer somewhere that I've missed that I can setup for quicker res times. My people seem to die--and the 15-20 secs later they get auto ressed... i've combed over the scripts and I can't find any...hehe HELP
 
Top