PDA

View Full Version : rations and waterskins



skj310
April 29th, 2019, 00:49
Hey there all you very intelligent and wonderful extension making people.

I had a thought as I was driving to work this morning and am wondering if anyone has put thought into an extension that has a configurable option menu item that allows a GM, via the calendar dialogue, choose whether or not rations and water is automatically consumed as the GM changes the date?

I hope that's enough information for a quick answer and perhaps a link. If not I've a lot more thoughts on this and am happy to fill this post in with more of those potential extension creation ideas, but before i do that i just wanna reach out and see if anyone has gone down this road already?

JohnD
April 29th, 2019, 01:02
Good idea.

damned
April 29th, 2019, 01:28
that could be done more easily if you had only one type of each...
not standard and iron rations for example.

LordEntrails
April 29th, 2019, 02:09
To answer your question, no, no one has yet gone down that road and their is no such extension that has been posted or talked about.

skj310
April 29th, 2019, 03:17
I hear your point @damned and it's understandable. As always there are caveats when coding and I suspect this would be the case here as well. I of course am only thinking of D&D5e ruleset and their standard name for rations. I suppose this could be better handled if foods had a type associated with them, and therefore the code could be more generic.

My reasoning for this is that no one likes to track inventory and as a GM, I hardly ever remember to make points to the players regarding their rations or water. Its just too much to handle and doesn't add to the immersion.

So why make a point of this now? Because FG can do all the hard work! And if a player receives a popup saying they have only a day of rations left, or their waterskin is empty ... i think this MIGHT add to the immersion. But only if its automated and a player doesn't have to do anything other than react to a warning (i.e. IRL thirst or hunger pangs)

Nowdays I love to use the variant weight rule because FG automates the tracking of weight (note: there is a coin weight extension which also automates the addition of coins and gems into the total weight). The players don't need to do anything other than be aware of what the total is. The result is that now i see a lot more of "I drop my backpack" before engaging in battle, which in turn gives me the opportunity (with intelligent mobs) to try and steal the backpack mid-battle. Which of course means tactics change for me as well as the players. I make this point because i've played with variant encumbrance for last couple yrs in FG, in addition to that coin weight extension and it's worked swimmingly well.

So this morning as I drove to work, the thought of tying rations and water to the changing of dates within a calendar, would be cool. So long as its automated.

In West Marches I don't normally use the calendar as I work with many GMs in Sleeper Island, and that is too complex to track time. But in a regular campaign I think this really could work and add a new dynamic to the texture of the immersion. Would be interesting to see ...

Anyway those are my thoughts :) Cheers!

LordEntrails
April 29th, 2019, 03:38
Or if the party shares rations, you could just put an entry on the calendar with the last day they have rations and water for. "Food runs out today" and then everyone can see it coming and you don't have to track it etc.

grimm182
April 29th, 2019, 04:36
Not that anyone asked me, but I always wanted a new tab on the Party sheet called Shared Resources. Rations & Waterskins is fine but why limit the tracking to just that. :)

Targas
April 29th, 2019, 08:33
One more factor to consider: Usually consumption is tight to a long rest. However, when taking a rest at an inn, rations and waterskin supply shouldn‘t be deducted. And some parties survive by using Goodberries produced by druids..

wrandalljr4
May 2nd, 2019, 06:04
Good Idea Targas, tie it to short and long rest GM button instead of the calendar if that would make it earlier. Although anything can be code if you know what you are doing, which I do not. LoL

DrakePD
May 2nd, 2019, 12:42
I wonder if it would work if you made rations and water into a currency. So instead of GP, you put Rations. The DM could then make a negative parcel -1 Ration and it would deduct? I am away from a FG table or I would try this.

Zacchaeus
May 2nd, 2019, 12:54
I wonder if it would work if you made rations and water into a currency. So instead of GP, you put Rations. The DM could then make a negative parcel -1 Ration and it would deduct? I am away from a FG table or I would try this.

You can do this since you can now specify currencies for your campaign. Staying with the parcel idea if you share the parcel with the players when they drag it onto their inventory it will deduct the rations from that.

paladiusdarkhelm
May 3rd, 2019, 21:14
We set them up as Ammo so they can tick them off on the actions tab. Maybe that is easier to do and automate if necessary?

MarianDz
May 28th, 2019, 20:39
I prepared tutorial how to do them as Ammo if somebody want know how to do it look here (https://www.fantasygrounds.com/forums/entry.php?349-How-to-quot-Tracking-FOOD-and-DRINKs-quot-easily).

Darce
May 28th, 2019, 23:01
Thanks for work on the how too. like what you're doing!:D

paladiusdarkhelm
May 29th, 2019, 00:33
@MarianDz, Did you mean for the Waterskins and Rations to be set as "Daily" in your tutorial? I think if you set them like that, whenever you select a long Rest in Fantasy Grounds, they sorta recharge because it thins it is a new day after that. I set mine as "Once" and players only get to increase them if they restock somehow.

MarianDz
May 29th, 2019, 06:27
You have right "paladiusdarkhelm", once is better for them, let rest automatically not restock them. Thank you for correction :o
I upload new image v. 1.2 in Blog

seycyrus
June 25th, 2019, 05:12
Greetings,

I’ve been trying to use the “Party Sheet” combined with the “Parcels” to figure out how to deal with rations and waterskins, but am not having much luck. I’d like to summarize my results in case I am missing something. I’m using the Gurps Ruleset.

1) Parcel Coins Method:

Using this method for legitimate parceling of real gems and currency seems to be pretty straightforward. The program will divide up the number of each item by the number of party members and increment each party members currency by that amount throwing away the remainder – integer division.

A) This method can be used to distribute items to the entire party at once, and seems to be promising in terms of using up rations and water. Unfortunately, the program doesn’t seem to like to divide negative numbers. Trying to dock the entire party all at once with a negative amount of food or drink doesn’t even toggle the chat window – as if the distribute button had not been pressed, even if the negative number is evenly divisible by the number of party members.

B) One CAN drag individual parcel that have Parcel Coins of “-1 ration” (etc.) to individual members of the party

2) Parcel Items

A) Cannot distribute among the entire party all at once (leaving the Assignment field blank) like in 1 A, even for positive additions.

B) Strangely, once the “Parcel Items” field in the party sheet is populated, you can drag items one at a time to members of the party, and inventory will be incremented by one.

C) Putting in a negative quantity in 2B, and then dragging the Parcel Item to the character INCREASES the characters inventory by one – no subtraction.

D) Can manually populate the assignment field one member at a time (by typing in the party member names), and then hitting the distribute button. This will add to a characters inventory, but negative numbers will not subtract.


In summary I don’t think either of these methods is very suitable for keeping track of rations and/or water supplies. If Parcel Items” handled negative numbers, then it could be used for resource management, albeit in a limited way.

Thank you for any comments and/or replies.

Govanon
June 27th, 2019, 01:30
I tried creating a currency called "Ration" and I used the Location extension to create a "shop" called "camp" and created the "eating" service at the cost of -1 Ration, dragged the character and it worked. My problem is that I would like to create besides the Ration, the water currency and Healing Kit, but the 5e ruleset only accepts in the inventory tab the maximum of 6 currencies that are already occupied by 5 types of coins. When this limit is extrapolated the record is made into rows (which does not have the property to perform aritimetic operations.

PS. English is not my native language.

LordEntrails
June 27th, 2019, 01:46
The healer's kit is usually added to the actions tab as a power with number of uses or a weapon with a set amount of ammo. Otherwise I suspect you are going to need to write a custom extension. Though maybe someone else has an ingenious idea?

seycyrus
June 27th, 2019, 02:13
Perhaps I'm missing something, but wouldn't it be better if EVERY member in the party was docked a food and/or water all at once?

Govanon
June 27th, 2019, 02:22
The healer's kit is usually added to the actions tab as a power with number of uses or a weapon with a set amount of ammo. Otherwise I suspect you are going to need to write a custom extension. Though maybe someone else has an ingenious idea?

Unfortunately I'm just a beginner in the extensions thing ... Maybe someone is interested in doing it.


The healer's kit is usually added to the actions tab as a power with number of uses or a weapon with a set amount of ammo. Otherwise I suspect you are going to need to write a custom extension. Though maybe someone else has an ingenious idea?

Some groups prefer to carry each their supplies.

LordEntrails
June 27th, 2019, 04:26
Some groups prefer to carry each their supplies.

The "ammo" is accounted for on each character. So isn't that the same as each carrying their own supplies? It might still work with parcels, you would have to make a custom weapon type of ammo though, just like an arrow or bolt.

But, you can also insist on using it like currency, but then you are limited to 6 currency types, which probably mean you have to stop using copper and maybe silver.

Govanon
June 27th, 2019, 04:30
which probably mean you have to stop using copper and maybe silver
Or Electrum...

Ammo idea is good. I think using a customizable power like the Lay of Hands is an elegant solution, but there is no warning that the uses have ended as the case of ammunition.

skj310
August 7th, 2019, 15:08
Just wanted to say that I really liked a lot of the feedback and ideas. Some really awesome efforts by many who also see where I was coming from. :)

Thank you all!

One day a savvy programmer like the mysterious DuluxOz and the magnificent Celestian, will solve this for us, and we'll be like ... dude(tte) you are a hero!

Beemanpat
April 28th, 2020, 12:31
Maybe a message can be generated in chat as a reminder for players or dm that rations and waterskin need to be deducted. Just add it onto the text stating party is taking a long rest. It just slips my mind to tell everyone to deduct rations.

pr6i6e6st
May 13th, 2020, 18:05
i have been working on code that uses the calendar to track things like when to regain health, when to lose stress points, when to gain or lose radiation, when to roll for a condition or lose health because of it, or when a critical injury has reached a count of passing time before the character has to roll, or to roll for consumable items when needed.

this is all for the Alien RPG ruleset of course, but i can break down some of the code i used here.
https://www.fantasygrounds.com/forums/showthread.php?50544-WIP-Alien-RPG-ruleset

in the manager_char.lua i have most of my code in place.



this one sets when you start the time for whatever you're needing. if you are using a button to "start tracking" hunger, for instance, you would put this in the script for that
function setStartTime(rActor, sFirst)
--Debug.console("setStartTime called; " .. sFirst .."");
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
nStartTime = getCurrentDateinMinutes(rActor);
--Debug.console("setStartTime; nStartTime =", nStartTime);
DB.setValue(nodeActor, "" .. sFirst .. ".starttime", "number", nStartTime);
--Debug.console("setStartTime; DB.setValue(nodeActor, " .. sFirst .. ".starttime, number, " .. nStartTime .. ") = ", DB.setValue(nodeActor, "" .. sFirst .. ".starttime", "number", nStartTime));
end


this one gets the current date and makes turns it all into minutes
function getCurrentDateinMinutes(rActor)
--Debug.console("getCurrentDateinMinutes; nRounds =", nRounds);
local nMinutes = DB.getValue("calendar.current.minute");
--Debug.console("getCurrentDateinMinutes; nMinutes =", nMinutes);
local nHours = DB.getValue("calendar.current.hour");
--Debug.console("getCurrentDateinMinutes; nHours =", nHours);
local nDays = DB.getValue("calendar.current.day");
--Debug.console("getCurrentDateinMinutes; nDays =", nDays);
local nMonths = DB.getValue("calendar.current.month");
--Debug.console("getCurrentDateinMinutes; nMonths =", nMonths);
local nYears = DB.getValue("calendar.current.year");


nRoundsinMinutes = convertRoundstoMinutes(rActor);
nHoursinMinutes = convertHourstoMinutes(nHours);
--Debug.console("getCurrentDateinMinutes; nHoursinMinutes =", nHoursinMinutes);
nDaysinMinutes = convertDaystoMinutes(nDays);
--Debug.console("getCurrentDateinMinutes; nDaysinMinutes =", nDaysinMinutes);
nMonthsinMinutes = convertMonthssnowtoMinutes(nMonths);
--Debug.console("getCurrentDateinMinutes; nMonthsinMinutes =", nMonthsinMinutes);
nYearsinMinutes = convertYearsnowtoMinutes(nYears);
--Debug.console("getCurrentDateinMinutes; nYearsinMinutes =", nYearsinMinutes);

nDateinMinutes = nHoursinMinutes + nDaysinMinutes + nMonthsinMinutes + nYearsinMinutes + nMinutes + nRoundsinMinutes;
--Debug.console(getCurrentDateinMinutes);

return nDateinMinutes;
end

you can send a number to these functions and either get the difference back or get a true or false statement
function isTimeGreaterThan(rActor, sFirst, nCompareBy)
--Debug.console("isTimeGreaterThan called, sFirst = " .. sFirst .. ", nCompareBy = " .. nCompareBy .. ";");
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nStartTime = getStartTime(rActor, sFirst);
--Debug.console("isTimeGreaterThan, nStartTime = " .. rActor .. "");
local nCurrentTime = getCurrentDateinMinutes(rActor);
--Debug.console("isTimeGreaterThan, nCurrentTime = " .. nCurrentTime .. ", nCompareBy = " .. nCompareBy .. "");

local nDifference = nCurrentTime - nStartTime;
--Debug.console("isTimeGreaterThan; nDifference = " .. nDifference .. ", nCurrentTime = " .. nCurrentTime .. ", nStartTime = " .. nStartTime .. "");
if nDifference >= nCompareBy then
return true;
elseif nDifference < nCompareBy then
return false;
end
end

function getTimeDifference(rActor, sFirst, nCompareBy)
--Debug.console("isTimeGreaterThan called, sFirst = " .. sFirst .. ", nCompareBy = " .. nCompareBy .. ";");
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.turn", 0);
local nStartTime = DB.getValue(nodeActor, "" .. sFirst .. ".starttime", 0);
--Debug.console("getTimeDifference; nStartTime = DB.getValue(nodeActor, " .. sFirst .. ".starttime, 0) = " .. DB.getValue(nodeActor, "" .. sFirst .. ".starttime", nStartTime) .. "");
local nCurrentTime = getCurrentDateinMinutes();
--Debug.console("getTimeDifference, nCurrentTime = " .. nCurrentTime .. "");

local nDifference = nCurrentTime - nStartTime;
--Debug.console("getTimeDifference, nDifference = " .. nDifference .. ", nCurrentTime = " .. nCurrentTime .. ", nStartTime = " .. nStartTime .. "");
return nDifference;
end

pr6i6e6st
May 13th, 2020, 18:06
these are the conversion scripts



function convertRoundstoMinutes(rActor)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRounds = DB.getValue("combattracker.round", 0);
local nSecondsperRounds = nRounds * DB.getValue(nodeActor, "game.round", 0);
local nRoundsinMinutes = convertSecondstoMinutes(nSecondsperRounds);
return nRoundsinMinutes;
end
function convertSecondstoMinutes(nNumber)
--Debug.console("convertRoundstoMinutes called, nNumber = " .. nNumber .. "");
local nMinutesTotaled = nNumber / 60;
--Debug.console("convertHourstoMinutes, nMinutesTotaled = " .. nMinutesTotaled .. "");
return nMinutesTotaled;
end
function convertHourstoMinutes(nNumber)
--Debug.console("convertHourstoMinutes called, nNumber = " .. nNumber .. "");
local nMinutesTotaled = nNumber * 60;
--Debug.console("convertHourstoMinutes, nMinutesTotaled = " .. nMinutesTotaled .. "");
return nMinutesTotaled;
end
function convertMinutestoHours(nNumber)
--Debug.console("convertHourstoMinutes called, nNumber = " .. nNumber .. "");
local nHoursTotaled = nNumber / 60;
--Debug.console("convertHourstoMinutes, nHoursTotaled = " .. nHoursTotaled .. "");
return nHoursTotaled;
end
function convertHourstoDays(nNumber)
--Debug.console("convertHourstoDays called, nNumber = " .. nNumber .. "");
local nDaysTotaled = nNumber / 24;
--Debug.console("convertHourstoDays, nDaysTotaled = " .. nDaysTotaled .. "");
return nDaysTotaled;
end
function convertDaystoHours(nNumber)
--Debug.console("convertDaystoHours called, nNumber = " .. nNumber .. "");
local nHoursTotaled = nNumber * 24;
--Debug.console("convertHourstoDays, nHoursTotaled = " .. nHoursTotaled .. "");
return nHoursTotaled;
end
function convertMinutestoDays(nNumber)
--Debug.console("convertMinutestoDays called, nNumber = " .. nNumber .. "");
local nHoursTotaled = convertMinutestoHours(nNumber);
local nDaysTotaled = convertHourstoDays(nHoursTotaled);
--Debug.console("convertMinutestoDays, nHoursTotaled = " .. nHoursTotaled .. ", nDaysTotaled = " .. nDaysTotaled .. "");
return nDaysTotaled;
end
function convertDaystoMinutes(nNumber)
--Debug.console("convertDaystoMinutes called, nNumber = " .. nNumber .. "");
local nDaysinHours = convertDaystoHours(nNumber);
local nMinutesTotaled = convertHourstoMinutes(nDaysinHours);
--Debug.console("convertDaystoMinutes, nDaysinHours = " .. nDaysinHours .. ", nMinutesTotaled = " .. nMinutesTotaled .. "");
return nMinutesTotaled;
end
function convertMonthtoHours(nNumber)
--Debug.console("convertMonthtoHours called, nNumber = " .. nNumber .. "");
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");
--Debug.console("convertMonthtoHours, nMonth = " .. nMonth .. ", nYear = " .. nYear .. "");
nDays = getDaysInMonth(nNumber, nYear, nDays);
nHoursTotaled = convertDaystoHours(nDays);
--Debug.console("convertMonthtoHours, nDays = " .. nDays .. ", nHoursTotaled = " .. nHoursTotaled .. "");
return nHoursTotaled;
end
function convertMonthtoMinutes(nNumber)
--Debug.console("convertMonthtoMinutes called, nNumber = " .. nNumber .. "");
local nYear = DB.getValue("calendar.current.year", 0);
local nDays = DB.getValue("calendar.data.periods.period" .. nNumber .. ".days", 0);
--Debug.console("convertMonthtoMinutes, nDays = " .. nDays .. ", nYear = " .. nYear .. "");
nDays = getDaysInMonth(nNumber, nYear, nDays);
nMinutesTotaled = convertDaystoMinutes(nDays);
--Debug.console("convertMonthtoMinutes, nDays = " .. nDays .. ", nMinutesTotaled = " .. nMinutesTotaled .. "");
return nMinutesTotaled;
end
function convertYeartoHours(nNumber)
--Debug.console("convertYeartoHours called, nNumber = " .. nNumber .. "");
local nYearinDays = 365;
bisLeapYear = isLeapYear(nNumber);
--Debug.console("convertYeartoHours, nYearinDays = " .. nYearinDays .. ", bisLeapYear = ", bisLeapYear);
if bisLeapYear == true then
nYearinDays = nYearinDays + 1;
--Debug.console("convertYeartoHours, nYearinHours = " .. nYearinHours .. ", nYearinDays = " .. nYearinDays .. ", bisLeapYear = ", bisLeapYear);
end
nYearinHours = nYearinDays * 24;
--Debug.console("convertYeartoHours, nYearinHours = " .. nYearinHours .. ", nYearinDays = " .. nYearinDays .. "");
return nYearinHours;
end
function convertYeartoMinutes(nNumber)
--Debug.console("convertYeartoMinutes called, nNumber = " .. nNumber .. "");
local nYearinHours = convertYeartoHours(nNumber);
nYearinMinutes = nYearinHours * 60;
--Debug.console("convertYeartoMinutes, nYearinHours = " .. nYearinHours .. ", nYearinMinutes = " .. nYearinMinutes .. "");
return nYearinMinutes;
end

function convertYearsnowtoMinutes(nYear)
--Debug.console("convertYeartoMinutes called, nNumber = " .. nYear .. "");
local nYearCount = 0;
local nYearinDays = 365;
local nLeapYear = 0;
local nDaysTotaled = 0

for i=1,nYear do
if nYearCount < nYear then
--Debug.console("convertYearsnowtoMinutes, nYearCount = " .. nYearCount .. ", nYear = " .. nYear .. "");
nYearinHours = convertYeartoHours(i);
nMinutesTotaled = nMinutesTotaled + convertHourstoMinutes(nYearinHours);
nYearCount = nYearCount + 1;
--Debug.console("convertYearsnowtoMinutes, nYearinHours = " .. nYearinHours .. ", nMinutesTotaled = " .. nMinutesTotaled .. ", nYearCount = " .. nYearCount .. "");
end
end
--Debug.console("convertYearsnowtoMinutes, nMinutesTotaled = " .. nMinutesTotaled .. "");
return nMinutesTotaled;
end
function convertMonthssnowtoMinutes(nMonth)
local nCount = 0;
local nMinutes = 0;
--Debug.console("convertMonthssnowtoMinutes called, nMonth = " .. nMonth .. "");
for i=1,nMonth do
if nCount < nMonth then
--Debug.console("convertMonthssnowtoMinutes, nCount = " .. nCount .. ", nMonth = " .. nMonth .. "");
nMinutes = convertMonthtoMinutes(nCount) + nMinutes;
nCount = nCount + 1;
--Debug.console("convertMonthssnowtoMinutes, nMinutes = " .. nMinutes .. ", nCount = " .. nCount .. "");
end
end
--Debug.console("convertMonthssnowtoMinutes, nMinutes = " .. nMinutes .. ", nCount = " .. nCount .. "");
return nMinutes;
end

--extra calculations --
function getDaysInMonth(nMonth, nYear, nDays)
--Debug.console("getDaysInMonth called, nMonth = " .. nMonth .. ", nYear = " .. nYear .. ", nDays = " .. nDays .. "");
if nMonth == 2 then
local nYear = DB.getValue("calendar.current.year", 0);
--Debug.console("getDaysInMonth called, nYear = " .. nYear .. "");
if (nYear % 400) == 0 then
nVar = 1;
--Debug.console("getDaysInMonth called, nVar = " .. nVar .. ", nYear = " .. nYear .. ", (nYear % 400) = " .. (nYear % 400) .. "");
elseif (nYear % 100) == 0 then
nVar = 0;
--Debug.console("getDaysInMonth called, nVar = " .. nVar .. ", nYear = " .. nYear .. ", (nYear % 400) = " .. (nYear % 400) .. "");
elseif (nYear % 4) == 0 then
nVar = 1;
--Debug.console("getDaysInMonth called, nVar = " .. nVar .. ", nYear = " .. nYear .. ", (nYear % 400) = " .. (nYear % 400) .. "");
end
else
nVar = 0;
end
nDays = nDays + nVar;
--Debug.console("getDaysInMonth called, nVar = " .. nVar .. ", nYear = " .. nYear .. ", nDays = " .. nDays .. "");

return nDays;
end

function isLeapYear(nYear)
return nYear%4==0 and (nYear%100~=0 or nYear%400==0)
end

pr6i6e6st
May 13th, 2020, 18:11
these are the handlers i set on my clock adjusters to get an accurate change of time, rather than looking at minutes and hours and days and months and years.



function onInit()
DB.addHandler("calendar.dateinminutes", "onUpdate", onTimeChanged);
end
function onTimeChanged()
local rActor = ActorManager.resolveActor(window.getDatabaseNode() );
CharManager.onRadiationTimeChange(rActor, nRound);
end


and then back in my manager_char.lua



we check if we're in radiation or not by the toggle on the character sheet
function isInRadiation(rActor)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
Debug.console("isInRadiation Called;");
if DB.getValue(nodeActor, "radiation.zone", 0) == 1 then
return true;
else
return false;
end
end

we get how strong the radiation is based on the buttoncycler on the character sheet when we are irradiated
function getRadiationStrength(rActor)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
Debug.console("getRadiationStrength Called;");
return DB.getValue(nodeActor, "radiation.strength", 0);
end

we see if our radiation has gone up or down in points and either roll for damage or roll for healing
function checkRadiation(rActor)
Debug.console("checkRadiation Called;");
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local PermRads = DB.getValue(nodeActor, "radiation.show", 0);
local RadMax = DB.getValue(nodeActor, "radiation.minval", 0);
local Rads = DB.getValue(nodeActor, "radiation.points", 0);
local RadStrength = getRadiationStrength(rActor);
local isInRadiation = isInRadiation(rActor);
local NewRadiationCheck = Rads;
local OldRadiationCheck = DB.getValue(nodeActor, "radiation.oldcheck", 0);

Debug.console("checkRadiation; PermRads = " .. NewRadiationCheck .. ", NewRadiationCheck = " .. PermRads .. ", RadMax = " .. RadMax .. ", Rads = " .. Rads .. ", RadStrength = " .. RadStrength .. "");
if OldRadiationCheck == nil then
OldRadiationCheck = NewRadiationCheck;
end
if NewRadiationCheck < OldRadiationCheck then
local RadiationDifference = OldRadiationCheck - NewRadiationCheck;
throwRadiationHealDice(rActor, RadiationDifference);
elseif NewRadiationCheck > OldRadiationCheck then
throwRadiationDamageDice(rActor);
end


local OldRadiationCheck = DB.getValue(nodeActor, "radiation.points", 0);
DB.setValue(nodeActor, "radiation.oldcheck", "number", OldRadiationCheck);
Debug.console("checkRadiation ;OldRadiationCheck = " .. OldRadiationCheck .. "");
end
we increase our radiation points
function increaseRadiation(rActor, nNumber)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
for i=1,nNumber do
if DB.getValue(nodeActor, "radiation.points", 0) < DB.getValue(nodeActor, "radiation.minval", 0) then
RadiationAmount = DB.getValue(nodeActor, "radiation.points", 0) + 1;
DB.setValue(nodeActor, "radiation.points", "number", RadiationAmount);
end
end
local OldRadiationCheck = DB.getValue(nodeActor, "radiation.points", 0);
DB.setValue(nodeActor, "radiation.oldcheck", "number", OldRadiationCheck);
end

we decrease our radiation points
function decreaseRadiation(rActor, nNumber)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
nCount = 0;
for i=1,nNumber do
if DB.getValue(nodeActor, "radiation.points", 0) > 0 then
RadiationAmount = DB.getValue(nodeActor, "radiation.points", 0) - 1;
DB.setValue(nodeActor, "radiation.points", "number", RadiationAmount);
nCount = nCount + 1;
end
end
local OldRadiationCheck = DB.getValue(nodeActor, "radiation.points", 0);
DB.setValue(nodeActor, "radiation.oldcheck", "number", OldRadiationCheck);
end

time has changed because of the handlers, lets see what we should do
function onRadiationTimeChange(rActor)
Debug.console("onRadiationTimeChange Called;");
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local PermRads = DB.getValue(nodeActor, "radiation.show", 0);
local RadMax = DB.getValue(nodeActor, "radiation.minval", 0);
local Rads = DB.getValue(nodeActor, "radiation.points", 0);
local RadStrength = getRadiationStrength(rActor);
local isInRadiation = isInRadiation(rActor);
local nShift = DB.getValue(nodeActor, "game.shift", 0);
local nTurn = DB.getValue( "game.turn", 0);
local nRound = DB.getValue(nodeActor, "game.round", 0);
local sFirst = "radiation";
Debug.console("checkRadiation; PermRads = " .. PermRads .. ", RadMax = " .. RadMax .. ", Rads = " .. Rads .. ", RadStrength = " .. RadStrength .. "");
if RadStrength == 0 then
Compareby = convertHourstoMinutes(nShift);
Debug.console("onRadiationTimeChange Compareby = " .. Compareby .. "");
elseif RadStrength == 1 then
Compareby = nTurn;
Debug.console("onRadiationTimeChange Compareby = " .. Compareby .. "");
elseif RadStrength == 2 then
Compareby = convertSecondstoMinutes(nRound);
Debug.console("onRadiationTimeChange Compareby = " .. Compareby .. "");
end

if isInRadiation == true then
if CharManager.isTimeGreaterThan(rActor, sFirst, Compareby) == true then
Debug.console("onRadiationTimeChange timeIsGreaterThan = " .. Compareby .. "");
DB.setValue(nodeActor, "radiation.oldcheck", "number", Rads);
increaseRadiation(rActor, 1);
setStartTime(rActor, sFirst);
Debug.console("onRadiationTimeChange isInRadiation");
checkRadiation(rActor);
end
elseif isInRadiation == false then
if CharManager.isTimeGreaterThan(rActor, sFirst, convertHourstoMinutes(nShift)) == true then
DB.setValue(nodeActor, "radiation.oldcheck", "number", Rads);
decreaseRadiation(rActor, 1);
setStartTime(rActor, sFirst);
Debug.console("onRadiationTimeChange isInRadiation");
checkRadiation(rActor);
end
end
end

throw them dice!
function throwRadiationDamageDice(rActor)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
Debug.console("throwRadiationHealDice Called;");
local RadiationDamage = Interface.getString("chatmessage_RadiationDamage");
local StateTime = CalendarManager.getCurrentTimeString()
local description = "" .. StateTime .. ": " .. RadiationDamage .. ":";
local nValue = DB.getValue(nodeActor, "radiation.points", 0) + DB.getValue(nodeActor, "radiation.show", 0)
local nTotal = DB.getValue(nodeActor, "radiation.points", 0).."dB";
local aDice, nMod = StringManager.convertStringToDice(nTotal);

local bDescNotEmpty = true;
local sStackDesc, nStackMod = ModifierStack.getStack(bDescNotEmpty);

local modifierDice = nStackMod;
local Negate = 0;

if nValue > 0 then
for i=1,nValue do
table.insert(aDice, "dB");
end
else
for i=1,-nValue do
table.remove(aDice);
end
end
if not User.isHost() then
Comm.throwDice( "dice", aDice, Negate, description);
end
end

function throwRadiationHealDice(rActor, nValue)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
Debug.console("throwRadiationHealDice Called;");
local RadiationDamage = Interface.getString("chatmessage_CheckRadPerm");
local StateTime = CalendarManager.getCurrentTimeString()
local description = "" .. StateTime .. ": " .. RadiationDamage .. ":";
local nTotal = nValue.. "dS";
local aDice, nMod = StringManager.convertStringToDice(nTotal);

local bDescNotEmpty = true;
local sStackDesc, nStackMod = ModifierStack.getStack(bDescNotEmpty);

local modifierDice = nStackMod;
local Negate = 0;

if nValue > 0 then
for i=1,nValue do
table.insert(aDice, "dS");
end
else
for i=1,-nValue do
table.remove(aDice);
end
end
if not User.isHost() then
Comm.throwDice( "dice", aDice, Negate, description);
end
end


edit: the following is on my desktop_panels.xml for my clock adjuster natively in the Alien RPG. you could do this for the ones on the calendar itself too. this makes sure we check the final result, and are not getting confused when a minute change causes the hour to change, or for when the hour changes and causes the day to change, etc, etc.


<label name="currenthour">
<anchored position="insidetopleft" width="20">
<left anchor="left" offset="20" />
<top offset="8" />
</anchored>
<frame name="fieldlight" offset="7,5,7,5" />
<stateframe>
<hover name="fieldfocus" offset="7,5,7,5" />
</stateframe>
<font>calendarbold</font>
<color>000000</color>
<center />
<tooltip textres="desktop_currenthour_tooltip" />
<script>
function onInit()
DB.addHandler("calendar.current.hour", "onUpdate", onSourceChanged);
DB.addHandler("calendar.current.day", "onUpdate", onSourceChanged);
nDay = DB.getValue("calendar.current.day");
onSourceChanged();
end

function onClose()
DB.removeHandler("calendar.current.hour", "onUpdate", onSourceChanged);
DB.removeHandler("calendar.current.day", "onUpdate", onSourceChanged);
end

function onSourceChanged()
local nHour, sPhase = CalendarManager.getDisplayHour();
setValue(string.format("%2d", nHour));
window.currentphase.setValue(sPhase);
if nDay ~= DB.getValue("calendar.current.day") then
CalendarManager.outputDate();
end
nDay = DB.getValue("calendar.current.day");
end
function onWheel(n)
if not Input.isControlPressed() then
return false;
end
CalendarManager.adjustHours(n);
local nDateinMinutes = CharManager.getCurrentDateinMinutes();
DB.setValue("calendar.dateinminutes", "number", nDateinMinutes);
return true;
end
</script>