Oggi mi sono svegliato annoiato quindi ho deciso di creare un piccolo evento Vero o Falso completamente automatico per Opennos.
Avviso:
Per questo evento è stata usata la versione di base di Opennos.
Non darò alcun supporto sulla seguente release se non ciò che segue nel seguente post ^^
Guida:
Iniziamo con la creazione di una tabella che andrà a contenere le nostre domande:
Avviso:
Per questo evento è stata usata la versione di base di Opennos.
Non darò alcun supporto sulla seguente release se non ciò che segue nel seguente post ^^
Guida:
Iniziamo con la creazione di una tabella che andrà a contenere le nostre domande:
OpenNos.DAL.EF
TrueOrFalse.cs
TrueOrFalse.cs
C#:
public sealed class TrueOrFalse
{
public long QuestionId { get; set; }
public string Question { get; set; }
public bool Answer { get; set; }
}
OpenNos.Data
TrueOrFalseDTO.cs
C#:
[Serializable]
public class TrueOrFalseDTO
{
public long QuestionId { get; set; }
public string Question { get; set; }
public bool Result { get; set; }
}
OpenNos.DAL.Interface
ITrueOrFalseDAO.cs
C#:
public interface ITrueOrFalseDAO
{
List<TrueOrFalseDTO> LoadAll();
TrueOrFalseDTO LoadById(long questionId);
TrueOrFalseDTO Insert(TrueOrFalseDTO question);
}
OpenNos.Mapper
TrueOrFalseMapper.cs
TrueOrFalseMapper.cs
C#:
public class TrueOrFalseMapper
{
public static bool ToTrueOrFalse(TrueOrFalseDTO input, TrueOrFalse output)
{
if (input == null) return false;
output.QuestionId = input.QuestionId;
output.Question = input.Question;
output.Result = input.Result;
return true;
}
public static bool ToTrueOrFalseDTO(TrueOrFalse input, TrueOrFalseDTO output)
{
if (input == null) return false;
output.QuestionId = input.QuestionId;
output.Question = input.Question;
output.Result = input.Result;
return true;
}
}
OpenNos.DAL.EF
Aggiunger il DbSet di TrueOrFalse a OpenNos.Context
Aggiunger il DbSet di TrueOrFalse a OpenNos.Context
C#:
public virtual DbSet<TrueOrFalse> TrueOrFalse { get; set; }
OpenNos.DAL
Aggiungere a DAOFactory
Aggiungere a DAOFactory
C#:
private static ITrueOrFalseDAO _trueOrFalseDAO;
public static ITrueOrFalseDAO TrueOrFalseDAO => _trueOrFalseDAO ?? (_trueOrFalseDAO = new TrueOrFalseDAO());
OpenNos.DAL.DAO
TrueOrFalseDAO.cs
C#:
public class TrueOrFalseDAO : ITrueOrFalseDAO
{
public TrueOrFalseDTO Insert(TrueOrFalseDTO question)
{
try
{
using (OpenNosContext context = DataAccessHelper.CreateContext())
{
TrueOrFalse entity = new TrueOrFalse();
Mapper.Mappers.TrueOrFalseMapper.ToTrueOrFalse(question, entity);
context.TrueOrFalse.Add(entity);
context.SaveChanges();
if (Mapper.Mappers.TrueOrFalseMapper.ToTrueOrFalseDTO(entity, question))
{
return question;
}
return null;
}
}
catch (Exception e)
{
Logger.Error(e);
return null;
}
}
public List<TrueOrFalseDTO> LoadAll()
{
try
{
using (OpenNosContext context = DataAccessHelper.CreateContext())
{
List<TrueOrFalseDTO> result = new List<TrueOrFalseDTO>();
foreach(var question in context.TrueOrFalse.AsNoTracking())
{
TrueOrFalseDTO dTO = new TrueOrFalseDTO();
Mapper.Mappers.TrueOrFalseMapper.ToTrueOrFalseDTO(question, dTO);
result.Add(dTO);
}
return result;
}
}
catch (Exception e)
{
Logger.Error(e);
return null;
}
}
public TrueOrFalseDTO LoadById(long questionId)
{
try
{
using (OpenNosContext context = DataAccessHelper.CreateContext())
{
TrueOrFalseDTO dTO = new TrueOrFalseDTO();
Mapper.Mappers.TrueOrFalseMapper.ToTrueOrFalseDTO(context.TrueOrFalse.AsNoYtacking().FirstOrDefault(q => q.QuestionId = questionId), dTO);
return dTO;
}
}
catch (Exception e)
{
Logger.Error(e);
return null;
}
}
}
Ovviamente, tabella e funzioni sono totalmente personalizzabili.
Per una mia comodità, ho preferito usare solo 3 funzioni essenziali per lo svolgersi dell'evento...
Insert: per inserire nuove domande direttamente dal gioco
LoadAll: per caricare tutte le domande ad inizio evento
LoadById: Per modifica, selezionare o eliminare la domanda selezionata
Per una mia comodità, ho preferito usare solo 3 funzioni essenziali per lo svolgersi dell'evento...
Insert: per inserire nuove domande direttamente dal gioco
LoadAll: per caricare tutte le domande ad inizio evento
LoadById: Per modifica, selezionare o eliminare la domanda selezionata
Iniziamo ora con la creazione dell'evento:
OpenNos.GameObject.Event.TrueOrFalse (creare una nuova cartella)
TrueOrFalseGame.cs
(Il seguente codice non è stato testato per mancanza di tempo e voglia... In caso di crash o bug vi chiedo di pubblicare qui uno screenshot dell'errore o di contattarmi su discord)
TrueOrFalseGame.cs
(Il seguente codice non è stato testato per mancanza di tempo e voglia... In caso di crash o bug vi chiedo di pubblicare qui uno screenshot dell'errore o di contattarmi su discord)
C#:
public static class TrueFalse
{
private static List<TrueOrFalseDTO> TrueOrFalseQuestion = new List<TrueOrFalseDTO>();
private static long[] QuestionAlreadyDone { get; set; }
public static void GenerateTrueFalse()
{
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 1 minute!", 0));
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 1 minute!", 1));
Observable.Timer(TimeSpan.FromSeconds(30)).Subscribe(observer =>
{
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 30 seconds!", 0));
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 30 seconds!", 1));
});
Observable.Timer(TimeSpan.FromSeconds(50)).Subscribe(observer =>
{
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 10 seconds!", 0));
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event will start in 10 seconds!", 1));
});
Observable.Timer(TimeSpan.FromSeconds(60)).Subscribe(observer =>
{
ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg("The True or False event start!", 1));
ServerManager.Instance.Broadcast(
$"qnaml 1 #guri^506 Want to partecipate on True or False event?");
ServerManager.Instance.EventInWaiting = true;
});
Observable.Timer(TimeSpan.FromSeconds(65)).Subscribe(observer =>
{
ServerManager.Instance.Broadcast(
UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("TRUE_FALSE_STARTED"), 1));
ServerManager.Instance.Sessions.Where(s => s.Character?.IsWaitingForEvent == false).ToList()
.ForEach(s => s.SendPacket("esf"));
ServerManager.Instance.EventInWaiting = false;
IEnumerable<ClientSession> sessions = ServerManager.Instance.Sessions.Where(s =>
s.Character?.IsWaitingForEvent == true &&
s.Character.MapInstance.MapInstanceType == MapInstanceType.BaseMapInstance);
MapInstance map = ServerManager.GenerateMapInstance(0, MapInstanceType.EventGameInstance, new InstanceBag());
foreach (ClientSession s in sessions)
{
if (map != null)
{
ServerManager.Instance.TeleportOnRandomPlaceInMap(s, map.MapInstanceId);
}
}
ServerManager.Instance.Sessions.Where(s => s.Character != null).ToList().ForEach(s => s.Character.IsWaitingForEvent = false);
ServerManager.Instance.StartedEvents.Remove(EventType.TRUEORFALSE);
TrueFalseTask task = new TrueFalseTask();
Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe(X => TrueFalseTask.Run(map));
});
}
public class TrueFalseTask
{
public static void Run(MapInstance mapinstance)
{
if (!mapinstance.Sessions.Any())
{
mapinstance.Dispose();
}
Observable.Timer(TimeSpan.FromMinutes(15)).Subscribe(X => mapinstance.Dispose());
TrueOrFalseQuestion = DAOFactory.TrueOrFalseDAO.LoadAll();
int id = mapinstance.GetNextNpcId();
#region Npc Spawn
MapNpc start = new MapNpc
{
NpcVNum = 922,
MapNpcId = id,
MapX = 24,
MapY = 23,
IsHostile = false,
IsMoving = false
};
MapNpc falses = new MapNpc
{
NpcVNum = 922,
MapNpcId = id + 1,
MapX = 14,
MapY = 23,
IsHostile = false,
IsMoving = false
};
MapNpc trues = new MapNpc
{
NpcVNum = 922,
MapNpcId = id + 2,
MapX = 34,
MapY = 23,
IsHostile = false,
IsMoving = false
};
Observable.Timer(TimeSpan.FromMilliseconds(10)).Subscribe(observer =>
{
start.Initialize(mapinstance);
mapinstance.AddNpc(start);
mapinstance.Broadcast(start.GenerateIn());
});
Observable.Timer(TimeSpan.FromMilliseconds(15)).Subscribe(observer =>
{
trues.Initialize(mapinstance);
mapinstance.AddNpc(trues);
mapinstance.Broadcast(trues.GenerateIn());
});
Observable.Timer(TimeSpan.FromMilliseconds(20)).Subscribe(observer =>
{
falses.Initialize(mapinstance);
mapinstance.AddNpc(falses);
mapinstance.Broadcast(falses.GenerateIn());
});
Observable.Timer(TimeSpan.FromMilliseconds(40)).Subscribe(observer =>
{
mapinstance.Broadcast($"shop 2 {start.MapNpcId} 6000 0 0 START");
mapinstance.Broadcast($"shop 2 {trues.MapNpcId} 6001 0 0 TRUE");
mapinstance.Broadcast($"shop 2 {falses.MapNpcId} 6002 0 0 FALSE");
});
#endregion
foreach (ClientSession cli in mapinstance.Sessions.Where(s => s.Character != null))
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("20 seconds for the event start!", 0));
Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe(observer =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("10 seconds for the event start!", 0));
});
Observable.Timer(TimeSpan.FromSeconds(20)).Subscribe(observer =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("Event start! Good Luck!", 0));
});
Observable.Timer(TimeSpan.FromSeconds(25)).Subscribe(observer => { Round(1); });
void Round(int number)
{
int rnd = ServerManager.RandomNumber(0, TrueOrFalseQuestion.Count);
var question = TrueOrFalseQuestion[rnd];
while (QuestionAlreadyDone.Contains(question.QuestionId))
{
question = TrueOrFalseQuestion[ServerManager.RandomNumber(0, TrueOrFalseQuestion.Count)];
}
QuestionAlreadyDone.Append(question.QuestionId);
cli.SendPacket(UserInterfaceHelper.GenerateMsg($"Question n°{number}:", 0));
Observable.Timer(TimeSpan.FromSeconds(3)).Subscribe(o =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg(question.Question, 0));
Observable.Timer(TimeSpan.FromSeconds(5)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("5", 0));
});
Observable.Timer(TimeSpan.FromSeconds(6)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("4", 0));
});
Observable.Timer(TimeSpan.FromSeconds(7)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("3", 0));
});
Observable.Timer(TimeSpan.FromSeconds(8)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("2", 0));
});
Observable.Timer(TimeSpan.FromSeconds(9)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("1", 0));
});
Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe(q =>
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("Result!", 0));
});
Observable.Timer(TimeSpan.FromSeconds(12)).Subscribe(q =>
{
if (question.Result)
{
var characterOut = mapinstance.GetCharactersInRange(34, 23, 4);
foreach (Character c in mapinstance.Characters.Where(ch => !characterOut.Contains(ch)))
{
ServerManager.Instance.ChangeMap(c.CharacterId, c.MapId, c.MapX, c.MapY);
c.Session.SendPacket(UserInterfaceHelper.GenerateSay("No... Was false :(", 0));
}
mapinstance.Broadcast(UserInterfaceHelper.GenerateMsg("Yeah! was true!", 0));
}
else
{
var characterOut = mapinstance.GetCharactersInRange(14, 23, 4);
foreach (Character c in mapinstance.Characters.Where(ch => !characterOut.Contains(ch)))
{
ServerManager.Instance.ChangeMap(c.CharacterId, c.MapId, c.MapX, c.MapY);
c.Session.SendPacket(UserInterfaceHelper.GenerateSay("No... Was false :(", 0));
}
mapinstance.Broadcast(UserInterfaceHelper.GenerateMsg("Yeah! was false!", 0));
}
});
Observable.Timer(TimeSpan.FromSeconds(14)).Subscribe(q =>
{
if (mapinstance.Characters.Any())
{
if (number < 10)
{
number++;
cli.SendPacket(UserInterfaceHelper.GenerateMsg("The next round will start in a few seconds!", 0));
Observable.Timer(TimeSpan.FromSeconds(5)).Subscribe(observer => Round(number));
}
else
{
cli.SendPacket(UserInterfaceHelper.GenerateMsg("You won!", 0));
cli.Character.SetReputation(cli.Character.Level * 150);
cli.Character.SpAdditionPoint += cli.Character.Level * 1000;
cli.Character.SpAdditionPoint = cli.Character.SpAdditionPoint > 1000000 ? 1000000 : cli.Character.SpAdditionPoint;
cli.Character.GenerateFamilyXp(200);
cli.SendPacket(cli.Character.GenerateSpPoint());
cli.SendPacket(cli.Character.GenerateGold());
cli.SendPacket(cli.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("WIN_REPUT"), cli.Character.Level * 150), 10));
cli.SendPacket(cli.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("WIN_SP_POINT"), cli.Character.Level * 1000), 10));
cli.SendPacket(cli.Character.GenerateSay(string.Format("You win {0} family xp!", 200), 10));
ServerManager.Instance.ChangeMap(cli.CharacterId, cli.MapId, cli.MapX, cli.MapY);
}
}
else
{
mapinstance.Dispose();
}
});
});
}
}
}
}
}
Come anticipato, l'evento l'ho scritto per pura noia quindi ci saranno MOLTI punti che potranno essere migliorati con un occhio in più ma dovrebbe comunque funzionare a dovere ^^
Spero che questo piccolo evento possa tornare utile a molti di voi ^^
Vi sarei inoltre grato se pubblicaste le migliorie portate al codice così da aiutare la community ^^
Nei prossimi giorni io stesso vedrò di rileggere e riscrivere parte dell'evento così da renderlo migliore
Buona fortuna a tutti!
PS:
Nel caso vogliate supportarmi :3