celestian
June 15th, 2018, 06:53
So tonight I was messing about with TYPE() effects and noticed that it wouldn't work for me when the npc type was set to "goblin" and the TYPE(goblin) was in the effect. It seems that for some reason the getCreatureTypeHelper() code depends on some static arrays. If the "type" isn't in those then it doesn't find it so the TYPE never works.
This is the function that splits up the TYPE() and compares it to the DataCommon.* arrays.
function getCreatureTypeHelper(sTypeCheck, bUseDefaultType)
local aCheckSplit = StringManager.split(sTypeCheck:lower(), ", %(%)", true);
local aTypeCheck = {};
local aSubTypeCheck = {};
-- Handle half races
local nHalfRace = 0;
for k = 1, #aCheckSplit do
if aCheckSplit[k]:sub(1, #DataCommon.creaturehalftype) == DataCommon.creaturehalftype then
aCheckSplit[k] = aCheckSplit[k]:sub(#DataCommon.creaturehalftype + 1);
nHalfRace = nHalfRace + 1;
end
end
if nHalfRace == 1 then
if not StringManager.contains (aCheckSplit, DataCommon.creaturehalftypesubrace) then
table.insert(aCheckSplit, DataCommon.creaturehalftypesubrace);
end
end
-- Check each word combo in the creature type string against standard creature types and subtypes
for k = 1, #aCheckSplit do
for _,sMainType in ipairs(DataCommon.creaturetype) do
local aMainTypeSplit = StringManager.split(sMainType, " ", true);
if #aMainTypeSplit > 0 then
local bMatch = true;
for i = 1, #aMainTypeSplit do
if aMainTypeSplit ~= aCheckSplit[k - 1 + i] then
bMatch = false;
break;
end
end
if bMatch then
table.insert(aTypeCheck, sMainType);
k = k + (#aMainTypeSplit - 1);
end
end
end
for _,sSubType in ipairs(DataCommon.creaturesubtype) do
local aSubTypeSplit = StringManager.split(sSubType, " ", true);
if #aSubTypeSplit > 0 then
local bMatch = true;
for i = 1, #aSubTypeSplit do
if aSubTypeSplit[i] ~= aCheckSplit[k - 1 + i] then
bMatch = false;
break;
end
end
if bMatch then
table.insert(aSubTypeCheck, sSubType);
k = k + (#aSubTypeSplit - 1);
end
end
end
end
-- Make sure we have a default creature type (if requested)
if bUseDefaultType then
if #aTypeCheck == 0 then
table.insert(aTypeCheck, DataCommon.creaturedefaulttype);
end
end
-- Combine into a single list
for _,vSubType in ipairs(aSubTypeCheck) do
table.insert(aTypeCheck, vSubType);
end
return aTypeCheck;
end
This is the function I ended up with. BOLD I replaced, italic I commented. Basically I just didn't use the above function.
function isCreatureType(rActor, sTypeCheck)
-- I dont like having static list of types
[I]--local aTypeCheck = getCreatureTypeHelper(sTypeCheck, false);
-- so ... just split on comma
local aTypeCheck = StringManager.split(sTypeCheck:lower(), ",", true);
if #aTypeCheck == 0 then
return false;
end
local sType, nodeActor = ActorManager.getTypeAndNode(rActor);
local sField = "race";
if sType ~= "pc" then
sField = "type";
end
-- I dont like having static list of types
--local aTypeActor = getCreatureTypeHelper(DB.getValue(nodeActor, sField, ""), true);
-- so split on comma and go.
local sTypeString = DB.getValue(nodeActor, sField, "")
local aTypeActor = StringManager.split(sTypeString:lower(), ",", true);
local bReturn = false;
for kCheck,vCheck in ipairs(aTypeCheck) do
if StringManager.contains(aTypeActor, vCheck) then
bReturn = true;
break;
end
end
return bReturn;
end
It by-passes those static array checks and checks for any TYPE() given with any possible creature TYPE set on an npc. To me it seems infinitely more useful to have it work for whatever the DM decides to set for a type because not using the arrays doesn't break it if it's never needed far as I can tell.
So, I know you guys did this for a reason and I'm curious, why?
This is the function that splits up the TYPE() and compares it to the DataCommon.* arrays.
function getCreatureTypeHelper(sTypeCheck, bUseDefaultType)
local aCheckSplit = StringManager.split(sTypeCheck:lower(), ", %(%)", true);
local aTypeCheck = {};
local aSubTypeCheck = {};
-- Handle half races
local nHalfRace = 0;
for k = 1, #aCheckSplit do
if aCheckSplit[k]:sub(1, #DataCommon.creaturehalftype) == DataCommon.creaturehalftype then
aCheckSplit[k] = aCheckSplit[k]:sub(#DataCommon.creaturehalftype + 1);
nHalfRace = nHalfRace + 1;
end
end
if nHalfRace == 1 then
if not StringManager.contains (aCheckSplit, DataCommon.creaturehalftypesubrace) then
table.insert(aCheckSplit, DataCommon.creaturehalftypesubrace);
end
end
-- Check each word combo in the creature type string against standard creature types and subtypes
for k = 1, #aCheckSplit do
for _,sMainType in ipairs(DataCommon.creaturetype) do
local aMainTypeSplit = StringManager.split(sMainType, " ", true);
if #aMainTypeSplit > 0 then
local bMatch = true;
for i = 1, #aMainTypeSplit do
if aMainTypeSplit ~= aCheckSplit[k - 1 + i] then
bMatch = false;
break;
end
end
if bMatch then
table.insert(aTypeCheck, sMainType);
k = k + (#aMainTypeSplit - 1);
end
end
end
for _,sSubType in ipairs(DataCommon.creaturesubtype) do
local aSubTypeSplit = StringManager.split(sSubType, " ", true);
if #aSubTypeSplit > 0 then
local bMatch = true;
for i = 1, #aSubTypeSplit do
if aSubTypeSplit[i] ~= aCheckSplit[k - 1 + i] then
bMatch = false;
break;
end
end
if bMatch then
table.insert(aSubTypeCheck, sSubType);
k = k + (#aSubTypeSplit - 1);
end
end
end
end
-- Make sure we have a default creature type (if requested)
if bUseDefaultType then
if #aTypeCheck == 0 then
table.insert(aTypeCheck, DataCommon.creaturedefaulttype);
end
end
-- Combine into a single list
for _,vSubType in ipairs(aSubTypeCheck) do
table.insert(aTypeCheck, vSubType);
end
return aTypeCheck;
end
This is the function I ended up with. BOLD I replaced, italic I commented. Basically I just didn't use the above function.
function isCreatureType(rActor, sTypeCheck)
-- I dont like having static list of types
[I]--local aTypeCheck = getCreatureTypeHelper(sTypeCheck, false);
-- so ... just split on comma
local aTypeCheck = StringManager.split(sTypeCheck:lower(), ",", true);
if #aTypeCheck == 0 then
return false;
end
local sType, nodeActor = ActorManager.getTypeAndNode(rActor);
local sField = "race";
if sType ~= "pc" then
sField = "type";
end
-- I dont like having static list of types
--local aTypeActor = getCreatureTypeHelper(DB.getValue(nodeActor, sField, ""), true);
-- so split on comma and go.
local sTypeString = DB.getValue(nodeActor, sField, "")
local aTypeActor = StringManager.split(sTypeString:lower(), ",", true);
local bReturn = false;
for kCheck,vCheck in ipairs(aTypeCheck) do
if StringManager.contains(aTypeActor, vCheck) then
bReturn = true;
break;
end
end
return bReturn;
end
It by-passes those static array checks and checks for any TYPE() given with any possible creature TYPE set on an npc. To me it seems infinitely more useful to have it work for whatever the DM decides to set for a type because not using the arrays doesn't break it if it's never needed far as I can tell.
So, I know you guys did this for a reason and I'm curious, why?