Can I simply have the .cs file in my mod's "script" folder ("blackhorsecourier/scripts") or do I need to adher to the folder structure of DFU (like "blackhorsecourier/scripts/game/questing/actions")?
Checking for specific date
- Hazelnut
- Posts: 3016
- Joined: Sat Aug 26, 2017 2:46 pm
- Contact:
Re: Checking for specific date
You can have it wherever you like since you register it with DFU it doesn't need to go looking.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods
- haloterm
- Posts: 391
- Joined: Sat Feb 16, 2019 5:21 am
Re: Checking for specific date
Hm... I am not sure how to do that correctly.
I have the following content of my action (posting it here, so maybe someone who knows what he's doing can tell me if that's basically correct; it should simply allow "yearly from day.month. to day.month." such as "yearly from 28.8. to 31.8."):
Code: Select all
// custom quest action for Black Horse Courier
//
// this creates a new quest action which checks if we are in a given range of days
//
// _Example_ task:
// when yearly from 15.1. to 4.5.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using DaggerfallWorkshop.Utility;
using FullSerializer;
namespace DaggerfallWorkshop.Game.Questing
{
/// <summary>
/// Raise or lower task state based on month
/// Date must be in day1.month1. to day2.month2. (like "1.8. to 15.8." for August 8th to 15th)
/// </summary>
public class YearlyFrom : ActionTemplate
{
int day1;
int day2;
int month1;
int month2;
public override string Pattern
{
get { return @"yearly from (?<day1>\d+).(?<month1>\d+). to (?<day2>\d+).(?<month2>\d+)."; }
}
public YearlyFrom(Quest parentQuest)
: base(parentQuest)
{
IsTriggerCondition = true;
IsAlwaysOnTriggerCondition = true;
}
public override IQuestAction CreateNew(string source, Quest parentQuest)
{
// Source must match pattern
Match match = Test(source);
if (!match.Success)
return null;
// Factory new action
YearlyFrom action = new YearlyFrom(parentQuest);
action.day1 = Parser.ParseInt(match.Groups["day1"].Value);
action.day2 = Parser.ParseInt(match.Groups["day2"].Value);
action.month1 = Parser.ParseInt(match.Groups["month1"].Value);
action.month2 = Parser.ParseInt(match.Groups["month2"].Value);
return action;
}
public override bool CheckTrigger(Task caller)
{
// Get live world time (day 1 to 30, month 1 to 12)
DaggerfallDateTime worldTime = DaggerfallUnity.Instance.WorldTime.Now;
int currentDay = worldTime.day;
int currentMonth = worldTime.month;
// Check if inside range
if ((currentDay >= day1 && currentDay <= day2) && (currentMonth >= month1 && currentMonth <= month2))
return true;
else
return false;
}
#region Serialization
[fsObject("v1")]
public struct SaveData_v1
{
public int day1;
public int day2;
public int month1;
public int month2;
}
public override object GetSaveData()
{
SaveData_v1 data = new SaveData_v1();
data.day1 = day1;
data.day2 = day2;
data.month1 = month1;
data.month2 = month2;
return data;
}
public override void RestoreSaveData(object dataIn)
{
if (dataIn == null)
return;
SaveData_v1 data = (SaveData_v1)dataIn;
day1 = data.day1;
day2 = data.day2;
month1 = data.month1;
month2 = data.month2;
}
#endregion
}
}
Code: Select all
// Black Horse Courier
using System;
using System.Collections.Generic;
using UnityEngine;
using DaggerfallConnect;
using DaggerfallConnect.Arena2;
using DaggerfallConnect.FallExe;
using DaggerfallWorkshop;
using DaggerfallWorkshop.Game;
using DaggerfallWorkshop.Game.Banking;
using DaggerfallWorkshop.Game.Guilds;
using DaggerfallWorkshop.Game.Questing;
using DaggerfallWorkshop.Game.Entity;
using DaggerfallWorkshop.Game.Formulas;
using DaggerfallWorkshop.Game.Items;
using DaggerfallWorkshop.Game.MagicAndEffects;
using DaggerfallWorkshop.Game.UserInterface;
using DaggerfallWorkshop.Game.UserInterfaceWindows;
using DaggerfallWorkshop.Game.Utility.ModSupport;
using DaggerfallWorkshop.Game.Utility.ModSupport.ModSettings;
using DaggerfallWorkshop.Utility;
namespace BlackHorseCourier
{
public class BlackHorseCourier : MonoBehaviour
{
protected static string[] placesTable =
{
"TuluneCity, 0x435d, 1, -1",
"CredenceHall, 0xc544, 1, -1",
"Camelford, 0xc545, 1, -1",
"Elizay, 0xc546, 1, -1",
"OldLysoldasFarm, 0x3FA7, 1, -1",
"PilgrimKynareth, 0x2E9E, 1, -1",
"PilgrimMara, 0x38F2, 1, -1",
"PilgrimDibella, 0x4FF4, 1, -1",
"PilgrimAkatosh, 0x57B7, 1, -1",
"PilgrimZenithar, 0x6582, 1, -1",
"PilgrimArkay, 0x6681, 1, -1",
"PilgrimStendarr, 0x67AF, 1, -1",
"PilgrimJulianos, 0x72DC, 1, -1",
};
static Mod mod;
[Invoke(StateManager.StateTypes.Start, 0)]
public static void Init(InitParams initParams)
{
mod = initParams.Mod;
var go = new GameObject(mod.Title);
go.AddComponent<BlackHorseCourier>();
}
public static void InitMod()
{
Debug.Log("Begin mod init: BlackHorseCourier");
Debug.Log("Registering quest list BlackHorseCourier");
if (!QuestListsManager.RegisterQuestList("BlackHorseCourier"))
throw new Exception("Quest list name is already in use, unable to register BlackHorseCourier quest list.");
// Add additional data into the quest machine for the quests
Debug.Log("Adding new BlackHorseCourier locations into quest places table");
QuestMachine questMachine = GameManager.Instance.QuestMachine;
questMachine.PlacesTable.AddIntoTable(placesTable);
Debug.Log("Finished mod init: BlackHorseCourier");
}
void Awake()
{
//var settings = mod.GetSettings();
// ---
InitMod();
mod.IsReady = true;
}
}
}
I would write
// Register new quest action DaysInYear
questMachine.RegisterAction( SOMETHING )
but what should that "SOMETHING" be?
It seems RegisterAction requires a parameter of the type "IQuestAction", but I have no idea how to relate that to my custom action.
Sorry for these dumb questions, but I am no programmer, I can just programming in non-object oriented FreePascal, and I just want to write a simple quest that checks for a given month period -.- So I really have no idea what I am doing here. More help (or simply the required code lines) would be appreciated.
- TheLacus
- Posts: 1305
- Joined: Wed Sep 14, 2016 6:22 pm
Re: Checking for specific date
Hi, this is how to register a new action:
While not strictly required, I'd also suggest to put all your mod code inside namespace BlackHorseCourier, inlcuding custom action.
Code: Select all
questMachine.RegisterAction(new YearlyFrom(null));
- haloterm
- Posts: 391
- Joined: Sat Feb 16, 2019 5:21 am
Re: Checking for specific date
Oh. That is easy Thank you.TheLacus wrote: ↑Wed Feb 17, 2021 3:21 pm Hi, this is how to register a new action:
While not strictly required, I'd also suggest to put all your mod code inside namespace BlackHorseCourier, inlcuding custom action.Code: Select all
questMachine.RegisterAction(new YearlyFrom(null));
I will also follow your namespace suggestion.
- haloterm
- Posts: 391
- Joined: Sat Feb 16, 2019 5:21 am
Re: Checking for specific date
Hmm.... after correcting a few typos (day instead of Day, month instead of Month) the scripts compile fine (checked in Unity editor with "precompile" option in mod builder).
However, it does not seem to have an effect while ingame. In the player.log I get
Unknown line signature encounted 'yearly from 1.1. to 30.12.'.
so it apparently does not recognize my action as valid.
(I use it in a test quest at the same place where usually one could use the "daily" action instead).
So either my action did not register successfully, or my pattern matching is wrong:
However, it does not seem to have an effect while ingame. In the player.log I get
Unknown line signature encounted 'yearly from 1.1. to 30.12.'.
so it apparently does not recognize my action as valid.
(I use it in a test quest at the same place where usually one could use the "daily" action instead).
So either my action did not register successfully, or my pattern matching is wrong:
Code: Select all
public override string Pattern
{
get { return @"yearly from (?<day1>\d+).(?<month1>\d+). to (?<day2>\d+).(?<month2>\d+)."; }
}
- Hazelnut
- Posts: 3016
- Joined: Sat Aug 26, 2017 2:46 pm
- Contact:
Re: Checking for specific date
Dots are a special regex char that mean match any character, so they will need backspaces I think. It might be easier to use dashes as date component separators.
for example:
should match "yearly from 1-1 to 30-12"
for example:
Code: Select all
public override string Pattern
{
get { return @"yearly from (?<day1>\d+)-(?<month1>\d+) to (?<day2>\d+)-(?<month2>\d+)"; }
}
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods