internal static int?PlaceBounty(Player player, Random rand = null)
        {
            // Only place bounties on PvP players
            if (player.GameMode != (int)GameModeStatics.GameModes.PvP)
            {
                return(null);
            }

            var numMappings = MAPPINGS.Count();

            if (numMappings == 0)
            {
                return(null);
            }

            rand = rand ?? new Random();
            var effect = MAPPINGS[rand.Next(numMappings)];

            if (EffectProcedures.PlayerHasEffect(player, effect.EffectSourceId))
            {
                return(null);
            }

            var possibleForms = JokeShopProcedures.Forms(e => e.Category == effect.Category).Select(e => e.FormSourceId).ToArray();
            var numForms      = possibleForms.Count();

            if (numForms == 0)
            {
                return(null);
            }

            EffectProcedures.GivePerkToPlayer(effect.EffectSourceId, player.Id, TURNS_OF_BOUNTY, TURNS_OF_BOUNTY + TURNS_OF_IMMUNITY);

            return(effect.EffectSourceId);
        }
        internal static BountyInfo BountyDetails(Player player, int effectId)
        {
            var effect = MAPPINGS.FirstOrDefault(e => e.EffectSourceId == effectId);

            if (effect == null || !EffectProcedures.PlayerHasEffect(player, effect.EffectSourceId))
            {
                return(null);
            }

            var possibleFormSourceIds = JokeShopProcedures.Forms(e => e.Category == effect.Category).Select(e => e.FormSourceId).ToArray();
            var numFormSourceIds      = possibleFormSourceIds.Count();

            if (numFormSourceIds == 0)
            {
                return(null);
            }

            var playerEffect = EffectProcedures.GetPlayerEffects2(player.Id).FirstOrDefault(e => e.dbEffect.EffectSourceId == effect.EffectSourceId);

            if (playerEffect == null || playerEffect.dbEffect.Duration == 0)
            {
                return(null);
            }

            var duration = playerEffect.dbEffect.Duration;

            if (duration <= 0)
            {
                return(null);
            }

            var turn = PvPStatics.LastGameTurn;

            if (turn == 0)
            {
                // Check server hasn't been restarted mid-game (in which case PvPStatics.LastGameTurn is not accurate)
                var worldStats = DomainRegistry.Repository.FindSingle(new GetWorld());
                turn = worldStats.TurnNumber;
            }

            var expiresTurn  = turn + duration;
            var formIndex    = player.Id + expiresTurn;
            var formSourceId = possibleFormSourceIds[formIndex % possibleFormSourceIds.Count()];

            // Locate the desired form
            IDbStaticFormRepository formsRepo = new EFDbStaticFormRepository();
            var form = formsRepo.DbStaticForms.FirstOrDefault(f => f.Id == formSourceId);

            if (form == null)
            {
                return(null);
            }

            // Calculate the reward that could be claimed right now
            var reward = Math.Min(MAXIMUM_REWARD, BASE_REWARD + (MAXIMUM_REWARD - BASE_REWARD) * duration / TURNS_OF_BOUNTY);

            if (form.MobilityType == PvPStatics.MobilityFull)
            {
                reward /= 2;
            }

            var category = MAPPINGS.Where(m => m.EffectSourceId == effect.EffectSourceId).Select(m => m.Category).FirstOrDefault();

            return(new BountyInfo {
                PlayerName = player.GetFullName(), Form = form, ExpiresTurn = expiresTurn, CurrentReward = reward, Category = category
            });
        }