Ask a simple question, get a simple answer
Re: Ask a simple question, get a simple answer
The other thing is this project I'm working on is a resource pack. So I wont have any levels at all. So I would rather have something that's already set up. The other idea I was thinking of is to just have an interior model inside the stem a little behind the main surface, then just sink in the areas I want to have a glow. That way I could have a material on that inner stem that could have a rotating texture. The only problem with that is more polys
Re: Ask a simple question, get a simple answer
Objects of the same kind typically have the same object name, and components. These work for isolating them from everything else; (mostly just the names). Sets of objects can be given specific IDs as well; this can differentiate one or more [otherwise common] items from the rest.
The iterator functions are map.allEntities() and map.entitiesAt(x,y).
So to find all doors, you could search objects whose name or ID* contains 'door', or search for objects with a door component—not all of these are, or appear as doors in the game; but this works well for detecting monsters, with a monster component.
*Id strings for automatically spawned objects will be numeric, and not helpful; this only works well with hand placed objects.
One can also [repeatedly] use the global function findEntity() with string concatenation, to find matching entities one by one.
To your example:
It would work like this:for int i=0; i<10; i++
{
door_"i".open();
}
Code: Select all
for i = 1, 10 do
local target = findEntity("door_"..i) --can be nil
if target ~= nil and target.door ~= nil then --check exist, and has door component
target.door:open()
end
end
--this checks every object in the game, but does not check inside containers, surfaces, or in champion & monster inventories.
Code: Select all
function openDoors()
local level = 1
local map = Dungeon.getMap(level)
if map ~= nil then
for obj in map:allEntities() do
if obj ~= nil and obj.door ~= nil then
obj.door:open()
end
end
else print("map "..level.." doesn't exist")
end
end
So it is possible to animate emissiveMaps in materials, using the onUpdate hook.
https://vimeo.com/330293832
Re: Ask a simple question, get a simple answer
I like what you did there Isaac but I decided to just do the extra work and design it this way.
Video here.
https://www.youtube.com/watch?v=Eu7FOeRSnWc
EDIT: I did like the way this came out but, if I try to design more mushrooms using this style the poly count would be ridiculous. So I re-designed it again using these spores that attach to the stem. This way its easier to have an lod0 and lod1 for the main part of the mushroom. The spores will not have to lod out because they're already low poly
Video here.
https://www.youtube.com/watch?v=Eu7FOeRSnWc
EDIT: I did like the way this came out but, if I try to design more mushrooms using this style the poly count would be ridiculous. So I re-designed it again using these spores that attach to the stem. This way its easier to have an lod0 and lod1 for the main part of the mushroom. The spores will not have to lod out because they're already low poly
Re: Ask a simple question, get a simple answer
I think the auto building base script still runs every time on load. I'll save the game and load, on that load everything seems to be fine, but when I save and reload again the objects I had auto removed come back. On my stairs down and stairs up I have them removing the pillars and ground slope objects. But the onInit only runs once on the stairs right?minmay wrote: ↑Sat Apr 13, 2019 5:39 am Remember, minimalSaveState objects only save their name, id, level, x, y, facing, and elevation, they don't store any data about the components. So when they are spawned again upon loading, they create all their components again based on the definition, and all those components will run their onInit hooks again.
I would strongly recommend you make your autoDecoEdgeCave and autoDecoFloorDetailAll functions destroy the object when they're done. Even without this issue, there's no reason to keep the base_cave_ground, base_cave_wall, etc. objects around when they no longer do anything useful.
Stairs up
SpoilerShow
Code: Select all
defineObject{
name = "rc_stairs_up",
baseObject = "base_stairs_up",
components = {
{
class = "Model",
model = "mod_assets/stotp_models/red_cave/env/rc_stairs_up.fbx",
staticShadow = true,
},
{
class = "Null",
onInit = function(self)
local x = self.go.x
local y = self.go.y
local facing = self.go.facing
local level = self.go.level
local fx,fy = getForward(facing)
local rx,ry = getForward((facing+1)%4)
do
local x = self.go.x + fx
local y = self.go.y + fy
if x >= 0 and y >= 0 and x < 32 and y < 32 then
self.go.map:setAutomapTile(x, y, 4) -- rocky wall
end
end
-- destroy all pillars and slopes
for yy=0,2 do
for xx=-1,1 do
local x = x + rx * xx + fx * yy
local y = y + ry * xx + fy * yy
if x >= 0 and y >= 0 and x < 32 and y < 32 then
for e in self.go.map:entitiesAt(x, y) do
if e.name == "rc_pillar_01a"
or e.name == "rc_pillar_01b"
or e.name == "rc_pillar_02a"
or e.name == "rc_wall_slope"
then e:destroy()
end
end
end
end
end
end,
},
},
tags = { "shadowgate", "red cave", "vanblam" },
}
SpoilerShow
Code: Select all
defineObject{
name = "rc_stairs_down",
baseObject = "base_stairs_down",
components = {
{
class = "Model",
model = "mod_assets/stotp_models/red_cave/env/rc_stairs_down.fbx",
staticShadow = true,
},
{
class = "Null",
onInit = function(self)
local x = self.go.x
local y = self.go.y
local facing = self.go.facing
local level = self.go.level
local fx,fy = getForward(facing)
local rx,ry = getForward((facing+1)%4)
do
local x = self.go.x + fx
local y = self.go.y + fy
if x >= 0 and y >= 0 and x < 32 and y < 32 then
self.go.map:setAutomapTile(x, y, 4) -- rocky wall
end
end
-- destroy all pillars and slopes
for yy=0,2 do
for xx=-1,1 do
local x = x + rx * xx + fx * yy
local y = y + ry * xx + fy * yy
if x >= 0 and y >= 0 and x < 32 and y < 32 then
for e in self.go.map:entitiesAt(x, y) do
if e.name == "rc_pillar_01a"
or e.name == "rc_pillar_01b"
or e.name == "rc_pillar_02a"
or e.name == "rc_wall_slope"
then e:destroy()
end
end
end
end
end
end,
},
},
tags = { "shadowgate", "red cave", "vanblam" },
}
SpoilerShow
Code: Select all
do
local autoDecoEdgeCave = function(self)
local g = self.go
local supports = {
rc_edge_support_01=true,
rc_edge_support_02=true,
rc_edge_support_03=true,
rc_edge_support_04=true,
rc_edge_support_01b=true,
rc_edge_support_02b=true,
rc_edge_support_03b=true,
rc_edge_support_04b=true,
}
local rocks = {
rc_rocks_trim_01=true,
rc_rocks_trim_02=true,
rc_rocks_trim_03=true,
rc_wall_slope=true,
}
if g.map:getElevation(g.x,g.y) == g.elevation then
local choice = math.random()
if choice >= 0.85 then
g:spawn("rc_edge_support_01")
elseif choice >= 0.7 then
g:spawn("rc_edge_support_02")
elseif choice >= 0.55 then
g:spawn("rc_edge_support_03")
elseif choice >= 0.4 then
g:spawn("rc_edge_support_04")
end
end
if g.map:getElevation(g.x,g.y) == g.elevation then
local choice = math.random()
if choice >= 0.85 then
g:spawn("rc_edge_support_01b")
elseif choice >= 0.7 then
g:spawn("rc_edge_support_02b")
elseif choice >= 0.55 then
g:spawn("rc_edge_support_03b")
elseif choice >= 0.4 then
g:spawn("rc_edge_support_04b")
end
end
if g.map:getElevation(g.x,g.y) == g.elevation then
local choice = math.random()
if choice >= 0.8 then
g:spawn("rc_rocks_trim_01")
elseif choice >= 0.6 then
g:spawn("rc_rocks_trim_02")
elseif choice >= 0.4 then
g:spawn("rc_rocks_trim_03")
else
g:spawn("rc_wall_slope",g.level,g.x,g.y,math.random(0,3),g.elevation)
end
end
if g.name == "base_cave_wall" then
g:destroy()
end
end
local autoDecoFloorDetailAll = function(self)
local g = self.go
local grass = {
rc_grass_01a=true,
rc_grass_01b=true,
rc_grass_01c=true,
}
local tiles = {
rc_ground_tiles_01=true,
rc_ground_tiles_02=true,
rc_ground_tiles_03=true,
rc_ground_tiles_04=true,
rc_ground_tiles_05=true,
}
local pebbles = {
rc_ground_pebbles_01=true,
rc_ground_pebbles_02=true,
rc_ground_pebbles_03=true,
rc_ground_pebbles_04=true,
}
local choice = math.random()
local choice2 = math.random()
local choice3 = math.random()
if choice >= 0.6 then
spawn("rc_grass_01a",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice >= 0.4 then
spawn("rc_grass_01b",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice >= 0.2 then
spawn("rc_grass_01c",g.level,g.x,g.y,math.random(0,3),g.elevation)
end
if choice2 >= 0.94 then
spawn("rc_ground_tiles_01",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice2 >= 0.88 then
spawn("rc_ground_tiles_02",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice2 >= 0.82 then
spawn("rc_ground_tiles_03",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice2 >= 0.76 then
spawn("rc_ground_tiles_04",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice2 >= 0.7 then
spawn("rc_ground_tiles_05",g.level,g.x,g.y,math.random(0,3),g.elevation)
end
if choice3 >= 0.8 then
spawn("rc_ground_pebbles_04",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice3 >= 0.6 then
spawn("rc_ground_pebbles_01",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice3 >= 0.4 then
spawn("rc_ground_pebbles_02",g.level,g.x,g.y,math.random(0,3),g.elevation)
elseif choice3 >= 0.2 then
spawn("rc_ground_pebbles_03",g.level,g.x,g.y,math.random(0,3),g.elevation)
end
if g.name == "base_cave_ground" then
g:destroy()
end
end
defineObject{
name = "base_cave_wall",
baseObject = "base_wall",
components = {
{
class = "Null",
onInit = autoDecoEdgeCave,
},
},
}
defineObject{
name = "base_cave_ground",
baseObject = "base_floor",
components = {
{
class = "Null",
onInit = autoDecoFloorDetailAll,
},
},
}
end
Re: Ask a simple question, get a simple answer
Are you doing high-poly baked normal maps?vanblam wrote: ↑Mon Apr 15, 2019 2:19 am I did like the way this came out but, if I try to design more mushrooms using this style the poly count would be ridiculous. So I re-designed it again using these spores that attach to the stem. This way its easier to have an lod0 and lod1 for the main part of the mushroom. The spores will not have to lod out because they're already low poly
Re: Ask a simple question, get a simple answer
No just using the basic blender surface normals and I use Quixel Suite 2 for texture normals.Isaac wrote: ↑Tue Apr 16, 2019 1:49 amAre you doing high-poly baked normal maps?vanblam wrote: ↑Mon Apr 15, 2019 2:19 am I did like the way this came out but, if I try to design more mushrooms using this style the poly count would be ridiculous. So I re-designed it again using these spores that attach to the stem. This way its easier to have an lod0 and lod1 for the main part of the mushroom. The spores will not have to lod out because they're already low poly
But when I designed the veins coming up the edges I had to create more faces just make it look right. It was around 1100 faces. The set up I have now its down to 650 for lod0 and 300 for lod1.
Re: Ask a simple question, get a simple answer
1,100 tris per mushroom would be fine honestly. The lod1_mesh for a forest oak is 718 tris and has the added overhead of rigged animation and a double-sided material.
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
True..To be honest it was also a pain to manipulate the shape of the stem to create other mushrooms that look different without designing a new stem from scratch, on top of that I had to do a lot more texture work to make the seams not as visible. The new style still looks nice and I'm able to pump out other mushrooms quicker, plus the texture work is easier (I'm lazy lol) .
_____________________
Is there a way to have particle effects disappear at a certain distance from the player?
_____________________
How do I add a part to this that will tell it not to spawn if there is a particular object in a 3x3 area?
Code: Select all
if g.map:getElevation(g.x,g.y) == g.elevation then
local choice = math.random()
if choice >= 0.85 then
g:spawn("rc_edge_support_01")
elseif choice >= 0.7 then
g:spawn("rc_edge_support_02")
elseif choice >= 0.55 then
g:spawn("rc_edge_support_03")
elseif choice >= 0.4 then
g:spawn("rc_edge_support_04")
end
end