there are different threads in the forum searching for controlling spells and different aspects of spell usage and light control for the party which are generally not answered / solved.
For further use I'm creating this thread with some info I found out over the last days.
Following topics are covered:
Completely disabling a spell
Disabling torches only in a certain level / in an area of an level (check if party is carrying torches in hand)
Punish the party for casting the light spell (also only in a certain area) (check when spell is cast)
Removing light / casting darkness
----------------------------------
Completely disabling a spell
In \mod_assets\scripts\init.lua create a duplicate of the party component.
As you can see in the following script, the spell "light" is completely disabled by "return false" (thanks to JKos for helping!)
Code: Select all
defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Party",
onCastSpell = function(party,champion,spellName)
if spellName == "light" then
return false
end
end
}
},
}
Disabling torches only in a certain level / in an area of an level
In my case I use a "lore-method": the party gets punished with damage if anyone puts a torch into his hand.
I use the damage party script by Nutjob:
viewtopic.php?f=22&t=8186&p=82799&hilit=damage#p82799
Set up a timer with for example 2 seconds and let it execute the function darkd3checklight in the following script:
The check about party.level == 13 is optional and check which level the party is currently walking in.
Code: Select all
function darkd3checklight()
if party.level == 13 then
for i = 1, 2 do
for k = 1, 4 do
local champion = party.party:getChampion(k):getItem(i)
if champion ~= nil and champion.go.name == "torch" then
dmgParty(20)
end
end
end
end
end
function dmgParty(power, _positions, percChance, dmgType, hasSound) --, directionOfAttk removed
_positions = _positions or {1,1,1,1};
percChance = percChance or 100;
power = power or math.random(1,1); -- change this (the 'random function parameters' to an integer|float)to have a different default
dmgType = dmgType or "physical";
if hasSound == nil then hasSound = true; end
local range = string.split(tostring(power), ".");
local minDmg, maxDmg = nil,nil;
if #range == 2 then
minDmg = tonumber(range[1]); maxDmg = tonumber(range[2]);
if minDmg > 0 and maxDmg > 0 and minDmg <= maxDmg then
power = nil
else print("Damage out of range or unrecognized format. "); return false; end
end
local _dmgTypes = {cold = 1, fire = 2, physical = 3, poison = 4, shock = 5}
local _sounds = {"frostbolt_hit" , "fireball_hit", "ogre_impact", "poison_bolt_hit", "lightning_bolt_hit_small"}
local sound = nil;
local p = party.party;
local _percChance = {}
if type(_positions) ~= "table" then print("_positions must be a four field table."); return false; end
if type(percChance) == "number" then
for _,_ in ipairs(_positions) do table.insert(_percChance, percChance); end
elseif type(percChance) == "table" then _percChance = percChance;
else print("percChance unrecognized format."); return false; end
-- if it doesn't exist as a definition lookup
if type(_dmgTypes[dmgType]) ~= "number" then
-- attempt to find it as a numerical key
for k,v in pairs(_dmgTypes) do
-- and if it's found assign the string reference for damage type
if dmgType == v then dmgType = k; sound = _sounds[v]; break; end
end
end
-- check if definition lookup failed
if type(dmgType) == "number" then print('dmgType must be "cold", "fire", "physical", "poison", or "shock" (1, 2, 3, 4, or 5)'); return false; end
if type(power) ~= "number" and minDmg == nil then print("The power for damage must be a number."); return false; end
if minDmg == nil then
if power < 1 then print("The damage power must be higher than zero (0)."); return false; end
end
if type(hasSound) ~= "boolean" then
-- apply supplied string reference
sound = hasSound
else
-- otherwise, get the numerically corresponding sound tbl
sound = _sounds[_dmgTypes[dmgType]]
end
if type(sound) ~= "string" then print('hasSound must be either (true|false) or your own ("string_reference").'); return false; end
local chance,d = nil,0;
for position,bDoDmg in ipairs(_positions) do
chance = _percChance[position];
if type(chance) ~= "number" then print("percChance must be a number") return false; end
if chance < 1 or chance > 100 then print("percChance must be a number between 1 - 100"); return false; end
if bDoDmg ~= 0 and p:getChampion(position):getEnabled() and p:getChampion(position):isAlive() then
if math.random(1,100) <= chance then
if power ~= nil then d = rollDamage(power)
else d = math.random(minDmg, maxDmg) end
p:getChampion(position):damage(d, dmgType)
end
end
end
if hasSound ~= false then playSound(sound); end
return true;
end
Let the first floor_trigger call "endlightdamage" (it's there for stopping the damage when the party walks back and returns to the previous part of the level).
Let the second floor_trigger call "startlightdamage" (to start the damage check for torches).
At the end of the damagearea you also set up two triggers, the first calling startlightdamage (if the party walks back in to the damage area) and the second at the end to stop the damagecheck.
Code: Select all
lightdamage = 0
function startlightdamage()
lightdamage = 1
end
function endlightdamage()
lightdamage = 0
end
Code: Select all
function darkd3checklight()
if party.level == 13 and lightdamage == 1 then
for i = 1, 2 do
for k = 1, 4 do
local champion = party.party:getChampion(k):getItem(i)
if champion ~= nil and champion.go.name == "torch" then
dmgParty(20)
end
end
end
end
end
Punish the party for casting the light spell
Put the function from the start again into \mod_assets\scripts\init.lua, but this time don't call "return false" but call a function in a script ("script_entity_88.script:lightcast()")
Code: Select all
defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Party",
onCastSpell = function(party,champion,spellName)
if spellName == "light" then
script_entity_88.script:lightcast()
end
end
}
},
}
In the function I kill the party for casting light.
The if-part is there to make sure, the party is only killed in the certain part of the level (see description above).
Code: Select all
function lightcast()
if party.level == 13 and lightdamage == 1 then
dmgParty(4000)
end
end
Removing light / casting darkness
When the party enters the area, where light is prohibited, I need to make sure that an existing light spell is not active, so that the party cannot cast light in one level and completely play through the next level, where light is prohibited.
So I give all chars full energy and try to cast darkness with each one right as I enter the area, where light casting will be punished by the other scripts.
That floor_trigger calls this function:
Code: Select all
function darknesscast()
for i = 1, 4 do
party.party:getChampion(i):regainEnergy(1000)
party.party:getChampion(i):castSpell(58)
end
end
castSpell(25) would be light (rune 2, then rune5)
castSpell(58) is darkness (rune 5, then rune 8)
----------------------------------
Kind regards,
Joerg