Commit 02be7978 authored by Chris Chua's avatar Chris Chua
Browse files

Merge branch 'dev-chris3' into 'main'

Two players cannot repeat meeting more often than once every 180 s

See merge request redpointgames/a-momentary-meeting!35
parents ba930694 dde51524
......@@ -17,6 +17,8 @@ namespace MomentaryMeeting.Game
public class InteractionManager : IEndMeetings
private const string _entryText = "A stranger appears in front of you.{1} You feel as though you could {b}say{/b} something to them.";
// Two players cannot meet more than once within this interval
private const int _reMeetingLockoutInterval = 180;
private readonly IDatabaseApi _databaseApi;
private readonly Database _database;
......@@ -25,6 +27,9 @@ namespace MomentaryMeeting.Game
private readonly IDistributedCache _distributedCache;
private List<Meeting> _meetings;
private GameInstance _gameInstance;
// key is player discord ID, value is a dictionary whose key is another
// other player's discord ID and value is the UNIX timestamp when they were last together
private Dictionary<ulong, Dictionary<ulong, long>> _lastMetRecord;
public InteractionManager(IDatabaseApi databaseApi, ILogger<InteractionManager> logger, ArrangementGenerator arrangementGenerator, IDistributedCache distributedCache)
......@@ -34,6 +39,42 @@ namespace MomentaryMeeting.Game
_arrangementGenerator = arrangementGenerator;
_distributedCache = distributedCache;
_meetings = new List<Meeting>();
_lastMetRecord = new Dictionary<ulong, Dictionary<ulong, long>>();
public static long Now()
return new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
// This should be called when a meeting occurs, to record when a player
// last met another player
private void RecordMeetingOccurred(UserModel player, UserModel otherUser)
if (!_lastMetRecord.ContainsKey(player.DiscordId))
_lastMetRecord[player.DiscordId] = new Dictionary<ulong, long>();
_lastMetRecord[player.DiscordId][otherUser.DiscordId] = Now();
// Check whether player and otherUser have met within
// _reMeetingLockoutInterval seconds, returns true if so
private bool LastMeetingTooSoon(UserModel player, UserModel otherUser)
if (!_lastMetRecord.ContainsKey(player.DiscordId))
// Wow, this player has met no-one ever
return false;
if (!_lastMetRecord[player.DiscordId].ContainsKey(otherUser.DiscordId))
// This player has never met otherUser
return false;
long lastMetSecondsAgo = Now() - _lastMetRecord[player.DiscordId][otherUser.DiscordId];
//_logger.LogInformation($"Players last met {lastMetSecondsAgo} s ago");
return lastMetSecondsAgo < _reMeetingLockoutInterval;
public async Task<string> CheckForInteraction(GameInstance gameInstance, UserModel player)
......@@ -43,14 +84,19 @@ namespace MomentaryMeeting.Game
foreach (UserModel otherUser in gameInstance.GetPlayers())
_logger.LogInformation($"ID: {player.DiscordId} {otherUser.DiscordId} {player.DiscordId != otherUser.DiscordId} object: {player != otherUser}");
// if someone else is in the room, and they are not me and they are not in meeting
if (otherUser.LocationName == player.LocationName && player.DiscordId != otherUser.DiscordId && otherUser.InMeeting == false)
// if someone else is in the room, and they are not me and they are not in meeting and they haven't already met recently
if ((otherUser.LocationName == player.LocationName)
&& (player.DiscordId != otherUser.DiscordId)
&& (otherUser.InMeeting == false)
&& !LastMeetingTooSoon(player, otherUser))
player.InMeeting = true;
otherUser.InMeeting = true;
Meeting meeting = new Meeting(this);
RecordMeetingOccurred(player, otherUser);
RecordMeetingOccurred(otherUser, player);
// let them know someone has entered their room
await _gameInstance.SendPromptToPlayer(otherUser, "<" + _entryText);
......@@ -71,7 +117,7 @@ namespace MomentaryMeeting.Game
player.InMeeting = false;
if (isTornApart)
if (isTornApart)
// send them several rooms away
ArrangementGenerator.Neighbours neighbours;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment