Hey, I would like to try to create an item similar to the Lens of Truth from OoT, and I would just like to make sure something like that is possible. My initial thought process is to make the item enable specific dynamic tiles while it is being used and then re-disable them when the item is no longer in use.
I have never done it yet. You probably want to do show/hide dynamic tiles, but also chests, enemies, etc.
Enabling/disabling entities is probably a way. Another way is to change visibility with set_visible(). It depends on whether you want entities to still be present and act as obstacle when not seen.
To control what entities you want to enable/disable or show/hide, you can do something based on their name. The lens of truth script would do something like
-- Hide all entities whose name starts with "lens_"
for entity in map:get_entities("lens_") do
entity:set_visible(false)
end
I am only giving the idea. You would probably hide the entities when a map starts with the lens off, show them with similar code when the lens is used, and hide them when the lens stops.
But maybe this would conflict with other systems that already do something based on names. Like the separator manager or a script that opens a door when all enemies with some prefix are killed.
So a more robust solution can be to store, on each map who needs it, a list of entities affected by the lens of truth.
Usually, there are not hundreds of maps with entities reacting to the lens of truth so this is okay to maintain.
The lens of truth script would look like
-- Hide all entities that the map wants to.
if map.lens_entities ~= nil then
for entity in ipairs(map.lens_entities) do
entity:set_visible(false)
end
end
And map scripts that want to make entities react to the lens of truth would do
local map = ...
map.lens_entities = { enemy_1, my_chest, an_invisible_tile }
-- ... rest of the map script
And for the displaying, you can show a semi-transparent pink image over the game, with a fully transparent circle at the center. Possibly as a HUD element.
The only problem is that the circle part at the center should remain centered on the hero, and the hero is not always centered on the screen due to map limits and separator. But this information can be retrieved by getting the position of the camera. Show the image centered at (hero_x - camera_x, hero_y - camera_y).
Hi! This seems a cool feature to script for a fangame, and it should not be too hard. You can also use the same kind of functions to hide false objects and walls. Enabling/disabling is worse because you could get stuck if you make the hero overlap some solid entity, so it would be better just changing the visibility with set_visible.
The only restriction you have is that you cannot show or hide only a part of each entity, so maybe it would be better to make the outer part of the circle completely opaque. This is better if you hide/show very large entities (like a bridge).
Hello !
I've done something like this when I developped the lens for my project with RM2K. I didn't make it yet with solarus but I have a lot of things to do before !!
You can first in you item script call a sprite representing the lens effect and create a sensor around the clear area that follows the hero and display the event / active it if it is in the sensor range.
This item is also in my todo, I might start it soon.
Since the Lens of Truth is separated in 2 process (on and off), it might be more complex, you might need more coding to do in on_using() and in on_map_changed (if you want to keep it active in another map while being teleported)
This is a mock up but this is what I'm going to do, but, I don't know how to control the magic
if state ==1then
magic_timer = sol.timer.start(500, function()
magic - 1
return true
end)
else magic_timer:stop()
end
This is a brieve thing on the current script, it works in-game but the magic drop drastivally, magic - 1 isn't stopped when the item is stopped
(http://i.imgur.com/8zEyr5A.png)
Perhaps you could give some context? Like, where those variables are defined and when the if-condition is checked. But anyway, it would probably be less error-prone to check inside of the timer whether it should still be executed. Like this:
sol.timer.start(500,function()
if state == 1 then --A state of one probably means that the lens are activated. Correct me if I'm wrong
magic = magic - 1
return true
end
end)
Quote from: the bread on November 18, 2015, 04:29:57 PM
Perhaps you could give some context? Like, where those variables are defined and when the if-condition is checked. But anyway, it would probably be less error-prone to check inside of the timer whether it should still be executed. Like this:
sol.timer.start(500,function()
if state == 1 then --A state of one probably means that the lens are activated. Correct me if I'm wrong
magic = magic - 1
return true
end
end)
State = what is the current item state (on or off)
magic : getting the current magic level and set an algorythm that will take 1 Magic P. each 500 milliseconds.
return true = the timer is looped
The condition is active when the state of the item, declared in a local (game:get_value()) reach 1., the others are also local variables.
This might be the culprit
Everything is explained in the API
There is another method to do the lens of truth much easier but it need pixel opacity calculations on a surface, which is still not possible to do with solarus