ToME: the Tales of Maj'Eyal

Everything about ToME
It is currently Fri Apr 10, 2020 4:50 am

All times are UTC




Post new topic Reply to topic  [ 57 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Fri Feb 17, 2012 1:54 pm 
Offline
Loremaster

Joined: Thu Sep 23, 2010 10:18 pm
Posts: 3516
Location: London, England
Planning my 7DRL and there's a few things that come to mind that I'm not sure how to do...

1. Play a sound. How ToME does it is a bit of a mystery - there seem to be weird files involved. What's the easiest way to trigger a sound to be played?

2. Trigger an action on moving onto a square.

3. Show a full screen image overlaid on the map with transparency (is this possible?) An animation would be good too.

4. Use the shader thingummies to make everything greyscale apart from the colour red, which would be upped in brightness. (Is this possible?) Alternatively just reshade everything red, but without making things darker.

5. Have randomised colours of map tiles, so for instance a load of #'s in a forest would all be slightly randomised colours of green. Can you set the numbers in the tile declarations to be slightly random?

6. Adding blood stains to the map on creature death - essentially just recolouring the tiles.

7. Effects across the whole level on boss death, such as recolouring all tiles, changing tiles (earthquake style effect) and killing all other creatures.

8. Have a door that only opens if a flag is set (such as a certain boss dead).

Also, apart from my 7DRL, there's a few other things I was wondering for Unstoppable:

9. How to have a looping map. Both spatially and visually if possible. Would look like an infinite plane, but with big enough screen you'd see yourself in all directions.

10. How to have a high score record that could be displayed on the main screen.

11. Online high scores? I know modules can use the profile system, but I'm guessing high scores might be another matter.

Edit: Oh, and one other Q... DarkGod, you told me once that there's a way of turning off the module asking for a name at the start?

Edit2: And another other Q... How do you make a graphical resource bar? I tried copying some code before from ToME and it didn't work. Is there a simple way?

_________________
http://www.gamesofgrey.com - My own T-Engine games!
Roguelike Radio - A podcast about roguelikes


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 4:17 pm 
Offline
Perspiring Physicist

Joined: Tue Jul 13, 2010 2:53 pm
Posts: 1332
A really good set of question! I am going to point you in what I feel is the right direction, usually by referring to things ToME is already doing. If you want me to give actual code then just say the word.

Grey wrote:
1. Play a sound. How ToME does it is a bit of a mystery - there seem to be weird files involved. What's the easiest way to trigger a sound to be played?


A bit of poking around and it looks like you need your game class in inherit from `engine.interface.GameSound` (and `engine.interface.GameMusic` for music). Then you can put a file `data/sound/deathcry.ogg` and play it with `game:playSound("deathcry")`. There appear to be some other tricks you can do, like use a lua file instead of an ogg or pass a table instead of the string "deathcry", but that should at least get you started.

Quote:
2. Trigger an action on moving onto a square.

The tutorials do this by laying special traps. If you want to go that route, look at `tome/data/zones/tutorial/traps.lua` for inspiration. Alternatively you can create special terrains that do something special on `block_move` (tome/data/general/grids/basic.lua and look for BASIC_LEVER) or `on_stand` (tome/data/general/grids/water.lua and look for POISON_WATER_DEEP). For the `block_move` and lever example, just be sure to `return false` so that the player can move on to the tile.

Quote:
5. Have randomised colours of map tiles, so for instance a load of #'s in a forest would all be slightly randomised colours of green. Can you set the numbers in the tile declarations to be slightly random?

The first thing that jumps to mind is how ToME handles trees. There is a single base TREE grid, but then if you look below it in `tome/data/general/grids/forest.lua` you will see a for loop creating TREE_1, TREE_2, ... TREE_30. Then DG uses the `nice_tiler` to replace them when actually generating the level. Be sure to grab `tome/class/NicerTiles.lua` if you decide to go that route. If you want something a more straight-forward you could skip the NicerTiles bit, but still use the for loop to generate TREE_1 through TREE_30 with varying colours (note the spelling!). Then in the zone's post_process function you could manually run through and every TREE tile you find replace it with a random choice of TREE_1 through TREE_30.

Quote:
6. Adding blood stains to the map on creature death - essentially just recolouring the tiles.

This is surprisingly complicated, although DG may have an elegant solution to it. The obvious thing to do is add some special code to the NPC's `on_die` function. There are a few ways to handle the actual changing of the tile, though. First, you can have a BLOODIED_FLOOR and you simply swap out the old FLOOR with BLOODIED_FLOOR. That would look like this:
Code:
on_die = function(self, src, death_note)
    local bloodied = game.zone:makeEntityByName(game.level, "terrain", "BLOODIED_FLOOR")
    game.level.map(self.x, self.x, engine.Map.TERRAIN, bloodied)
end

If you would rather toss a specific image down on top of a tile instead of overwriting the terrain every time you could create a BLOODSTAIN object and place it on the map in one of the unused locations (locations are TERRAIN, TRAP, ACTOR, PROJECTILE, and OBJECT). You could even add a new location if you wanted by making a `mod.class.Map` and tweaking some of the code, but I'll leave that explanation for later and only if you want it.

Quote:
7. Effects across the whole level on boss death, such as recolouring all tiles, changing tiles (earthquake style effect) and killing all other creatures.

This is a special case of the above answer. Again we would put an `on_die` function on the boss and then iterate through all of the x/y coordinates of `game.level.map` and do something.

Quote:
8. Have a door that only opens if a flag is set (such as a certain boss dead).

You want to add some special checks in your Grid's `block_move` function. You can derive inspiration from ToME's vault doors (`tome/class/Grid.lua`), particularly the `if self.door_player_check` section. You can use something similar to check a flag, perhaps using a quest.

_________________
Quote:
<DarkGod> lets say it's intended


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 4:23 pm 
Offline
Sher'Tul

Joined: Sat Mar 01, 2003 4:01 pm
Posts: 1067
Grey wrote:

6. Adding blood stains to the map on creature death - essentially just recolouring the tiles.

Check BloodyDeath.lua in /engine/interface.lua
Might take some tweaking for what you want to do, though, but I did get it to work time ago.

_________________
ToME online profile: http://te4.org/users/zonk
Addons (most likely obsolete): Wights, Trolls, Starting prodigy, Alternate save/resistance system


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 4:43 pm 
Offline
Sher'Tul

Joined: Mon Jun 13, 2011 4:10 pm
Posts: 1262
Grey, if you are just looking for a very simple resource bar display, check out the Gene Revolution code. I did some slash-and-burn coding to display life and energy values. If you'd like I could find the specific commit.

_________________
Sorry about all the parentheses (sometimes I like to clarify things).


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 4:58 pm 
Offline
Loremaster

Joined: Thu Sep 23, 2010 10:18 pm
Posts: 3516
Location: London, England
Thanks, guys! Just to check, what does the BloodyDeath thing do, Zonk?

bricks: Slash and burn is my style of coding :D If you've got the code handy it would be nice to see (or I had check with someone on IRC how to peek at it).

_________________
http://www.gamesofgrey.com - My own T-Engine games!
Roguelike Radio - A podcast about roguelikes


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 5:21 pm 
Offline
Sher'Tul

Joined: Mon Jun 13, 2011 4:10 pm
Posts: 1262
The bulk of the code:
https://github.com/TE4-Module-Developer ... 9f9598589c

Yufra's fix for display on first turn:
https://github.com/TE4-Module-Developer ... 0316d5c550

There's a lot of junk in there for resources we had earlier but dropped. Honestly, I don't know how I made that code work :D.

_________________
Sorry about all the parentheses (sometimes I like to clarify things).


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 5:30 pm 
Offline
Sher'Tul

Joined: Sat Mar 01, 2003 4:01 pm
Posts: 1067
Grey wrote:
Thanks, guys! Just to check, what does the BloodyDeath thing do, Zonk?

When a monster dies, it's supposed to color a few tiles a round it based on its has_blood field.

_________________
ToME online profile: http://te4.org/users/zonk
Addons (most likely obsolete): Wights, Trolls, Starting prodigy, Alternate save/resistance system


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 7:03 pm 
Offline
Wyrmic

Joined: Mon Sep 26, 2011 1:49 pm
Posts: 244
Also planning my 7drl, here is what I am not sure about how to do either:

1. Temporarily light up particular squares. Do I just convert those squares into Lit squares and set a timer on them, and convert them to unlit squares when the timer expires?

2. Have allies that follow the player around (do I just have to have the allies treat the player as a "target"?)

3. Set the amount of time a particular action takes (possibly based on various calculations). For example, faster movement in a particular situation, or faster casting of spells.

4. Have the monsters wander around the level, instead of staying put. Do I just need to change the AI?


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 7:34 pm 
Offline
Perspiring Physicist

Joined: Tue Jul 13, 2010 2:53 pm
Posts: 1332
Zonk wrote:
When a monster dies, it's supposed to color a few tiles a round it based on its has_blood field.


It actually clones the grid that was originally there and then tweaks the color to look "bloodied". This would probably work for ASCII tiles quite well. Thanks for remembering that one Zonk!

_________________
Quote:
<DarkGod> lets say it's intended


Top
 Profile  
 
PostPosted: Fri Feb 17, 2012 7:45 pm 
Offline
Perspiring Physicist

Joined: Tue Jul 13, 2010 2:53 pm
Posts: 1332
eliotn wrote:
1. Temporarily light up particular squares. Do I just convert those squares into Lit squares and set a timer on them, and convert them to unlit squares when the timer expires?

Yes, you use the `game.level.map.lites` function call (actually called `maplite` in `engine/Map.lua`).

Quote:
2. Have allies that follow the player around (do I just have to have the allies treat the player as a "target"?)

That is the easiest way to handle this.

Quote:
3. Set the amount of time a particular action takes (possibly based on various calculations). For example, faster movement in a particular situation, or faster casting of spells.

The turn-based game operates on a concept of `energy`. An actor will be able to `act` once it has accumulated 1000 energy, and when it acts it calls its `useEnergy` function. By default that function call will use up the entire 1000 energy, but you can pass in an argument saying exactly how much energy you want to use. Look at `tome/class/Actor.lua` and search for `self:useEnergy` to see how it is handled there.

Quote:
4. Have the monsters wander around the level, instead of staying put. Do I just need to change the AI?

Yes just change the AI. The easiest think would be to do a random walk (no target the pick random direction and move in it) although more "interesting" approaches would be to pick a direction and travel in it, with a chance every turn to choose a different direction to travel in.

EDIT: Fixed some formatting.

_________________
Quote:
<DarkGod> lets say it's intended


Top
 Profile  
 
PostPosted: Sat Feb 18, 2012 7:50 pm 
Offline
Wyrmic

Joined: Mon Sep 26, 2011 1:49 pm
Posts: 244
Thanks for the help. Other things I would like to do:

1. How do I make items that have an effect on another item when used on another item? Like the spellblaze crystal?

2. How do I generate a dungeon that can randomly place a fixed map (like a vault)? I tried using some of the vault functions in the example code, but it didn't work.


Top
 Profile  
 
PostPosted: Mon Feb 20, 2012 1:59 am 
Offline
Master of Eyal

Joined: Wed Jul 24, 2002 9:26 pm
Posts: 10478
Location: Angolwen
Quote:
3. Show a full screen image overlaid on the map with transparency (is this possible?) An animation would be good too.


You load your image in your Game:run() code, something like that:
Code:
self.foo = {core.display.loadImage("/data/gfx/foo.png"):glTexture()}


Then in your Game:display(), right after the map is drawn to draw it:
* streched:
Code:
self.foo[1]:toScreenFull(map.display_x, map.display_y, map.viewport.width, map.viewport.height, map.viewport.width * self.foo[2] / self.foo[7], map.viewport.height * self.foo[3] / self.foo[7], 1, 1, 1, 0.6)

* tiled:
Code:
self.foo[1]:toScreenFull(map.display_x, map.display_y, map.viewport.width, map.viewport.height, self.foo[2], self.foo[3], 1, 1, 1, 0.6)


Each time the 1, 1, 1, 0.6 is the "color" to draw as. Use 1,1,1 to draw the image with normal colors and the 0.6 is the alpha transparency to apply.

Quote:
Edit: Oh, and one other Q... DarkGod, you told me once that there's a way of turning off the module asking for a name at the start?

Easy, in init.lua you add:
Code:
no_get_name = true


Quote:
10. How to have a high score record that could be displayed on the main screen.

Simply have a "score_formatter" in init.lua like tome does and then look for "highscore" in time's Game.lua, there are very few lines required.

Quote:
11. Online high scores? I know modules can use the profile system, but I'm guessing high scores might be another matter.

Unsupported yet

Quote:
9. How to have a looping map. Both spatially and visually if possible. Would look like an infinite plane, but with big enough screen you'd see yourself in all directions.

Hum C core support would be needed, I can add it on the todo list :)

Quote:
4. Use the shader thingummies to make everything greyscale apart from the colour red, which would be upped in brightness. (Is this possible?) Alternatively just reshade everything red, but without making things darker.


Hum shaders ... :) You need to understand one thing about how this all works.
To use a fullscreen or fullmap shader the game makes a FBO (framebuffer object, like a virtual screen that outputs to a texture), displays the map inside it and then displays the FBO's texture through the shader. The shader is applied to each and every pixel drawn from the texture.

So first you setup your FBOs, for that just copy ToME's Game:createFBOs() method and call it as tome does (in setupDisplayMode).
Now your fbos are created and your shaders are loaded. You need to use them now. Not all displays can do shaders or FBO though, so you need two versions of your map display code:
Where your module probably just does (if you copied example module):
Code:
      self.level.map:display(nil, nil, nb_keyframe)
      self.target:display()


You instead do:
Code:
      -- Display using Framebuffer, so that we can use shaders and all
      local map = game.level.map
      if self.fbo then
         self.fbo:use(true)
            map:display(0, 0, nb_keyframes)
         self.fbo:use(false, self.full_fbo)
         self.fbo:toScreen(map.display_x, map.display_y, map.viewport.width, map.viewport.height, self.fbo_shader.shad)

         if self.target then self.target:display() end

      -- Basic display; no FBOs
      else
         map:display(nil, nil, nb_keyframes)
         if self.target then self.target:display() end
      end


This will make the map display in its own texture and then use the fbo shader on it.
ToME uses two fbos, one for the map and one for the whole screen.
The fullscreen one must thus also be used:
At the top of Game:display() right after the "if self.change_res_dialog" you add a line:
Code:
   if self.full_fbo then self.full_fbo:use(true) end

And then at the very bottom of Game:display() you do:
Code:
   if self.full_fbo then
      self.full_fbo:use(false)
      self.full_fbo:toScreen(0, 0, self.w, self.h, self.full_fbo_shader.shad)
   end


This will display all the game inside a fbo and then display it with the given shader.

Now shaders themselves. They live in data/gfx/shaders/ There must usualy be two file per shaders, a .lua file that describes it and a .frag one that is the shader code to run on the GPU. Try to see how main_fbo and full_fbo shaders in ToME work. They probably are enough for your needs but you can play with them as you need (or ask more specific questions).

Now if you did it all right your game should display .. just as before!
So we need to tell the shaders to do stuff. First tell the full_fbo shader to handle gamme correction instead of the OS (it usualy looks better):
define
Code:
support_shader_gamma = true
in Game.lua, before the init method (like ToME does).
If at that point you get a fully dark screen, try to add
Code:
self:setGamma(config.settings.gamma_correction / 100)
right at the end of createFBOs.

Now the fun part!
Say you want to colorize your game in red, you simply do:
Code:
game.fbo_shader:setUniform("colorize", {1,0.2,0,1})

Somewhere in your code. To restore default you do:
Code:
game.fbo_shader:setUniform("colorize", {0,0,0,0})


ToME's relevant code for that is in Player:updateMainShader()

Go play with those :)

_________________
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)


Top
 Profile  
 
PostPosted: Mon Feb 20, 2012 2:41 am 
Offline
Loremaster

Joined: Thu Sep 23, 2010 10:18 pm
Posts: 3516
Location: London, England
Thanks for answers, DG!

I got the shaders thing working as you describe in Run from the Shadow, and it can make some snazzy effects. But colorize doesn't do what I want - it just passes everything through a colour filter. It makes the white stuff turn whatever colour you put in and tones everything else down. Ultimately I want white to stay white, red to stay red (or turn redder) and everything else to appear greyed. Is this possible?

_________________
http://www.gamesofgrey.com - My own T-Engine games!
Roguelike Radio - A podcast about roguelikes


Top
 Profile  
 
PostPosted: Mon Feb 20, 2012 1:15 pm 
Offline
Master of Eyal

Joined: Wed Jul 24, 2002 9:26 pm
Posts: 10478
Location: Angolwen
Is this what you wish ?
Image

If so you can take ToME's main_fbo.frag file from svn and use instead of "colorize" "intensify".
The above result is done with an intensify of {1.1, 0, 0, 1}

_________________
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)


Top
 Profile  
 
PostPosted: Mon Feb 20, 2012 1:31 pm 
Offline
Loremaster

Joined: Thu Sep 23, 2010 10:18 pm
Posts: 3516
Location: London, England
That's getting close to what I'm after - I'll have a fiddle and find the snazziest setting. Thanks, DarkGod!

_________________
http://www.gamesofgrey.com - My own T-Engine games!
Roguelike Radio - A podcast about roguelikes


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 57 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group