Ask a simple question, get a simple answer
Re: Ask a simple question, get a simple answer
This doesn't work for maps with non-default water elevations.
*And doesn't detect if they are in the water. ( ?)
(Though it could work reasonably well on default overland maps. )
*And doesn't detect if they are in the water. ( ?)
(Though it could work reasonably well on default overland maps. )
Re: Ask a simple question, get a simple answer
Yeah I didn't have to check if they were actually in the water because usually you won't have solid ground in a part of the map that's below the water in another section of the same map. So checking if you're below the level of any watersurface in the map was enough
Then I guess you could do waterLevel = entity:getWorldPositionY() - 0.4 instead of the -0.6 so it works for water that isn't at height 0
Then I guess you could do waterLevel = entity:getWorldPositionY() - 0.4 instead of the -0.6 so it works for water that isn't at height 0
Re: Ask a simple question, get a simple answer
Here is a map with water at level zero:
https://player.vimeo.com/video/335643649
Your method would work with it, but (also) its only submerged area is a type 2 water tile. So being on that tile means they are under water.
*Yet another way to detect a party under water (suitable for small areas) is to simply to place underwater floor_triggers that only activate for the party; and check if they are pressed.
https://player.vimeo.com/video/335643649
Your method would work with it, but (also) its only submerged area is a type 2 water tile. So being on that tile means they are under water.
*Yet another way to detect a party under water (suitable for small areas) is to simply to place underwater floor_triggers that only activate for the party; and check if they are pressed.
Re: Ask a simple question, get a simple answer
Thanks for the replies, but the whole underwater bit just makes my head hurt and nothing seems to work. Gonna leave that to those who know what they're doing.
Are there any known downsides to this when used in huge mods, such as lag or crashes or the likes? And does a reload of the game reset the timer or is its progress saved? This would be especially important for long timers, such as 3600 or 7200 second ones.
I am still trying to turn levers and buttons unclickable after a single use, the below only allows for disableSelf on a button, but it is still animated. It does work with scripts for individual objects like "wall_button_1.clickable:disable()", but I cannot get it to work on the item definition to have it click into place by default if the disableSelf box is ticked.
Just to clarify things: With the party object and the timer attached I now have a global timer running "in the background", right? So whenever I connect timer objects with scripts for respawn and individual timers for each of those, I get to use numerous timers simultaneously?Zo Kath Ra wrote: ↑Thu Jun 03, 2021 9:50 am Or you can attach timers to the party dynamically:
http://www.grimrock.net/forum/viewtopic ... 23#p121823
Are there any known downsides to this when used in huge mods, such as lag or crashes or the likes? And does a reload of the game reset the timer or is its progress saved? This would be especially important for long timers, such as 3600 or 7200 second ones.
I am still trying to turn levers and buttons unclickable after a single use, the below only allows for disableSelf on a button, but it is still animated. It does work with scripts for individual objects like "wall_button_1.clickable:disable()", but I cannot get it to work on the item definition to have it click into place by default if the disableSelf box is ticked.
SpoilerShow
Code: Select all
defineObject{
name = "wall_button",
baseObject = "wall_button",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
return self:isEnabled()
end,
},
}
}
Re: Ask a simple question, get a simple answer
Code: Select all
defineObject{
name = "wall_button",
baseObject = "wall_button",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
local enabled = self:isEnabled()
if not enabled then
self.go.clickable:disable()
end
return enabled
end,
},
}
}
- Zo Kath Ra
- Posts: 937
- Joined: Sat Apr 21, 2012 9:57 am
- Location: Germany
Re: Ask a simple question, get a simple answer
> With the party object and the timer attached I now have a global timer running "in the background", right?Lorial wrote: ↑Fri Jun 04, 2021 8:27 am Just to clarify things: With the party object and the timer attached I now have a global timer running "in the background", right? So whenever I connect timer objects with scripts for respawn and individual timers for each of those, I get to use numerous timers simultaneously?
Are there any known downsides to this when used in huge mods, such as lag or crashes or the likes? And does a reload of the game reset the timer or is its progress saved? This would be especially important for long timers, such as 3600 or 7200 second ones.
You'll have a timer that's always running.
They'll probably work even when the party is resting, but I haven't tried this yet.
> So whenever I connect timer objects with scripts for respawn and individual timers for each of those, I get to use numerous timers simultaneously?
As long as the timer components have different names, you can have as many as you need.
> Are there any known downsides to this when used in huge mods, such as lag or crashes or the likes?
Maybe if there are thousands of timers, and they all have a timer interval of 0.
But if your timers only fire once per hour, there shouldn't be a problem.
If your timers negatively affect performance, you can move all code into a single timer, and keep a table of countdowns.
Or you can disable all timers, and start them manually, with their starting times offset slightly. This will prevent them from all activating at the same time.
> And does a reload of the game reset the timer or is its progress saved?
The progress is saved, otherwise some puzzles wouldn't work.
Re: Ask a simple question, get a simple answer
Thank you so much for that, Isaac.
Unfortunately, this leaves it clickable twice, even though the second click does nothing (tested with toggles). Fiddled around a bit and I now have a single-use button, just like I wanted. However, the disableSelf box has no effect. So now there are three versions.
1) Single activation if disableSelf is checked, remains clickable:
2) Single activation if disableSelf is checked, clickable twice (confusing):
3) Single use, disregarding disableSelf box:
The ideal version would, of course, be a single interaction/click when disableSelf is checked, but I can't figure it out. What am I missing?!
Unfortunately, this leaves it clickable twice, even though the second click does nothing (tested with toggles). Fiddled around a bit and I now have a single-use button, just like I wanted. However, the disableSelf box has no effect. So now there are three versions.
1) Single activation if disableSelf is checked, remains clickable:
SpoilerShow
Code: Select all
defineObject{
name = "wall_button",
baseObject = "wall_button",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
return self:isEnabled()
end,
},
}
}
SpoilerShow
Code: Select all
defineObject{
name = "wall_button_disable",
baseObject = "wall_button",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
local enabled = self:isEnabled()
if not enabled then
self.go.clickable:disable()
end
return enabled
end,
},
}
}
SpoilerShow
Code: Select all
defineObject{
name = "wall_button_single",
baseObject = "wall_button",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
if not enabled then
self.go.clickable:disable()
end
end,
},
}
}
The ideal version would, of course, be a single interaction/click when disableSelf is checked, but I can't figure it out. What am I missing?!
Thanks for clearing that up, Zo Kath Ra. Time to put it to good use, no pun intended.Zo Kath Ra wrote: ↑Fri Jun 04, 2021 1:08 pm You'll have a timer that's always running.
They'll probably work even when the party is resting, but I haven't tried this yet.[...]
- Zo Kath Ra
- Posts: 937
- Joined: Sat Apr 21, 2012 9:57 am
- Location: Germany
Re: Ask a simple question, get a simple answer
If you want the Button component's disableSelf checkbox to have an effect, you need to look at its value.Lorial wrote: ↑Sat Jun 05, 2021 7:14 am Thank you so much for that, Isaac.
Unfortunately, this leaves it clickable twice, even though the second click does nothing (tested with toggles). Fiddled around a bit and I now have a single-use button, just like I wanted. However, the disableSelf box has no effect. So now there are three versions.
Code: Select all
defineObject{
baseObject = "wall_button",
name = "wall_button_new",
components = {
{
class = "Button",
sound = "button",
onActivate = function(self)
print(self.go.id, "onActivate")
print(self.go.id, "isEnabled", self:isEnabled())
if self:getDisableSelf() then
self.go.clickable:disable()
end
return self:isEnabled()
end,
},
},
}
Re: Ask a simple question, get a simple answer
Perfect, works like a charm and for all buttons, secret buttons and levers. Now disableSelf is finally working as intended. Now off to removing all the scripts for individual buttons, yay. Thanks again, Zu Kath Ra.Zo Kath Ra wrote: ↑Sat Jun 05, 2021 10:35 am If you want the Button component's disableSelf checkbox to have an effect, you need to look at its value.
Re: Ask a simple question, get a simple answer
coucou there,
I wonder if you can help to resolve this:
I got an issue with a monster/and it's attack, it can crash the game after it spawns its shock attacks all around:
here is the error message that I got in the editor: in this case the monster was on the ground, and I stood 2 heights above.
this is the line mentionned in the screen (and the whole function):
This is the complete monster script:
It is actually a copy of the magma golem monster, except it does shock damage.
Here are the spawned objects:
The shock_wave:
----------------------------------------------------------
----- long range attack --------------------------
Originaly, its spawned a mini monster on the hit, instead of the shock_fire object, I removed that for testing, after a crash report. I thought that this can come from spawning a monster, in an obstacle or wall.
the shock fire effect:
Object:
Particle:
The blast effect:
I wonder if you can help to resolve this:
I got an issue with a monster/and it's attack, it can crash the game after it spawns its shock attacks all around:
here is the error message that I got in the editor: in this case the monster was on the ground, and I stood 2 heights above.
SpoilerShow
SpoilerShow
Code: Select all
onAttack = function(self)
local x,y = self.go.x,self.go.y
local dx,dy = getForward(self.go.facing)
x = x + dx
y = y + dy
spawn("shock_wave", self.go.level, x, y, 0, self.go.elevation)
party.party:shakeCamera(0.7, 0.3)
end,
SpoilerShow
Code: Select all
defineObject{
name = "redrock_golem",
baseObject = "base_monster",
components = {
{
class = "Model",
model = "assets/models/monsters/magma_golem.fbx",
material = "mountain_wall_01",
storeSourceData = true, -- must be enabled for mesh particles to work
},
{
class = "Animation",
animations = {
idle = "assets/animations/monsters/magma_golem/magma_golem_idle.fbx",
moveForward = "assets/animations/monsters/magma_golem/magma_golem_walk.fbx",
turnLeft = "assets/animations/monsters/magma_golem/magma_golem_turn_left.fbx",
turnRight = "assets/animations/monsters/magma_golem/magma_golem_turn_right.fbx",
turnAround = "assets/animations/monsters/magma_golem/magma_golem_turn_around.fbx",
attack = "assets/animations/monsters/magma_golem/magma_golem_attack.fbx",
attack2 = "assets/animations/monsters/magma_golem/magma_golem_punch_attack.fbx",
groundPound = "assets/animations/monsters/magma_golem/magma_golem_ground_pound.fbx",
rangedAttack = "assets/animations/monsters/magma_golem/magma_golem_ranged_attack.fbx",
turnAttackLeft = "assets/animations/monsters/magma_golem/magma_golem_turn_attack_left.fbx",
turnAttackRight = "assets/animations/monsters/magma_golem/magma_golem_turn_attack_right.fbx",
getHitFrontLeft = "assets/animations/monsters/magma_golem/magma_golem_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/magma_golem/magma_golem_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/magma_golem/magma_golem_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/magma_golem/magma_golem_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/magma_golem/magma_golem_get_hit_right.fbx",
fall = "assets/animations/monsters/magma_golem/magma_golem_get_hit_front_left.fbx",
meteorFall = "assets/animations/monsters/magma_golem/magma_golem_meteor.fbx",
},
currentLevelOnly = true,
onAnimationEvent = function(self, event)
if event == "footstep" then
if self.go.brain.partyOnLevel then
local dist = math.abs(party.x - self.go.x) + math.abs(party.y - self.go.y)
if dist < 5 then
party.party:shakeCamera(0.7 / dist, 0.3)
end
end
end
end,
},
{
class = "Monster",
meshName = "stone_elemental_mesh",
hitSound = "magma_golem_hit",
dieSound = "magma_golem_die",
footstepSound = "magma_golem_footstep",
hitEffect = "hit_flame",
capsuleHeight = 0.2,
capsuleRadius = 0.7,
collisionRadius = 1.5,
collisionHeight = 2.5,
health = 3000,
protection = 70,
evasion = -10,
exp = 2000,
lootDrop = { 100, "red_rock", 60, "red_rock", 40, "red_rock", 20, "red_rock", 10, "red_rock" },
immunities = { "sleep", "blinded", "knockback", "frozen", "poisoned" },
resistances = {
shock = "immune",
fire = "weak",
frost = "resist",
poison = "immune",
},
traits = { "elemental" },
},
{
class = "MagmaGolemBrain",
name = "brain",
sight = 30,
morale = 100,
},
{
class = "MonsterMove",
name = "move",
sound = "magma_golem_walk",
cooldown = 3,
},
{
class = "MonsterTurn",
name = "turn",
sound = "magma_golem_walk",
},
{
class = "MonsterAttack",
name = "basicAttack",
animation = "attack",
attackPower = 110,
woundChance = 40,
cooldown = 2,
sound = "magma_golem_attack",
onBeginAction = function(self)
-- randomize animation
if math.random() < 0.5 then
self:setAnimation("attack")
else
self:setAnimation("attack2")
end
end,
},
{
class = "MonsterAttack",
name = "turnAttack",
attackPower = 140,
cooldown = 3,
sound = "magma_golem_turn_attack",
accuracy = 70,
woundChance = 40,
turnToAttackDirection = true,
cameraShake = true,
cameraShakeIntensity = 0.7,
screenEffect = "damage_screen",
},
{
class = "MonsterAttack",
name = "groundPound",
animation = "groundPound",
cooldown = 10,
repeatChance = 0,
sound = "magma_golem_ground_pound",
onAttack = function(self)
local x,y = self.go.x,self.go.y
local dx,dy = getForward(self.go.facing)
x = x + dx
y = y + dy
spawn("shock_wave", self.go.level, x, y, 0, self.go.elevation)
party.party:shakeCamera(0.7, 0.3)
end,
},
{
class = "MonsterAttack",
name = "rangedAttack",
attackType = "projectile",
cooldown = 5,
animation = "rangedAttack",
sound = "magma_golem_ranged_attack",
onBeginAction = function(self)
self.go.spitParticle:restart()
end,
onAttack = function(self)
local projectile = self.go.monster:shootProjectile("redrock2_meteor", 3, 10, "jaw").projectile
projectile:setVelocity(15)
projectile:setGravity(16)
projectile:setIgnoreEntity(self.go, 1)
local dist = self.go.brain.partyDistY
if dist < 3 then
projectile:setFallingVelocity(0.1)
projectile:setVelocity(10)
elseif dist == 3 then
projectile:setFallingVelocity(1)
elseif dist == 4 then
projectile:setFallingVelocity(2.7)
elseif dist == 5 then
projectile:setFallingVelocity(5.5)
else
projectile:setFallingVelocity(7.5)
end
return false
end,
},
{
class = "Particle",
name = "spitParticle",
parentNode = "jaw",
particleSystem = "redrock_golem_spit",
offset = vec(0, 0, 0.1),
enabled = false,
},
},
}
Here are the spawned objects:
The shock_wave:
SpoilerShow
Code: Select all
defineObject{
name = "shock_wave",
baseObject = "base_spell",
components = {
{
class = "Blast",
delay = 0.2,
effect = "shockburst",
}
}
}
----- long range attack --------------------------
SpoilerShow
Code: Select all
defineParticleSystem{
name = "redrock_golem_spit",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,0},
boxMax = {0,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {0.7, 0.7},
colorAnimation = false,
color0 = {0.25, 0.5, 1},
opacity = 0.2,
fadeIn = 0.4,
fadeOut = 0.5,
size = {2, 2},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 2,
blendMode = "Additive",
objectSpace = true,
depthBias = 0.2,
},
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,-0.1},
boxMax = {0,0,-0.1},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {0.7, 0.7},
colorAnimation = false,
color0 = {0.25, 0.5, 1},
opacity = 1,
fadeIn = 0.3,
fadeOut = 0.5,
size = {0.6, 0.6},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 2,
blendMode = "Additive",
objectSpace = true,
depthBias = 0.2,
}
}
}
defineObject{
name = "redrock2_meteor",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "lightning_bolt_greater",
},
{
class = "Light",
color = vec(0.25, 0.5, 1),
brightness = 15,
range = 7,
castShadow = true,
fillLight = true,
},
{
class = "Sound",
sound = "lightning_bolt",
},
{
class = "Sound",
name = "launchSound",
sound = "lightning_bolt_launch",
},
{
class = "Projectile",
spawnOffsetY = 1.35,
velocity = 10,
radius = 0.1,
hitEffect = "redrockgolem_blast",
onProjectileHit = function(self, what, entity)
local x,y,level,map = self.go.x,self.go.y,self.go.level,self.go.map
local elevation = map:getElevation(x, y)
spawn("shock_fire", level, x, y, 0, elevation)
if y > 0 then spawn("shock_fire", level, x, y-1, 0, elevation) end
if y < map:getHeight() - 1 then spawn("shock_fire", level, x, y+1, 1, elevation) end
if x > 0 then spawn("shock_fire", level, x-1, y, 2, elevation) end
if x < map:getWidth() - 1 then spawn("shock_fire", level, x+1, y, 3, elevation) end
end,
},
},
}
the shock fire effect:
Object:
SpoilerShow
Code: Select all
defineObject{
name = "shock_fire",
baseObject = "base_spell",
components = {
{
class = "Model",
-- model = "mod_assets/models/wall_fire2.fbx",
model = "assets/models/effects/wall_fire.fbx",
materialOverrides = { ["flame_streak"] = "flame_streak2", ["fire_puddle"] = "fire_puddle2" },
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 = "shock_fire",
offset = vec(0, 0, 0),
--destroyObject = true,
},
{
class = "Particle",
name = "impact",
particleSystem = "shock_fire_impact",
offset = vec(0, 0, 0),
sortOffset = 3,
--destroyObject = true,
},
{
class = "Light",
color = vec(0.25, 0.4, 1.25),
brightness = 35,
range = 6,
offset = vec(0, 1.2, 0),
--fadeOut = 0.75,
disableSelf = true,
},
{
class = "TileDamager",
attackPower = 35,
damageType = "shock",
repeatCount = 5,
repeatDelay = 4.3/5,
},
},
}
SpoilerShow
Code: Select all
defineParticleSystem{
name = "shock_fire",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0, 1, 0},
boxMax = {0, 1, 0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow_ring.tga",
lifetime = {1000, 1000},
colorAnimation = false,
color0 = {0.090000, 0.495000, 1.500000},
opacity = 0.1,
fadeIn = 0.01,
fadeOut = 0.5,
size = {7, 7},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
},
-- sparkles
{
emissionRate = 200,
emissionTime = 0,
maxParticles = 300,
boxMin = {-1.3, -0.3,-1.3 },
boxMax = { 1.3, 1.5, 1.3 },
sprayAngle = {0,180},
velocity = {0.1,0.5},
objectSpace = false,
texture = "assets/textures/particles/force_field_particle.tga",
lifetime = {0.4,1},
color0 = {0.8*1.5,1.2*1.5,1.9*1.5},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.1,
size = {0.03, 0.1},
gravity = {0,2.3,0},
airResistance = 0.01,
rotationSpeed = 10,
blendMode = "Additive",
},
-- glow sparkles
{
emissionRate = 30,
emissionTime = 0,
maxParticles = 100,
boxMin = {-1.3, 0.0,-1.3 },
boxMax = { 1.3, 0.5, 1.3 },
sprayAngle = {0,180},
velocity = {0.1,0.5},
texture = "assets/textures/particles/glow.tga",
lifetime = {0.2, 0.6},
colorAnimation = false,
color0 = {0.090000, 0.495000, 1.500000},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.5,
size = {0.3, 1.8},
gravity = {0,1.5,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
},
}
}
defineParticleSystem{
name = "shock_fire_impact",
emitters = {
-- sparkles
{
spawnBurst = true,
maxParticles = 1000,
boxMin = {-1.3, 0.0, -1.3 },
boxMax = { 1.3, 0.1, 1.3 },
sprayAngle = {0,180},
velocity = {2,5},
objectSpace = false,
texture = "assets/textures/particles/force_field_particle.tga",
lifetime = {0.3,0.6},
color0 = {0.8*1.5,1.2*1.5,1.8*1.5},
opacity = 1,
fadeIn = 0.01,
fadeOut = 0.3,
size = {0.05, 0.3},
gravity = {0,0,0},
airResistance = 0.01,
rotationSpeed = 3,
blendMode = "Additive",
},
-- glow sparkles
{
spawnBurst = true,
maxParticles = 20,
boxMin = {-1.3, 0.0,-1.3 },
boxMax = { 1.3, 0.1, 1.3 },
sprayAngle = {0,180},
velocity = {0.1,0.5},
texture = "assets/textures/particles/glow.tga",
lifetime = {0.2, 0.6},
colorAnimation = false,
color0 = {0.090000, 0.495000, 1.500000},
opacity = 1,
fadeIn = 0.01,
fadeOut = 0.5,
size = {0.3, 1.8},
gravity = {0,1.5,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
},
}
}
SpoilerShow
Code: Select all
defineObject{
name = "redrockgolem_blast",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "redrockgolem_blasteffect",
destroyObject = true,
},
{
class = "Light",
color = vec(0.25, 0.5, 1),
brightness = 40,
range = 10,
fadeOut = 0.5,
disableSelf = true,
fillLight = true,
},
{
class = "TileDamager",
attackPower = 80,
damageType = "shock",
screenEffect = "frozen_screen",
sound = "mortar_hit_2",
},
},
}
defineParticleSystem{
name = "redrockgolem_blasteffect",
emitters = {
{ -- globe
spawnBurst = true,
maxParticles = Config.getRenderingQuality() == 1 and 512 or 4096,
sprayAngle = {0,180},
boxMin = {0,0,0},
boxMax = {0,0,0},
velocity = {40,48},
texture = "assets/textures/particles/goromorg_lantern.tga",
frameRate = 35,
frameSize = 64,
frameCount = 16,
lifetime = {0.5, 2.5},
colorAnimation = true,
color0 = {1, 1, 2},
color1 = {0.75, 0.90, 1.75},
color2 = {0.5, 0.65, 1.25},
color3 = {0.25, 0.5, 1},
opacity = 1,
fadeIn = 0.001,
fadeOut = 0.8,
size = {0.1, 0.3},
gravity = {0,0,0},
airResistance = 9,
rotationSpeed = 1,
blendMode = "Additive",
},
{ -- smoke
emissionRate = Config.getRenderingQuality() == 1 and 64 or 1024,
emissionTime = 0.3,
maxParticles = 512,
boxMin = {-5, -5, -5},
boxMax = {5, 5, 5},
sprayAngle = {0,100},
velocity = {0.1, 0.5},
texture = "assets/textures/particles/smoke_01.tga",
lifetime = {1,4},
color0 = {0.25, 0.5, 1},
opacity = 1,
fadeIn = 0.3,
fadeOut = 0.9,
size = {1, 3},
gravity = {0,0,0},
airResistance = 0.1,
rotationSpeed = 0.5,
blendMode = "Translucent",
},
{ -- not so floaty sparks
spawnBurst = true,
maxParticles = Config.getRenderingQuality() == 1 and 32 or 256,
boxMin = {-1,0.1,-1},
boxMax = {1,0.2,1},
sprayAngle = {0,50},
velocity = {16, 24},
texture = "assets/textures/particles/glow.tga",
lifetime = {1, 1.5},
colorAnimation = true,
color0 = {1, 2, 2},
color1 = {0.75, 0.7, 1},
color2 = {0.35, 0.6, 1},
color3 = {0.25, 0.5, 1},
opacity = 1,
fadeIn = 0.001,
fadeOut = 0.8,
size = {0.04, 0.08},
gravity = {0,-8,0},
rotationSpeed = 1,
airResistance = 2.6,
blendMode = "Additive",
depthBias = 0.006,
},
}
}