Refactor majority of CTF code, and probably break it in the process.

This commit is contained in:
UnknownShadow200 2017-06-29 22:20:43 +10:00
parent 7c4d6f0394
commit e27c8ec482
8 changed files with 564 additions and 678 deletions

View File

@ -29,10 +29,11 @@ namespace MCGalaxy {
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic;
public static ConfigElement[] GetAll(params Type[] types) {
public static ConfigElement[] GetAll(Type type) {
List<ConfigElement> elems = new List<ConfigElement>();
foreach (Type type in types) {
FieldInfo[] fields = type.GetFields(flags);
for (int i = 0; i < fields.Length; i++) {
FieldInfo field = fields[i];
Attribute[] attributes = Attribute.GetCustomAttributes(field, typeof(ConfigAttribute));
@ -43,7 +44,6 @@ namespace MCGalaxy {
elem.Attrib = (ConfigAttribute)attributes[0];
elems.Add(elem);
}
}
return elems.ToArray();
}

View File

@ -31,6 +31,7 @@ namespace MCGalaxy.Config {
if (color == "") {
color = Colors.Name(value);
if (color != "") return value;
Logger.Log(LogType.Warning, "Config key \"{0}\" is not a valid color, using default of {1}", Name, DefaultValue);
return DefaultValue;
}

View File

@ -18,68 +18,76 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.SQL;
using MCGalaxy.Config;
namespace MCGalaxy.Games {
public sealed partial class CTFGame {
void LineProcessor(string key, string value) {
switch (key.ToLower()) {
case "base.red.x":
redbase.x = ushort.Parse(value); break;
case "base.red.y":
redbase.y = ushort.Parse(value); break;
case "game.maxpoints":
maxpoints = int.Parse(value); break;
case "game.tag.points-gain":
tagpoint = int.Parse(value); break;
case "game.tag.points-lose":
taglose = int.Parse(value); break;
case "game.capture.points-gain":
cappoint = int.Parse(value); break;
case "game.capture.points-lose":
caplose = int.Parse(value); break;
case "auto.setup":
needSetup = bool.Parse(value); break;
case "base.red.z":
redbase.z = ushort.Parse(value); break;
case "base.red.block":
redbase.block = ExtBlock.FromRaw(byte.Parse(value)); break;
case "base.blue.block":
bluebase.block = ExtBlock.FromRaw(byte.Parse(value)); break;
case "base.blue.spawnx":
bluebase.spawnx = ushort.Parse(value); break;
case "base.blue.spawny":
bluebase.spawny = ushort.Parse(value); break;
case "base.blue.spawnz":
bluebase.spawnz = ushort.Parse(value); break;
case "base.red.spawnx":
redbase.spawnx = ushort.Parse(value); break;
case "base.red.spawny":
redbase.spawny = ushort.Parse(value); break;
case "base.red.spawnz":
redbase.spawnz = ushort.Parse(value); break;
case "base.blue.x":
bluebase.x = ushort.Parse(value); break;
case "base.blue.y":
bluebase.y = ushort.Parse(value); break;
case "base.blue.z":
bluebase.z = ushort.Parse(value); break;
case "map.line.z":
zline = ushort.Parse(value); break;
}
}
public sealed class CTFConfig {
bool LoadConfig() {
//Load some configs
if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");
if (!File.Exists("CTF/maps.config")) return false;
[ConfigInt("base.red.x", null, 0)]
public int RedFlagX;
[ConfigInt("base.red.y", null, 0)]
public int RedFlagY;
[ConfigInt("base.red.z", null, 0)]
public int RedFlagZ;
[ConfigByte("base.red.block", null, 0)]
public byte RedFlagBlock;
string[] lines = File.ReadAllLines("CTF/maps.config");
maps = new List<string>(lines);
return maps.Count > 0;
[ConfigInt("base.blue.x", null, 0)]
public int BlueFlagX;
[ConfigInt("base.blue.y", null, 0)]
public int BlueFlagY;
[ConfigInt("base.blue.z", null, 0)]
public int BlueFlagZ;
[ConfigByte("base.blue.block", null, 0)]
public byte BlueFlagBlock;
[ConfigInt("base.red.spawnx", null, 0)]
public int RedSpawnX;
[ConfigInt("base.red.spawny", null, 0)]
public int RedSpawnY;
[ConfigInt("base.red.spawnz", null, 0)]
public int RedSpawnZ;
[ConfigInt("base.blue.spawnx", null, 0)]
public int BlueSpawnX;
[ConfigInt("base.blue.spawny", null, 0)]
public int BlueSpawnY;
[ConfigInt("base.blue.spawnz", null, 0)]
public int BlueSpawnZ;
[ConfigInt("map.line.z", null, 0)]
public int ZDivider;
[ConfigInt("game.maxpoints", null, 0)]
public int MaxPoints;
[ConfigInt("game.tag.points-gain", null, 0)]
public int Tag_PointsGained;
[ConfigInt("game.tag.points-lose", null, 0)]
public int Tag_PointsLost;
[ConfigInt("game.capture.points-gain", null, 0)]
public int Capture_PointsGained;
[ConfigInt("game.capture.points-lose", null, 0)]
public int Capture_PointsLost;
public void SetDefaults(Level map) {
ZDivider = map.Length / 2;
RedFlagBlock = Block.red;
BlueFlagBlock = Block.blue;
int midX = map.Width / 2, maxZ = map.Length - 1;
RedFlagX = midX; RedSpawnX = midX * 32;
RedFlagY = 6; RedSpawnY = 4 * 32 + Entities.CharacterHeight;
RedFlagZ = 0; RedSpawnZ = 0 * 32;
BlueFlagX = midX; BlueSpawnX = midX * 32;
BlueFlagY = 6; BlueSpawnY = 4 * 32 + Entities.CharacterHeight;
BlueFlagZ = maxZ; BlueSpawnZ = maxZ * 32;
MaxPoints = 3;
Tag_PointsGained = 5;
Tag_PointsLost = 5;
Capture_PointsGained = 10;
Capture_PointsLost = 10;
}
}
}

View File

@ -1,75 +0,0 @@
/*
Copyright 2011 MCForge
Written by fenderrock87
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.Config;
namespace MCGalaxy.Games {
public sealed class CTFConfig {
[ConfigInt("base.red.x", null, 0)]
public int RedFlagX;
[ConfigInt("base.red.y", null, 0)]
public int RedFlagY;
[ConfigInt("base.red.z", null, 0)]
public int RedFlagZ;
[ConfigByte("base.red.block", null, 0)]
public byte RedFlagBlock;
[ConfigInt("base.blue.x", null, 0)]
public int BlueFlagX;
[ConfigInt("base.blue.y", null, 0)]
public int BlueFlagY;
[ConfigInt("base.blue.z", null, 0)]
public int BlueFlagZ;
[ConfigByte("base.blue.block", null, 0)]
public byte BlueFlagBlock;
[ConfigInt("base.red.spawnx", null, 0)]
public int RedSpawnX;
[ConfigInt("base.red.spawny", null, 0)]
public int RedSpawnY;
[ConfigInt("base.red.spawnz", null, 0)]
public int RedSpawnZ;
[ConfigInt("base.blue.spawnx", null, 0)]
public int BlueSpawnX;
[ConfigInt("base.blue.spawny", null, 0)]
public int BlueSpawnY;
[ConfigInt("base.blue.spawnz", null, 0)]
public int BlueSpawnZ;
[ConfigBool("auto.setup", null, false)]
public bool NeedSetup;
[ConfigInt("map.line.z", null, 0)]
public int ZLine;
[ConfigInt("game.maxpoints", null, 0)]
public int MaxPoints;
[ConfigInt("game.tag.points-gain", null, 0)]
public int Tag_PointsGained;
[ConfigInt("game.tag.points-lose", null, 0)]
public int Tag_PointsLost;
[ConfigInt("game.capture.points-gain", null, 0)]
public int Capture_PointsGained;
[ConfigInt("game.capture.points-lose", null, 0)]
public int Capture_PointsLost;
}
}

View File

@ -23,69 +23,16 @@ using System.IO;
using System.Threading;
using MCGalaxy.Commands.World;
using MCGalaxy.Events;
using MCGalaxy.Maths;
using MCGalaxy.SQL;
namespace MCGalaxy.Games {
/// <summary> This is the team class for CTF </summary>
public sealed class Teams {
public string color;
public int points = 0;
public List<Player> members;
/// <summary> Create a new Team Object </summary>
public Teams(string color) {
color = Colors.Parse(color);
members = new List<Player>();
}
/// <summary> Add a player to the team </summary>
public void Add(Player p) {
members.Add(p);
}
/// <summary> Checks to see if the player is on this team </summary>
public bool Has(Player p) {
return members.IndexOf(p) != -1;
}
}
internal sealed class Data {
public Player p;
public int cap, tag, points;
public int cap, Tags, points;
public bool hasflag, tagging, chatting;
public bool blue;
public Data(bool team, Player p) {
blue = team; this.p = p;
}
}
internal sealed class Base {
public ushort x, y, z;
public ushort spawnx, spawny, spawnz;
public ExtBlock block;
public void SendToSpawn(Level mainlevel, CTFGame game, Player p1) {
Position pos = new Position(spawnx, spawny, spawny);
if (spawnx == 0 && spawny == 0 && spawnz == 0) {
Random rand = new Random();
ushort xx, yy, zz;
do {
xx = (ushort)(rand.Next(0, mainlevel.Width));
yy = (ushort)(rand.Next(0, mainlevel.Height));
zz = (ushort)(rand.Next(0, mainlevel.Length));
} while (!mainlevel.IsAirAt(xx, yy, zz) && game.OnSide(zz, this));
pos.X = xx * 32; pos.Y = yy * 32; pos.Z = zz * 32;
}
p1.SendPos(Entities.SelfID, pos, p1.Rot);
}
public Base(ushort x, ushort y, ushort z, Teams team) {
this.x = x; this.y = y; this.z = z;
}
public Base() { }
public Data(Player p) { this.p = p; }
}
public sealed partial class CTFGame {
@ -97,42 +44,21 @@ namespace MCGalaxy.Games {
string map1 = "";
string map2 = "";
string map3 = "";
public int xline;
public bool started = false;
public int zline;
public int yline;
int tagpoint = 5;
int cappoint = 10;
int taglose = 5;
int caplose = 10;
bool needSetup = false;
public int maxpoints = 3;
Teams redteam;
Teams blueteam;
Base bluebase;
Base redbase;
Level mainlevel;
CtfTeam2 red;
CtfTeam2 blue;
Level map;
List<string> maps = new List<string>();
List<Data> cache = new List<Data>();
string mapname = "";
/// <summary> Load a map into CTF </summary>
/// <param name="map">The map to load</param>
public void LoadMap(string map) {
mapname = map;
PropertiesFile.Read("CTF/" + mapname + ".config", LineProcessor);
Command.all.Find("unload").Use(null, "ctf");
if (File.Exists("levels/ctf.lvl"))
File.Delete("levels/ctf.lvl");
File.Copy("CTF/maps/" + mapname + ".lvl", "levels/ctf.lvl");
CmdLoad.LoadLevel(null, "ctf");
mainlevel = LevelInfo.FindExact("ctf");
}
public CTFConfig Config = new CTFConfig();
ConfigElement[] ctfConfigElems;
/// <summary> Create a new CTF object </summary>
public CTFGame() {
redbase = new Base();
bluebase = new Base();
red = new CtfTeam2("Red", Colors.red);
blue = new CtfTeam2("Blue", Colors.blue);
tagging.Elapsed += CheckTagging;
tagging.Start();
@ -144,7 +70,7 @@ namespace MCGalaxy.Games {
tagging.Stop();
tagging.Dispose();
mainlevel = null;
map = null;
started = false;
if (LevelInfo.FindExact("ctf") != null)
Command.all.Find("unload").Use(null, "ctf");
@ -159,66 +85,93 @@ namespace MCGalaxy.Games {
Level.LevelUnload += HandleLevelUnload;
}
/// <summary> Load a map into CTF </summary>
public void LoadMap(string mapName) {
Command.all.Find("unload").Use(null, "ctf");
if (File.Exists("levels/ctf.lvl"))
File.Delete("levels/ctf.lvl");
File.Copy("CTF/maps/" + mapName + ".lvl", "levels/ctf.lvl");
CmdLoad.LoadLevel(null, "ctf");
map = LevelInfo.FindExact("ctf");
LoadMapConfig();
}
void LoadMapConfig() {
if (ctfConfigElems == null)
ctfConfigElems = ConfigElement.GetAll(typeof(CTFConfig));
Config.SetDefaults(map);
PropertiesFile.Read("CTF/" + map.name + ".config", LineProcessor);
CTFConfig cfg = Config;
red.FlagBlock = ExtBlock.FromRaw(cfg.RedFlagBlock);
red.FlagPos = new Vec3U16((ushort)cfg.RedFlagX, (ushort)cfg.RedFlagY, (ushort)cfg.RedFlagZ);
red.SpawnPos = new Position(cfg.RedSpawnX, cfg.RedSpawnY, cfg.RedSpawnZ);
blue.FlagBlock = ExtBlock.FromRaw(cfg.BlueFlagBlock);
blue.FlagPos = new Vec3U16((ushort)cfg.BlueFlagX, (ushort)cfg.BlueFlagY, (ushort)cfg.BlueFlagZ);
blue.SpawnPos = new Position(cfg.BlueSpawnX, cfg.BlueSpawnY, cfg.BlueSpawnZ);
}
void LineProcessor(string key, string value) {
if (!ConfigElement.Parse(ctfConfigElems, key, value, Config)) {
Logger.Log(LogType.Warning, "\"{0}\" was not a recognised CTF config key.", key);
}
}
bool LoadConfig() {
//Load some configs
if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");
if (!File.Exists("CTF/maps.config")) return false;
string[] lines = File.ReadAllLines("CTF/maps.config");
maps = new List<string>(lines);
return maps.Count > 0;
}
void CheckTagging(object sender, System.Timers.ElapsedEventArgs e) {
Player[] online = PlayerInfo.Online.Items;
foreach (Player p in online) {
if (p.level != mainlevel) continue;
if (p.level != map) continue;
Base b = null;
if (redteam.members.Contains(p)) {
b = redbase;
} else if (blueteam.members.Contains(p)) {
b = bluebase;
} else {
continue;
}
if (GetPlayer(p).tagging) continue;
if (!OnSide(p.Pos.BlockZ, b)) continue;
List<Player> opponents = redteam.members;
if (redteam.members.Contains(p))
opponents = blueteam.members;
CtfTeam2 team = TeamOf(p);
if (team == null || DataOf(p).tagging) continue;
if (!OnOwnTeamSide(p.Pos.BlockZ, team)) continue;
CtfTeam2 opposing = Opposing(team);
Player[] opponents = opposing.Members.Items;
foreach (Player other in opponents) {
if (!MovementCheck.InRange(p, other, 5 * 32)) continue;
if (!MovementCheck.InRange(p, other, 2 * 32)) continue;
GetPlayer(other).tagging = true;
DataOf(other).tagging = true;
Player.Message(other, p.ColoredName + " %Stagged you!");
b.SendToSpawn(mainlevel, this, other);
team.SendToSpawn(other);
Thread.Sleep(300);
if (GetPlayer(other).hasflag) {
Chat.MessageLevel(mainlevel, redteam.color + p.name + " DROPPED THE FLAG!");
GetPlayer(other).points -= caplose;
mainlevel.Blockchange(b.x, b.y, b.z, b.block);
GetPlayer(other).hasflag = false;
}
GetPlayer(p).points += tagpoint;
GetPlayer(other).points -= taglose;
GetPlayer(p).tag++;
GetPlayer(other).tagging = false;
if (DataOf(other).hasflag) DropFlag(p, opposing);
DataOf(p).points += Config.Tag_PointsGained;
DataOf(other).points -= Config.Tag_PointsLost;
DataOf(p).Tags++;
DataOf(other).tagging = false;
}
}
}
void HandlePlayerDisconnect(Player p, string reason) {
if (p.level != mainlevel) return;
if (p.level != map) return;
CtfTeam2 team = TeamOf(p);
if (team == null) return;
if (blueteam.members.Contains(p)) {
//cache.Remove(GetPlayer(p));
blueteam.members.Remove(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + blueteam.color + "left the ctf game");
} else if (redteam.members.Contains(p)) {
//cache.Remove(GetPlayer(p));
redteam.members.Remove(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + redteam.color + "left the ctf game");
}
DropFlag(p, team);
team.Remove(p);
Chat.MessageLevel(map, team.Color + p.DisplayName + " %Sleft the ctf game");
}
void HandleLevelUnload(Level l) {
if (started && l == mainlevel) {
if (started && l == map) {
Logger.Log(LogType.GameActivity, "Unload Failed!, A ctf game is currently going on!");
Plugin.CancelLevelEvent(LevelEvents.LevelUnload, l);
}
@ -246,47 +199,23 @@ namespace MCGalaxy.Games {
Player.Message(p, "No CTF maps were found."); return false;
}
blueteam = new Teams("blue");
redteam = new Teams("red");
blue = new CtfTeam2("blue", Colors.blue);
red = new CtfTeam2("red", Colors.red);
LoadMap(maps[new Random().Next(maps.Count)]);
if (needSetup) AutoSetup();
redbase.block = (ExtBlock)Block.red;
bluebase.block = (ExtBlock)Block.blue;
Logger.Log(LogType.GameActivity, "[Auto_CTF] Running...");
Logger.Log(LogType.GameActivity, "[CTF] Running...");
started = true;
Database.Backend.CreateTable("CTF", createSyntax);
return true;
}
void AutoSetup() {
for (ushort y = 0; y < mainlevel.Height; y++)
for (ushort z = 0; z < mainlevel.Length; z++)
for (ushort x = 0; x < mainlevel.Width; x++)
{
byte block = mainlevel.GetTile(x, y, z);
if (block == Block.red) {
redbase.x = x; redbase.y = y; redbase.z = z;
} else if (block == Block.blue || block == Block.cyan) {
bluebase.x = x; bluebase.y = y; bluebase.z = z;
}
}
zline = mainlevel.Length / 2;
}
internal void SpawnPlayer(Player p) {
if (p.level != mainlevel) return;
if (GetPlayer(p).blue) {
bluebase.SendToSpawn(mainlevel, this, p);
} else {
redbase.SendToSpawn(mainlevel, this, p);
}
if (p.level != map) return;
CtfTeam2 team = TeamOf(p);
if (team != null) team.SendToSpawn(p);
}
string Vote()
{
string Vote() {
started = false;
vote1 = 0;
vote2 = 0;
@ -298,147 +227,131 @@ namespace MCGalaxy.Games {
map2 = maps1[rand.Next(maps1.Count)];
maps1.Remove(map2);
map3 = maps1[rand.Next(maps1.Count)];
Chat.MessageLevel(mainlevel, "%2VOTE:");
Chat.MessageLevel(mainlevel, "1. " + map1 + " 2. " + map2 + " 3. " + map3);
Chat.MessageLevel(map, "%2VOTE:");
Chat.MessageLevel(map, "1. " + map1 + " 2. " + map2 + " 3. " + map3);
voting = true;
int seconds = rand.Next(15, 61);
Chat.MessageLevel(mainlevel, "You have " + seconds + " seconds to vote!");
Chat.MessageLevel(map, "You have " + seconds + " seconds to vote!");
Thread.Sleep(seconds * 1000);
voting = false;
Chat.MessageLevel(mainlevel, "VOTING ENDED!");
Chat.MessageLevel(map, "VOTING ENDED!");
Thread.Sleep(rand.Next(1, 10) * 1000);
if (vote1 > vote2 && vote1 > vote3)
{
Chat.MessageLevel(mainlevel, map1 + " WON!");
Chat.MessageLevel(map, map1 + " WON!");
return map1;
}
if (vote2 > vote1 && vote2 > vote3)
{
Chat.MessageLevel(mainlevel, map2 + " WON!");
Chat.MessageLevel(map, map2 + " WON!");
return map2;
}
if (vote3 > vote2 && vote3 > vote1)
{
Chat.MessageLevel(mainlevel, map3 + " WON!");
Chat.MessageLevel(map, map3 + " WON!");
return map3;
}
else
{
Chat.MessageLevel(mainlevel, "There was a tie!");
Chat.MessageLevel(mainlevel, "I'll choose!");
Chat.MessageLevel(map, "There was a tie!");
Chat.MessageLevel(map, "I'll choose!");
return maps[rand.Next(maps.Count)];
}
}
void End()
{
void End() {
started = false;
string nextmap = "";
string winner = "";
Teams winnerteam = null;
if (blueteam.points >= maxpoints || blueteam.points > redteam.points)
{
winnerteam = blueteam;
winner = "blue team";
if (blue.Points >= Config.MaxPoints || blue.Points > red.Points) {
Chat.MessageLevel(map, blue.ColoredName + " %Swon this round of CTF!");
} else if (red.Points >= Config.MaxPoints || red.Points > blue.Points) {
Chat.MessageLevel(map, red.ColoredName + " %Swon this round of CTF!");
} else {
Chat.MessageLevel(map, "The round ended in a tie!");
}
else if (redteam.points >= maxpoints || redteam.points > blueteam.points)
{
winnerteam = redteam;
winner = "red team";
}
else
{
Chat.MessageLevel(mainlevel, "The game ended in a tie!");
}
Chat.MessageLevel(mainlevel, "The winner was " + winnerteam.color + winner + "!!");
Thread.Sleep(4000);
//MYSQL!
cache.ForEach(delegate(Data d) {
d.hasflag = false;
Database.Backend.UpdateRows("CTF", "Points=@1, Captures=@2, tags=@3",
"WHERE Name = @0", d.p.name, d.points, d.cap, d.tag);
"WHERE Name = @0", d.p.name, d.points, d.cap, d.Tags);
});
nextmap = Vote();
Chat.MessageLevel(mainlevel, "Starting a new game!");
redbase = null;
redteam = null;
bluebase = null;
blueteam = null;
bluebase = new Base();
redbase = new Base();
Chat.MessageLevel(map, "Starting a new game!");
blue.Members.Clear();
red.Members.Clear();
Thread.Sleep(2000);
LoadMap(nextmap);
}
void HandlePlayerBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block) {
if (!started || p.level != mainlevel) return;
if (!blueteam.members.Contains(p) && !redteam.members.Contains(p)) {
if (!started || p.level != map) return;
CtfTeam2 team = TeamOf(p);
if (team == null) {
p.RevertBlock(x, y, z);
Player.Message(p, "You are not on a team!");
Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
}
if (blueteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && !mainlevel.IsAirAt(x, y, z)) {
Chat.MessageLevel(mainlevel, blueteam.color + p.name + " took the " + redteam.color + " red team's FLAG!");
GetPlayer(p).hasflag = true;
Vec3U16 pos = new Vec3U16(x, y, z);
if (pos == Opposing(team).FlagPos && !map.IsAirAt(x, y, z)) TakeFlag(p, team);
if (pos == team.FlagPos && !map.IsAirAt(x, y, z)) ReturnFlag(p, team);
}
if (redteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && !mainlevel.IsAirAt(x, y, z)) {
Chat.MessageLevel(mainlevel, redteam.color + p.name + " took the " + blueteam.color + " blue team's FLAG");
GetPlayer(p).hasflag = true;
void TakeFlag(Player p, CtfTeam2 team) {
CtfTeam2 opposing = Opposing(team);
Chat.MessageLevel(map, team.Color + p.DisplayName + " took the " + blue.ColoredName + " %Steam's FLAG");
DataOf(p).hasflag = true;
}
if (blueteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && !mainlevel.IsAirAt(x, y, z)) {
if (GetPlayer(p).hasflag) {
Chat.MessageLevel(mainlevel, blueteam.color + p.name + " RETURNED THE FLAG!");
GetPlayer(p).hasflag = false;
GetPlayer(p).cap++;
GetPlayer(p).points += cappoint;
blueteam.points++;
mainlevel.Blockchange(redbase.x, redbase.y, redbase.z, (ExtBlock)Block.red);
p.RevertBlock(x, y, z);
void ReturnFlag(Player p, CtfTeam2 team) {
Vec3U16 flagPos = team.FlagPos;
p.RevertBlock(flagPos.X, flagPos.Y, flagPos.Z);
Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
if (blueteam.points >= maxpoints) { End(); return; }
} else {
Player.Message(p, "You cant take your own flag!");
p.RevertBlock(x, y, z);
Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
}
}
if (redteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && !mainlevel.IsAirAt(x, y, z)) {
if (GetPlayer(p).hasflag) {
Chat.MessageLevel(mainlevel, redteam.color + p.name + " RETURNED THE FLAG!");
GetPlayer(p).hasflag = false;
GetPlayer(p).points += cappoint;
GetPlayer(p).cap++;
redteam.points++;
if (DataOf(p).hasflag) {
Chat.MessageLevel(map, team.Color + p.DisplayName + " RETURNED THE FLAG!");
DataOf(p).hasflag = false;
DataOf(p).points += Config.Capture_PointsGained;
DataOf(p).cap++;
mainlevel.Blockchange(bluebase.x, bluebase.y, bluebase.z, (ExtBlock)Block.blue);
p.RevertBlock(x, y, z);
Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
if (redteam.points >= maxpoints) { End(); return; }
CtfTeam2 opposing = Opposing(team);
team.Points++;
flagPos = opposing.FlagPos;
map.Blockchange(flagPos.X, flagPos.Y, flagPos.Z, opposing.FlagBlock);
if (team.Points >= Config.MaxPoints) { End(); return; }
} else {
Player.Message(p, "You cannot take your own flag!");
p.RevertBlock(x, y, z);
Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
}
}
}
internal Data GetPlayer(Player p) {
void DropFlag(Player p, CtfTeam2 team) {
if (!DataOf(p).hasflag) return;
DataOf(p).hasflag = false;
Chat.MessageLevel(map, team.Color + p.DisplayName + " DROPPED THE FLAG!");
DataOf(p).points -= Config.Capture_PointsLost;
CtfTeam2 opposing = Opposing(team);
Vec3U16 pos = opposing.FlagPos;
map.Blockchange(pos.X, pos.Y, pos.Z, opposing.FlagBlock);
}
internal Data DataOf(Player p) {
foreach (Data d in cache) {
if (d.p == p) return d;
}
return null;
}
void HandlePlayerCommand(string cmd, Player p, string message) {
if (!started) return;
if (cmd == "teamchat" && p.level == mainlevel) {
if (GetPlayer(p) != null) {
Data d = GetPlayer(p);
if (cmd == "teamchat" && p.level == map) {
if (DataOf(p) != null) {
Data d = DataOf(p);
if (d.chatting) {
Player.Message(d.p, "You are no longer chatting with your team!");
d.chatting = !d.chatting;
@ -451,53 +364,36 @@ namespace MCGalaxy.Games {
}
if (cmd != "goto") return;
if (message == "ctf" && p.level != mainlevel) {
if (blueteam.members.Count > redteam.members.Count) {
JoinRedTeam(p);
} else if (redteam.members.Count > blueteam.members.Count) {
JoinBlueTeam(p);
if (message == "ctf" && p.level != map) {
if (blue.Members.Count > red.Members.Count) {
JoinTeam(p, red);
} else if (red.Members.Count > blue.Members.Count) {
JoinTeam(p, blue);
} else if (new Random().Next(2) == 0) {
JoinRedTeam(p);
JoinTeam(p, red);
} else {
JoinBlueTeam(p);
}
} else if (message != "ctf" && p.level == mainlevel) {
if (blueteam.members.Contains(p)) {
//cache.Remove(GetPlayer(p));
blueteam.members.Remove(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + blueteam.color + "left the ctf game");
} else if (redteam.members.Contains(p)) {
//cache.Remove(GetPlayer(p));
redteam.members.Remove(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + redteam.color + "left the ctf game");
JoinTeam(p, blue);
}
} else if (message != "ctf" && p.level == map) {
CtfTeam2 team = TeamOf(p);
if (team == null) return;
DropFlag(p, team);
team.Remove(p);
Chat.MessageLevel(map, team.Color + p.DisplayName + " %Sleft the ctf game");
}
}
void JoinBlueTeam(Player p) {
if (GetPlayer(p) == null) {
cache.Add(new Data(true, p));
void JoinTeam(Player p, CtfTeam2 team) {
if (DataOf(p) == null) {
cache.Add(new Data(p));
} else {
GetPlayer(p).hasflag = false;
GetPlayer(p).blue = true;
DataOf(p).hasflag = false;
}
blueteam.Add(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + Colors.blue + "joined the BLUE Team");
Player.Message(p, Colors.blue + "You are now on the blue team!");
}
void JoinRedTeam(Player p) {
if (GetPlayer(p) == null) {
cache.Add(new Data(false, p));
} else {
GetPlayer(p).hasflag = false;
GetPlayer(p).blue = false;
}
redteam.Add(p);
Chat.MessageLevel(mainlevel, p.ColoredName + " " + Colors.red + "joined the RED Team");
Player.Message(p, Colors.red + "You are now on the red team!");
team.Members.Add(p);
Chat.MessageLevel(map, p.ColoredName + " joined the " + team.ColoredName + " %Steam");
Player.Message(p, team.Color + "You are now on the " + team.Name + " team!");
}
void HandlePlayerChat(Player p, string message) {
@ -521,46 +417,42 @@ namespace MCGalaxy.Games {
}
}
if (!started || p.level != mainlevel) return;
if (!GetPlayer(p).chatting) return;
if (!started || p.level != map) return;
if (!DataOf(p).chatting) return;
if (blueteam.members.Contains(p)) {
Player[] online = PlayerInfo.Online.Items;
foreach (Player p1 in online) {
if (blueteam.members.Contains(p1))
Player.Message(p1, "(Blue) " + p.ColoredName + ":&f " + message);
CtfTeam2 team = TeamOf(p);
if (team == null) return;
Player[] members = team.Members.Items;
foreach (Player pl in members) {
Player.Message(pl, "({0}) {1}: &f{2}", team.Name, p.ColoredName, message);
}
Plugin.CancelPlayerEvent(PlayerEvents.PlayerChat, p);
} else if (redteam.members.Contains(p)) {
Player[] online = PlayerInfo.Online.Items;
foreach (Player p1 in online) {
if (redteam.members.Contains(p1))
Player.Message(p1, "(Red) " + p.ColoredName + ":&f " + message);
}
Plugin.CancelPlayerEvent(PlayerEvents.PlayerChat, p);
}
}
void HandlePlayerDeath(Player p, ExtBlock deathblock) {
if (!started || p.level != mainlevel) return;
if (!GetPlayer(p).hasflag) return;
if (!started || p.level != map) return;
if (!DataOf(p).hasflag) return;
if (redteam.members.Contains(p)) {
Chat.MessageLevel(mainlevel, redteam.color + p.name + " DROPPED THE FLAG!");
GetPlayer(p).points -= caplose;
mainlevel.Blockchange(redbase.x, redbase.y, redbase.z, (ExtBlock)Block.red);
} else if (blueteam.members.Contains(p)) {
Chat.MessageLevel(mainlevel, blueteam.color + p.name + " DROPPED THE FLAG!");
GetPlayer(p).points -= caplose;
mainlevel.Blockchange(bluebase.x, bluebase.y, bluebase.z, (ExtBlock)Block.blue);
}
GetPlayer(p).hasflag = false;
CtfTeam2 team = TeamOf(p);
if (team != null) DropFlag(p, team);
}
internal bool OnSide(int z, Base b) {
if (b.z < zline && z < zline) return true;
if (b.z > zline && z > zline) return true;
bool OnOwnTeamSide(int z, CtfTeam2 team) {
int baseZ = team.FlagPos.Z, zline = Config.ZDivider;
if (baseZ < zline && z < zline) return true;
if (baseZ > zline && z > zline) return true;
return false;
}
CtfTeam2 TeamOf(Player p) {
if (red.Members.Contains(p)) return red;
if (blue.Members.Contains(p)) return blue;
return null;
}
CtfTeam2 Opposing(CtfTeam2 team) {
return team == red ? blue : red;
}
}
}

View File

@ -1,4 +1,4 @@
/*
/*
Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and
@ -16,174 +16,45 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
namespace MCGalaxy.Games
{
public sealed class CtfTeam
{
public char color;
public int points = 0;
public ushort[] flagBase = new ushort[3];
public ushort[] flagLocation = new ushort[3];
public List<Spawn> spawns = new List<Spawn>();
public List<Player> players = new List<Player>();
public Level mapOn;
public bool flagishome;
public bool spawnset;
public bool flagmoved;
public string teamstring = "";
public Player holdingFlag = null;
public CatchPos tempFlagblock;
public CatchPos tfb;
public int ftcount = 0;
using MCGalaxy.Maths;
public void AddMember(Player p)
{
if (p.Game.team != this)
{
if (p.Game.team != null) { p.Game.team.RemoveMember(p); }
p.Game.team = this;
Entities.GlobalDespawn(p, false);
//p.CTFtempcolor = p.color;
//p.CTFtempprefix = p.prefix;
p.color = "&" + color;
//p.carryingFlag = false;
p.Game.hasflag = null;
p.prefix = p.color + "[" + Colors.Name("&" + color).ToUpper() + "] ";
players.Add(p);
mapOn.ChatLevel(p.ColoredName + " %Shas joined the " + teamstring + ".");
Entities.GlobalSpawn(p, false);
namespace MCGalaxy.Games {
/// <summary> Represents a team in Capture the Flag. </summary>
public sealed class CtfTeam2 {
/// <summary> The name of this team. </summary>
public string Name;
/// <summary> The color code of this team. </summary>
public string Color;
public string ColoredName { get { return Color + Name; } }
/// <summary> Total points this team has collected. </summary>
public int Points;
/// <summary> Players on this team. </summary>
public VolatileArray<Player> Members = new VolatileArray<Player>(false);
/// <summary> Position in the world the flag is located at. </summary>
public Vec3U16 FlagPos;
/// <summary> Position in the world members of this team spawn at. </summary>
public Position SpawnPos;
/// <summary> Block type of this team's flag. </summary>
public ExtBlock FlagBlock;
public CtfTeam2(string name, string color) { Name = name; Color = color; }
/// <summary> Removes a player from this team. </summary>
public bool Remove(Player p) { return Members.Remove(p); }
public void SendToSpawn(Player p) {
p.SendPos(Entities.SelfID, SpawnPos, p.Rot);
}
}
public void RemoveMember(Player p)
{
if (p.Game.team == this)
{
p.Game.team = null;
Entities.GlobalDespawn(p, false);
//p.color = p.CTFtempcolor;
//p.prefix = p.CTFtempprefix;
//p.carryingFlag = false;
p.Game.hasflag = null;
players.Remove(p);
mapOn.ChatLevel(p.ColoredName + " %Shas left the " + teamstring + ".");
Entities.GlobalSpawn(p, false);
}
}
public void SpawnPlayer(Player p)
{
Position pos = default(Position);
byte yaw = 0, pitch = 0;
if (spawns.Count != 0) {
Random random = new Random();
int rnd = random.Next(0, spawns.Count);
pos.X = 16 + spawns[rnd].x * 32;
pos.Y = 32 + spawns[rnd].y * 32;
pos.Z = 16 + spawns[rnd].z * 32;
yaw = (byte)spawns[rnd].rotx;
//p.health = 100;
} else {
pos = mapOn.SpawnPos;
yaw = mapOn.rotx; pitch = mapOn.roty;
}
Entities.Spawn(p, p, pos, new Orientation(yaw, pitch));
}
public void AddSpawn(ushort x, ushort y, ushort z, ushort rotx, ushort roty)
{
Spawn workSpawn = new Spawn();
workSpawn.x = x;
workSpawn.y = y;
workSpawn.z = z;
workSpawn.rotx = rotx;
workSpawn.roty = roty;
spawns.Add(workSpawn);
}
public void Drawflag()
{
ushort x = flagLocation[0];
ushort y = flagLocation[1];
ushort z = flagLocation[2];
if (mapOn.IsAirAt(x, (ushort)(y - 1), z)) {
flagLocation[1] = (ushort)(flagLocation[1] - 1);
}
mapOn.Blockchange(tfb.x, tfb.y, tfb.z, tfb.type);
mapOn.Blockchange(tfb.x, (ushort)(tfb.y + 1), tfb.z, ExtBlock.Air);
mapOn.Blockchange(tfb.x, (ushort)(tfb.y + 2), tfb.z, ExtBlock.Air);
if (holdingFlag == null)
{
//DRAW ON GROUND SHIT HERE
tfb.type = mapOn.GetBlock(x, y, z);
if (mapOn.GetBlock(x, y, z) != (ExtBlock)Block.flagbase) {
mapOn.Blockchange(x, y, z, (ExtBlock)Block.flagbase);
}
if (mapOn.GetBlock(x, (ushort)(y + 1), z) != (ExtBlock)Block.mushroom) {
mapOn.Blockchange(x, (ushort)(y + 1), z, (ExtBlock)Block.mushroom);
}
if (mapOn.GetBlock(x, (ushort)(y + 2), z) != (ExtBlock)GetColorBlock(color)) {
mapOn.Blockchange(x, (ushort)(y + 2), z, (ExtBlock)GetColorBlock(color));
}
tfb.x = x;
tfb.y = y;
tfb.z = z;
}
else
{
//DRAW ON PLAYER HEAD
x = (ushort)(holdingFlag.Pos.BlockX);
y = (ushort)(holdingFlag.Pos.BlockY + 3);
z = (ushort)(holdingFlag.Pos.BlockZ);
if (tempFlagblock.x == x && tempFlagblock.y == y && tempFlagblock.z == z) { return; }
mapOn.Blockchange(tempFlagblock.x, tempFlagblock.y, tempFlagblock.z, tempFlagblock.type);
tempFlagblock.type = mapOn.GetBlock(x, y, z);
mapOn.Blockchange(x, y, z, (ExtBlock)GetColorBlock(color));
tempFlagblock.x = x;
tempFlagblock.y = y;
tempFlagblock.z = z;
}
}
public static byte GetColorBlock(char color)
{
if (color == '2')
return Block.green;
if (color == '5')
return Block.purple;
if (color == '8')
return Block.darkgrey;
if (color == '9')
return Block.blue;
if (color == 'c')
return Block.red;
if (color == 'e')
return Block.yellow;
if (color == 'f')
return Block.white;
else
return Block.air;
}
public struct CatchPos { public ushort x, y, z; public ExtBlock type; }
public struct Spawn { public ushort x, y, z, rotx, roty; }
}
}

View File

@ -0,0 +1,189 @@
/*
Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
namespace MCGalaxy.Games
{
public sealed class CtfTeam
{
public char color;
public int points = 0;
public ushort[] flagBase = new ushort[3];
public ushort[] flagLocation = new ushort[3];
public List<Spawn> spawns = new List<Spawn>();
public List<Player> players = new List<Player>();
public Level mapOn;
public bool flagishome;
public bool spawnset;
public bool flagmoved;
public string teamstring = "";
public Player holdingFlag = null;
public CatchPos tempFlagblock;
public CatchPos tfb;
public int ftcount = 0;
public void AddMember(Player p)
{
if (p.Game.team != this)
{
if (p.Game.team != null) { p.Game.team.RemoveMember(p); }
p.Game.team = this;
Entities.GlobalDespawn(p, false);
//p.CTFtempcolor = p.color;
//p.CTFtempprefix = p.prefix;
p.color = "&" + color;
//p.carryingFlag = false;
p.Game.hasflag = null;
p.prefix = p.color + "[" + Colors.Name("&" + color).ToUpper() + "] ";
players.Add(p);
mapOn.ChatLevel(p.ColoredName + " %Shas joined the " + teamstring + ".");
Entities.GlobalSpawn(p, false);
}
}
public void RemoveMember(Player p)
{
if (p.Game.team == this)
{
p.Game.team = null;
Entities.GlobalDespawn(p, false);
//p.color = p.CTFtempcolor;
//p.prefix = p.CTFtempprefix;
//p.carryingFlag = false;
p.Game.hasflag = null;
players.Remove(p);
mapOn.ChatLevel(p.ColoredName + " %Shas left the " + teamstring + ".");
Entities.GlobalSpawn(p, false);
}
}
public void SpawnPlayer(Player p)
{
Position pos = default(Position);
byte yaw = 0, pitch = 0;
if (spawns.Count != 0) {
Random random = new Random();
int rnd = random.Next(0, spawns.Count);
pos.X = 16 + spawns[rnd].x * 32;
pos.Y = 32 + spawns[rnd].y * 32;
pos.Z = 16 + spawns[rnd].z * 32;
yaw = (byte)spawns[rnd].rotx;
//p.health = 100;
} else {
pos = mapOn.SpawnPos;
yaw = mapOn.rotx; pitch = mapOn.roty;
}
Entities.Spawn(p, p, pos, new Orientation(yaw, pitch));
}
public void AddSpawn(ushort x, ushort y, ushort z, ushort rotx, ushort roty)
{
Spawn workSpawn = new Spawn();
workSpawn.x = x;
workSpawn.y = y;
workSpawn.z = z;
workSpawn.rotx = rotx;
workSpawn.roty = roty;
spawns.Add(workSpawn);
}
public void Drawflag()
{
ushort x = flagLocation[0];
ushort y = flagLocation[1];
ushort z = flagLocation[2];
if (mapOn.IsAirAt(x, (ushort)(y - 1), z)) {
flagLocation[1] = (ushort)(flagLocation[1] - 1);
}
mapOn.Blockchange(tfb.x, tfb.y, tfb.z, tfb.type);
mapOn.Blockchange(tfb.x, (ushort)(tfb.y + 1), tfb.z, ExtBlock.Air);
mapOn.Blockchange(tfb.x, (ushort)(tfb.y + 2), tfb.z, ExtBlock.Air);
if (holdingFlag == null)
{
//DRAW ON GROUND SHIT HERE
tfb.type = mapOn.GetBlock(x, y, z);
if (mapOn.GetBlock(x, y, z) != (ExtBlock)Block.flagbase) {
mapOn.Blockchange(x, y, z, (ExtBlock)Block.flagbase);
}
if (mapOn.GetBlock(x, (ushort)(y + 1), z) != (ExtBlock)Block.mushroom) {
mapOn.Blockchange(x, (ushort)(y + 1), z, (ExtBlock)Block.mushroom);
}
if (mapOn.GetBlock(x, (ushort)(y + 2), z) != (ExtBlock)GetColorBlock(color)) {
mapOn.Blockchange(x, (ushort)(y + 2), z, (ExtBlock)GetColorBlock(color));
}
tfb.x = x;
tfb.y = y;
tfb.z = z;
}
else
{
//DRAW ON PLAYER HEAD
x = (ushort)(holdingFlag.Pos.BlockX);
y = (ushort)(holdingFlag.Pos.BlockY + 3);
z = (ushort)(holdingFlag.Pos.BlockZ);
if (tempFlagblock.x == x && tempFlagblock.y == y && tempFlagblock.z == z) { return; }
mapOn.Blockchange(tempFlagblock.x, tempFlagblock.y, tempFlagblock.z, tempFlagblock.type);
tempFlagblock.type = mapOn.GetBlock(x, y, z);
mapOn.Blockchange(x, y, z, (ExtBlock)GetColorBlock(color));
tempFlagblock.x = x;
tempFlagblock.y = y;
tempFlagblock.z = z;
}
}
public static byte GetColorBlock(char color)
{
if (color == '2')
return Block.green;
if (color == '5')
return Block.purple;
if (color == '8')
return Block.darkgrey;
if (color == '9')
return Block.blue;
if (color == 'c')
return Block.red;
if (color == 'e')
return Block.yellow;
if (color == 'f')
return Block.white;
else
return Block.air;
}
public struct CatchPos { public ushort x, y, z; public ExtBlock type; }
public struct Spawn { public ushort x, y, z, rotx, roty; }
}
}

View File

@ -486,8 +486,8 @@
<Compile Include="Games\Countdown\CountdownMapGen.cs" />
<Compile Include="Games\Countdown\CountdownPlugin.cs" />
<Compile Include="Games\CTF\CtfConfig.cs" />
<Compile Include="Games\CTF\CtfConfig2.cs" />
<Compile Include="Games\CTF\CtfTeam.cs" />
<Compile Include="Games\CTF\CtfTeamOld.cs" />
<Compile Include="Games\GameProps.cs" />
<Compile Include="Games\IGame.cs" />
<Compile Include="Games\LavaSurvival\LavaSurvival.Game.cs" />