Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,889 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.ContextMenus;
using Server.Gumps;
using Solaris.BoardGames;
namespace Server.Items
{
public enum BoardGameState
{
Disabled = 0,
Inactive = 1,
Pending = 2,
Recruiting = 3,
Active = 4,
GameOver = 5
}
//the main control object for a boardgame system. Each board game needs exactly one control object
public abstract class BoardGameControlItem : Item
{
public virtual string GameName{ get{ return "-UNDEFINED-"; } }
public virtual string GameDescription{ get{ return "-UNDEFINED-"; } }
public virtual string GameRules{ get{ return "-UNDEFINED-"; } }
public virtual bool CanCastSpells{ get{ return true; } }
public virtual bool CanUseSkills{ get{ return true; } }
public virtual bool CanUsePets{ get{ return true; } }
public virtual bool UseFromBackpack{ get{ return true; } }
public virtual TimeSpan WinDelay{ get{ return TimeSpan.Zero; } }
protected BoardGameState _State;
protected WinnerTimer _WinnerTimer;
protected EndGameTimer _EndGameTimer;
//valid distance from the control item
public virtual int UseRange{ get{ return 10; } }
public virtual int MinPlayers{ get{ return 0; } }
public virtual int MaxPlayers{ get{ return 0; } }
public int CurrentMaxPlayers;
protected int _CostToPlay;
//the list of all players participating in the game
protected List<Mobile> _Players;
//the list of all players pending a decision when interacting with the boardgame controller
protected List<Mobile> _PendingPlayers;
//the defined region where the game is taking place
public Rectangle3D GameZone;
protected Point3D _BoardOffset;
public Point3D BoardOffset{ get{ return _BoardOffset; } }
protected bool _SettingsReady;
public bool SettingsReady
{
get{ return _SettingsReady; }
set
{
_SettingsReady = value;
if( _SettingsReady && Players.Count == CurrentMaxPlayers && _State < BoardGameState.Active && _State != BoardGameState.Disabled )
{
InitializeGame();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D BoardLocation
{
get
{
return new Point3D( X + _BoardOffset.X, Y + _BoardOffset.Y, Z + _BoardOffset.Z );
}
set
{
Point3D location = value;
_BoardOffset = new Point3D( location.X - X, location.Y - Y, location.Z - Z );
UpdatePosition();
}
}
protected Map _BoardMap;
[CommandProperty( AccessLevel.GameMaster )]
public Map BoardMap
{
get{ return _BoardMap; }
set
{
_BoardMap = value;
UpdatePosition();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool ForceGameOver
{
get{ return false; }
set
{
if( value )
{
EndGame();
}
}
}
protected bool _AllowPlayerConfiguration;
[CommandProperty( AccessLevel.GameMaster )]
public bool AllowPlayerConfiguration
{
get{ return _AllowPlayerConfiguration; }
set
{
_AllowPlayerConfiguration = value;
if( _State != BoardGameState.Recruiting )
{
_SettingsReady = !value;
}
}
}
//these hold the height and width of the game board
protected int _BoardWidth;
protected int _BoardHeight;
[CommandProperty( AccessLevel.GameMaster )]
public virtual int BoardWidth
{
get
{
return _BoardWidth;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardWidth = value;
ResetBoard();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public virtual int BoardHeight
{
get
{
return _BoardHeight;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardHeight = value;
ResetBoard();
}
}
}
//the list of all items used as background for the game board
protected List<GamePiece> _BackgroundItems;
protected BoardGameRegion _BoardGameRegion;
[CommandProperty( AccessLevel.GameMaster )]
public BoardGameState State
{
get
{
return _State;
}
set
{
_State = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int CostToPlay
{
get{ return _CostToPlay; }
set
{
_CostToPlay = value;
InvalidateProperties();
}
}
public List<Mobile> Players
{
get
{
if( _Players == null )
{
_Players = new List<Mobile>();
}
return _Players;
}
}
public List<Mobile> PendingPlayers
{
get
{
if( _PendingPlayers == null )
{
_PendingPlayers = new List<Mobile>();
}
return _PendingPlayers;
}
}
public List<GamePiece> BackgroundItems
{
get
{
if( _BackgroundItems == null )
{
_BackgroundItems = new List<GamePiece>();
}
return _BackgroundItems;
}
}
//main constructor
public BoardGameControlItem() : base( 4006 ) //default itemid 4006: checkerboard
{
_AllowPlayerConfiguration = true;
CurrentMaxPlayers = MinPlayers;
InitializeControl();
}
//deserialization constructor
public BoardGameControlItem( Serial serial ) : base( serial )
{
}
//this method initializes the game control and connects it with this item
protected virtual void InitializeControl()
{
ResetBoard();
Movable = UseFromBackpack;
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
list.Add( new ViewBoardGameScoresEntry( from, this, 1 ) );
if( from.AccessLevel >= AccessLevel.GameMaster )
{
list.Add( new ResetBoardGameScoresEntry( from, this, 2 ) );
}
}
//this method builds the game board
public virtual void BuildBoard()
{
}
//this resets the gameboard and refreshes it
public virtual void ResetBoard()
{
WipeBoard();
BuildBoard();
}
protected virtual void PrimePlayers()
{
foreach( Mobile player in Players )
{
player.CloseGump( typeof( AwaitRecruitmentGump ) );
player.CloseGump( typeof( SelectStyleGump ) );
}
}
public virtual void WipeBoard()
{
foreach( GamePiece piece in BackgroundItems )
{
piece.BoardGameControlItem = null; //detach reference to this boardgame so that it doesn't wipe the board itself
piece.Delete();
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
_BackgroundItems = null;
}
//this moves the players into the board, gives them the equipment they need, and starts the game
protected virtual void StartGame()
{
//define and clear the game field, then rebuild it
ResetBoard();
//move players into the board, give them game interface items, or otherwise get them set up
PrimePlayers();
}
public virtual void EndGame()
{
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
_PendingPlayers = null;
_SettingsReady = !_AllowPlayerConfiguration;
InvalidateProperties();
foreach( Mobile player in Players )
{
player.CloseGump( typeof( BoardGameGump ) );
}
}
protected void StartEndGameTimer( TimeSpan delay )
{
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
_EndGameTimer = new EndGameTimer( this, delay );
_EndGameTimer.Start();
}
//this triggers the actual engame detection
protected virtual void OnEndGameTimer()
{
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
}
protected virtual void AnnounceWinner()
{
_State = BoardGameState.GameOver;
if( _WinnerTimer == null )
{
_WinnerTimer = new WinnerTimer( this, WinDelay );
_WinnerTimer.Start();
}
}
//this method is called by the control item when a player doubleclicks it
public override void OnDoubleClick( Mobile from )
{
if( CanUse( from ) )
{
OnUse( from );
}
}
public virtual bool CanUse( Mobile from )
{
//if they've logged out
if( from.NetState == null )
{
return false;
}
if( UseFromBackpack )
{
if( !IsChildOf( from.Backpack ) )
{
from.SendMessage( "This must be in your backpack to use." );
return false;
}
}
else
{
if( !from.InRange( this, UseRange ) )
{
from.SendMessage( "You are out of range." );
return false;
}
}
return CheckRequirements( from );
}
public virtual bool CheckRequirements( Mobile from )
{
if( !CanUsePets && from.Followers > 0 )
{
from.SendMessage( "You are not allowed to have pets in this game." );
return false;
}
if( !CheckCost( from, false ) )
{
from.SendMessage( "You lack the gold to play this game." );
return false;
}
return true;
}
//this checks for money, and withdraws it if necessary
public bool CheckCost( Mobile from, bool withdraw )
{
if( CostToPlay == 0 )
{
return true;
}
Gold gold = (Gold)from.Backpack.FindItemByType( typeof( Gold ) );
if( gold == null || gold.Amount < CostToPlay )
{
Container bankbox = from.FindBankNoCreate();
if( bankbox != null )
{
gold = (Gold)bankbox.FindItemByType( typeof( Gold ) );
if( gold != null && gold.Amount >= CostToPlay )
{
if( withdraw )
{
bankbox.ConsumeTotal( typeof( Gold ), CostToPlay );
}
return true;
}
}
return false;
}
if( withdraw )
{
from.Backpack.ConsumeTotal( typeof( Gold ), CostToPlay );
}
return true;
}
//updates all game pieces position
public virtual void UpdatePosition()
{
if( _BoardMap == null || _BoardMap == Map.Internal )
{
_BoardMap = Map;
}
foreach( GamePiece piece in BackgroundItems )
{
piece.UpdatePosition();
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
_BoardGameRegion = new BoardGameRegion( this );
_BoardGameRegion.Register();
}
//mouse-over properties info
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1070722, "Status: " + Enum.GetName( typeof( BoardGameState ), _State ) ); //~1_NOTHING~
list.Add( 1060658, "Cost to play\t{0}", CostToPlay.ToString() ); // ~1_val~: ~2_val~
}
//this method is called when a successful OnDoubleClick method is performed
protected virtual void OnUse( Mobile from )
{
switch( _State )
{
case BoardGameState.Disabled:
{
DisabledGame( from );
break;
}
case BoardGameState.Inactive:
{
OfferNewGame( from );
break;
}
case BoardGameState.Pending:
{
GamePending( from );
break;
}
case BoardGameState.Recruiting:
{
OfferRecruiting( from );
break;
}
case BoardGameState.Active:
{
GameActive( from );
break;
}
case BoardGameState.GameOver:
{
GameOver( from );
break;
}
}
}
protected virtual void DisabledGame( Mobile from )
{
if( from.AccessLevel < AccessLevel.GameMaster )
{
from.SendMessage( "That game has been disabled by staff." );
}
}
protected virtual void OfferNewGame( Mobile from )
{
PendingPlayers.Add( from );
State = BoardGameState.Pending;
from.SendGump( new OfferNewGameGump( from, this, true ) );
}
protected virtual void GamePending( Mobile from )
{
from.SendMessage( "This game is pending use from another player. Please try again later." );
}
protected virtual void OfferRecruiting( Mobile from )
{
if( PendingPlayers.IndexOf( from ) == -1 )
{
if( PendingPlayers.Count < CurrentMaxPlayers )
{
PendingPlayers.Add( from );
from.SendGump( new OfferNewGameGump( from, this, false ) );
}
else
{
from.SendMessage( "This game has enough players attempting to start a game. Please try again later." );
}
}
else
{
from.SendGump( new AwaitRecruitmentGump( from, this ) );
}
}
protected virtual void GameActive( Mobile from )
{
if( Players.IndexOf( from ) == -1 )
{
from.SendMessage( "A game is already in progess. Please try again later." );
}
}
protected virtual void GameOver( Mobile from )
{
from.SendMessage( "The last game has just ended. Please try again later." );
}
//this is called by the recruitment gump when a player agrees to play the game
public virtual void AddPlayer( Mobile from )
{
Players.Add( from );
from.SendGump( new AwaitRecruitmentGump( from, this ) );
if( Players.Count == CurrentMaxPlayers && SettingsReady )
{
InitializeGame();
}
else
{
State = BoardGameState.Recruiting;
}
}
public void InitializeGame()
{
//perform final check on all players to make sure they're still good to play
Mobile toboot = null;
foreach( Mobile player in Players )
{
if( !CanUse( player ) )
{
player.SendMessage( "You can no longer enter the game, and have been removed from the list." );
toboot = player;
break;
}
}
if( toboot != null )
{
if( Players.IndexOf( toboot ) == 0 )
{
_SettingsReady = !_AllowPlayerConfiguration;
}
RemovePlayer( toboot );
return;
}
_PendingPlayers = null;
State = BoardGameState.Active;
foreach( Mobile player in Players )
{
CheckCost( player, true );
player.SendMessage( "Game on!" );
}
//Start the game!
StartGame();
}
//this is called by the await recruitment gump when the player chooses to cancel waiting
public virtual void RemovePlayer( Mobile from )
{
from.CloseGump( typeof( AwaitRecruitmentGump ) );
from.CloseGump( typeof( SelectStyleGump ) );
Players.Remove( from );
PendingPlayers.Remove( from );
if( Players.Count == 0 )
{
State = BoardGameState.Inactive;
_SettingsReady = !_AllowPlayerConfiguration;
}
}
//these are used to update all movable addon components
public override void OnLocationChange( Point3D oldLoc )
{
if ( Deleted )
{
return;
}
UpdatePosition();
}
//these are used to update all movable addon components
public override void OnMapChange()
{
if ( Deleted )
{
return;
}
UpdatePosition();
}
public override void Delete()
{
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
base.Delete();
}
//this cleans up all movable addon components, and removes the reference to this addon in the key item
public override void OnAfterDelete()
{
base.OnAfterDelete();
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
foreach( GamePiece piece in BackgroundItems )
{
if( piece != null && !piece.Deleted )
{
piece.Delete();
}
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 2 );
writer.Write( BoardMap );
writer.Write( _AllowPlayerConfiguration );
writer.Write( (int)_State );
writer.Write( _CostToPlay );
writer.Write( CurrentMaxPlayers );
writer.Write( _BoardWidth );
writer.Write( _BoardHeight );
writer.Write( GameZone.Start.X );
writer.Write( GameZone.Start.Y );
writer.Write( GameZone.Start.Z );
writer.Write( GameZone.End.X );
writer.Write( GameZone.End.Y );
writer.Write( GameZone.End.Z );
writer.Write( _BoardOffset.X );
writer.Write( _BoardOffset.Y );
writer.Write( _BoardOffset.Z );
writer.Write( Players.Count );
foreach( Mobile mobile in Players )
{
writer.Write( mobile );
}
writer.Write( BackgroundItems.Count );
foreach( GamePiece piece in BackgroundItems )
{
writer.Write( (Item)piece );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if( version >= 2 )
{
_BoardMap = reader.ReadMap();
}
else
{
_BoardMap = Map;
}
if( version >= 1 )
{
_AllowPlayerConfiguration = reader.ReadBool();
}
else
{
_AllowPlayerConfiguration = true;
}
State = (BoardGameState)reader.ReadInt();
_CostToPlay = reader.ReadInt();
CurrentMaxPlayers = reader.ReadInt();
_BoardWidth = reader.ReadInt();
_BoardHeight = reader.ReadInt();
GameZone = new Rectangle3D( new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() ), new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() ) );
_BoardOffset = new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() );
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
Players.Add( reader.ReadMobile() );
}
count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BackgroundItems.Add( (GamePiece)reader.ReadItem() );
}
if( _State == BoardGameState.Pending || _State == BoardGameState.Recruiting )
{
_State = BoardGameState.Inactive;
_Players = null;
}
_BoardGameRegion = new BoardGameRegion( this );
_BoardGameRegion.Register();
_SettingsReady = !_AllowPlayerConfiguration;
}
protected class EndGameTimer : Timer
{
private BoardGameControlItem _ControlItem;
public EndGameTimer( BoardGameControlItem controlitem, TimeSpan delay ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
_ControlItem = controlitem;
}
protected override void OnTick()
{
_ControlItem.OnEndGameTimer();
}
}
//this timer delays the game a bit, so the winner can stand proud over the game
protected class WinnerTimer : Timer
{
private BoardGameControlItem _ControlItem;
public WinnerTimer( BoardGameControlItem controlitem, TimeSpan delay ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
_ControlItem = controlitem;
}
protected override void OnTick()
{
_ControlItem.EndGame();
Stop();
}
}
}
}

View File

@@ -0,0 +1,333 @@
using System;
using System.IO;
using System.Collections.Generic;
using Server;
namespace Solaris.BoardGames
{
//this data class is used to keep track of player scores for various boardgames
public class BoardGameData
{
public const string SAVE_PATH = @"Saves\BoardGame Data";
public const string FILENAME = "boardgames.bin";
protected static List<BoardGameData> _GameData;
public static List<BoardGameData> GameData
{
get
{
if( _GameData == null )
{
_GameData = new List<BoardGameData>();
}
return _GameData;
}
}
protected string _GameName;
protected List<BoardGamePlayerScore> _Scores;
public string GameName{ get{ return _GameName; } }
public List<BoardGamePlayerScore> Scores
{
get
{
if( _Scores == null )
{
_Scores = new List<BoardGamePlayerScore>();
}
return _Scores;
}
}
protected BoardGameData( string gamename )
{
_GameName = gamename;
}
protected BoardGameData( GenericReader reader )
{
Deserialize( reader );
}
protected virtual void Serialize( GenericWriter writer )
{
writer.Write( 0 );
writer.Write( _GameName );
writer.Write( Scores.Count );
foreach( BoardGamePlayerScore score in Scores )
{
score.Serialize( writer );
}
}
protected virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
_GameName = reader.ReadString();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BoardGamePlayerScore playerscore = new BoardGamePlayerScore( reader );
if( playerscore.Player != null && !playerscore.Player.Deleted )
{
Scores.Add( playerscore );
}
}
}
protected static BoardGamePlayerScore GetScoreData( string gamename, Mobile player )
{
List<BoardGamePlayerScore> scores = GetScores( gamename );
if( scores == null )
{
BoardGameData gamedata = new BoardGameData( gamename );
GameData.Add( gamedata );
scores = gamedata.Scores;
}
int index = BoardGamePlayerScore.IndexOf( scores, player );
if( index == -1 )
{
BoardGamePlayerScore newscore = new BoardGamePlayerScore( player );
scores.Add( newscore );
return newscore;
}
else
{
return scores[ index ];
}
}
public static List<BoardGamePlayerScore> GetScores( string gamename )
{
int gameindex = IndexOf( gamename );
if( gameindex == -1 )
{
return null;
}
else
{
return GameData[ gameindex ].Scores;
}
}
public static void SetScore( string gamename, Mobile player, int score )
{
BoardGamePlayerScore scoredata = GetScoreData( gamename, player );
if( scoredata != null )
{
scoredata.Score = score;
}
else
{
}
}
public static int GetScore( string gamename, Mobile player )
{
BoardGamePlayerScore scoredata = GetScoreData( gamename, player );
if( scoredata != null )
{
return scoredata.Score;
}
else
{
return 0;
}
}
public static void ChangeScore( string gamename, Mobile player, int delta )
{
SetScore( gamename, player, Math.Max( 0, GetScore( gamename, player ) + delta ) );
}
public static void AddWin( string gamename, Mobile player )
{
BoardGamePlayerScore playerscore = GetScoreData( gamename, player );
playerscore.Wins += 1;
}
public static void AddLose( string gamename, Mobile player )
{
BoardGamePlayerScore playerscore = GetScoreData( gamename, player );
playerscore.Losses += 1;
}
public static void ResetScores( string gamename )
{
int gameindex = IndexOf( gamename );
if( gameindex > -1 )
{
GameData.RemoveAt( gameindex );
}
}
public static int IndexOf( string gamename )
{
for( int i = 0; i < GameData.Count; i++ )
{
if( GameData[i].GameName == gamename )
{
return i;
}
}
return -1;
}
public static void Configure()
{
EventSink.WorldLoad += new WorldLoadEventHandler( OnLoad );
EventSink.WorldSave += new WorldSaveEventHandler( OnSave );
}
public static void OnSave( WorldSaveEventArgs e )
{
if( !Directory.Exists( SAVE_PATH ) )
{
Directory.CreateDirectory( SAVE_PATH );
}
GenericWriter writer = new BinaryFileWriter( Path.Combine( SAVE_PATH, FILENAME ), true );
writer.Write( 0 );
writer.Write( GameData.Count );
foreach( BoardGameData data in GameData )
{
data.Serialize( writer );
}
writer.Close();
}
public static void OnLoad()
{
//don't load the file if it don't exist!
if( !File.Exists( Path.Combine( SAVE_PATH, FILENAME ) ) )
{
return;
}
using( FileStream bin = new FileStream( Path.Combine( SAVE_PATH, FILENAME ), FileMode.Open, FileAccess.Read, FileShare.Read ) )
{
GenericReader reader = new BinaryFileReader( new BinaryReader( bin ) );
int version = reader.ReadInt();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
GameData.Add( new BoardGameData( reader ) );
}
reader.End();
}
}
}
public class BoardGamePlayerScore : IComparable
{
protected Mobile _Player;
public Mobile Player{ get{ return _Player; } }
public int Score;
public int Wins;
public int Losses;
public BoardGamePlayerScore( Mobile player ) : this( player, 0 )
{
}
public BoardGamePlayerScore( Mobile player, int score )
{
_Player = player;
Score = score;
}
//deserialize constructor
public BoardGamePlayerScore( GenericReader reader )
{
Deserialize( reader );
}
public int CompareTo( object obj )
{
if( !( obj is BoardGamePlayerScore ) )
{
return 0;
}
BoardGamePlayerScore comparescore = (BoardGamePlayerScore)obj;
return -Score.CompareTo( comparescore.Score );
}
public virtual void Serialize( GenericWriter writer )
{
writer.Write( 0 );
writer.Write( _Player );
writer.Write( Score );
writer.Write( Wins );
writer.Write( Losses );
}
public virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
_Player = reader.ReadMobile();
Score = reader.ReadInt();
Wins = reader.ReadInt();
Losses = reader.ReadInt();
}
public static int IndexOf( List<BoardGamePlayerScore> scores, Mobile player )
{
if( scores == null )
{
return -1;
}
for( int i = 0; i < scores.Count; i++ )
{
if( scores[i].Player == player )
{
return i;
}
}
return -1;
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using Server;
using Server.Accounting;
namespace Solaris.BoardGames
{
//this class defines all data access for tracking player scores within boardgames
public class BoardGamePlayer
{
//current plan is to use account tags.
//TODO: explore XML tags and such to better integrate with XML quest systems?
//this sets the players score for a particular game type
public static bool SetScore( Mobile mobile, string gametype, int score )
{
if( mobile.Account == null )
{
return false;
}
Account acct = (Account)mobile.Account;
acct.SetTag( "BoardGames-" + gametype, score.ToString() );
return true;
}
public static int GetScore( Mobile mobile, string gametype )
{
try
{
Account acct = (Account)mobile.Account;
return Convert.ToInt32( acct.GetTag( "BoardGames-" + gametype ) );
}
catch
{
return -1;
}
}
}
}

View File

@@ -0,0 +1,108 @@
using Server;
using System;
using System.Collections;
using Server.Items;
using Server.Spells;
using Server.Mobiles;
using Server.Regions;
namespace Solaris.BoardGames
{
//a boardgame region is a custom region that handles rules for players within the region (no casting, no pets, etc)
public class BoardGameRegion : GuardedRegion
{
protected static int _RegionIndex = 0;
protected BoardGameControlItem _BoardGameControlItem;
public static string GetUniqueName( BoardGameControlItem controlitem )
{
return controlitem.GameName + " " + ( _RegionIndex++ ).ToString();
}
public BoardGameControlItem BoardGameControlItem
{
get{ return _BoardGameControlItem; }
}
public BoardGameRegion( BoardGameControlItem controlitem ): base( GetUniqueName( controlitem ), controlitem.Map, 255, controlitem.GameZone )
{
Disabled = true;
_BoardGameControlItem = controlitem;
}
public override bool AllowHousing(Mobile from, Point3D p)
{
return false;
}
public override bool AllowSpawn()
{
return false;
}
public override bool CanUseStuckMenu( Mobile m )
{
return false;
}
public override bool OnDamage( Mobile m, ref int Damage )
{
return false;
}
public override bool OnBeginSpellCast( Mobile from, ISpell s )
{
if( from.AccessLevel > AccessLevel.Player )
{
return true;
}
return _BoardGameControlItem.CanCastSpells;
}
public override void OnEnter( Mobile m )
{
m.SendMessage( "Entering boardgame" );
if( _BoardGameControlItem.Players.IndexOf( m ) == -1 && m.AccessLevel == AccessLevel.Player )
{
m.SendMessage( "You are not allowed in there." );
m.MoveToWorld( _BoardGameControlItem.Location, _BoardGameControlItem.Map );
}
}
public override void OnExit( Mobile m )
{
m.SendMessage( "Exiting boardgame" );
}
public override bool OnSkillUse( Mobile m, int skill )
{
return _BoardGameControlItem.CanUseSkills;
}
public override bool OnMoveInto( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation )
{
if( m is BaseCreature && !_BoardGameControlItem.CanUsePets )
{
return false;
}
if( _BoardGameControlItem.Players.IndexOf( m ) == -1 )
{
if( !( m is PlayerMobile ) || m.AccessLevel > AccessLevel.Player )
{
return true;
}
return false;
}
return true;
}
public override bool OnDoubleClick( Mobile m, object o )
{
//TODO: put shrunken pet control here
return base.OnDoubleClick( m, o );
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using Server;
using Server.ContextMenus;
using Server.Gumps;
using Server.Items;
namespace Solaris.BoardGames
{
public class ViewBoardGameScoresEntry : ContextMenuEntry
{
Mobile _From;
BoardGameControlItem _ControlItem;
//3006239 = "View events"
public ViewBoardGameScoresEntry( Mobile from, BoardGameControlItem controlitem, int index ) : base( 6239, index )
{
_From = from;
_ControlItem = controlitem;
}
public override void OnClick()
{
if ( _ControlItem == null || _ControlItem.Deleted )
{
return;
}
_From.SendGump( new BoardGameScoresGump( _From, _ControlItem ) );
}
}
public class ResetBoardGameScoresEntry : ContextMenuEntry
{
Mobile _From;
BoardGameControlItem _ControlItem;
//3006162 = "Reset Game"
public ResetBoardGameScoresEntry( Mobile from, BoardGameControlItem controlitem, int index ) : base( 6162, index )
{
_From = from;
_ControlItem = controlitem;
}
public override void OnClick()
{
if ( _ControlItem == null || _ControlItem.Deleted )
{
return;
}
_From.SendGump( new ConfirmResetGameScoreGump( _From, _ControlItem ) );
}
}
}

View File

@@ -0,0 +1,158 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a gamepiece behaves much like an addon component
public class GamePiece : Item
{
//offset from the boardgame control item
public Point3D Offset;
//reference to the LOSBlocker used to block line of sight thru this gamepiece
public LOSBlocker _Blocker;
//reference to the boardgame control item that this piece belongs to
public BoardGameControlItem BoardGameControlItem;
//randomize itemid constructor
public GamePiece( int itemidmin, int itemidmax, string name ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name )
{
}
//randomize itemid constructor
public GamePiece( int itemidmin, int itemidmax, string name, bool blocklos ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name, blocklos )
{
}
//default no block los constructor
public GamePiece( int itemid, string name ) : this( itemid, name, false )
{
}
//master constructor
public GamePiece( int itemid, string name, bool blocklos ) : base( itemid )
{
Movable = false;
Name = name;
if( blocklos )
{
_Blocker = new LOSBlocker();
}
}
//deserialize constructor
public GamePiece( Serial serial ) : base( serial )
{
}
public void RegisterToBoardGameControlItem( BoardGameControlItem boardgamecontrolitem, Point3D offset )
{
BoardGameControlItem = boardgamecontrolitem;
Offset = offset;
UpdatePosition();
}
//move the item based on its position with respect to the boardgame control item
public void UpdatePosition()
{
if( BoardGameControlItem != null )
{
MoveToWorld( new Point3D( BoardGameControlItem.X + BoardGameControlItem.BoardOffset.X + Offset.X, BoardGameControlItem.Y + BoardGameControlItem.BoardOffset.Y + Offset.Y, BoardGameControlItem.Z + BoardGameControlItem.BoardOffset.Z + Offset.Z ), BoardGameControlItem.BoardMap );
}
else
{
Delete();
}
}
public override void OnLocationChange( Point3D old )
{
if( BoardGameControlItem != null )
{
BoardGameControlItem.Location = new Point3D( X - BoardGameControlItem.BoardOffset.X - Offset.X, Y - BoardGameControlItem.BoardOffset.Y - Offset.Y, Z - BoardGameControlItem.BoardOffset.Z - Offset.Z );
}
if( _Blocker != null )
{
_Blocker.MoveToWorld( Location, Map );
}
}
public override void OnMapChange()
{
if( BoardGameControlItem != null && BoardGameControlItem.BoardMap != Map )
{
BoardGameControlItem.BoardMap = Map;
}
if( _Blocker != null )
{
_Blocker.MoveToWorld( Location, Map );
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if( BoardGameControlItem != null )
{
BoardGameControlItem.Delete();
}
if( _Blocker != null )
{
_Blocker.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 1 );
writer.Write( (Item)_Blocker );
writer.Write( (Item)BoardGameControlItem );
writer.Write( Offset.X );
writer.Write( Offset.Y );
writer.Write( Offset.Z );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch( version )
{
default:
case 1:
{
_Blocker = (LOSBlocker)reader.ReadItem();
goto case 0;
}
case 0:
{
BoardGameControlItem = (BoardGameControlItem)reader.ReadItem();
Offset.X = reader.ReadInt();
Offset.Y = reader.ReadInt();
Offset.Z = reader.ReadInt();
break;
}
}
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//offers a new game to a player
public class AwaitRecruitmentGump : BoardGameGump
{
public override int Height{ get{ return 200; } }
public override int Width{ get{ return 400; } }
public AwaitRecruitmentGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
//force it so players can't close this gump
Closable = false;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddHtml( 40, 50, Width - 80, 80, "You are waiting for more players to join this game. When there are enough, this window will automatically close and the game will start. If you wish to cancel waiting, click the Cancel button.", true, false );
AddButton( 160, 160, 0xF1, 0xF2, 1, GumpButtonType.Reply, 0 );
}
protected override void DeterminePageLayout()
{
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
//cancel button
if( buttonid == 1 )
{
_Owner.CloseGump( typeof( SelectStyleGump ) );
_ControlItem.RemovePlayer( _Owner );
_Owner.SendMessage( "You are no longer waiting to play this game." );
}
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//main gump class for boardgames
public class BoardGameGump : Gump
{
public virtual int Height{ get{ return 100; } }
public virtual int Width{ get{ return 100; } }
//reference to the control system for the boardgame
protected BoardGameControlItem _ControlItem;
protected Mobile _Owner;
public BoardGameGump( Mobile owner, BoardGameControlItem controlitem ) : base( 50, 50 )
{
_Owner = owner;
_ControlItem = controlitem;
_Owner.CloseGump( typeof( BoardGameGump ) );
DrawBackground();
}
protected virtual void DrawBackground()
{
AddPage(0);
//determine page layout, sizes, and what gets displayed where
DeterminePageLayout();
AddBackground( 0, 0, Width, Height, 9270 );
AddImageTiled( 11, 10, Width - 22, Height - 20, 2624 );
AddAlphaRegion( 11, 10, Width - 22, Height - 20 );
}
protected virtual void DeterminePageLayout()
{
}
public void AddTextField( int x, int y, int width, int height, int index, string text )
{
AddImageTiled( x - 2, y - 2, width + 4, height + 4, 0xA2C );
AddAlphaRegion( x -2, y - 2, width + 4, height + 4 );
AddTextEntry( x + 2, y + 2, width - 4, height - 4, 1153, index, text );
}
public string GetTextField( RelayInfo info, int index )
{
TextRelay relay = info.GetTextEntry( index );
return ( relay == null ? null : relay.Text.Trim() );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameLostGump : BoardGameGump
{
public override int Height{ get{ return 140; } }
public override int Width{ get{ return 300; } }
public BoardGameLostGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "You've lost the game!" );
//TODO: add info about points earned?
AddButton( 100, 80, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameScoresGump : BoardGameGump
{
public const int ENTRIES_PER_PAGE = 10;
public override int Height{ get{ return 440; } }
public override int Width{ get{ return 350; } }
protected List<BoardGamePlayerScore> _PlayerScores;
protected int _X;
protected int _Y;
//maximum entry listing height, for multi-page calculation
public int MaxEntryDisplayHeight{ get{ return 300; } }
//line spacing between entries
public int EntryLineSpacing{ get{ return 20; } }
protected int _Page;
//this is determined based on the number of entries and the maximum number to display per page
protected int _MaxPages;
public BoardGameScoresGump( Mobile owner, BoardGameControlItem controlitem ) : this( owner, controlitem, 0 )
{
}
public BoardGameScoresGump( Mobile owner, BoardGameControlItem controlitem, int page ) : base( owner, controlitem )
{
_Page = page;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Scores" );
_PlayerScores = BoardGameData.GetScores( controlitem.GameName );
if( _PlayerScores == null || _PlayerScores.Count == 0 )
{
AddLabel( 40, 80, 1152, "- NO SCORES SET YET -" );
return;
}
_PlayerScores.Sort();
_X = 20;
_Y = 80;
_MaxPages = _PlayerScores.Count / ENTRIES_PER_PAGE + 1;
if( _PlayerScores.Count % ENTRIES_PER_PAGE == 0 )
{
_MaxPages -= 1;
}
_Page = Math.Max( 0, Math.Min( _Page, _MaxPages ) );
int listingstart = _Page * ENTRIES_PER_PAGE;
int listingend = Math.Min( _PlayerScores.Count, (_Page + 1 ) * ENTRIES_PER_PAGE );
AddLabel( _X, _Y, 1152, "Name" );
AddLabel( _X + 150, _Y, 1152, "Score" );
AddLabel( _X+ 200, _Y, 1152, "Wins" );
AddLabel( _X + 250, _Y, 1152, "Losses" );
for( int i = listingstart; i < listingend; i++ )
{
AddLabel( _X, _Y += 20, 1152, _PlayerScores[i].Player.Name );
AddLabel( _X + 150, _Y, 1152, _PlayerScores[i].Score.ToString() );
AddLabel( _X + 200, _Y, 1152, _PlayerScores[i].Wins.ToString() );
AddLabel( _X + 250, _Y, 1152, _PlayerScores[i].Losses.ToString() );
}
AddPageButtons();
AddButton( 60, Height - 40, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
protected void AddPageButtons()
{
//page buttons
_Y = Height - 90;
if ( _Page > 0 )
{
AddButton( 20, _Y, 0x15E3, 0x15E7, 4, GumpButtonType.Reply, 0 );
}
else
{
AddImage( 20, _Y, 0x25EA );
}
AddLabel( 40, _Y, 88, "Previous Page" );
if ( _Page < _MaxPages - 1 )
{
AddButton( Width - 40, _Y, 0x15E1, 0x15E5, 5, GumpButtonType.Reply, 0 );
}
else
{
AddImage( Width - 40, _Y, 0x25E6 );
}
AddLabel( Width - 120, _Y, 88, "Next Page" );
AddLabel( Width / 2 - 10, _Y, 88, String.Format( "({0}/{1})", _Page + 1, _MaxPages ) );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
if( buttonid == 4 )
{
_Owner.SendGump( new BoardGameScoresGump( _Owner, _ControlItem, _Page - 1 ) );
}
else if( buttonid == 5 )
{
_Owner.SendGump( new BoardGameScoresGump( _Owner, _ControlItem, _Page + 1 ) );
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameWonGump : BoardGameGump
{
public override int Height{ get{ return 140; } }
public override int Width{ get{ return 300; } }
public BoardGameWonGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Congratulations, you won the game!!" );
//TODO: add info about points earned?
AddButton( 100, 80, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
_ControlItem.EndGame();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class ConfirmResetGameScoreGump : BoardGameGump
{
public override int Height{ get{ return 200; } }
public override int Width{ get{ return 400; } }
protected int _Y = 30;
protected int _X = 20;
public ConfirmResetGameScoreGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddHtml( 40, 50, Width - 80, 80, "You are about to reset all the score data for " + _ControlItem.GameName + ". Once you do this, it cannot be undone. Are you sure you wish to do this?", true, false );
AddButton( 30, 160, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 );
AddButton( 160, 160, 0xF1, 0xF2, 0, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if( info.ButtonID == 1 )
{
BoardGameData.ResetScores( _ControlItem.GameName );
_Owner.SendMessage( "You have now reset all the scores." );
}
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//offers a new game to a player
public class OfferNewGameGump : BoardGameGump
{
protected bool _ControlNumberOfPlayers;
public override int Height{ get{ return 500; } }
public override int Width{ get{ return 400; } }
public OfferNewGameGump( Mobile owner, BoardGameControlItem controlitem, bool controlnumberofplayers ) : base( owner, controlitem )
{
_ControlNumberOfPlayers = controlnumberofplayers;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Description:" );
AddHtml( 40, 70, 300, 100, _ControlItem.GameDescription, true, true );
AddLabel( 40, 180, 1152, "Rules:" );
AddHtml( 40, 200, 300, 150, _ControlItem.GameRules, true, true );
if( _ControlItem.CostToPlay > 0 )
{
AddLabel( 40, 370, 1152, "Cost to play:" );
AddLabel( 240, 370, 1172, _ControlItem.CostToPlay.ToString() + " gold" );
}
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers )
{
AddLabel( 40, 430, 1152, "# of players (" + _ControlItem.MinPlayers.ToString() + "-" + _ControlItem.MaxPlayers.ToString() + "):" );
if( _ControlNumberOfPlayers )
{
AddLabel( 60, 410, 1172, "Pick the number of players" );
AddTextField( 240, 430, 30, 20, 0, _ControlItem.CurrentMaxPlayers.ToString() );
}
else
{
AddLabel( 240, 430, 1152, _ControlItem.CurrentMaxPlayers.ToString() );
}
}
AddLabel( 40, 470, 1152, "Play this game?" );
AddButton( 200, 460, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 );
AddButton( 300, 460, 0xF1, 0xF2, 0, GumpButtonType.Reply, 0 );
}
protected override void DeterminePageLayout()
{
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
//cancel or right click
if( buttonid == 0 )
{
_ControlItem.RemovePlayer( _Owner );
_Owner.SendMessage( "You decide not to play this game" );
}
else
{
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers && _ControlNumberOfPlayers )
{
try
{
_ControlItem.CurrentMaxPlayers = Int32.Parse( GetTextField( info, 0 ) );
if( _ControlItem.CurrentMaxPlayers > _ControlItem.MaxPlayers || _ControlItem.CurrentMaxPlayers < _ControlItem.MinPlayers )
{
throw( new Exception() );
}
}
catch
{
_Owner.SendMessage( "Invalid number of players selected. Please try again." );
_Owner.SendGump( new OfferNewGameGump( _Owner, _ControlItem, _ControlNumberOfPlayers ) );
return;
}
}
_Owner.SendMessage( "You have signed up for this game." );
_ControlItem.AddPlayer( _Owner );
}
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class SelectStyleGump : Gump
{
public virtual int Height{ get{ return 150; } }
public virtual int Width{ get{ return 200; } }
protected int _Y = 30;
protected int _X = 20;
protected BoardGameControlItem _ControlItem;
public SelectStyleGump( Mobile owner, BoardGameControlItem controlitem ) : base( 450, 80 )
{
Closable = false;
owner.CloseGump( typeof( SelectStyleGump ) );
_ControlItem = controlitem;
if( _ControlItem.Players.IndexOf( owner ) == -1 )
{
return;
}
AddPage( 0 );
AddBackground( 0, 0, Width, Height, 0x1400 );
AddLabel( 20, 60, 1152, "# of players (" + _ControlItem.MinPlayers.ToString() + "-" + _ControlItem.MaxPlayers.ToString() + "):" );
int minplayers = Math.Max( _ControlItem.MinPlayers, _ControlItem.Players.Count );
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers && !_ControlItem.SettingsReady )
{
AddLabel( 20, 40, 1172, "Pick the number of players" );
AddTextField( 150, 60, 30, 20, 0, _ControlItem.CurrentMaxPlayers.ToString() );
AddButton( 182, 62, 0x4B9, 0x4BA, 500, GumpButtonType.Reply, 0 );
}
else
{
AddLabel( 150, 60, 1152, _ControlItem.CurrentMaxPlayers.ToString() );
}
//AddButton( Width - 15, 0, 3, 4, 0, GumpButtonType.Reply, 0 );
}
public void AddTextField( int x, int y, int width, int height, int index, string text )
{
AddImageTiled( x - 2, y - 2, width + 4, height + 4, 0xA2C );
AddAlphaRegion( x -2, y - 2, width + 4, height + 4 );
AddTextEntry( x + 2, y + 2, width - 4, height - 4, 1153, index, text );
}
public string GetTextField( RelayInfo info, int index )
{
TextRelay relay = info.GetTextEntry( index );
return ( relay == null ? null : relay.Text.Trim() );
}
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if( _ControlItem.Players.IndexOf( from ) != 0 )
{
return;
}
try
{
if( !_ControlItem.SettingsReady )
{
_ControlItem.CurrentMaxPlayers = Math.Max( Int32.Parse( GetTextField( info, 0 ) ), _ControlItem.Players.Count );
if( _ControlItem.CurrentMaxPlayers > _ControlItem.MaxPlayers || _ControlItem.CurrentMaxPlayers < _ControlItem.MinPlayers )
{
throw( new Exception() );
}
}
}
catch
{
from.SendMessage( "Invalid number of players selected. Please try again." );
}
}
}
}

View File

@@ -0,0 +1,622 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Gumps;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Items
{
//a test of the boardgame system
public class BombermanControlItem : BoardGameControlItem
{
public override string GameName{ get{ return "Bomberman"; } }
public override string GameDescription{ get{ return "Blow up walls and players with bombs. Collect upgrades to improve your number of bombs, blast size, etc."; } }
public override string GameRules
{
get
{
return "Each game can have up to eight players, and everyone starts in a corner or edge of the arena. " +
"A bomb bag is placed in the players' backpacks. Players use this bag to place bombs at their feet. " +
"A bomb will detonate after some time, and has a limited blast size. The number of bombs any player can place at any time is limited.<BR><BR>" +
"Players must blast at the breakable walls to navigate the arena. " +
"While blasting, upgrades can be found which improve the blast size or number of bombs a player can place at once. " +
"There is also a detonator upgrade that lets a player choose when they want their bombs to blow up. " +
"Watch out for other players' blasts! A bomb can trigger another bomb to go off, creating interesting chain reactions!<BR><BR>" +
"The game ends when there is only one player left standing. ";
}
}
public override bool CanCastSpells{ get{ return false; } }
public override bool CanUseSkills{ get{ return false; } }
public override bool CanUsePets{ get{ return false; } }
public override TimeSpan WinDelay{ get{ return TimeSpan.FromSeconds( 5 ); } }
//bomberman main controller must be accessed from ground
public override bool UseFromBackpack{ get{ return false; } }
//only 1 to 8 players allowed in a bomberman game
public override int MinPlayers{ get{ return 2; } }
public override int MaxPlayers{ get{ return 8; } }
protected BombermanStyle _Style;
[CommandProperty( AccessLevel.GameMaster )]
public BombermanStyle Style
{
get{ return _Style; }
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_Style = value;
ResetBoard();
}
}
}
//reference to be bomb bags that are handed out for the game
protected List<BombBag> _BombBags;
public List<BombBag> BombBags
{
get
{
if( _BombBags == null )
{
_BombBags = new List<BombBag>();
}
return _BombBags;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public override int BoardWidth
{
get
{
_BoardWidth = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, _BoardWidth ) );
return _BoardWidth;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardWidth = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, value ) );
if( ( _BoardWidth & 1 ) == 0 )
{
_BoardWidth += 1;
}
ResetBoard();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public override int BoardHeight
{
get
{
_BoardHeight = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, _BoardHeight ) );
return _BoardHeight;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardHeight = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, value ) );
if( ( _BoardHeight & 1 ) == 0 )
{
_BoardHeight += 1;
}
ResetBoard();
}
}
}
protected int _DefaultMaxBombs = 2;
protected int _DefaultBombStrength = 1;
protected bool _DefaultDetonatorMode = false;
protected bool _DefaultBaddaBoom = false;
[CommandProperty( AccessLevel.GameMaster )]
public int DefaultMaxBombs
{
get{ return _DefaultMaxBombs; }
set
{
_DefaultMaxBombs = Math.Max( 1, value );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int DefaultBombStrength
{
get{ return _DefaultBombStrength; }
set
{
_DefaultBombStrength = Math.Max( 1, value );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DefaultDetonatorMode
{
get{ return _DefaultDetonatorMode; }
set
{
_DefaultDetonatorMode = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DefaultBaddaBoom
{
get{ return _DefaultBaddaBoom; }
set
{
_DefaultBaddaBoom = value;
}
}
//main constructor
[Constructable]
public BombermanControlItem()
{
ItemID = 0xED4; //guild gravestone
Name = "Bomberman Game Controller";
BoardWidth = BombermanSettings.DEFAULT_BOARD_SIZE;
BoardHeight = BombermanSettings.DEFAULT_BOARD_SIZE;
_State = BoardGameState.Inactive;
_BoardOffset = new Point3D( 2, 2, 0 );
}
//deserialization constructor
public BombermanControlItem( Serial serial ) : base( serial )
{
}
//this method initializes the game control and connects it with this item
protected override void InitializeControl()
{
base.InitializeControl();
}
public override void UpdatePosition()
{
GameZone = new Rectangle3D( new Point3D( X + BoardOffset.X, Y + BoardOffset.X, BoardOffset.Z - 100 ), new Point3D( X + BoardOffset.X + BoardWidth, Y + BoardOffset.Y + BoardHeight, BoardOffset.Z + 100 ) );
base.UpdatePosition();
}
public override void AddPlayer( Mobile m )
{
base.AddPlayer( m );
PublicOverheadMessage( MessageType.Regular, 1153, false, "Adding " + m.Name + " to the game!" );
//if this is the first player to be added, they can also choose the board style
if( Players.Count == 1 && _AllowPlayerConfiguration )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " is now in charge of this game!" );
m.SendGump( new SelectBombermanStyleGump( m, this ) );
}
if( Players.Count < CurrentMaxPlayers )
{
int requiredplayers = CurrentMaxPlayers - Players.Count;
PublicOverheadMessage( MessageType.Regular, 1153, false, requiredplayers.ToString() + " more needed!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " needs to confirm style!" );
}
}
public override void RemovePlayer( Mobile m )
{
if( Players.IndexOf( m ) > -1 )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "Removing " + m.Name + " from the game!" );
}
if( Players.IndexOf( m ) == 0 && Players.Count > 1 )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[1].Name + " is now in charge of this game!" );
SettingsReady = false;
Players[1].SendGump( new SelectBombermanStyleGump( Players[1], this ) );
Players[1].SendMessage( "You are now in charge of setting up the game!" );
}
base.RemovePlayer( m );
if( Players.Count > 0 )
{
int requiredplayers = CurrentMaxPlayers - Players.Count;
PublicOverheadMessage( MessageType.Regular, 1153, false, requiredplayers.ToString() + " more needed!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "No more players... resetting." );
}
}
public override void BuildBoard()
{
UpdatePosition();
for( int i = 0; i < BoardWidth; i++ )
{
for( int j = 0; j < BoardHeight; j++ )
{
//build the ground
BombermanFloorTile groundpiece = new BombermanFloorTile( _Style );
groundpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j,0 ) );
BackgroundItems.Add( groundpiece );
//build the outer walls and inner grid walls
if( i == 0 || i == BoardWidth - 1 || j == 0 || j == BoardHeight - 1 || j % 2 == 0 && i % 2 == 0 )
{
IndestructableWall wallpiece = new IndestructableWall( _Style, true );
wallpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j, 0 ) );
BackgroundItems.Add( wallpiece );
}
else
{
if( _State == BoardGameState.Active ) //if a game is active, then build obstacles and such
{
//don't put obstacles in the player starting positions
if( i < 3 && j < 3 || i > BoardWidth - 4 && j < 3 || i < 3 && j > BoardHeight - 4 || i > BoardWidth - 4 && j > BoardHeight - 4 )
{
continue;
}
else if( j > BoardHeight / 2 - 2 && j < BoardHeight / 2 + 2 && ( i < 3 || i > BoardWidth - 4 ) )
{
continue;
}
else if( i > BoardWidth / 2 - 2 && i < BoardWidth / 2 + 2 && ( j < 3 || j > BoardHeight - 4 ) )
{
continue;
}
//obstacles
if( Utility.RandomDouble() < BombermanSettings.OBSTACLE_CHANCE )
{
DestructableWall wallpiece = new DestructableWall( _Style );
wallpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j, 0 ) );
BackgroundItems.Add( wallpiece );
}
}
}
}
}
base.BuildBoard();
}
protected override void PrimePlayers()
{
base.PrimePlayers();
for( int i = 0; i < Players.Count; i++ )
{
Mobile player = Players[i];
Point3D movepoint;
switch( i )
{
case 0:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 1:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth - 2, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 2:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 3:
{
movepoint = new Point3D( X + BoardOffset.X + + BoardWidth - 2, Y + BoardOffset.Y + + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 4:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth / 2, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 5:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth - 2, Y + BoardOffset.Y + BoardHeight / 2, Z + BoardOffset.Z );
break;
}
case 6:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth / 2, Y + BoardOffset.Y + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 7:
default:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + BoardHeight / 2, Z + BoardOffset.Z );
break;
}
}
player.MoveToWorld( movepoint, BoardMap );
BombBag bag = new BombBag( this, _DefaultMaxBombs, _DefaultBombStrength );
BombBags.Add( bag );
bag.Owner = player;
player.Backpack.DropItem( bag );
if( _DefaultDetonatorMode )
{
BombDetonator detonator = new BombDetonator( bag );
bag.Detonator = detonator;
player.Backpack.DropItem( detonator );
}
bag.BaddaBoom = _DefaultBaddaBoom;
}
}
public void CheckForMobileVictims( Point3D location, Map map, BombBag sourcebag )
{
IPooledEnumerable ie = map.GetMobilesInRange( location, 0 );
List<Mobile> tomove = new List<Mobile>();
foreach( Mobile m in ie )
{
if( Players.IndexOf( m ) > -1 )
{
if( m != sourcebag.Owner )
{
m.SendMessage( "You've been blown up by " + sourcebag.Owner.Name + "'s blast!" );
sourcebag.Owner.SendMessage( "You've blown " + m.Name + "!" );
//handle scoring
BoardGameData.ChangeScore( GameName, sourcebag.Owner, BombermanSettings.KILL_SCORE );
BoardGameData.ChangeScore( GameName, m, BombermanSettings.DEATH_SCORE );
PublicOverheadMessage( MessageType.Regular, 1153, false, sourcebag.Owner.Name + " has blown up " + m.Name + "!" );
}
else
{
m.SendMessage( "You just blew yourself up!!" );
PublicOverheadMessage( MessageType.Regular, 1153, false, m.Name + " has just blown themself up!" );
BoardGameData.ChangeScore( GameName, m, BombermanSettings.SUICIDE_SCORE );
}
BoardGameData.AddLose( GameName, m );
m.PlaySound( m.Female? 0x32E : 0x549 );
//0x54A - yelp1
tomove.Add( m );
}
}
ie.Free();
foreach( Mobile m in tomove )
{
m.MoveToWorld( new Point3D( X - 1, Y - 1, Z ), Map );
m.SendGump( new BoardGameLostGump( m, this ) );
Players.Remove( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
//don't let players run around blowing stuff up outside the game while they wait for others to finish
bag.Active = false;
}
//start the timer to check for endgame, delay for 1s
}
//test big bomb chain!
StartEndGameTimer( TimeSpan.FromSeconds( 1 ) );
}
//TODO: move into base group?
protected override void OnEndGameTimer()
{
base.OnEndGameTimer();
if( Players.Count < 2 )
{
AnnounceWinner();
}
}
protected override void AnnounceWinner()
{
base.AnnounceWinner();
if( Players.Count == 1 )
{
Players[0].SendGump( new BoardGameWonGump( Players[0], this ) );
BoardGameData.ChangeScore( GameName, Players[0], BombermanSettings.WIN_SCORE );
BoardGameData.AddWin( GameName, Players[0] );
BombBag bag = (BombBag)Players[0].Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
//don't let players run around blowing stuff up outside the game while they wait for others to finish
bag.Active = false;
}
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " wins the game!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "It's a draw!" );
}
}
public override void EndGame()
{
base.EndGame();
if( Map != null )
{
IPooledEnumerable ie = Map.GetItemsInBounds( new Rectangle2D( new Point2D( GameZone.Start.X, GameZone.Start.Y ), new Point2D( GameZone.End.X, GameZone.End.Y ) ) );
List<BombermanUpgrade> todelete = new List<BombermanUpgrade>();
foreach( Item item in ie )
{
if( item is BombermanUpgrade )
{
todelete.Add( (BombermanUpgrade)item );
}
}
ie.Free();
foreach( BombermanUpgrade item in todelete )
{
item.Destroy();
}
//there should only be one left.. the winner
foreach( Mobile player in Players )
{
player.MoveToWorld( new Point3D( X - 1, Y - 1, Z ), Map );
}
}
foreach( BombBag bag in BombBags )
{
if( bag != null )
{
bag.Delete();
}
}
_BombBags = null;
//announce winner?
if( Players.Count == 1 )
{
Players[0].SendMessage( "You've won the game!" );
}
_Players = null;
_State = BoardGameState.Inactive;
InvalidateProperties();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
foreach( BombBag bag in BombBags )
{
if( bag != null )
{
bag.Delete();
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (int)_Style );
writer.Write( _DefaultMaxBombs );
writer.Write( _DefaultBombStrength );
writer.Write( _DefaultDetonatorMode );
writer.Write( _DefaultBaddaBoom );
writer.Write( BombBags.Count );
foreach( BombBag bag in BombBags )
{
writer.Write( (Item)bag );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Style = (BombermanStyle)reader.ReadInt();
_DefaultMaxBombs = reader.ReadInt();
_DefaultBombStrength = reader.ReadInt();
_DefaultDetonatorMode = reader.ReadBool();
_DefaultBaddaBoom = reader.ReadBool();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BombBags.Add( (BombBag)reader.ReadItem() );
}
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using Server;
namespace Solaris.BoardGames
{
public enum BombermanStyle
{
Default = 0,
Rocky = 1,
Woodland = 2,
Warehouse = 3,
Ruins,
Graveyard,
Crystal,
}
//all the default settings for the bomberman game, in a convenient place
public class BombermanSettings
{
//min, max, and default bomberman playing field settings
public const int MAX_BOARD_SIZE = 65;
public const int MIN_BOARD_SIZE = 11;
public const int DEFAULT_BOARD_SIZE = 21;
//chance that a destructable wall will be generated when the gameboard is being built
public const double OBSTACLE_CHANCE = 0.7;
//delay before explosion, in seconds
public const int EXPLODE_DELAY = 3;
//propagation delay of bomb blast, in milliseconds
public const int BLAST_DELAY = 50;
//chance that a demolished wall will spawn an upgrade
public const double UPGRADE_SPAWN_CHANCE = .2;
public const int KILL_SCORE = 1;
public const int DEATH_SCORE = -1;
public const int WIN_SCORE = 2;
public const int SUICIDE_SCORE = -2;
//time until an upgrade will disappear, in seconds
public const int UPGRADE_DECAY_DELAY = 20;
public static int GetDestructableWallID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 1900;
}
case BombermanStyle.Rocky:
{
return Utility.RandomMinMax( 0x1363, 0x136D );
}
case BombermanStyle.Woodland:
{
return Utility.RandomMinMax( 0xCC8, 0xCC9 );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomMinMax( 0xE3C, 0xE3F );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x3B7, 0x3BD );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x1AD8, 0x1ADC );
}
case BombermanStyle.Crystal:
{
return Utility.RandomMinMax( 0x2224, 0x222C );
}
}
}
public static int GetIndestructableWallID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 1801;
}
case BombermanStyle.Rocky:
{
return 0x177A;
}
case BombermanStyle.Woodland:
{
return Utility.RandomList( new int[]{ 0xE57, 0xE59 } );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomList( new int[]{ 0x720, 0x721 } );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x3BE, 0x3C1 );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x1165, 0x1184 );
}
case BombermanStyle.Crystal:
{
return Utility.RandomList( new int[]{ 0x35EB, 0x35EC, 0x35EF, 0x35F6, 0x35F7 } );
}
}
}
public static int GetFloorTileID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 0x496;
}
case BombermanStyle.Rocky:
{
return Utility.RandomMinMax( 0x53B, 0x53F );
}
case BombermanStyle.Woodland:
{
return Utility.RandomMinMax( 0x177D, 0x1781 );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomMinMax( 0x4A9, 0x4AC );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x525, 0x528 );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x515, 0x518 );
}
case BombermanStyle.Crystal:
{
return Utility.RandomMinMax( 0x579, 0x57E );
}
}
}
}
}

View File

@@ -0,0 +1,110 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class SelectBombermanStyleGump : SelectStyleGump
{
public override int Height{ get{ return 200 + Enum.GetNames( typeof( BombermanStyle ) ).Length * 20; } }
public SelectBombermanStyleGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
if( _ControlItem.Players.IndexOf( owner ) == -1 )
{
return;
}
AddLabel( 20, 14, 1152, "Bomberman Board Style" );
//AddButton( Width - 15, 0, 3, 4, 0, GumpButtonType.Reply, 0 );
string[] stylenames = Enum.GetNames( typeof( BombermanStyle ) );
_Y += 50;
foreach( string stylename in stylenames )
{
int index = (int)Enum.Parse( typeof( BombermanStyle ), stylename );
int buttonid = ( (int)((BombermanControlItem)_ControlItem).Style == index ? 0x2C92 : 0x2C88 );
AddButton( _X, _Y += 20, buttonid, buttonid, index + 1, GumpButtonType.Reply, 0 );
AddLabel( _X + 20, _Y - 2, 1152, stylename );
}
AddLabel( _X, _Y += 30, 1152, "Width:" );
AddLabel( _X + 90, _Y, 1152, "Height:" );
if( !_ControlItem.SettingsReady )
{
AddTextField( _X + 50, _Y, 30, 20, 1, _ControlItem.BoardWidth.ToString() );
AddTextField( _X + 140, _Y, 30, 20, 2, _ControlItem.BoardHeight.ToString() );
}
else
{
AddLabel( _X + 50, _Y, 1152, _ControlItem.BoardWidth.ToString() );
AddLabel( _X + 140, _Y, 1152, _ControlItem.BoardHeight.ToString() );
}
AddLabel( _X, _Y += 40, 1152, "Ready to start:" );
int startgamebuttonid = _ControlItem.SettingsReady ? 0xD3: 0xD2;
AddButton( _X + 120, _Y, startgamebuttonid, startgamebuttonid, 1000, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState state, RelayInfo info )
{
base.OnResponse( state, info );
Mobile from = state.Mobile;
if( _ControlItem.Players.IndexOf( from ) != 0 )
{
return;
}
try
{
if( !_ControlItem.SettingsReady )
{
_ControlItem.BoardWidth = Int32.Parse( GetTextField( info, 1 ) );
_ControlItem.BoardHeight = Int32.Parse( GetTextField( info, 2 ) );
}
}
catch
{
}
int selection = info.ButtonID - 1;
if( selection >= 0 && !_ControlItem.SettingsReady )
{
try
{
if( info.ButtonID < 100 )
{
((BombermanControlItem)_ControlItem).Style = (BombermanStyle)selection;
}
}
catch
{
from.SendMessage( "Invalid value" );
}
}
if( info.ButtonID == 1000 )
{
_ControlItem.SettingsReady = !_ControlItem.SettingsReady;
}
if( !_ControlItem.SettingsReady || _ControlItem.Players.Count != _ControlItem.CurrentMaxPlayers )
{
from.SendGump( new SelectBombermanStyleGump( from, _ControlItem ) );
}
}
}
}

View File

@@ -0,0 +1,369 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomb - has a reference to a bomb candle that sits above it
public class Bomb : GamePiece
{
protected BombCandle _Candle;
protected DetonatorReceiver _Detonator;
protected BaddaBoom _BaddaBoom;
public BombBag BombBag;
public Mobile Planter;
protected FuseTimer _FuseTimer;
protected int _Strength;
//master constructor
public Bomb( BombBag bombbag ) : base( 0x2256, bombbag == null ? "Bomb" : bombbag.Owner.Name + "'s Bomb" )
{
Hue = 1;
//link this bomb up to the bomb bag it came from
BombBag = bombbag;
Planter = BombBag.Owner;
_Strength = BombBag.BombStrength;
if( BombBag.BaddaBoom )
{
_BaddaBoom = new BaddaBoom( this );
}
else
{
_Candle = new BombCandle( this );
}
if( BombBag.Detonator != null )
{
_Detonator = new DetonatorReceiver( this );
}
else
{
StartFuse();
}
}
//deserialize constructor
public Bomb( Serial serial ) : base( serial )
{
}
//start the timer for the explosion
public void StartFuse()
{
_FuseTimer = new FuseTimer( this );
_FuseTimer.Start();
}
public void Explode()
{
Explode( BlastDirection.None );
}
public void Explode( BlastDirection inhibitdirection )
{
if( _FuseTimer != null )
{
_FuseTimer.Stop();
_FuseTimer = null;
}
if( BombBag != null )
{
BombBag.Bombs.Remove( this );
}
//sound effect of explosion
Effects.PlaySound( Location, Map, Utility.RandomList( 0x11B, 0x305, 0x306, 0x307, 0x11C, 0x308, 0x11D, 0x309, 0x4CF, 0x11E, 0x207 ) );
//bomb explosion graphics effect: 0x36CB
Effects.SendLocationEffect( new Point3D( X + 1, Y + 1, Z ), Map, 0x36CB, 10 );
//set off fire blowout
foreach( int blastdirection in Enum.GetValues( typeof( BlastDirection ) ) )
{
BlastDirection curdirection = (BlastDirection)blastdirection;
if( curdirection != BlastDirection.None && curdirection != inhibitdirection )
{
BombBlast blast = new BombBlast( Location, Map, curdirection, BombBag, Planter, _Strength - 1, _BaddaBoom != null );
}
}
//check for damagable at spot
if( BombBag != null && !BombBag.Deleted )
{
BombBag.ControlItem.CheckForMobileVictims( Location, Map, BombBag );
}
Delete();
}
public override void OnLocationChange( Point3D old )
{
if ( _Candle != null )
{
_Candle.Location = new Point3D( X, Y, Z + 3 );
}
if ( _Detonator != null )
{
_Detonator.Location = new Point3D( X, Y, Z + 2 );
}
if( _BaddaBoom != null )
{
_BaddaBoom.Location = new Point3D( X, Y, Z + 2 );
}
}
public override void OnMapChange()
{
if ( _Candle != null )
{
_Candle.Map = Map;
}
if ( _Detonator != null )
{
_Detonator.Map = Map;
}
if( _BaddaBoom != null )
{
_BaddaBoom.Map = Map;
}
}
public override void Delete()
{
//stop the fuse first, before beginning the delete process!
if( _FuseTimer != null )
{
_FuseTimer.Stop();
_FuseTimer = null;
}
base.Delete();
}
public override void OnAfterDelete()
{
if( _Candle != null && !_Candle.Deleted )
{
_Candle.Delete();
}
if( _Detonator != null && !_Detonator.Deleted )
{
_Detonator.Delete();
}
if( _BaddaBoom != null && !_BaddaBoom.Deleted )
{
_BaddaBoom.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)BombBag );
writer.Write( _Strength );
writer.Write( (Item)_Candle );
writer.Write( (Item)_Detonator );
writer.Write( (Item)_BaddaBoom );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
BombBag = (BombBag)reader.ReadItem();
_Strength = reader.ReadInt();
_Candle = (BombCandle)reader.ReadItem();
_Detonator = (DetonatorReceiver)reader.ReadItem();
_BaddaBoom = (BaddaBoom)reader.ReadItem();
if( _Detonator == null )
{
StartFuse();
}
}
protected class FuseTimer : Timer
{
private Bomb _Bomb;
public FuseTimer( Bomb bomb ) : base( TimeSpan.FromSeconds( BombermanSettings.EXPLODE_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
Priority = TimerPriority.TwoFiftyMS;
_Bomb = bomb;
}
protected override void OnTick()
{
if( !_Bomb.Deleted && _Bomb.Map != null )
{
_Bomb.Explode();
}
}
}
}
public class BombCandle : GamePiece
{
Bomb _Bomb;
public BombCandle( Bomb bomb ) : base( 0x1430, bomb.Name )
{
Hue = 1;
_Bomb = bomb;
}
public BombCandle( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
public class DetonatorReceiver : GamePiece
{
Bomb _Bomb;
public DetonatorReceiver( Bomb bomb ) : base( 0xF13, bomb.Name )
{
_Bomb = bomb;
}
public DetonatorReceiver( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
//this bomb upgrade makes the bomb blasts tear thru breakable obstacles
public class BaddaBoom : GamePiece
{
Bomb _Bomb;
public BaddaBoom( Bomb bomb ) : base( 0x1858, "If you can read this, you are probably going to die..." )
{
Hue = 1161;
_Bomb = bomb;
}
public BaddaBoom( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
}

View File

@@ -0,0 +1,267 @@
//To enable RunUO 2.0 RC1 compatibility, uncomment the following line
//#define RunUO2RC1
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Solaris.BoardGames
{
//a bomb - has a reference to a bomb candle that sits above it
public class BombBag : Item
{
protected bool _Active;
protected Mobile _Owner;
public Mobile Owner
{
get{ return _Owner; }
set
{
_Owner = value;
//disable any speed boost from polymorph, so it's fair for all players
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Disabled );
#else
Owner.Send( SpeedControl.Disable );
#endif
}
}
public int MaxBombs;
public int BombStrength;
protected bool _SpeedUpgraded;
public BombDetonator Detonator;
//this indicates if the bombs have unstoppable blasts
public bool BaddaBoom;
protected List<Bomb> _Bombs;
public bool Active
{
get{ return _Active; }
set
{
_Active = value;
if( Detonator != null )
{
Detonator.Active = value;
}
}
}
public List<Bomb> Bombs
{
get
{
if( _Bombs == null )
{
_Bombs = new List<Bomb>();
}
return _Bombs;
}
}
public BombermanControlItem ControlItem;
//master constructor
public BombBag( BombermanControlItem controlitem, int maxbombs, int bombstrength ) : base( 0xE76 )
{
ControlItem = controlitem;
Hue = 1161;
Name = "Bomb Bag";
//locked down in backpack
Movable = false;
MaxBombs = maxbombs;
BombStrength = bombstrength;
Active = true;
}
//deserialize constructor
public BombBag( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if( Owner == null )
{
from.SendMessage( "You are now the owner of this bomb bag!" );
Owner = from;
}
//make sure the person using the bomb bag is the owner, and that it's in their backpack
if( from != Owner || !IsChildOf( from.Backpack ) || !Active )
{
from.SendMessage( "You cannot use that" );
return;
}
if( from.Followers > 0 )
{
from.SendMessage( "You can't use this with pets!" );
return;
}
//check if there's a bomb at feet already
if( BombAtFeet( from ) )
{
from.SendMessage( "There is a bomb at your feet already!" );
return;
}
if( Bombs.Count < MaxBombs )
{
Bomb newbomb = new Bomb( this );
Owner.PlaySound( 0x42 );
newbomb.MoveToWorld( new Point3D( Owner.X, Owner.Y, Owner.Z ), Owner.Map );
Bombs.Add( newbomb );
from.SendMessage( "Planting bomb!" );
}
else
{
from.SendMessage( "You have too many bombs on the field." );
}
}
//boosts the player walking speed
public void SpeedBoost()
{
_SpeedUpgraded = true;
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Enabled );
#else
Owner.Send( SpeedControl.MountSpeed );
#endif
}
public void DetonateFirstBomb()
{
if( Bombs.Count > 0 )
{
Bombs[0].Explode();
}
}
//TODO: find a better place for this, like in the BombermanControlItem?
public static bool BombAtFeet( Mobile player )
{
IPooledEnumerable ie = player.Map.GetItemsInRange( player.Location, 0 );
bool founditem = false;
foreach( Item item in ie )
{
if( item is Bomb )
{
founditem = true;
break;
}
}
ie.Free();
return founditem;
}
public override void OnAfterDelete()
{
foreach( Bomb bomb in Bombs )
{
if( bomb != null )
{
bomb.Delete();
}
}
if( Detonator != null && !Detonator.Deleted )
{
Detonator.Delete();
}
if( _SpeedUpgraded )
{
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Disabled );
#else
Owner.Send( SpeedControl.Disable );
#endif
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( Owner );
writer.Write( MaxBombs );
writer.Write( BombStrength );
writer.Write( _SpeedUpgraded );
writer.Write( (Item)Detonator );
writer.Write( (Item)ControlItem );
writer.Write( Bombs.Count );
foreach( Bomb bomb in Bombs )
{
writer.Write( (Item)bomb );
}
writer.Write( Active );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Owner = reader.ReadMobile();
MaxBombs = reader.ReadInt();
BombStrength = reader.ReadInt();
_SpeedUpgraded = reader.ReadBool();
Detonator = (BombDetonator)reader.ReadItem();
ControlItem = (BombermanControlItem)reader.ReadItem();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
Bombs.Add( (Bomb)reader.ReadItem() );
}
Active = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Solaris.BoardGames
{
//a detonator allows the player to select when their bombs explode
public class BombDetonator : Item
{
public bool Active;
public Mobile Owner;
protected BombBag _BombBag;
//master constructor
public BombDetonator( BombBag bag ) : base( 0xFC1 )
{
_BombBag = bag;
Hue = 1161;
Name = "Detonator";
//locked down in backpack
Movable = false;
Active = true;
}
//deserialize constructor
public BombDetonator( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if( Owner == null )
{
Owner = from;
}
//make sure the person using the detonator is the owner, and that it's in their backpack
if( from != Owner || !IsChildOf( from.Backpack ) || !Active )
{
from.SendMessage( "You cannot use that" );
return;
}
if( _BombBag != null )
{
_BombBag.DetonateFirstBomb();
}
}
public override void OnAfterDelete()
{
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_BombBag );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_BombBag = (BombBag)reader.ReadItem();
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombermanFloorTile : BombermanObstacle
{
public BombermanFloorTile( BombermanStyle style ) : base( BombermanSettings.GetFloorTileID( style ), "Floor" )
{
if( style == BombermanStyle.Default )
{
Hue = 0x237;
}
}
//deserialize constructor
public BombermanFloorTile( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombermanObstacle : GamePiece
{
public virtual bool Destructable{ get{ return false; } }
//randomize itemid constructors
public BombermanObstacle( int itemidmin, int itemidmax, string name ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name )
{
}
public BombermanObstacle( int itemidmin, int itemidmax, string name, bool blocklos ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name, blocklos )
{
}
//default no LOS blocker constructor
public BombermanObstacle( int itemid, string name ) : this( itemid, name, false )
{
}
//master constructor
public BombermanObstacle( int itemid, string name, bool blocklos ) : base( itemid, name, blocklos )
{
}
//deserialize constructor
public BombermanObstacle( Serial serial ) : base( serial )
{
}
public virtual void Destroy()
{
if( BoardGameControlItem != null )
{
BoardGameControlItem.BackgroundItems.Remove( this );
BoardGameControlItem = null;
}
Delete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class DestructableWall : BombermanObstacle
{
public override bool Destructable{ get{ return true; } }
public DestructableWall( BombermanStyle style ) : base( BombermanSettings.GetDestructableWallID( style ), "Bombable Wall" )
{
if( style == BombermanStyle.Default )
{
Hue = 0x3BB;
}
}
//deserialize constructor
public DestructableWall( Serial serial ) : base( serial )
{
}
public override void Destroy()
{
//spawn powerup
if( Utility.RandomDouble() < BombermanSettings.UPGRADE_SPAWN_CHANCE )
{
if( BoardGameControlItem.State == BoardGameState.Active )
{
BombermanUpgrade upgrade = BombermanUpgrade.GetRandomUpgrade();
upgrade.RegisterToBoardGameControlItem( BoardGameControlItem, new Point3D( Offset.X, Offset.Y, Offset.Z + 3 ) );
}
}
base.Destroy();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class IndestructableWall : BombermanObstacle
{
public IndestructableWall( BombermanStyle style, bool blocklos ) : base( BombermanSettings.GetIndestructableWallID( style ), "Wall", blocklos )
{
if( style == BombermanStyle.Default )
{
Hue = 0x3E4;
}
}
//deserialize constructor
public IndestructableWall( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//this causes unstoppable explosions
public class BaddaBoomUpgrade : BombermanUpgrade
{
public BaddaBoomUpgrade() : base( 0x1858, "Big BaddaBoom Upgrade" )
{
Hue = 1161;
}
//deserialize constructor
public BaddaBoomUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.BaddaBoom = true;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BlastStrengthUpgrade : BombermanUpgrade
{
public BlastStrengthUpgrade() : base( 0x283B, "Blast Strength Upgrade" )
{
Hue = 1161;
}
//deserialize constructor
public BlastStrengthUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.BombStrength += 1;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombCountUpgrade : BombermanUpgrade
{
public BombCountUpgrade() : base( 0x284F, "Bomb Count Upgrade" )
{
Hue = 1;
}
//deserialize constructor
public BombCountUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.MaxBombs += 1;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//bomberman upgrades are upgrades that are randomly found while demolishing the game field
public abstract class BombermanUpgrade : BombermanObstacle
{
public override bool Destructable{ get{ return true; } }
public override bool HandlesOnMovement{ get{ return true; } } // Tell the core that we implement OnMovement
protected DecayTimer _DecayTimer;
public BombermanUpgrade( int itemid, string name ) : base( itemid, name )
{
StartDecayTimer();
}
//deserialize constructor
public BombermanUpgrade( Serial serial ) : base( serial )
{
}
protected void StartDecayTimer()
{
_DecayTimer = new DecayTimer( this );
_DecayTimer.Start();
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if( BoardGameControlItem == null )
{
return;
}
//ignore anyone who is not a player of this game
if( BoardGameControlItem.Players.IndexOf( m ) == -1 )
{
return;
}
if( m.Location == oldLocation )
return;
if( m.InRange( this, 0 ) )
{
Upgrade( m );
Destroy();
}
}
protected virtual void Upgrade( Mobile m )
{
m.SendMessage( "You picked up an upgrade!" );
m.PlaySound( m.Female ? 0x337 : 0x44A );
}
public override void OnAfterDelete()
{
if( _DecayTimer != null )
{
_DecayTimer.Stop();
_DecayTimer = null;
}
base.OnAfterDelete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
StartDecayTimer();
}
protected class DecayTimer : Timer
{
private BombermanUpgrade _BombermanUpgrade;
public DecayTimer( BombermanUpgrade upgrade ) : base( TimeSpan.FromSeconds( BombermanSettings.UPGRADE_DECAY_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
_BombermanUpgrade = upgrade;
}
protected override void OnTick()
{
_BombermanUpgrade.Destroy();
}
}
public static BombermanUpgrade GetRandomUpgrade()
{
double prizeroll = Utility.RandomDouble();
if( prizeroll < .1 )
{
return new SpeedUpgrade();
}
else if( prizeroll < .15 )
{
return new DetonatorUpgrade();
}
else if( prizeroll < .2 )
{
return new BaddaBoomUpgrade();
}
else if( prizeroll < .6 )
{
return new BlastStrengthUpgrade();
}
else
{
return new BombCountUpgrade();
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class DetonatorUpgrade : BombermanUpgrade
{
public DetonatorUpgrade() : base( 0xFC1, "Detonator" )
{
Hue = 1161;
}
//deserialize constructor
public DetonatorUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null && bag.Detonator == null )
{
BombDetonator detonator = new BombDetonator( bag );
bag.Detonator = detonator;
m.Backpack.DropItem( detonator );
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class SpeedUpgrade : BombermanUpgrade
{
public SpeedUpgrade() : base( 0x2308, "Speed Upgrade" )
{
Hue = 1152;
}
//deserialize constructor
public SpeedUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.SpeedBoost();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,190 @@
using System;
using Server;
namespace Solaris.BoardGames
{
public enum BlastDirection
{
None = 0x0,
West = 0x1,
North = 0x2,
East = 0x4,
South = 0x8
}
public class BombBlast
{
protected Point3D _Location;
protected Map _Map;
protected int _DeltaX;
protected int _DeltaY;
protected BlastDirection _Direction;
protected Mobile _Planter;
protected bool _BaddaBoom;
protected BombBag _BombBag;
protected int _Strength;
protected BlastTimer _BlastTimer;
public BombBlast( Point3D location, Map map, BlastDirection direction, BombBag bombbag, Mobile planter, int strength, bool baddaboom )
{
_Direction = direction;
_DeltaX = ( _Direction == BlastDirection.West ? -1 : 0 ) + ( _Direction == BlastDirection.East ? 1 : 0 );
_DeltaY = ( _Direction == BlastDirection.North ? -1 : 0 ) + ( _Direction == BlastDirection.South ? 1 : 0 );
_Location = new Point3D( location.X + _DeltaX, location.Y + _DeltaY, location.Z );
_Map = map;
_BombBag = bombbag;
_Planter = planter;
_Strength = strength;
_BaddaBoom = baddaboom;
_BlastTimer = new BlastTimer( this );
_BlastTimer.Start();
//check for any victims of the blast
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.ControlItem.CheckForMobileVictims( _Location, _Map, _BombBag );
}
}
public void Explode()
{
if( _BlastTimer != null )
{
_BlastTimer.Stop();
_BlastTimer = null;
}
if( _Map == null )
{
return;
}
IPooledEnumerable ie = _Map.GetItemsInRange( _Location, 0 );
bool hitwall = false;
foreach( Item item in ie )
{
if( item is BombermanObstacle && !( item is BombermanFloorTile ) )
{
BombermanObstacle obstacle = (BombermanObstacle)item;
if( obstacle.Destructable )
{
obstacle.Destroy();
}
else
{
hitwall = true;
_Strength = 0;
}
//stop the fires here if you don't have a baddaboom bomb
if( !_BaddaBoom )
{
_Strength = 0;
}
break;
}
if( item is Bomb )
{
Bomb bomb = (Bomb)item;
//reassign who planted it so that the bomb who originally exploded will get credit for any kills
bomb.Planter = _BombBag.Owner;
bomb.Explode( ReverseDirection( _Direction ) );
//stop the fires here
_Strength = 0;
break;
}
}
ie.Free();
if( !hitwall )
{
RenderBlast();
}
//check for any victims of the blast
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.ControlItem.CheckForMobileVictims( _Location, _Map, _BombBag );
}
if( !hitwall )
{
}
if( _Strength > 0 )
{
BombBlast newblast = new BombBlast( _Location, _Map, _Direction, _BombBag, _Planter, _Strength - 1, _BaddaBoom );
}
}
protected void RenderBlast()
{
Effects.SendLocationEffect( new Point3D( _Location.X + 1, _Location.Y + 1, _Location.Z ), _Map, Utility.RandomList( 0x36CB, 0x36BD, 0x36B0 ), 10 );
}
//this determines the opposite direction to the specified blast direction
protected BlastDirection ReverseDirection( BlastDirection direction )
{
switch( direction )
{
case BlastDirection.West:
{
return( BlastDirection.East );
}
case BlastDirection.East:
{
return( BlastDirection.West );
}
case BlastDirection.North:
{
return( BlastDirection.South );
}
case BlastDirection.South:
{
return( BlastDirection.North );
}
}
return BlastDirection.None;
}
protected class BlastTimer : Timer
{
private BombBlast _BombBlast;
public BlastTimer( BombBlast bombblast ) : base( TimeSpan.FromMilliseconds( BombermanSettings.BLAST_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
_BombBlast = bombblast;
}
protected override void OnTick()
{
_BombBlast.Explode();
}
}
}
}

View File

@@ -0,0 +1,113 @@
Board Games and Bomberman - developed by Fenn of BES Oasis shard
=========================
If you choose to use this or develop on this, please leave this file intact.
Version: Last Modified Wednesday, May 6, 2009
========
Changelog:
==========
-Version 2009-05-05
-Improved user interface for registering players to the bomberman game. The first person to register can control the number of players while others register. Also, the control stone is more verbose
-Increased region priority around boargame. It now properly blocks spells and skills if the boardgame is contained within another region
-Added more verbose reports from the stone during bomberman game.
-Version 2009-05-01
-Fixed a long-annoying bug that causes the Bomberman game to break after a game ends. (thanks mikeymaze and fcondon!)
-Version 2009-01-26
-When the bomb is deleted, the fuse is stopped first. This may prevent bombs that blow up while being deleted. Also added some extra checks just in case. (thanks nevar2006!)
-Restructured the gameover condition. Now a tie game is properly detected, and Bomberman does not get broken when two players die at the same time. (thanks test444!)
-Plugged a crash bug when a broken boardgame is deleted.
-Version 2009-01-18
-Fixed a crash issue that was only apparent on RC1 servers. The game should now be playable with RC1 servers. (thanks purplemouse91!)
-Added a preventative measure to keep players from fooling around with pets while playing Bomberman. Players, consider this your one and only warning! (Thanks Robbie!)
-Added a staff-only context menu command that clears the game scores of the selected boardgame type (thanks oiii88!)
-Version 2009-01-15
-Added compatibility code for RunUO 2.0 RC1 servers. If you are running on a RC1-based server, open the file BoardGames\Bomberman\Items\BombBag.cs
and uncomment the second line.
-Added LOSBlockers to Bomberman's indestructable walls. This will remove any chance of PvP interference from external players. (thanks Hammerhand!)
-Added a delay to the end of the game, and win/lose gumps sent to the winner/losers of the game. (thanks test444!)
-Added staff-controllable property AllowPlayerConfiguration to BoardGameControlItem. When this is set false, the players can no longer adjust
the game's size and artwork style. Default is true. (thanks test444!)
-Added a scorekeeping system that tracks players wins, losses, and "score". Points are awarded or deducted based on whether they win, lose, blow
up another player, or blow themselves up. The score points awarded can be adjusted in the BombermanSettings.cs file. Players can view this
score listing by using the context menu on the control item. (thanks mikeymaze!)
-Improved staff control of board position with respect to controller position. When you [props the control stone, the new properties BoardLocation
and BoardMap will let the staff member choose where to position the board explicitly. Note that the board is still tied to the stone. If you
move the stone east by 5 tiles, the board, wherever it is, will also move east by 5 tiles. However, the map of the board is no longer tied to the
map of the stone, and can be set independent to the stone position. (thanks test444!)
-Version 2009-01-12
-initial release
Compatibility:
--------------
This was developed using a freshly downloaded RunUO 2.0 SVN server
-RunUO RC1 (check the Notes section for details)
-RunUO RC2
-RunUO 2.0 SVN version 300 (downloaded October 7, 2008)
Notes:
------
If you wish to use this script on a RC1-based server, you will need to edit one file. Open the file BoardGames\Bomberman\Items\BombBag.cs
and uncomment the second line. This sets it so the speedboost upgrade in Bomberman will use the correct syntax for a RC1 server.
Overview:
---------
The BoardGame system provides a base for the Bomberman system. The basic system is designed to automatically generate a collection of items to be
used in some kind of game. Players interact with a control item, and the game gets underway when all conditions are met. The game runs automatically,
moving players into the board game when it starts, and out of the game when its over. It is intended to run without any staff support.
The Bomberman game is an implementation of this base system, where players navigate an arena, cutting their way through destroyable walls, trying
to blow each other up with bombs. A bomb bag is placed in the players' backpacks. Players use this bag to place bombs at their feet.
A bomb will detonate after some time, and has a limited blast size. The number of bombs any player can place at any time is limited.
Players must blast at the breakable walls to navigate the arena. While blasting, upgrades can be found which improve the blast size or number of
bombs a player can place at once. There is also a detonator upgrade that lets a player choose when they want their bombs to blow up, and a
"big badda boom" upgrade that causes bombs to tear through destructable walls to their maximum blast size. A bomb can trigger another bomb to go off,
creating interesting chain reactions. The game ends when there is only one player left standing.
Staff can set up the game by adding the constructable BombermanControlItem device. The field is automatically generated to the southeast of the control
device. Some consideration will be needed to properly place the gamefield. Luckily, the control item and game field can be moved together like an
addon. There are various properties accessible to staff, including game field size, style, and default bomb upgrade settings.
When a player uses the control item, they are given some information and instructions related to the game. The first person to use the
control item can select the number of players, as well as some game properties. For Bomberman, they can choose the playfield size, and
the artwork style. When the required number of players have signed up for the game, the players will be automatically transported onto
the game field.
Additional controls are accessible to the staff, via the properties gump. For bomberman, staff can adjust the default upgrade
configuration for each player when they start the game. In the case of an emergency, staff can force a game over. Additionally, staff
can adjust the game artwork style and board size manually. Finally, staff can configure the game to charge gold when players play the game.
For the developer, there are various properties that can be adjusted. in the file BoardGames\Bomberman\BombermanSettings.cs, there are
various constants and variables that can be modified to suit your shard's needs.
Installation:
-------------
Basic installation: Drop this entire folder somewhere in your Scripts Directory. Be mindful of class name conflicts.
Deinstallation:
---------------
Basic deinstallation: Remove this entire folder from your scripts directory.
Contact:
--------
Questions, comments? Contact me at the RunUO Forums under username Fenn.

View File

@@ -0,0 +1,20 @@
//indicate # of players
//make some way of changing # of players when people are waiting on the setup gump
//when player 1 leaves, give the next in line the setup gump
make list of who is signed up, who is waiting
list players left in game
//announce # of players required when player join/leave
kick a player if they log out in game
spectator mode for players who want to watch
//block all hiding and stealth
create game queue when other people are waiting for game to finish