Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
271
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Arcade.cs
Normal file
271
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Arcade.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
[CoreModule("Games Arcade", "1.0.0.0")]
|
||||
public static class Arcade
|
||||
{
|
||||
public const AccessLevel Access = AccessLevel.Administrator;
|
||||
|
||||
public static ArcadeOptions CMOptions { get; private set; }
|
||||
|
||||
public static BinaryDataStore<Type, IGame> Games { get; private set; }
|
||||
|
||||
public static BinaryDataStore<Mobile, ArcadeProfile> Profiles { get; private set; }
|
||||
|
||||
public static Type[] GameTypes { get; private set; }
|
||||
|
||||
static Arcade()
|
||||
{
|
||||
CMOptions = new ArcadeOptions();
|
||||
|
||||
Games = new BinaryDataStore<Type, IGame>(VitaNexCore.SavesDirectory + "/Arcade", "Games")
|
||||
{
|
||||
Async = true,
|
||||
OnSerialize = SerializeGames,
|
||||
OnDeserialize = DeserializeGames
|
||||
};
|
||||
|
||||
Profiles = new BinaryDataStore<Mobile, ArcadeProfile>(VitaNexCore.SavesDirectory + "/Arcade", "Profiles")
|
||||
{
|
||||
Async = true,
|
||||
OnSerialize = SerializeProfiles,
|
||||
OnDeserialize = DeserializeProfiles
|
||||
};
|
||||
|
||||
GameTypes = typeof(IGame).GetConstructableChildren();
|
||||
|
||||
foreach (var t in GameTypes)
|
||||
{
|
||||
var g = CreateGame(t);
|
||||
|
||||
if (g != null)
|
||||
{
|
||||
Games[t] = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CMConfig()
|
||||
{
|
||||
CommandUtility.Register("Arcade", AccessLevel.Player, HandleCommand);
|
||||
CommandUtility.RegisterAlias("Arcade", "Games");
|
||||
}
|
||||
|
||||
private static void CMInvoke()
|
||||
{ }
|
||||
|
||||
private static void CMSave()
|
||||
{
|
||||
Games.Export();
|
||||
}
|
||||
|
||||
private static void CMLoad()
|
||||
{
|
||||
Games.Import();
|
||||
}
|
||||
|
||||
private static void HandleCommand(CommandEventArgs e)
|
||||
{
|
||||
if (CMOptions.ModuleEnabled)
|
||||
{
|
||||
new ArcadeUI(e.Mobile).Send();
|
||||
}
|
||||
}
|
||||
|
||||
private static IGame CreateGame(Type t)
|
||||
{
|
||||
try
|
||||
{
|
||||
return t.CreateInstanceSafe<IGame>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArcadeProfile EnsureProfile(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var p = Profiles.GetValue(m);
|
||||
|
||||
if (p == null || p.Owner != m)
|
||||
{
|
||||
if (!m.Player || m.Deleted)
|
||||
{
|
||||
Profiles.Remove(m);
|
||||
|
||||
if (p != null)
|
||||
{
|
||||
p.Clear();
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Profiles[m] = p = new ArcadeProfile(m);
|
||||
}
|
||||
}
|
||||
else if (!m.Player || m.Deleted)
|
||||
{
|
||||
Profiles.Remove(m);
|
||||
|
||||
p.Clear();
|
||||
p = null;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public static bool OpenGame(Type t, Mobile m)
|
||||
{
|
||||
return VitaNexCore.TryCatchGet(
|
||||
() =>
|
||||
{
|
||||
var g = Games.GetValue(t);
|
||||
|
||||
return g != null && g.Open(m);
|
||||
},
|
||||
CMOptions.ToConsole);
|
||||
}
|
||||
|
||||
public static bool OpenGame<T>(Mobile m)
|
||||
where T : IGame
|
||||
{
|
||||
return OpenGame(typeof(T), m);
|
||||
}
|
||||
|
||||
public static void CloseGame(Mobile m, Type t)
|
||||
{
|
||||
VitaNexCore.TryCatch(
|
||||
() =>
|
||||
{
|
||||
var g = Games.GetValue(t);
|
||||
|
||||
if (g != null)
|
||||
{
|
||||
g.Close(m);
|
||||
}
|
||||
},
|
||||
CMOptions.ToConsole);
|
||||
}
|
||||
|
||||
private static bool SerializeGames(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.WriteBlockDictionary(
|
||||
Games,
|
||||
(w, t, g) =>
|
||||
{
|
||||
w.WriteType(t);
|
||||
g.Serialize(w);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeGames(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
reader.ReadBlockDictionary(
|
||||
r =>
|
||||
{
|
||||
var t = r.ReadType();
|
||||
var g = Games.GetValue(t) ?? CreateGame(t);
|
||||
|
||||
g.Deserialize(r);
|
||||
|
||||
return new KeyValuePair<Type, IGame>(t, g);
|
||||
},
|
||||
Games);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool SerializeProfiles(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.WriteBlockDictionary(
|
||||
Profiles,
|
||||
(w, m, p) =>
|
||||
{
|
||||
w.Write(m);
|
||||
p.Serialize(w);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeProfiles(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
reader.ReadBlockDictionary(
|
||||
r =>
|
||||
{
|
||||
var m = r.ReadMobile();
|
||||
var p = new ArcadeProfile(r);
|
||||
|
||||
return new KeyValuePair<Mobile, ArcadeProfile>(m, p);
|
||||
},
|
||||
Profiles);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public sealed class TrapSweeper : Game<TrapSweeperEngine>
|
||||
{
|
||||
private readonly IconDefinition _Icon = IconDefinition.FromGump(24013, 1258);
|
||||
|
||||
public override IconDefinition Icon => _Icon;
|
||||
|
||||
public override string Name => "Trap Sweeper";
|
||||
|
||||
public override string Desc => "Sweep the castle for traps!";
|
||||
|
||||
public override string Help => _Help;
|
||||
|
||||
private static readonly string _Help = String.Concat(
|
||||
"<BIG>Rules & Basics</BIG>",
|
||||
"<BR>",
|
||||
"<BR><BIG>Objective</BIG>",
|
||||
"<BR>Find the empty tiles while avoiding the traps.",
|
||||
"<BR>The faster you clear the floor, the better your score.",
|
||||
"<BR>",
|
||||
"<BR><BIG>Floors</BIG>",
|
||||
"<BR>There are three floors to choose from, each more difficult than the last.",
|
||||
"<BR>",
|
||||
"<BR><B>* Rookie:</B> Easy mode, small floor.",
|
||||
"<BR><B>* Guard:</B> Normal mode, medium floor.",
|
||||
"<BR><B>* Knight:</B> Expert mode, large floor.",
|
||||
"<BR><B>* Random:</B> Generates a random floor.",
|
||||
"<BR>",
|
||||
"<BR><BIG>Rules</BIG>",
|
||||
"<BR>Reveal a trap, you die.",
|
||||
"<BR>Reveal an empty tile, you continue sweeping.",
|
||||
"<BR>Reveal a bonus tile, you continue and collect a reward when you win.",
|
||||
"<BR>Reveal a number tile, you continue and it tells you how many traps lay hidden in the eight surrounding tiles.",
|
||||
"<BR><I>These numbers will help you decide which tiles are safe to reveal.</I>",
|
||||
"<BR>",
|
||||
"<BR><BIG>Tips</BIG>",
|
||||
"<BR>Mark the traps!",
|
||||
"<BR>If you think a tile hides a trap, select Mark and click it, this will highlight the tile.",
|
||||
"<BR>You can unhighlight a tile by selecting Mark and clicking it again.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,789 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public class TrapSweeperEngine : GameEngine<TrapSweeper, TrapSweeperUI>
|
||||
{
|
||||
public const int MinWidth = 10;
|
||||
public const int MaxWidth = 22;
|
||||
|
||||
public const int MinHeight = 10;
|
||||
public const int MaxHeight = 15;
|
||||
|
||||
public const int MinDensity = 10;
|
||||
public const int MaxDensity = 30;
|
||||
|
||||
public const int MinBonusDensity = 1;
|
||||
public const int MaxBonusDensity = 3;
|
||||
|
||||
public const int MinPoints = 100;
|
||||
public const int MaxPoints = 500;
|
||||
|
||||
private Grid<TrapSweeperTile> _Grid;
|
||||
|
||||
public int Width => _Grid != null ? _Grid.Width : 0;
|
||||
public int Height => _Grid != null ? _Grid.Height : 0;
|
||||
public int Capacity => _Grid != null ? _Grid.Capacity : 0;
|
||||
public int Count => _Grid != null ? _Grid.Count : 0;
|
||||
|
||||
public TrapSweeperState State { get; private set; }
|
||||
public TrapSweeperMode Mode { get; private set; }
|
||||
|
||||
public DateTime Started { get; private set; }
|
||||
public DateTime Ended { get; private set; }
|
||||
|
||||
public bool Mark { get; private set; }
|
||||
|
||||
public int Blanks { get; private set; }
|
||||
public int Traps { get; private set; }
|
||||
public int Bonuses { get; private set; }
|
||||
|
||||
public int Visible { get; private set; }
|
||||
public int Marked { get; private set; }
|
||||
|
||||
public int Rewards { get; private set; }
|
||||
|
||||
public TrapSweeperEngine(TrapSweeper game, Mobile user)
|
||||
: base(game, user)
|
||||
{
|
||||
_Grid = new Grid<TrapSweeperTile>();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
Visible = 0;
|
||||
Marked = 0;
|
||||
|
||||
Rewards = 0;
|
||||
|
||||
Mark = false;
|
||||
}
|
||||
|
||||
public IEnumerable<TrapSweeperTile> AllTiles()
|
||||
{
|
||||
return _Grid ?? _Grid.Ensure();
|
||||
}
|
||||
|
||||
public IEnumerable<TrapSweeperTile> FindTiles(int x, int y, int w, int h)
|
||||
{
|
||||
return _Grid == null ? _Grid.Ensure() : _Grid.FindCells(x, y, w, h);
|
||||
}
|
||||
|
||||
public IEnumerable<T> AllTiles<T>()
|
||||
where T : TrapSweeperTile
|
||||
{
|
||||
return (_Grid ?? _Grid.Ensure()).OfType<T>();
|
||||
}
|
||||
|
||||
public IEnumerable<T> FindTiles<T>(int x, int y, int w, int h)
|
||||
where T : TrapSweeperTile
|
||||
{
|
||||
return (_Grid == null ? _Grid.Ensure() : _Grid.FindCells(x, y, w, h)).OfType<T>();
|
||||
}
|
||||
|
||||
public void Generate(int w, int h, int d, int b, int p)
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
w = Math.Max(MinWidth, Math.Min(MaxWidth, w));
|
||||
h = Math.Max(MinHeight, Math.Min(MaxHeight, h));
|
||||
d = Math.Max(MinDensity, Math.Min(MaxDensity, d));
|
||||
b = Math.Max(MinBonusDensity, Math.Min(MaxBonusDensity, b));
|
||||
p = Math.Max(MinPoints, Math.Min(MaxPoints, p));
|
||||
|
||||
if (_Grid == null)
|
||||
{
|
||||
_Grid = new Grid<TrapSweeperTile>(w, h);
|
||||
}
|
||||
else if (_Grid.Width != w || _Grid.Height != h)
|
||||
{
|
||||
_Grid.Resize(w, h);
|
||||
}
|
||||
|
||||
_Grid.SetAllContent((x, y) => null);
|
||||
|
||||
var q = new List<Point2D>(_Grid.Capacity);
|
||||
|
||||
_Grid.ForEach((x, y, t) => q.Add(new Point2D(x, y)));
|
||||
|
||||
q.Shuffle();
|
||||
|
||||
var traps = (int)Math.Floor(q.Count * (d / 100.0));
|
||||
var bonus = (int)Math.Floor((q.Count - traps) * (b / 100.0));
|
||||
|
||||
Parallel.ForEach(
|
||||
q,
|
||||
t =>
|
||||
{
|
||||
if (traps > 0)
|
||||
{
|
||||
_Grid[t.X, t.Y] = new TrapSweeperTileTrap(this, t.X, t.Y);
|
||||
Interlocked.Decrement(ref traps);
|
||||
}
|
||||
else if (bonus > 0)
|
||||
{
|
||||
_Grid[t.X, t.Y] = new TrapSweeperTileBonus(this, t.X, t.Y);
|
||||
Interlocked.Decrement(ref bonus);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Grid[t.X, t.Y] = new TrapSweeperTileBlank(this, t.X, t.Y);
|
||||
}
|
||||
});
|
||||
|
||||
q.Free(true);
|
||||
|
||||
Blanks = Traps = Bonuses = 0;
|
||||
|
||||
foreach (var t in AllTiles())
|
||||
{
|
||||
if (t is TrapSweeperTileBlank)
|
||||
{
|
||||
++Blanks;
|
||||
|
||||
t.Points = p;
|
||||
}
|
||||
else if (t is TrapSweeperTileTrap)
|
||||
{
|
||||
++Traps;
|
||||
|
||||
t.Points = 0;
|
||||
}
|
||||
else if (t is TrapSweeperTileBonus)
|
||||
{
|
||||
++Bonuses;
|
||||
|
||||
t.Points = p * 2;
|
||||
}
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void GenerateEasy()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Generate(MinWidth, MinHeight, MinDensity, MinBonusDensity, MinPoints);
|
||||
}
|
||||
|
||||
public void GenerateNormal()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
const int w = MinWidth + ((MaxWidth - MinWidth) / 2);
|
||||
const int h = MinHeight + ((MaxHeight - MinHeight) / 2);
|
||||
const int d = MinDensity + ((MaxDensity - MinDensity) / 2);
|
||||
const int b = MinBonusDensity + ((MaxBonusDensity - MinBonusDensity) / 2);
|
||||
const int p = MinPoints + ((MaxPoints - MinPoints) / 2);
|
||||
|
||||
Generate(w, h, d, b, p);
|
||||
}
|
||||
|
||||
public void GenerateHard()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Generate(MaxWidth, MaxHeight, MaxDensity, MaxBonusDensity, MaxPoints);
|
||||
}
|
||||
|
||||
public void GenerateRandom()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Generate(
|
||||
Utility.RandomMinMax(MinWidth, MaxWidth),
|
||||
Utility.RandomMinMax(MinHeight, MaxHeight),
|
||||
Utility.RandomMinMax(MinDensity, MaxDensity),
|
||||
Utility.RandomMinMax(MinBonusDensity, MaxBonusDensity),
|
||||
Utility.RandomMinMax(MinPoints, MaxPoints));
|
||||
}
|
||||
|
||||
public void DoCollect()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Give Rewards
|
||||
|
||||
DoMenu();
|
||||
}
|
||||
|
||||
public void DoMenu()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
UI.CanDispose = true;
|
||||
|
||||
if (State == TrapSweeperState.Play)
|
||||
{
|
||||
State = TrapSweeperState.Menu;
|
||||
DoEnd(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
State = TrapSweeperState.Menu;
|
||||
UI.Refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoMode(TrapSweeperMode opt)
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Mode = opt;
|
||||
|
||||
UI.Refresh(true);
|
||||
}
|
||||
|
||||
public void DoMark()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Mark = !Mark;
|
||||
|
||||
UI.Refresh(true);
|
||||
}
|
||||
|
||||
public void DoPlay()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
UI.CanDispose = false;
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case TrapSweeperMode.Easy:
|
||||
GenerateEasy();
|
||||
break;
|
||||
case TrapSweeperMode.Normal:
|
||||
GenerateNormal();
|
||||
break;
|
||||
case TrapSweeperMode.Hard:
|
||||
GenerateHard();
|
||||
break;
|
||||
case TrapSweeperMode.Random:
|
||||
GenerateRandom();
|
||||
break;
|
||||
}
|
||||
|
||||
DoStart();
|
||||
}
|
||||
|
||||
public void DoQuit()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
UI.CanDispose = true;
|
||||
|
||||
if (State == TrapSweeperState.Play)
|
||||
{
|
||||
State = TrapSweeperState.Menu;
|
||||
DoEnd(false);
|
||||
}
|
||||
else if (State != TrapSweeperState.Menu)
|
||||
{
|
||||
State = TrapSweeperState.Menu;
|
||||
UI.Refresh(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
State = TrapSweeperState.Menu;
|
||||
UI.Close(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoStart()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
UI.CanDispose = false;
|
||||
|
||||
State = TrapSweeperState.Play;
|
||||
Started = DateTime.UtcNow;
|
||||
|
||||
UI.Refresh(true);
|
||||
}
|
||||
|
||||
public void DoEnd(bool win)
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
UI.CanDispose = true;
|
||||
|
||||
State = win ? TrapSweeperState.Win : TrapSweeperState.Lose;
|
||||
Ended = DateTime.UtcNow;
|
||||
|
||||
if (win)
|
||||
{
|
||||
var factor = 1.0;
|
||||
|
||||
var time = Ended - Started;
|
||||
|
||||
if (time.TotalMinutes > 0)
|
||||
{
|
||||
double threshold, multiplier;
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case TrapSweeperMode.Easy:
|
||||
{
|
||||
threshold = 10.0;
|
||||
multiplier = 0.33;
|
||||
}
|
||||
break;
|
||||
case TrapSweeperMode.Normal:
|
||||
{
|
||||
threshold = 10.0;
|
||||
multiplier = 0.66;
|
||||
}
|
||||
break;
|
||||
case TrapSweeperMode.Hard:
|
||||
{
|
||||
threshold = 10.0;
|
||||
multiplier = 1.00;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
threshold = Utility.RandomMinMax(10.0, 30.0);
|
||||
multiplier = Utility.RandomMinMax(0.33, 1.00);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (time.TotalMinutes <= threshold)
|
||||
{
|
||||
factor += (1.0 - (time.TotalMinutes / threshold)) * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
OffsetPoints(Points * factor, true);
|
||||
|
||||
Log("Victories", 1, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
OffsetPoints(-Points, true);
|
||||
|
||||
Log("Defeats", 1, true);
|
||||
}
|
||||
|
||||
UI.Refresh(true);
|
||||
}
|
||||
|
||||
protected override void OnDispose()
|
||||
{
|
||||
base.OnDispose();
|
||||
|
||||
if (_Grid != null)
|
||||
{
|
||||
_Grid.ForEach(
|
||||
(x, y, t) =>
|
||||
{
|
||||
if (t != null)
|
||||
{
|
||||
t.Dispose();
|
||||
}
|
||||
});
|
||||
|
||||
_Grid.Free(true);
|
||||
_Grid = null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class TrapSweeperTile : IDisposable
|
||||
{
|
||||
public virtual int HiddenID => 9026;
|
||||
public virtual int MarkID => 9026;
|
||||
public virtual int ClickID => 9021;
|
||||
public virtual int DisplayID => 9021;
|
||||
|
||||
public virtual int Hue => 0;
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
public TrapSweeperEngine Engine { get; private set; }
|
||||
|
||||
public int X { get; private set; }
|
||||
public int Y { get; private set; }
|
||||
|
||||
public int Points { get; set; }
|
||||
|
||||
private bool _Marked;
|
||||
|
||||
public bool Marked
|
||||
{
|
||||
get => _Marked;
|
||||
set
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_Marked && value)
|
||||
{
|
||||
if (Engine.Marked < Engine.Traps)
|
||||
{
|
||||
_Marked = true;
|
||||
OnMarked();
|
||||
}
|
||||
}
|
||||
else if (_Marked && !value)
|
||||
{
|
||||
_Marked = false;
|
||||
OnUnmarked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _Visible;
|
||||
|
||||
public bool Visible
|
||||
{
|
||||
get => _Visible;
|
||||
set
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_Visible && value)
|
||||
{
|
||||
_Visible = true;
|
||||
OnReveal();
|
||||
}
|
||||
else if (_Visible && !value)
|
||||
{
|
||||
_Visible = false;
|
||||
OnHide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TrapSweeperTile(TrapSweeperEngine g, int x, int y)
|
||||
{
|
||||
Engine = g;
|
||||
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
~TrapSweeperTile()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public bool Validate()
|
||||
{
|
||||
return !IsDisposed && Engine != null && Engine.Validate();
|
||||
}
|
||||
|
||||
public void Click()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Engine.Mark)
|
||||
{
|
||||
ToggleMark();
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleVisibility();
|
||||
}
|
||||
|
||||
Engine.UI.Refresh(true);
|
||||
}
|
||||
|
||||
protected void ToggleMark()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Visible)
|
||||
{
|
||||
Marked = !Marked;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ToggleVisibility()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Marked = false;
|
||||
Visible = !Visible;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDisposed = true;
|
||||
|
||||
OnDispose();
|
||||
|
||||
if (Engine != null)
|
||||
{
|
||||
if (Engine._Grid != null)
|
||||
{
|
||||
Engine._Grid[X, Y] = null;
|
||||
}
|
||||
|
||||
Engine = null;
|
||||
}
|
||||
|
||||
X = Y = -1;
|
||||
}
|
||||
|
||||
protected virtual void OnHide()
|
||||
{
|
||||
--Engine.Visible;
|
||||
|
||||
Engine.OffsetPoints(-Points, true);
|
||||
}
|
||||
|
||||
protected virtual void OnReveal()
|
||||
{
|
||||
++Engine.Visible;
|
||||
|
||||
Engine.OffsetPoints(Points, true);
|
||||
}
|
||||
|
||||
protected virtual void OnMarked()
|
||||
{
|
||||
++Engine.Marked;
|
||||
}
|
||||
|
||||
protected virtual void OnUnmarked()
|
||||
{
|
||||
--Engine.Marked;
|
||||
}
|
||||
|
||||
protected virtual void OnDispose()
|
||||
{
|
||||
if (Engine == null || Engine.IsDisposed)
|
||||
{
|
||||
_Visible = _Marked = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_Visible)
|
||||
{
|
||||
--Engine.Visible;
|
||||
}
|
||||
|
||||
if (_Marked)
|
||||
{
|
||||
--Engine.Marked;
|
||||
}
|
||||
|
||||
_Visible = _Marked = false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TrapSweeperTileBlank : TrapSweeperTile
|
||||
{
|
||||
private int _Traps = -1;
|
||||
|
||||
public int Traps
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
Dispose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_Traps < 0)
|
||||
{
|
||||
_Traps = Engine.FindTiles<TrapSweeperTileTrap>(X - 1, Y - 1, 3, 3).Count();
|
||||
}
|
||||
|
||||
return _Traps;
|
||||
}
|
||||
}
|
||||
|
||||
public override int DisplayID => Traps > 0 ? 2225 + (Traps - 1) : 9021;
|
||||
|
||||
public TrapSweeperTileBlank(TrapSweeperEngine g, int x, int y)
|
||||
: base(g, x, y)
|
||||
{ }
|
||||
|
||||
protected override void OnReveal()
|
||||
{
|
||||
base.OnReveal();
|
||||
|
||||
if (Engine.AllTiles<TrapSweeperTileBlank>().All(t => t.Visible))
|
||||
{
|
||||
Engine.DoEnd(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Engine.IncreasePoints(Points, true);
|
||||
|
||||
if (Traps > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var p = 0.0;
|
||||
|
||||
foreach (var t in Engine.FindTiles<TrapSweeperTileBlank>(X - 1, Y - 1, 3, 3).Where(t => t != this && !t.Visible))
|
||||
{
|
||||
t.Visible = true;
|
||||
p += t.Points;
|
||||
}
|
||||
|
||||
Engine.OffsetPoints(p, true);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TrapSweeperTileTrap : TrapSweeperTile
|
||||
{
|
||||
public override int DisplayID => 9020;
|
||||
public override int Hue => 34;
|
||||
|
||||
public TrapSweeperTileTrap(TrapSweeperEngine g, int x, int y)
|
||||
: base(g, x, y)
|
||||
{ }
|
||||
|
||||
/*protected override void OnMarked()
|
||||
{
|
||||
base.OnMarked();
|
||||
|
||||
if (!Engine.AllTiles<SweeperTileTrap>().All(t => t.Marked))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Engine.Rewards += Engine.AllTiles<SweeperTileBonus>().Count(t => !t.Visible);
|
||||
|
||||
Engine.DoEnd(true);
|
||||
}*/
|
||||
|
||||
protected override void OnReveal()
|
||||
{
|
||||
base.OnReveal();
|
||||
|
||||
Engine.DecreasePoints(Points, true);
|
||||
|
||||
Engine.DoEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TrapSweeperTileBonus : TrapSweeperTile
|
||||
{
|
||||
public override int DisplayID => 9027;
|
||||
public override int Hue => 85;
|
||||
|
||||
public TrapSweeperTileBonus(TrapSweeperEngine g, int x, int y)
|
||||
: base(g, x, y)
|
||||
{ }
|
||||
|
||||
protected override void OnReveal()
|
||||
{
|
||||
base.OnReveal();
|
||||
|
||||
++Engine.Rewards;
|
||||
}
|
||||
|
||||
protected override void OnHide()
|
||||
{
|
||||
base.OnHide();
|
||||
|
||||
--Engine.Rewards;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public enum TrapSweeperMode
|
||||
{
|
||||
Easy,
|
||||
Normal,
|
||||
Hard,
|
||||
Random
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public enum TrapSweeperState
|
||||
{
|
||||
Menu,
|
||||
Play,
|
||||
Win,
|
||||
Lose
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public class TrapSweeperUI : GameUI<TrapSweeperEngine>
|
||||
{
|
||||
public TrapSweeperUI(TrapSweeperEngine engine)
|
||||
: base(engine)
|
||||
{
|
||||
HighlightHue = 1258;
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
if (Engine == null || Engine.IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Engine.State)
|
||||
{
|
||||
case TrapSweeperState.Menu:
|
||||
CompileMenuLayout(layout);
|
||||
break;
|
||||
default:
|
||||
CompilePlayLayout(layout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void CompileMenuLayout(SuperGumpLayout layout)
|
||||
{
|
||||
layout.Add(
|
||||
"window/menu/start",
|
||||
() =>
|
||||
{
|
||||
AddImage(354, 256, 4501, HighlightHue);
|
||||
AddButton(351, 254, 4501, 4501, b => Engine.DoPlay());
|
||||
|
||||
AddHtml(
|
||||
140,
|
||||
300,
|
||||
435,
|
||||
40,
|
||||
"START SWEEPING!".WrapUOHtmlBold().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Gold, false),
|
||||
false,
|
||||
false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/menu/option/easy",
|
||||
() =>
|
||||
{
|
||||
var s = false;
|
||||
|
||||
// EASY
|
||||
if (Engine.Mode != TrapSweeperMode.Easy)
|
||||
{
|
||||
AddImage(155, 330, 1417);
|
||||
AddButton(164, 339, 5575, 5576, b => Engine.DoMode(TrapSweeperMode.Easy));
|
||||
AddButton(145, 420, 5403, 5403, b => Engine.DoMode(TrapSweeperMode.Easy));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(155, 330, 1417, HighlightHue);
|
||||
AddImage(164, 339, 5576);
|
||||
|
||||
s = true;
|
||||
}
|
||||
|
||||
var text = "ROOKIE";
|
||||
|
||||
text = s ? text.WrapUOHtmlTag("U") : text;
|
||||
text = text.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Green, false);
|
||||
|
||||
AddBackground(145, 415, 100, 30, 9350);
|
||||
AddHtml(145, 420, 100, 40, text, false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/menu/option/normal",
|
||||
() =>
|
||||
{
|
||||
var s = false;
|
||||
|
||||
// NORMAL
|
||||
if (Engine.Mode != TrapSweeperMode.Normal)
|
||||
{
|
||||
AddImage(262, 330, 1417);
|
||||
AddButton(271, 339, 5587, 5588, b => Engine.DoMode(TrapSweeperMode.Normal));
|
||||
AddButton(252, 420, 5403, 5403, b => Engine.DoMode(TrapSweeperMode.Normal));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(262, 330, 1417, HighlightHue);
|
||||
AddImage(271, 339, 5588);
|
||||
|
||||
s = true;
|
||||
}
|
||||
|
||||
var text = "GUARD";
|
||||
|
||||
text = s ? text.WrapUOHtmlTag("U") : text;
|
||||
text = text.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Yellow, false);
|
||||
|
||||
AddBackground(252, 415, 100, 30, 9350);
|
||||
AddHtml(252, 420, 100, 40, text, false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/menu/option/hard",
|
||||
() =>
|
||||
{
|
||||
var s = false;
|
||||
|
||||
// HARD
|
||||
if (Engine.Mode != TrapSweeperMode.Hard)
|
||||
{
|
||||
AddImage(368, 330, 1417);
|
||||
AddButton(377, 339, 5547, 5548, b => Engine.DoMode(TrapSweeperMode.Hard));
|
||||
AddButton(358, 420, 5403, 5403, b => Engine.DoMode(TrapSweeperMode.Hard));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(368, 330, 1417, HighlightHue);
|
||||
AddImage(377, 339, 5548);
|
||||
|
||||
s = true;
|
||||
}
|
||||
|
||||
var text = "KNIGHT";
|
||||
|
||||
text = s ? text.WrapUOHtmlTag("U") : text;
|
||||
text = text.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Red, false);
|
||||
|
||||
AddBackground(358, 415, 100, 30, 9350);
|
||||
AddHtml(358, 420, 100, 40, text, false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/menu/option/random",
|
||||
() =>
|
||||
{
|
||||
var s = false;
|
||||
|
||||
// RANDOM
|
||||
if (Engine.Mode != TrapSweeperMode.Random)
|
||||
{
|
||||
AddImage(475, 330, 1417);
|
||||
AddButton(484, 339, 5583, 5584, b => Engine.DoMode(TrapSweeperMode.Random));
|
||||
AddButton(465, 420, 5403, 5403, b => Engine.DoMode(TrapSweeperMode.Random));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(475, 330, 1417, HighlightHue);
|
||||
AddImage(484, 339, 5584);
|
||||
|
||||
s = true;
|
||||
}
|
||||
|
||||
var text = "RANDOM";
|
||||
|
||||
text = s ? text.WrapUOHtmlTag("U") : text;
|
||||
text = text.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Blue, false);
|
||||
|
||||
AddBackground(465, 415, 100, 30, 9350);
|
||||
AddHtml(465, 420, 100, 40, text, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void CompilePlayLayout(SuperGumpLayout layout)
|
||||
{
|
||||
layout.Add(
|
||||
"window/play",
|
||||
() =>
|
||||
{
|
||||
AddBackground(133, 100, 450, 350, 9200);
|
||||
AddBackground(142, 130, 435, 315, 9300);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/play/info",
|
||||
() =>
|
||||
{
|
||||
if (Engine.State == TrapSweeperState.Lose)
|
||||
{
|
||||
AddImage(325, 55, 7034, 34);
|
||||
AddImage(270, 32, 50562);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(325, 55, 7034);
|
||||
}
|
||||
|
||||
AddImage(230, 60, 30082, HighlightHue);
|
||||
AddImage(315, 45, 30061, HighlightHue);
|
||||
AddImage(390, 60, 30080, HighlightHue);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/play/info/traps",
|
||||
() =>
|
||||
{
|
||||
AddImage(260, 50, 20999);
|
||||
AddBackground(185, 50, 75, 44, 9300);
|
||||
|
||||
var count = Engine.Traps - Engine.Marked;
|
||||
|
||||
AddHtml(185, 65, 75, 40, count.ToString("#,0").WrapUOHtmlCenter(), false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/play/info/time",
|
||||
() =>
|
||||
{
|
||||
AddImage(415, 50, 23000);
|
||||
AddBackground(460, 50, 75, 44, 9300);
|
||||
|
||||
TimeSpan time;
|
||||
|
||||
switch (Engine.State)
|
||||
{
|
||||
case TrapSweeperState.Lose:
|
||||
time = Engine.Ended - Engine.Started;
|
||||
break;
|
||||
default:
|
||||
time = DateTime.UtcNow - Engine.Started;
|
||||
break;
|
||||
}
|
||||
|
||||
AddHtml(460, 65, 75, 40, time.ToSimpleString("h:m:s").WrapUOHtmlCenter(), false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/play/game/grid",
|
||||
() =>
|
||||
{
|
||||
var w = Engine.Width * 19;
|
||||
var h = Engine.Height * 20;
|
||||
|
||||
var xo = 148 + ((418 - w) / 2);
|
||||
var yo = 137 + ((300 - h) / 2);
|
||||
|
||||
foreach (var t in Engine.AllTiles())
|
||||
{
|
||||
if (t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Engine.State == TrapSweeperState.Play && !t.Visible)
|
||||
{
|
||||
AddButton(xo + (t.X * 19), yo + (t.Y * 20), t.Marked ? t.MarkID : t.HiddenID, t.ClickID, b => t.Click());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(xo + (t.X * 19), yo + (t.Y * 20), t.DisplayID, t.Hue);
|
||||
}
|
||||
|
||||
AddImage(xo + (t.X * 19), yo + (t.Y * 20), 9028, t.Marked ? HighlightHue : 0);
|
||||
}
|
||||
});
|
||||
|
||||
switch (Engine.State)
|
||||
{
|
||||
case TrapSweeperState.Play:
|
||||
{
|
||||
layout.Add(
|
||||
"window/play/mark",
|
||||
() =>
|
||||
{
|
||||
var text = "MARK";
|
||||
|
||||
text = text.WrapUOHtmlBold().WrapUOHtmlCenter().WrapUOHtmlColor(Color.PaleGoldenrod, false);
|
||||
|
||||
AddHtml(45, 355, 80, 40, text, false, false);
|
||||
AddButton(50, 380, 7031, 7031, b => Engine.DoMark());
|
||||
|
||||
if (Engine.Mark)
|
||||
{
|
||||
AddImage(50, 380, 7031, HighlightHue);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case TrapSweeperState.Win:
|
||||
{
|
||||
layout.Add("window/play/results", () => AddAlphaRegion(142, 130, 435, 315));
|
||||
|
||||
layout.Add(
|
||||
"window/play/collect",
|
||||
() =>
|
||||
{
|
||||
var text = "COLLECT";
|
||||
|
||||
text = text.WrapUOHtmlBold().WrapUOHtmlCenter().WrapUOHtmlColor(Color.LawnGreen, false);
|
||||
|
||||
AddHtml(45, 355, 80, 40, text, false, false);
|
||||
AddButton(50, 380, 7012, 7012, b => Engine.DoCollect());
|
||||
AddImage(50, 380, 7012, 85);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case TrapSweeperState.Lose:
|
||||
{
|
||||
layout.Add(
|
||||
"window/play/menu",
|
||||
() =>
|
||||
{
|
||||
var text = "RESURRECT";
|
||||
|
||||
text = text.WrapUOHtmlBold().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Orange, false);
|
||||
|
||||
AddHtml(45, 355, 80, 40, text, false, false);
|
||||
AddButton(50, 380, 7007, 7007, b => Engine.DoMenu());
|
||||
AddImage(50, 380, 7007, HighlightHue);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/play/blood",
|
||||
() =>
|
||||
{
|
||||
AddItem(65, 73, 7572);
|
||||
AddItem(273, 59, 7574);
|
||||
AddItem(348, 58, 4655);
|
||||
AddItem(599, 37, 7573);
|
||||
AddItem(585, 310, 4652);
|
||||
AddItem(603, 327, 4653);
|
||||
AddItem(594, 450, 4650);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnQuit()
|
||||
{
|
||||
base.OnQuit();
|
||||
|
||||
if (Engine.State == TrapSweeperState.Win)
|
||||
{
|
||||
Engine.DoCollect();
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.DoQuit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Games/UI/GameUI.cs
Normal file
178
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Games/UI/GameUI.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public abstract class GameUI<TEngine> : SuperGump, IGameUI
|
||||
where TEngine : class, IGameEngine
|
||||
{
|
||||
public bool IsDisposing { get; private set; }
|
||||
|
||||
public TEngine Engine { get; private set; }
|
||||
|
||||
public GameUI(TEngine engine)
|
||||
: base(engine.User)
|
||||
{
|
||||
Engine = engine;
|
||||
|
||||
RandomButtonID = true;
|
||||
ForceRecompile = true;
|
||||
}
|
||||
|
||||
public bool Validate()
|
||||
{
|
||||
return !IsDisposed && !IsDisposing && Engine != null && !Engine.IsDisposed && User != null && !User.Deleted;
|
||||
}
|
||||
|
||||
protected override void OnDispose()
|
||||
{
|
||||
if (IsDisposed || IsDisposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDisposing = true;
|
||||
|
||||
base.OnDispose();
|
||||
}
|
||||
|
||||
protected override void OnDisposed()
|
||||
{
|
||||
base.OnDisposed();
|
||||
|
||||
IsDisposing = false;
|
||||
}
|
||||
|
||||
protected override void OnClosed(bool all)
|
||||
{
|
||||
base.OnClosed(all);
|
||||
|
||||
if (!all)
|
||||
{
|
||||
OnQuit();
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
layout.Add(
|
||||
"window",
|
||||
() =>
|
||||
{
|
||||
AddBackground(0, 0, 650, 490, 2620);
|
||||
|
||||
AddImage(5, 5, 9001);
|
||||
AddImage(5, 5, 9002, 901);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/title",
|
||||
() =>
|
||||
{
|
||||
var title = GetTitle();
|
||||
|
||||
AddImage(10, 10, 2440, 901);
|
||||
AddHtml(10, 12, 166, 40, title, false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"window/score",
|
||||
() =>
|
||||
{
|
||||
var points = GetPoints();
|
||||
|
||||
AddImage(180, 10, 2440, 901);
|
||||
AddHtml(180, 12, 166, 40, points, false, false);
|
||||
});
|
||||
|
||||
layout.Add("window/quit", () => { AddButton(560, 5, 5514, 5515, Close); });
|
||||
}
|
||||
|
||||
protected virtual void OnQuit()
|
||||
{ }
|
||||
|
||||
public virtual string GetPoints()
|
||||
{
|
||||
if (Engine == null)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
var p = String.Format("Points: {0:#,0.##}", Engine.Points);
|
||||
|
||||
var t = new StringBuilder();
|
||||
|
||||
var c1 = Color.Gold;
|
||||
var c2 = Color.PaleGoldenrod;
|
||||
|
||||
for (var i = 0; i < p.Length; i++)
|
||||
{
|
||||
if (!Char.IsWhiteSpace(p, i))
|
||||
{
|
||||
t.Append(p[i].ToString().WrapUOHtmlColor(c1.Interpolate(c2, i / (p.Length - 1.0)), false));
|
||||
}
|
||||
else
|
||||
{
|
||||
t.Append(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return t.ToString().WrapUOHtmlBig().WrapUOHtmlCenter();
|
||||
}
|
||||
|
||||
public virtual string GetTitle()
|
||||
{
|
||||
if (Engine == null || Engine.Game == null)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
var n = Engine.Game.Name.Trim();
|
||||
|
||||
var t = new StringBuilder();
|
||||
|
||||
var c1 = Color.Gold;
|
||||
var c2 = Color.PaleGoldenrod;
|
||||
|
||||
for (var i = 0; i < n.Length; i++)
|
||||
{
|
||||
if (!Char.IsWhiteSpace(n, i))
|
||||
{
|
||||
t.Append(n[i].ToString().WrapUOHtmlColor(c1.Interpolate(c2, i / (n.Length - 1.0)), false));
|
||||
}
|
||||
else
|
||||
{
|
||||
t.Append(n[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return t.ToString().WrapUOHtmlBig().WrapUOHtmlCenter();
|
||||
}
|
||||
|
||||
#region Explicit Impl
|
||||
IGameEngine IGameUI.Engine => Engine;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public interface IGame
|
||||
{
|
||||
Type EngineType { get; }
|
||||
|
||||
IconDefinition Icon { get; }
|
||||
|
||||
string Name { get; }
|
||||
string Desc { get; }
|
||||
string Help { get; }
|
||||
|
||||
bool Enabled { get; set; }
|
||||
|
||||
IEnumerable<IGameEngine> Sessions { get; }
|
||||
|
||||
int SessionCount { get; }
|
||||
|
||||
IGameEngine this[Mobile user] { get; set; }
|
||||
|
||||
GameStatistics Statistics { get; }
|
||||
|
||||
void Enable();
|
||||
void Disable();
|
||||
|
||||
bool Validate(Mobile user);
|
||||
bool Open(Mobile user);
|
||||
void Close(Mobile user);
|
||||
void Reset(Mobile user);
|
||||
|
||||
void Log(string context, double value, bool offset);
|
||||
void LogIncrease(string context, double value);
|
||||
void LogDecrease(string context, double value);
|
||||
|
||||
void Serialize(GenericWriter writer);
|
||||
void Deserialize(GenericReader reader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public interface IGameEngine : IDisposable
|
||||
{
|
||||
Type UIType { get; }
|
||||
|
||||
bool IsDisposed { get; }
|
||||
bool IsDisposing { get; }
|
||||
|
||||
Mobile User { get; }
|
||||
|
||||
IGame Game { get; }
|
||||
IGameUI UI { get; }
|
||||
|
||||
ArcadeProfile Profile { get; }
|
||||
|
||||
GameStatistics Statistics { get; }
|
||||
|
||||
double Points { get; }
|
||||
|
||||
bool Validate();
|
||||
|
||||
bool Open();
|
||||
void Close();
|
||||
void Reset();
|
||||
|
||||
void LogStatistics();
|
||||
|
||||
void Log(string context, double value, bool offset);
|
||||
void LogIncrease(string context, double value);
|
||||
void LogDecrease(string context, double value);
|
||||
|
||||
void OffsetPoints(double value, bool log);
|
||||
void IncreasePoints(double value, bool log);
|
||||
void DecreasePoints(double value, bool log);
|
||||
|
||||
void Serialize(GenericWriter writer);
|
||||
void Deserialize(GenericReader reader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public interface IGameUI : IDisposable
|
||||
{
|
||||
bool IsDisposed { get; }
|
||||
bool IsDisposing { get; }
|
||||
|
||||
IGameEngine Engine { get; }
|
||||
|
||||
Mobile User { get; }
|
||||
|
||||
bool Validate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public sealed class ArcadeProfile : PropertyObject, IEnumerable<KeyValuePair<string, GameStatistics>>
|
||||
{
|
||||
private Dictionary<string, GameStatistics> _Statistics = new Dictionary<string, GameStatistics>();
|
||||
|
||||
public GameStatistics this[string key]
|
||||
{
|
||||
get => _Statistics.GetValue(key) ?? (_Statistics[key] = new GameStatistics());
|
||||
set => _Statistics[key] = value;
|
||||
}
|
||||
|
||||
public Dictionary<string, GameStatistics>.KeyCollection Categories => _Statistics.Keys;
|
||||
|
||||
public Mobile Owner { get; private set; }
|
||||
|
||||
public int Credits { get; set; }
|
||||
|
||||
public ArcadeProfile(Mobile owner)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
public ArcadeProfile(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
foreach (var v in _Statistics.Values)
|
||||
{
|
||||
v.Clear();
|
||||
}
|
||||
|
||||
_Statistics.Clear();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
foreach (var v in _Statistics.Values)
|
||||
{
|
||||
v.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(IGame g, string context, double value, bool offset)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
LogIncrease(g, context, value);
|
||||
}
|
||||
else if (value < 0)
|
||||
{
|
||||
LogDecrease(g, context, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this[g.Name][context] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void LogIncrease(IGame g, string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
this[g.Name][context] += value;
|
||||
}
|
||||
|
||||
public void LogDecrease(IGame g, string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
this[g.Name][context] -= value;
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, GameStatistics>> GetEnumerator()
|
||||
{
|
||||
return _Statistics.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
writer.Write(Owner);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Credits);
|
||||
|
||||
writer.WriteBlockDictionary(
|
||||
_Statistics,
|
||||
(w, k, v) =>
|
||||
{
|
||||
w.Write(k);
|
||||
v.Serialize(w);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
Owner = reader.ReadMobile();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Credits = reader.ReadInt();
|
||||
|
||||
_Statistics = reader.ReadBlockDictionary(
|
||||
r =>
|
||||
{
|
||||
var k = r.ReadString();
|
||||
var v = new GameStatistics(r);
|
||||
|
||||
return new KeyValuePair<string, GameStatistics>(k, v);
|
||||
},
|
||||
_Statistics);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
343
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Objects/Game.cs
Normal file
343
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/Objects/Game.cs
Normal file
@@ -0,0 +1,343 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public abstract class Game<TEngine> : IGame, IEnumerable<TEngine>
|
||||
where TEngine : class, IGameEngine
|
||||
{
|
||||
private readonly Type _EngineType = typeof(TEngine);
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public Type EngineType => _EngineType;
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public abstract IconDefinition Icon { get; }
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public abstract string Name { get; }
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public abstract string Desc { get; }
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public abstract string Help { get; }
|
||||
|
||||
private bool _Enabled;
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public bool Enabled
|
||||
{
|
||||
get => _Enabled;
|
||||
set
|
||||
{
|
||||
if (_Enabled && !value)
|
||||
{
|
||||
_Enabled = false;
|
||||
|
||||
OnDisabled();
|
||||
Flush();
|
||||
}
|
||||
else if (!_Enabled && value)
|
||||
{
|
||||
_Enabled = true;
|
||||
|
||||
OnEnabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<TEngine> _Sessions;
|
||||
|
||||
public IEnumerable<TEngine> Sessions
|
||||
{
|
||||
get
|
||||
{
|
||||
var c = _Sessions.Count;
|
||||
|
||||
while (--c >= 0)
|
||||
{
|
||||
if (!_Sessions.InBounds(c))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var e = _Sessions[c];
|
||||
|
||||
if (e != null && !e.IsDisposed && !e.IsDisposing)
|
||||
{
|
||||
yield return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public int SessionCount => _Sessions.Count;
|
||||
|
||||
public TEngine this[Mobile user]
|
||||
{
|
||||
get => _Sessions.Find(e => e != null && e.User == user);
|
||||
private set
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var e = this[user];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
if (e == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
|
||||
_Sessions.Remove(e);
|
||||
}
|
||||
|
||||
_Sessions.Update(value);
|
||||
}
|
||||
else if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
|
||||
_Sessions.Remove(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(Arcade.Access)]
|
||||
public GameStatistics Statistics { get; private set; }
|
||||
|
||||
public Game()
|
||||
{
|
||||
_Sessions = new List<TEngine>();
|
||||
|
||||
Statistics = new GameStatistics();
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
foreach (var e in Sessions)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
|
||||
_Sessions.Clear();
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
protected virtual void OnEnabled()
|
||||
{ }
|
||||
|
||||
protected virtual void OnDisabled()
|
||||
{ }
|
||||
|
||||
protected TEngine EnsureSession(Mobile user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var e = this[user];
|
||||
|
||||
if (e == null || !e.IsDisposing || e.IsDisposed)
|
||||
{
|
||||
if (user.Deleted || !user.IsOnline())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
this[user] = e = EngineType.CreateInstanceSafe<TEngine>(this, user);
|
||||
}
|
||||
else if (user.Deleted || !user.IsOnline())
|
||||
{
|
||||
this[user] = null;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public bool Validate(Mobile user)
|
||||
{
|
||||
var e = EnsureSession(user);
|
||||
|
||||
return e != null && e.Validate();
|
||||
}
|
||||
|
||||
public bool Open(Mobile user)
|
||||
{
|
||||
var e = EnsureSession(user);
|
||||
|
||||
if (e == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!e.Open() || !e.Validate())
|
||||
{
|
||||
e.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Close(Mobile user)
|
||||
{
|
||||
this[user] = null;
|
||||
}
|
||||
|
||||
public void Reset(Mobile user)
|
||||
{
|
||||
var e = EnsureSession(user);
|
||||
|
||||
if (e != null && e.Validate())
|
||||
{
|
||||
e.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(string context, double value, bool offset)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
LogIncrease(context, value);
|
||||
}
|
||||
else if (value < 0)
|
||||
{
|
||||
LogDecrease(context, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Statistics[context] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void LogIncrease(string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Statistics[context] += value;
|
||||
}
|
||||
|
||||
public void LogDecrease(string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Statistics[context] -= value;
|
||||
}
|
||||
|
||||
public IEnumerator<TEngine> GetEnumerator()
|
||||
{
|
||||
return _Sessions.GetEnumerator();
|
||||
}
|
||||
|
||||
public virtual void Serialize(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(_Enabled);
|
||||
|
||||
Statistics.Serialize(writer);
|
||||
|
||||
writer.WriteBlockList(
|
||||
_Sessions,
|
||||
(w, e) =>
|
||||
{
|
||||
w.Write(e.User);
|
||||
e.Serialize(w);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Deserialize(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
_Enabled = reader.ReadBool();
|
||||
|
||||
Statistics.Deserialize(reader);
|
||||
|
||||
_Sessions = reader.ReadBlockList(
|
||||
r =>
|
||||
{
|
||||
var e = EnsureSession(r.ReadMobile());
|
||||
|
||||
e.Deserialize(r);
|
||||
|
||||
return e;
|
||||
},
|
||||
_Sessions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region Explicit Impl
|
||||
IEnumerable<IGameEngine> IGame.Sessions => Sessions;
|
||||
|
||||
IGameEngine IGame.this[Mobile user]
|
||||
{
|
||||
get => this[user];
|
||||
set
|
||||
{
|
||||
if (value == null || value is TEngine)
|
||||
{
|
||||
this[user] = (TEngine)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public abstract class GameEngine<TGame, TGump> : IGameEngine
|
||||
where TGame : class, IGame
|
||||
where TGump : SuperGump, IGameUI
|
||||
{
|
||||
private readonly Type _UIType = typeof(TGump);
|
||||
|
||||
public Type UIType => _UIType;
|
||||
|
||||
public bool IsDisposing { get; private set; }
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
public Mobile User { get; private set; }
|
||||
|
||||
public TGame Game { get; private set; }
|
||||
public TGump UI { get; private set; }
|
||||
|
||||
public ArcadeProfile Profile => Arcade.EnsureProfile(User);
|
||||
|
||||
public GameStatistics Statistics { get; private set; }
|
||||
|
||||
public double PointsTotal
|
||||
{
|
||||
get => Statistics["Points Total"];
|
||||
private set => Statistics["Points Total"] = value;
|
||||
}
|
||||
|
||||
public double PointsGained
|
||||
{
|
||||
get => Statistics["Points Gained"];
|
||||
private set => Statistics["Points Gained"] = value;
|
||||
}
|
||||
|
||||
public double PointsLost
|
||||
{
|
||||
get => Statistics["Points Lost"];
|
||||
private set => Statistics["Points Lost"] = value;
|
||||
}
|
||||
|
||||
public double Points { get; private set; }
|
||||
|
||||
public GameEngine(TGame game, Mobile user)
|
||||
{
|
||||
Game = game;
|
||||
User = user;
|
||||
|
||||
Statistics = new GameStatistics();
|
||||
}
|
||||
|
||||
~GameEngine()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
protected bool EnsureUI()
|
||||
{
|
||||
if (IsDisposed || IsDisposing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (User == null || User.Deleted)
|
||||
{
|
||||
if (UI != null)
|
||||
{
|
||||
UI.Close(true);
|
||||
UI = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UI != null && UI.User != User)
|
||||
{
|
||||
UI.Close(true);
|
||||
UI = null;
|
||||
}
|
||||
|
||||
if (UI == null || UI.IsDisposed || UI.IsDisposing)
|
||||
{
|
||||
UI = UIType.CreateInstanceSafe<TGump>(this);
|
||||
}
|
||||
|
||||
return UI != null && UI.Validate();
|
||||
}
|
||||
|
||||
public bool Validate()
|
||||
{
|
||||
return !IsDisposed && !IsDisposing && UI != null && UI.Validate();
|
||||
}
|
||||
|
||||
public virtual bool Open()
|
||||
{
|
||||
if (!EnsureUI() || !Validate())
|
||||
{
|
||||
Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
UI.Refresh(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
if (UI != null && !UI.IsDisposed)
|
||||
{
|
||||
UI.Close(true);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Points = 0;
|
||||
|
||||
Statistics.Reset();
|
||||
}
|
||||
|
||||
public void LogStatistics()
|
||||
{
|
||||
var p = Profile;
|
||||
|
||||
foreach (var kv in Statistics)
|
||||
{
|
||||
Game.Log(kv.Key, kv.Value, true);
|
||||
|
||||
if (p != null)
|
||||
{
|
||||
p.Log(Game, kv.Key, kv.Value, true);
|
||||
}
|
||||
}
|
||||
|
||||
Statistics.Reset();
|
||||
}
|
||||
|
||||
public void Log(string context, double value, bool offset)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
LogIncrease(context, value);
|
||||
}
|
||||
else if (value < 0)
|
||||
{
|
||||
LogDecrease(context, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Statistics[context] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void LogIncrease(string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Statistics[context] += value;
|
||||
}
|
||||
|
||||
public void LogDecrease(string context, double value)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Statistics[context] -= value;
|
||||
}
|
||||
|
||||
public void OffsetPoints(double value, bool log)
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
IncreasePoints(value, log);
|
||||
}
|
||||
else if (value < 0)
|
||||
{
|
||||
DecreasePoints(value, log);
|
||||
}
|
||||
}
|
||||
|
||||
public void IncreasePoints(double value, bool log)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Points += value;
|
||||
PointsTotal += value;
|
||||
|
||||
if (log)
|
||||
{
|
||||
PointsGained += value;
|
||||
}
|
||||
}
|
||||
|
||||
public void DecreasePoints(double value, bool log)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
|
||||
Points -= value;
|
||||
PointsTotal -= value;
|
||||
|
||||
if (log)
|
||||
{
|
||||
PointsLost += value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsDisposed || IsDisposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDisposing = true;
|
||||
|
||||
LogStatistics();
|
||||
|
||||
Close();
|
||||
|
||||
if (UI == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (UI.IsOpen || UI.Hidden)
|
||||
{
|
||||
UI.Close(true);
|
||||
}
|
||||
|
||||
UI = null;
|
||||
|
||||
OnDispose();
|
||||
|
||||
if (Game != null && User != null)
|
||||
{
|
||||
Game[User] = null;
|
||||
}
|
||||
|
||||
Statistics.Clear();
|
||||
Statistics = null;
|
||||
|
||||
Game = null;
|
||||
User = null;
|
||||
|
||||
IsDisposed = true;
|
||||
|
||||
OnDisposed();
|
||||
|
||||
IsDisposing = false;
|
||||
}
|
||||
|
||||
protected virtual void OnDispose()
|
||||
{ }
|
||||
|
||||
protected virtual void OnDisposed()
|
||||
{ }
|
||||
|
||||
public virtual void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.Write(Points);
|
||||
|
||||
Statistics.Serialize(writer);
|
||||
}
|
||||
|
||||
public virtual void Deserialize(GenericReader reader)
|
||||
{
|
||||
reader.GetVersion();
|
||||
|
||||
Points = reader.ReadDouble();
|
||||
|
||||
Statistics.Deserialize(reader);
|
||||
}
|
||||
|
||||
#region Explicit Impl
|
||||
IGame IGameEngine.Game => Game;
|
||||
IGameUI IGameEngine.UI => UI;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public sealed class GameStatistics : PropertyObject, IEnumerable<KeyValuePair<string, double>>
|
||||
{
|
||||
private readonly Dictionary<string, double> _Statistics = new Dictionary<string, double>();
|
||||
|
||||
public double this[string key] { get => _Statistics.GetValue(key); set => _Statistics[key] = value; }
|
||||
|
||||
public Dictionary<string, double>.KeyCollection Entries => _Statistics.Keys;
|
||||
|
||||
public GameStatistics()
|
||||
{ }
|
||||
|
||||
public GameStatistics(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
_Statistics.Clear();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Statistics.Keys.ForEach(k => _Statistics[k] = 0);
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
return key != null && _Statistics.Remove(key);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, double>> GetEnumerator()
|
||||
{
|
||||
return _Statistics.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.WriteDictionary(
|
||||
_Statistics,
|
||||
(w, k, v) =>
|
||||
{
|
||||
w.Write(k);
|
||||
w.Write(v);
|
||||
});
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
reader.ReadDictionary(
|
||||
r =>
|
||||
{
|
||||
var k = r.ReadString();
|
||||
var v = r.ReadDouble();
|
||||
|
||||
return new KeyValuePair<string, double>(k, v);
|
||||
},
|
||||
_Statistics);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public sealed class ArcadeOptions : CoreModuleOptions
|
||||
{
|
||||
public ArcadeOptions()
|
||||
: base(typeof(Arcade))
|
||||
{ }
|
||||
|
||||
/*
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
}
|
||||
*/
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
493
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/UI/ArcadeUI.cs
Normal file
493
Scripts/SubSystem/VitaNex/Core/Modules/Arcade/UI/ArcadeUI.cs
Normal file
@@ -0,0 +1,493 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.Games
|
||||
{
|
||||
public sealed class ArcadeUI : SuperGumpList<IGame>
|
||||
{
|
||||
public ArcadeProfile Profile { get; private set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
|
||||
public int Margin { get; set; }
|
||||
public int Padding { get; set; }
|
||||
|
||||
public int MenuSize { get; set; }
|
||||
public int IconSize { get; set; }
|
||||
|
||||
public int Rows { get; private set; }
|
||||
public int Cols { get; private set; }
|
||||
|
||||
public IGame SelectedGame { get; private set; }
|
||||
|
||||
public ArcadeUI(Mobile user)
|
||||
: base(user)
|
||||
{
|
||||
Profile = Arcade.EnsureProfile(User);
|
||||
|
||||
Sorted = true;
|
||||
|
||||
EnsureDefaults();
|
||||
}
|
||||
|
||||
public void EnsureDefaults()
|
||||
{
|
||||
Width = 800;
|
||||
Height = 600;
|
||||
|
||||
Margin = 30;
|
||||
Padding = 15;
|
||||
|
||||
MenuSize = 250;
|
||||
IconSize = 120;
|
||||
|
||||
InvalidateGrid();
|
||||
}
|
||||
|
||||
public void InvalidateGrid()
|
||||
{
|
||||
Width = Math.Max(300, Math.Min(1024, Width));
|
||||
Height = Math.Max(300, Math.Min(768, Height));
|
||||
|
||||
MenuSize = Math.Max(200, Math.Min(400, MenuSize));
|
||||
IconSize = Math.Max(100, Math.Min(250, IconSize));
|
||||
|
||||
Rows = (int)Math.Floor(((Width - MenuSize) - (Padding * 2)) / (double)IconSize);
|
||||
Cols = (int)Math.Floor((Height - (Padding * 2)) / (double)IconSize);
|
||||
|
||||
EntriesPerPage = Rows * Cols;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
if (Profile == null || Profile.Owner != User)
|
||||
{
|
||||
Profile = Arcade.EnsureProfile(User);
|
||||
}
|
||||
|
||||
InvalidateGrid();
|
||||
|
||||
base.Compile();
|
||||
}
|
||||
|
||||
protected override void CompileList(List<IGame> list)
|
||||
{
|
||||
list.Clear();
|
||||
list.AddRange(Arcade.Games.Values);
|
||||
|
||||
base.CompileList(list);
|
||||
}
|
||||
|
||||
public override int SortCompare(IGame a, IGame b)
|
||||
{
|
||||
var res = 0;
|
||||
|
||||
if (a.CompareNull(b, ref res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
return Insensitive.Compare(a.Name, b.Name);
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
layout.Add(
|
||||
"body",
|
||||
() =>
|
||||
{
|
||||
AddBackground(0, 0, Width + (Margin * 2), Height + (Margin * 2), 2600);
|
||||
AddBackground(Margin, Margin, MenuSize, Height, 9250);
|
||||
AddBackground(Margin + MenuSize, Margin, Width - MenuSize, Height, 9250);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"title",
|
||||
() =>
|
||||
{
|
||||
var x = Margin + MenuSize + Padding;
|
||||
var y = Margin + Padding;
|
||||
var w = Width - (MenuSize + (Padding * 2));
|
||||
|
||||
var title = "Games Arcade";
|
||||
|
||||
title = title.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Gold, false);
|
||||
|
||||
AddHtml(x, y, w, 40, title, false, false);
|
||||
});
|
||||
|
||||
layout.Add(
|
||||
"menu",
|
||||
() =>
|
||||
{
|
||||
var x = Margin + Padding;
|
||||
var y = Margin + Padding;
|
||||
var w = MenuSize - (Padding * 2);
|
||||
var h = Height - (Padding * 2);
|
||||
|
||||
CompileMenuLayout(x, y, w, h);
|
||||
});
|
||||
|
||||
var games = GetListRange();
|
||||
|
||||
if (games != null)
|
||||
{
|
||||
var width = Cols * IconSize;
|
||||
var height = Rows * IconSize;
|
||||
|
||||
var initX = Margin + MenuSize;
|
||||
var initY = Margin + Padding;
|
||||
|
||||
if (width < Width - MenuSize)
|
||||
{
|
||||
initX += ((Width - MenuSize) - width) / 2;
|
||||
}
|
||||
|
||||
if (height < Height)
|
||||
{
|
||||
initY += (Height - height) / 2;
|
||||
}
|
||||
|
||||
var xOffset = initX;
|
||||
var yOffset = initY;
|
||||
|
||||
var index = 0;
|
||||
|
||||
var col = 0;
|
||||
var row = 0;
|
||||
|
||||
foreach (var game in games.Values)
|
||||
{
|
||||
CompileGameLayout(layout, index++, xOffset, yOffset, game);
|
||||
|
||||
xOffset += IconSize;
|
||||
|
||||
if (++col % Cols == 0)
|
||||
{
|
||||
xOffset = initX;
|
||||
yOffset += IconSize;
|
||||
|
||||
if (++row % Rows == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (col < Cols || row < Rows)
|
||||
{
|
||||
while (index < EntriesPerPage)
|
||||
{
|
||||
CompileGameLayout(layout, index++, xOffset, yOffset, null);
|
||||
|
||||
xOffset += IconSize;
|
||||
|
||||
if (++col % Cols == 0)
|
||||
{
|
||||
xOffset = initX;
|
||||
yOffset += IconSize;
|
||||
|
||||
if (++row % Rows == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CompileGameLayout(SuperGumpLayout layout, int index, int x, int y, IGame game)
|
||||
{
|
||||
layout.Add("games/" + index, () => CompileGameLayout(x, y, IconSize, IconSize, game));
|
||||
}
|
||||
|
||||
private void CompileGameLayout(int x, int y, int w, int h, IGame game)
|
||||
{
|
||||
if (game != null)
|
||||
{
|
||||
AddTileButton(x + Margin, y + Margin, w - (Margin * 2), h - (Margin * 2), b => SelectGame(game));
|
||||
}
|
||||
|
||||
AddBackground(x, y, w, h, 2600);
|
||||
|
||||
if (game == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
y += Margin;
|
||||
h -= Margin;
|
||||
|
||||
if (game.Icon != null && !game.Icon.IsEmpty)
|
||||
{
|
||||
var s = game.Icon.Size;
|
||||
|
||||
if (game.Enabled)
|
||||
{
|
||||
game.Icon.AddToGump(this, x + ((w - s.Width) / 2), y);
|
||||
}
|
||||
else
|
||||
{
|
||||
game.Icon.AddToGump(this, x + ((w - s.Width) / 2), y, 900);
|
||||
}
|
||||
|
||||
y += s.Height + 5;
|
||||
h -= s.Height + 5;
|
||||
}
|
||||
|
||||
var text = game.Name.WrapUOHtmlBig().WrapUOHtmlCenter().WrapUOHtmlColor(Color.Gold, false);
|
||||
|
||||
AddHtml(x, y, w, h, text, false, false);
|
||||
}
|
||||
|
||||
private void CompileMenuLayout(int x, int y, int w, int h)
|
||||
{
|
||||
if (SelectedGame == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddHtml(x, y, w, h - 95, GetDescription(SelectedGame), false, false);
|
||||
|
||||
y += h - 85;
|
||||
|
||||
var help = "Help";
|
||||
|
||||
help = help.WrapUOHtmlCenter();
|
||||
|
||||
if (SupportsUltimaStore)
|
||||
{
|
||||
help = help.WrapUOHtmlColor(Color.Gold, false);
|
||||
|
||||
AddButton(x + ((w - 126) / 2), y, 40019, 40029, b => SelectHelp(SelectedGame));
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, help, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
help = help.WrapUOHtmlBig();
|
||||
|
||||
AddHtmlButton(x + ((w - 126) / 2), y, 126, 25, b => SelectHelp(SelectedGame), help, Color.White, Color.Empty);
|
||||
}
|
||||
|
||||
y += 25;
|
||||
|
||||
var play = "Play";
|
||||
|
||||
play = play.WrapUOHtmlCenter();
|
||||
|
||||
if (SupportsUltimaStore)
|
||||
{
|
||||
if (SelectedGame.Enabled || User.AccessLevel >= Arcade.Access)
|
||||
{
|
||||
play = play.WrapUOHtmlColor(Color.Gold, false);
|
||||
|
||||
AddButton(x + ((w - 126) / 2), y, 40019, 40029, b => PlayGame(SelectedGame));
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, play, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
play = play.WrapUOHtmlColor(Color.Gray, false);
|
||||
|
||||
AddImage(x + ((w - 126) / 2), y, 40019, 900);
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, play, false, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectedGame.Enabled)
|
||||
{
|
||||
play = play.WrapUOHtmlBig();
|
||||
|
||||
AddHtmlButton(x + ((w - 126) / 2), y, 126, 25, b => PlayGame(SelectedGame), play, Color.White, Color.Black);
|
||||
}
|
||||
else
|
||||
{
|
||||
play = play.WrapUOHtmlColor(Color.Gray, false);
|
||||
|
||||
AddRectangle(x + ((w - 126) / 2), y, 126, 25, Color.Black, true);
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, play, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (User.AccessLevel < Arcade.Access)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
y += 25;
|
||||
|
||||
var label = SelectedGame.Enabled ? "Enabled" : "Disabled";
|
||||
|
||||
label = label.WrapUOHtmlCenter();
|
||||
|
||||
if (SupportsUltimaStore)
|
||||
{
|
||||
if (SelectedGame.Enabled)
|
||||
{
|
||||
label = label.WrapUOHtmlColor(Color.PaleGreen, false);
|
||||
|
||||
AddButton(x + ((w - 126) / 2), y, 40019, 40029, b => DisableGame(SelectedGame));
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, label, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
label = label.WrapUOHtmlColor(Color.Gray, false);
|
||||
|
||||
AddButton(x + ((w - 126) / 2), y, 40019, 40029, b => EnableGame(SelectedGame));
|
||||
AddHtml(x + ((w - 126) / 2), y + 2, 126, 40, label, false, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectedGame.Enabled)
|
||||
{
|
||||
label = label.WrapUOHtmlBig();
|
||||
|
||||
AddHtmlButton(
|
||||
x + ((w - 126) / 2),
|
||||
y,
|
||||
126,
|
||||
25,
|
||||
b => DisableGame(SelectedGame),
|
||||
label,
|
||||
Color.PaleGreen,
|
||||
Color.Black);
|
||||
}
|
||||
else
|
||||
{
|
||||
label = label.WrapUOHtmlBig();
|
||||
|
||||
AddHtmlButton(x + ((w - 126) / 2), y, 126, 25, b => EnableGame(SelectedGame), label, Color.Gray, Color.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDescription(IGame game)
|
||||
{
|
||||
if (game == null)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
var desc = new StringBuilder();
|
||||
|
||||
desc.Append("<CENTER>");
|
||||
desc.AppendLine(game.Name.WrapUOHtmlBig().WrapUOHtmlColor(Color.Gold, false));
|
||||
desc.AppendLine(String.Empty.WrapUOHtmlColor(Color.White, false));
|
||||
desc.AppendLine(game.Desc);
|
||||
desc.Append("</CENTER>");
|
||||
|
||||
return desc.ToString();
|
||||
}
|
||||
|
||||
public void EnableGame(IGame game)
|
||||
{
|
||||
if (game == null)
|
||||
{
|
||||
Refresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
game.Enabled = true;
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public void DisableGame(IGame game)
|
||||
{
|
||||
if (game == null)
|
||||
{
|
||||
Refresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
game.Enabled = false;
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public void PlayGame(IGame game)
|
||||
{
|
||||
if (game == null || !game.Open(User))
|
||||
{
|
||||
Refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectGame(IGame game)
|
||||
{
|
||||
SelectedGame = SelectedGame == game ? null : game;
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public void SelectHelp(IGame game)
|
||||
{
|
||||
if (game == null)
|
||||
{
|
||||
Refresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
new NoticeDialogGump(User, Refresh())
|
||||
{
|
||||
Title = game.Name,
|
||||
Html = game.Help,
|
||||
Width = 500,
|
||||
Height = 400,
|
||||
HtmlColor = Color.White,
|
||||
AcceptHandler = Refresh,
|
||||
CancelHandler = Refresh
|
||||
}.Send();
|
||||
}
|
||||
|
||||
protected override void OnLayoutApplied()
|
||||
{
|
||||
base.OnLayoutApplied();
|
||||
|
||||
if (!SupportsUltimaStore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in Entries.OfType<GumpBackground>())
|
||||
{
|
||||
switch (e.GumpID)
|
||||
{
|
||||
case 2600:
|
||||
e.GumpID = 39925;
|
||||
break;
|
||||
case 9250:
|
||||
e.GumpID = 40000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user