Page 398 of 399

Re: Ask a simple question, get a simple answer

Posted: Sat Dec 14, 2024 3:26 am
by Eleven Warrior
Found the potion Thanks :)

Re: Ask a simple question, get a simple answer

Posted: Tue Dec 17, 2024 11:59 am
by Slava
Is there any way to check how much the party object or tile underneath it is lit?
i.e. is it in the shade or in the sun?
I understand that there are dynamic shadows under the open sky during the day and it is difficult to implement. But i want to neglect this. Just having day and night. I want to find a way (maybe someone already has it) how to determine the degree of light in the dungeon? Let's say there is a monster. I can getSight its component brain then depending on getAllAroundSight() check if it is looking towards the party. And this functionality I want to extend. We can always check seesParty, so I want to reduce the Sight of all monsters in the level depending on the lighting of the party.
What I'm envisioning. I need to get all the light components in the level, and then depending on getType() check getDirection(), getRange() and maybe getSpotAngle(), getSpotSharpness(). I have no idea what the last two do.
But I hope that all this is needed and can be done in a simpler way. After all, the game somehow understands what part of the texture is illuminated.

Re: Ask a simple question, get a simple answer

Posted: Tue Dec 17, 2024 7:28 pm
by Eleven Warrior
How do I stop the player from taking torches from the torch holder?

PS: I found it sorry.

Re: Ask a simple question, get a simple answer

Posted: Wed Dec 18, 2024 1:18 pm
by minmay
Slava wrote: Tue Dec 17, 2024 11:59 am Is there any way to check how much the party object or tile underneath it is lit?
i.e. is it in the shade or in the sun?
I understand that there are dynamic shadows under the open sky during the day and it is difficult to implement. But i want to neglect this. Just having day and night. I want to find a way (maybe someone already has it) how to determine the degree of light in the dungeon? Let's say there is a monster. I can getSight its component brain then depending on getAllAroundSight() check if it is looking towards the party. And this functionality I want to extend. We can always check seesParty, so I want to reduce the Sight of all monsters in the level depending on the lighting of the party.
What I'm envisioning. I need to get all the light components in the level, and then depending on getType() check getDirection(), getRange() and maybe getSpotAngle(), getSpotSharpness(). I have no idea what the last two do.
But I hope that all this is needed and can be done in a simpler way. After all, the game somehow understands what part of the texture is illuminated.
This is not a simple question. It is probably the most complicated question that has ever been asked in Grimrock modding. But I guess I might as well answer it here anyway.

You basically have two real options here, both of which are completely horrible. One is to use a umod (or equivalent) to execute native code that does additional render passes to get the lighting information you need (see here for an example of such an approach). Adding native code is necessary because there's nothing in Grimrock's Lua functions to copy the contents of render buffers or textures into main memory, nor to receive information from shaders. You will need to write 6 slightly different versions of a lot of this code (one each for D3D9 notebook renderer, D3D9 normal renderer, Windows OpenGL notebook, Windows OpenGL, Mac OpenGL notebook, Mac OpenGL).

The other option, which is worse in every way except portability, is to use the CPU to calculate how much light the party would theoretically receive. While this is easy in the notebook renderer, it's almost hopeless in normal rendering modes since those have shadows and you can't even access the shadow maps. You'll basically need to go through every shadow-casting model in your dungeon that's of significant size and choose a shape that approximates it and can be checked for collision with a ray very cheaply. Then, on any frame where you need this lighting information, cast a ray to the party from every light within range, checking for collision with all of those shapes in range. Oh, and you'll need to apply node transforms to the shapes for any animated models - you seem to want to include monsters in your dungeon, which are usually large, shadow-casting, and animated.

Other options that people may propose, which I do not consider real options:
3. designing your dungeon's levels, spells, monsters, etc. in such a way that whenever this lighting value would matter, it's just trivial to determine and can be baked into the tiles or whatever.
4. have your code just guess how much lighting the party is in and regularly get it completely wrong

I don't think these are real options because the only reason you'd consider adding this mechanic in the first place is that you want to actually do something with it, with moving light sources and shadows (rules out 3.) and the lighting value actually mattering to the player (rules out 4.)

Re: Ask a simple question, get a simple answer

Posted: Thu Dec 19, 2024 7:38 am
by Slava
It is probably the most complicated question that has ever been asked in Grimrock modding.
In that case, thank you very much for your reply Minmay!
One is to use a umod
Unfortunately I don't have access to steam (don't want to) and don't have access to umod. I have seen the source code though, and a way to modify it without using umod. The whole thing really seems horrible to me. Despite being a bit of a programmer, I'm not a game developer. I have no idea how to implement this.
cast a ray to the party
I haven't found anything that allows raytracing to be used in a game or mod. Even if this functionality is there, I don't see a way to control it other than again climbing into the source code of the game.
3. designing your dungeon's levels, spells, monsters, etc.
I was also thinking about the third option. It seems more realistic to me. There is no problem to design a dungeon so that then manually set the light level. I see it the same way we draw a map of heights, noise and reflections.
4. have your code just guess how much lighting the party is in and regularly get it completely wrong
That's something I already agree with.
I don't think these are real options because the only reason you'd consider adding this mechanic in the first place is that you want to actually do something with it, with moving light sources and shadows (rules out 3.) and the lighting value actually mattering to the player (rules out 4.)
My goal is to add stels mechanics everywhere, not just where it may have been planned and programmed. I think that would be interesting for players.

Anyway. I'll give it some thought. You've clarified the issue for me. Thanks again!

Re: Ask a simple question, get a simple answer

Posted: Sat Dec 21, 2024 8:55 am
by minmay
Slava wrote: Thu Dec 19, 2024 7:38 am
cast a ray to the party
I haven't found anything that allows raytracing to be used in a game or mod. Even if this functionality is there, I don't see a way to control it other than again climbing into the source code of the game.
I'm not talking about ray tracing, this is much more primitive than that: just checking if a ray would intersect any of the aforementioned shapes at a distance smaller than its distance to the party's position.
Grimrock has some functions for getting ray intersection distances already (isectRayTriangle, isectRayBox, isectRayPlane, isectRaySphere, Mesh:raycast()), but they aren't available in the scripting interface and you'd probably want to write more specialized code here for performance reasons anyway.

The intersection testing itself isn't complicated if you have a passing familiarity with linear algebra; you can get the distance at which a ray intersects a box/plane/sphere with a few dot products and comparisons, and if the shape is transformed you can just transform the ray to the shape's local space first. Most of the work would be in:
1. making sure every shadow-casting thing in your dungeon has appropriate shapes for this attached to it, and that you don't accidentally put them on any non-shadow-casting things - you can imagine ways to automate this, but those would themselves take time to design and still require a lot of manual refinement.
2. partitioning those shapes so that the performance is acceptable (no matter how optimized your ray intersection code is, if you're going through every shape on the map for every shadow-casting light source near the party, it probably won't be as fast as you'd like).

Re: Ask a simple question, get a simple answer

Posted: Tue Dec 24, 2024 7:37 pm
by 7Soul
For some reason, this works:

Code: Select all

local altar = spawn("altar", self.go.level, self.go.x, self.go.y + dy, self.go.facing, self.go.elevation, "s_" .. "altar" .. "_" ..  s)
altar.surface:addItem(spawn(item).item)
But this causes an exception saying addItem requires an ItemComponent:

Code: Select all

for e in self.go.map:entitiesAt(self.go.x, self.go.y + dy) do
	if e.surface then 
		print(e.id) -- it prints the id of the altar I just spawned
		e.surface:addItem(spawn(item).item) 
		break
	end
end
I assume I messed something up with uModding, but maybe I'm just doing something dumb so I'm asking here. These are being called by a script_entity btw


edit:

huh but if I use

Code: Select all

local altar = findEntity(altarId)
if altar then
	altar.surface:addItem(spawn("blue_gem").item)
end
It works fine

Re: Ask a simple question, get a simple answer

Posted: Tue Dec 24, 2024 11:08 pm
by Zo Kath Ra
7Soul wrote: Tue Dec 24, 2024 7:37 pm But this causes an exception saying addItem requires an ItemComponent:

Code: Select all

e.surface:addItem(spawn(item).item) 
What's the value of the "item" variable?
If the "item" variable has the wrong value, then the spawned entity will not have an item component.

Maybe add a "print(item)" to the loop?

Re: Ask a simple question, get a simple answer

Posted: Tue Dec 24, 2024 11:25 pm
by 7Soul
Zo Kath Ra wrote: Tue Dec 24, 2024 11:08 pm
7Soul wrote: Tue Dec 24, 2024 7:37 pm But this causes an exception saying addItem requires an ItemComponent:

Code: Select all

e.surface:addItem(spawn(item).item) 
What's the value of the "item" variable?
If the "item" variable has the wrong value, then the spawned entity will not have an item component.

Maybe add a "print(item)" to the loop?
It works if I spawn it outside of the loop. If I spawn the altar and then spawn the item on it it's fine. If I spawn the altar and then use entitiesAt to find the altar, it doesn't work. And as you can see in the code, the loop does find the altar and does call addItem but the function doesn't recognize the ItemComponent

I also just noticed that I can't access the .name property of an object in the entitiesAt loop either:

Code: Select all

for obj in self.go.map:entitiesAt(self.go.x, self.go.y) do
	print(obj.name, obj.id) -- prints nil, and the correct id of the obj
end

Code: Select all

local ob = spawn("blue_gem")
print(obj.name, obj.id) -- prints "blue_gem, blue_gem_1"
This probably has something to do with how my map generator creates the map, but I have no idea what's going on, specially since other map functions seem to work fine

Re: Ask a simple question, get a simple answer

Posted: Wed Dec 25, 2024 8:47 am
by Slava
7Soul wrote: Tue Dec 24, 2024 7:37 pm But this causes an exception saying addItem requires an ItemComponent:
Try this

Code: Select all

local gem = "blue_gem"
for e in self.go.map:entitiesAt(self.go.x, self.go.y + dy) do
	if e and e.surface then
		local o = spawn(gem).item		
		e.go.surface:addItem(o) 
		break
	end
end