Ask a simple question, get a simple answer
Re: Ask a simple question, get a simple answer
Ok, figured out!
print(party.party:getChampionByOrdinal(1):getCurrentStat("cooldown_rate"))
print(party.party:getChampionByOrdinal(1):getCurrentStat("cooldown_rate"))
Re: Ask a simple question, get a simple answer
Hey, does the following spell spawn an object that stay in the dungeon forever and is saved also?
Base spell:
Object and blast:
particle system:
Blast particle:
I'm askink because someone reported to me that an object is spawned and stay after blast, while using a script in the console at the impact point. So maybe I did something wrong while creating that spell.
(The script he used)
Also, does it create a conflict if you use the same name for a particle and an object?
Base spell:
SpoilerShow
Code: Select all
defineSpell{--used by minor wizard virge
name = "minorvirgespell",
uiName = "Light Bolt",
gesture = 0,
manaCost = 30,
skill = "light_magic",
requirements = {"light_magic", 3},
icon = 58,
spellIcon = 18,
description = "Cast a bolt of pure light on your foes.",
hidden = true,
onCast = function(champion,x,y,direction,elevation,skill)
local bolt = spawn("minorvirgespell_bolt",party.level,x,y,direction,elevation)
bolt.projectile:setIgnoreEntity(party)
local ord = champion:getOrdinal()
local left = nil
for i = 1,4 do
if party.party:getChampion(i):getOrdinal() == ord then
left = i == 1 or i == 3
break
end
end
local wpos = party:getWorldPosition()
local dx = nil
local dz = nil
if party.facing == 0 then
dx = left and -0.1 or 0.1
dz = -1
elseif party.facing == 1 then
dz = left and 0.1 or -0.1
dx = -1
elseif party.facing == 2 then
dx = left and 0.1 or -0.1
dz = 1
else -- party.facing == 3
dz = left and -0.1 or 0.1
dx = 1
end
bolt:setWorldPosition(vec(wpos[1]+dx,wpos[2]+1.35,wpos[3]+dz))
end,
}
SpoilerShow
Code: Select all
defineObject{
name = "minorvirgespell_bolt",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "arcane_bolt",
},
{
class = "Light",
color = vec(1, 0.6, 1),
brightness = 7,
range = 5,
},
{
class = "Sound",
sound = "blob",
pitch = 0.5,
},
{
class = "Sound",
name = "launchSound",
sound = "arcane_launch",
onInit = function(self) self:setPitch(1.2+math.random()*0.6) end,
},
{
class = "Projectile",
spawnOffsetY = 1.15,
velocity = 35,
radius = 0.1,
hitEffect = "minorvirgespell_blast",
},
},
}
defineObject{
name = "minorvirgespell_blast",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "arcane_blast",
},
{
class = "Light",
color = vec(1, 0.6, 1),
brightness = 10,
range = 7,
fadeOut = 0.5,
disableSelf = true,
},
{
class = "Sound",
sound = "blob_hit",
onInit = function(self) self:setPitch(1.2+math.random()*0.6) end,
},
{
class = "TileDamager",
attackPower = 1100,
damageType = "pure",
sound = "blob_hit",
onInit = function(self)
-- Award experience.
self:setDamageFlags(DamageFlags.Champion1)
end,
},
},
}
SpoilerShow
Code: Select all
defineParticleSystem{
name = "arcane_bolt",
emitters = {
{
emissionRate = 256,
emissionTime = 0,
maxParticles = 32,
sprayAngle = {0,360},
velocity = {0,1},
objectSpace = false,
texture = "assets/textures/particles/glitter_silver.tga",
lifetime = {0.5,1},
color0 = {3,1,1},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.1,
size = {0.1, 1.0},
gravity = {0,0,0},
airResistance = 5,
rotationSpeed = 5,
blendMode = "Additive",
},
{
emissionRate = 256,
emissionTime = 0,
maxParticles = 32,
sprayAngle = {0,360},
velocity = {0,1},
objectSpace = false,
texture = "assets/textures/particles/glitter_silver.tga",
lifetime = {0.5,1},
color0 = {1,1,3},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.1,
size = {0.1, 1.0},
gravity = {0,0,0},
airResistance = 5,
rotationSpeed = 5,
blendMode = "Additive",
},
{
spawnBurst = true,
maxParticles = 1,
sprayAngle = {0,0},
velocity = {0,0},
objectSpace = true,
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000,1000000},
color0 = {0.25,0.2,0.25},
opacity = 1,
fadeIn = 0.001,
fadeOut = 0.001,
size = {1.0, 1.0},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
},
}
}
SpoilerShow
Code: Select all
defineParticleSystem{
name = "arcane_blast",
emitters = {
{
spawnBurst = true,
maxParticles = 128,
sprayAngle = {0,360},
velocity = {2,5},
objectSpace = false,
texture = "assets/textures/particles/glitter_silver.tga",
lifetime = {0.6,1},
color0 = {3.0,3.0,3.0},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.5,
size = {0.16, 0.8},
gravity = {0,0,0},
airResistance = 4,
rotationSpeed = 2,
blendMode = "Additive",
},
{
spawnBurst = true,
maxParticles = 128,
sprayAngle = {0,360},
velocity = {2,5},
objectSpace = false,
texture = "assets/textures/particles/glitter_silver.tga",
lifetime = {0.6,1},
color0 = {3.0,1.8,3.0},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.5,
size = {0.16, 0.8},
gravity = {0,0,0},
airResistance = 4,
rotationSpeed = -2,
blendMode = "Additive",
},
{
spawnBurst = true,
maxParticles = 1,
sprayAngle = {0,0},
velocity = {0,0},
objectSpace = false,
texture = "assets/textures/particles/glow.tga",
lifetime = {1,1},
color0 = {1.0,0.6,1.0},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.9,
size = {7.2, 7.2},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
},
}
}
(The script he used)
Code: Select all
for i in party.map:entitiesAt(party.x,party.y) do print(i.name,i.id) end
Re: Ask a simple question, get a simple answer
minorvirgespell_blast will stay in the dungeon forever, yes. You should add "destroyObject = true" to the ParticleComponent.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: Ask a simple question, get a simple answer
ok, thank you!
Then, would it be ok to add the destroyObject for the light or particle too?
like in this one?
destroyObject is disabled there, this is a custom spell that use a copy of the wallfire in the asset pack.
Again, the same person reported, while checking fot that minor wizard virge blast:
Those comes from goromorg, I've checked in my definitions, they use the standard spells in the asset pack, except for a variation of a monster using a custom spell, which does not happen in that check.
I've lookd in the asset pack, but both fireball large and poison bolt blasts got the destroyObject to true.
Don't know how to fix that, as nothing seems wrong in the definition.
That's the goromorg ranged attack:
Then, would it be ok to add the destroyObject for the light or particle too?
like in this one?
destroyObject is disabled there, this is a custom spell that use a copy of the wallfire in the asset pack.
SpoilerShow
Code: Select all
defineObject{
name = "wallOffire",
baseObject = "base_spell",
components = {
{
class = "Model",
model = "assets/models/effects/wall_fire.fbx",
sortOffset = 1,
},
{
class = "Animation",
animations = {
idle = "assets/animations/effects/wall_fire.fbx",
},
playOnInit = "idle",
onAnimationEvent = function(self, event)
if event == "end" then
self.go.particle:stop()
self.go.particle2:stop()
self.go.particle:fadeOut(1)
self.go.particle2:fadeOut(1)
self.go.light:fadeOut(1)
end
end,
},
{
class = "Particle",
particleSystem = "wall_fire_smoke",
offset = vec(0, 0, 0),
sortOffset = 3,
--destroyObject = true,
},
{
class = "Particle",
name = "particle2",
particleSystem = "wall_fire",
offset = vec(0, 0, 0),
--destroyObject = true,
},
{
class = "Particle",
name = "impact",
particleSystem = "wall_fire_impact",
offset = vec(0, 0, 0),
sortOffset = 3,
--destroyObject = true,
},
{
class = "Light",
color = vec(0.75, 0.4, 0.25),
brightness = 40,
range = 6,
offset = vec(0, 1.2, 0),
--fadeOut = 0.75,
disableSelf = true,
},
{
class = "TileDamager",
attackPower = 27,
damageType = "fire",
repeatCount = 5,
repeatDelay = 4.3/5,
onInit = function(self)
-- Award experience.
self:setDamageFlags(DamageFlags.Champion1)
end
},
},
}
SpoilerShow
Code: Select all
fireball_blast_large
poison_bolt_blast
I've lookd in the asset pack, but both fireball large and poison bolt blasts got the destroyObject to true.
Don't know how to fix that, as nothing seems wrong in the definition.
That's the goromorg ranged attack:
SpoilerShow
Code: Select all
{
class = "MonsterAttack",
name = "rangedAttack",
attackPower = 100,
cooldown = 2,
animation = "attack",
sound = "goromorg_attack",
onAttack = function(self)
local h = 1.4
local r = math.random()
if r < 0.45 then
-- cast fireball
self.go.monster:shootProjectile("fireball_large", h, 100)
elseif r < 0.7 then
-- cast lightning bolt
self.go.monster:shootProjectile("lightning_bolt_greater", h, 100)
elseif r < 0.8 then
-- cast poison bolt
self.go.monster:shootProjectile("poison_bolt", h, 100)
else
-- cast ice shards
local dx,dy = getForward(self.go.facing)
local spell = spawn("ice_shards", self.go.level, self.go.x + dx, self.go.y + dy, self.go.facing, self.go.elevation)
spell.tiledamager:setAttackPower(100)
end
end,
},
Re: Ask a simple question, get a simple answer
Yes, LightComponent and ParticleComponent both have a destroyObject property, and it's fine to use it on multiple components on the same object (although it rarely makes any sense to put it on more than one of an object's components).
On ParticleComponent it destroys the parent object if, when it updates, it is enabled and either its particle system has finished or it has been fully faded out (by the fadeOut property or setFadeOut() method).
On LightComponent it destroys the parent object if, when it updates, it is enabled and either its brightness is 0 or it has been fully faded out.
Of course, both of these will still result in an object that stays around forever if the particle system never finishes (due to any of its emitters having an emissionTime or lifetime of 0 or very long), or the LightComponent never goes to 0 brightness or fully fades out, respectively.
Related enough to mention: ParticleComponent, but not LightComponent, has a destroySelf property, which is like destroyObject except it only destroys the ParticleComponent itself and doesn't affect the rest of the parent object. This is rarely useful, but it's there.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: Ask a simple question, get a simple answer
Sorry, but you're confusing me. From what I understand, you said it is ok to add the destroyObject to particle or light, but it is not necessary, if one of the component already got it, assuming that particle or light has no unlimited living time.minmay wrote: ↑Sun Mar 26, 2023 9:24 pmYes, LightComponent and ParticleComponent both have a destroyObject property, and it's fine to use it on multiple components on the same object (although it rarely makes any sense to put it on more than one of an object's components).
On ParticleComponent it destroys the parent object if, when it updates, it is enabled and either its particle system has finished or it has been fully faded out (by the fadeOut property or setFadeOut() method).
On LightComponent it destroys the parent object if, when it updates, it is enabled and either its brightness is 0 or it has been fully faded out.
Of course, both of these will still result in an object that stays around forever if the particle system never finishes (due to any of its emitters having an emissionTime or lifetime of 0 or very long), or the LightComponent never goes to 0 brightness or fully fades out, respectively.
Related enough to mention: ParticleComponent, but not LightComponent, has a destroySelf property, which is like destroyObject except it only destroys the ParticleComponent itself and doesn't affect the rest of the parent object. This is rarely useful, but it's there.
Do I understand it right?
Re: Ask a simple question, get a simple answer
Hey there, again one silly question:
is that script ok?
it is in a single script file, without anything else, and linked to 2 buttons named mkbforge1 and mkbforge2
I'm asking because some players seems to have trouble with that, if the right combination is not found at first.
Maybe I have done something wrong here. This is just copy paste and modify from another script that someone made for me.
is that script ok?
SpoilerShow
Code: Select all
combination = 11222121211121
comb = {}
count = 0
solved = false
function buttonCombination(self)
if solved == false then
count = count + 1
for i = 1,2 do
if string.match(self.go.id, i) then
comb[count] = i
local order = table.concat(comb)
local s, b = string.find(combination, order)
if s == 1 and b == count and count < string.len(combination) then
elseif s == 1 and b == string.len(combination) then
force_field_94.controller:deactivate()
playSound("force_field_cast")
solved = true
else
combinationReset()
end
end
end
end
end
function combinationReset()
-- playSound("lock_incorrect")
playSound("no_sound")
for i = 1,string.len(combination) do
comb[i] = nil
end
count = 0
end
I'm asking because some players seems to have trouble with that, if the right combination is not found at first.
Maybe I have done something wrong here. This is just copy paste and modify from another script that someone made for me.
- Zo Kath Ra
- Posts: 940
- Joined: Sat Apr 21, 2012 9:57 am
- Location: Germany
Re: Ask a simple question, get a simple answer
How does the puzzle work?bongobeat wrote: ↑Thu Apr 06, 2023 10:33 am it is in a single script file, without anything else, and linked to 2 buttons named mkbforge1 and mkbforge2
I'm asking because some players seems to have trouble with that, if the right combination is not found at first.
Maybe I have done something wrong here. This is just copy paste and modify from another script that someone made for me.
And how does the script work?
(if you can't answer this question, then that's the problem)
And what "trouble" are the players having?
It helps to be precise when reporting bugs...
Re: Ask a simple question, get a simple answer
Just testing something in chatgtp ...
It answered:
First, the variable combination is assigned a string of numbers which represents a combination to be solved. Then, there are three global variables: count to keep track of the number of buttons pressed, solved to check if the combination has been solved, and buttons to store the possible values of the buttons.
The function buttonCombination is called when a button is pressed. It first checks if the combination has already been solved, and if so, returns immediately. It then loops through the buttons table to find which button was pressed. If the button was pressed, count is incremented, and the order variable is created by replacing the button value in the button's id with the current count.
If order is a substring of combination and is not equal to combination, the function returns immediately without doing anything else. If order is equal to combination, it deactivates a controller and plays a sound, sets solved to true, and returns. Otherwise, it calls combinationReset function to reset count.
The combinationReset function resets the count variable to 0.
Overall, this code checks if the button presses match a specific combination and activates the corresponding action if successful.
And on the question: what happens when the player does not find the right combination right away in this script? it answered
If the player does not find the right combination right away, the combinationReset() function is called. This function resets the count variable to 0, effectively starting over the combination guessing process. Additionally, it plays a sound (either "lock_incorrect" or "no_sound" depending on which one is commented out), indicating to the player that they have made a mistake. The player can then try again to find the correct combination. This process continues until the player enters the correct combination or chooses to give up.
Code: Select all
local combination = "11222121211121"
local count = 0
local solved = false
local buttons = {"1", "2"}
function buttonCombination(self)
if solved then return end
for i = 1, #buttons do
if self.go.id:find(buttons[i]) then
count = count + 1
local order = self.go.id:gsub(buttons[i], count)
if combination:find(order, 1, true) == 1 and #order < #combination then
return
elseif combination == order then
force_field_94.controller:deactivate()
playSound("force_field_cast")
solved = true
return
end
combinationReset()
end
end
end
function combinationReset()
-- playSound("lock_incorrect")
playSound("no_sound")
count = 0
end
First, the variable combination is assigned a string of numbers which represents a combination to be solved. Then, there are three global variables: count to keep track of the number of buttons pressed, solved to check if the combination has been solved, and buttons to store the possible values of the buttons.
The function buttonCombination is called when a button is pressed. It first checks if the combination has already been solved, and if so, returns immediately. It then loops through the buttons table to find which button was pressed. If the button was pressed, count is incremented, and the order variable is created by replacing the button value in the button's id with the current count.
If order is a substring of combination and is not equal to combination, the function returns immediately without doing anything else. If order is equal to combination, it deactivates a controller and plays a sound, sets solved to true, and returns. Otherwise, it calls combinationReset function to reset count.
The combinationReset function resets the count variable to 0.
Overall, this code checks if the button presses match a specific combination and activates the corresponding action if successful.
And on the question: what happens when the player does not find the right combination right away in this script? it answered
If the player does not find the right combination right away, the combinationReset() function is called. This function resets the count variable to 0, effectively starting over the combination guessing process. Additionally, it plays a sound (either "lock_incorrect" or "no_sound" depending on which one is commented out), indicating to the player that they have made a mistake. The player can then try again to find the correct combination. This process continues until the player enters the correct combination or chooses to give up.
Re: Ask a simple question, get a simple answer
Offtopic: I wonder what would happen if you paste a complete dungeon.lua into chatgpt and ask it to tell a story from it ?