Example #1
0
        /// <summary>
        /// Add a custom topic to the game. Check the other overloads for more info.
        /// Warning: This overload skips most of the parameter checks! It's best to use the other overload instead.
        /// </summary>
        public static IDisposable RegisterTopic(Topic.Param param, GetTopicADVscript getAdvScript, GetTopicADVresult getAdvResult)
        {
            if (StudioAPI.InsideStudio)
            {
                return(Disposable.Empty);
            }

            if (param == null)
            {
                throw new ArgumentNullException(nameof(param));
            }
            if (getAdvScript == null)
            {
                throw new ArgumentNullException(nameof(getAdvScript), "You need to return some sort of ADV script or picking the topic will crash the game. You can return a null if you don't want to show any ADV.");
            }
            if (getAdvResult == null)
            {
                throw new ArgumentNullException(nameof(getAdvResult), "You need to return some sort of ADV result. You can return a null if you don't want to add any stats.");
            }

            if (param.No < 100)
            {
                throw new ArgumentOutOfRangeException(nameof(param), param.No, "No has to be above 100");
            }

            TopicHooks.ApplyHooksIfNeeded();

            _customTopics.Add(param.No, new CustomTopicInfo(param, getAdvScript, getAdvResult));

            // All topics get added by a hook when ActionScene is loaded, need to add manually after that
            if (ActionScene.initialized && ActionScene.instance.topicDic != null)
            {
                ActionScene.instance.topicDic.Add(param.No, param);
            }

            return(Disposable.Create(() =>
            {
                _customTopics.Remove(param.No);
                ActionScene.instance.topicDic.Remove(param.No);
            }));
        }
Example #2
0
 public CustomTopicInfo(Topic.Param param, GetTopicADVscript scriptGetter, GetTopicADVresult resultGetter)
 {
     Param        = param;
     ScriptGetter = scriptGetter;
     ResultGetter = resultGetter;
 }
Example #3
0
        /// <summary>
        /// Add a custom topic to the game.
        /// Custom topics can not be asked about by heroines when using the "listen" option, and selecting a custom topic as an answer will always result in failing the prompt. You can only use custom topics when talking to the heroine (speech bubble icon).
        /// If you want your topic to not be obtainable outside of giving it to the player through code, you need to set rarity to <see cref="TopicRarity.Rarity4"/> or higher (unless the category is <see cref="TopicCategory.Love"/>, then it has to be <see cref="TopicRarity.Rarity5"/>. (??? drop tables would make it safe as long as it's not buyable)
        /// </summary>
        /// <param name="topicNo">Unique ID of the topic.
        /// This ID is used in the save file to keep track of owned and used topics, so it has to always be the same between game starts (i.e. use a hardcoded number and never change it).
        /// Topic IDs below 100 are reserved for the base game. For safety it's best to use IDs above 100000. Be careful to not conflict with other plugins!</param>
        /// <param name="topicName">Name of your topic shown on the lists.</param>
        /// <param name="category">Category of your topic. Changes which icon is shown, how it can be obtained and when it is shown.</param>
        /// <param name="rarity">Rarity of your topic. Changes what color background is used and how it can be obtained.</param>
        /// <param name="getAdvScript">Called when player chooses your topic to talk about. It should return a valid ADV event (remember to add Close at the end!) or null if you don't want to display anything. You can use the ADVEditor plugin to create your own scenes. The base game uses different variations of events based on the personality and sometimes relationship of the character you talk to. You can do the same by checking the personality and isNPC parameters.</param>
        /// <param name="getAdvResult">Called after your ADV event from 'getAdvScript' finishes. You can change basic stats with the return value (they will be animated), or do something else (return null if you don't want to change any basic stats).</param>
        /// <returns>Dispose the return value to remove the topic. Warning: This is intended only for development use! This might not remove the topic immediately or fully, and you might need to go back to title menu and load the game again for the changes to take effect. Disposing won't clear the topic from topic inventory or other similar lists.</returns>
        public static IDisposable RegisterTopic(int topicNo, string topicName, TopicCategory category, TopicRarity rarity, GetTopicADVscript getAdvScript, GetTopicADVresult getAdvResult)
        {
            if (StudioAPI.InsideStudio)
            {
                return(Disposable.Empty);
            }

            if (topicNo < 100)
            {
                throw new ArgumentOutOfRangeException(nameof(topicNo), topicNo, "Topic IDs below 100 are reserved for the base game");
            }
            if (topicName == null)
            {
                throw new ArgumentNullException(nameof(topicName));
            }
            if (!Enum.IsDefined(typeof(TopicCategory), category))
            {
                throw new ArgumentOutOfRangeException(nameof(category), category, "Invalid TopicCategory");
            }
            if (!Enum.IsDefined(typeof(TopicRarity), rarity))
            {
                throw new ArgumentOutOfRangeException(nameof(rarity), rarity, "Invalid TopicRarity");
            }

            // As far as I can see RarityName is unused in the game so it doesn't matter what it's set to
            return(RegisterTopic(
                       new Topic.Param
            {
                No = topicNo, Name = topicName, Category = (int)category, Rarity = (int)rarity, RarityName = "Modded"
            },
                       getAdvScript, getAdvResult));
        }