How to... ?

This forum is for the Lua scriptable clone of DM/CSB called Dungeon Strikes Back by Sophia. Use DSB to build your own highly customised games.

Moderator: Sophia

Forum rules
Please read the Forum rules and policies before posting.
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Trantor wrote:It shows just how creative you can be with DSB, and how to put the creativity in a dungeon.
I'm glad it's having the desired effect. :mrgreen:
Mon Ful Ir wrote:I probably want it to hurt quite a bit more than it does at the moment. The current version takes about five or six hits to kill a novice-level character with 40 WIS. Presumably that's just a case of upping the missile_power parameter to about 250?
That's one way to do it, but not necessarily the only one. It certainly works, but if you don't like how big the projectile gets at that high of a power, there's nothing set in stone about my code, either. For example, if you want to drain mana according to the full damage value, instead of 0.75, go for it. You could even multiply this damage value by something, in order to boost the mana and wisdom drain further. Fine-tuning it this way then allows missile_power to be used to create different monsters who have the same attack at varying strengths-- just like normal DM does with fireballs. It's up to you how you want to tweak it. :)
Mon Ful Ir wrote:I can and will write several other specials (e.g. shadows will drain STR, etc.) But I'm afraid the petrifaction business is still quite beyond me.
Well, the "instant death attack" is not a problem, of course. Having the character show up as a statue instead of bones is probably going to be. The main reason is, right now, the base code doesn't separate the "housekeeping" stuff that happens when a character dies (such as disabling magical shields and dropping all items to the ground) from some of the more fun tasks that designers may wish to customize. This makes things like what you want rather difficult. There is also no way to dynamically change the skull icon for a single character, yet. I'll certainly get around to that when I improve the other mechanics, though.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Okay, I'll put petrifaction in the "difficult" box for the moment and await improvements in the mechanics. :)

Apart from petrifaction there are two other potentially things I can see a designer might want...

1) Underwater levels, with an "underwater" screen overlay; these would locally disable certain spells (fireball, lightning bolt). Limited period air supply from holding your breath, or potions of water breathing to extend that, or items with a permanent water breathing effect. Each character would need a separate "air supply" bar.

2) Dialogue screens for talking to NPCs. You'd have "dialogue" methods, giving one, two or three options for what the character says, and scripted NPC replies; the conversation would appear on the screen. (Subrenderer?)

The dialogue screens would let you write quite complex plots, did you ever play Planescape: Torment?
User avatar
ian_scho
High Lord
Posts: 2806
Joined: Fri Apr 07, 2006 8:30 am
Location: Zaragoza, Spain

Re: How to... ?

Post by ian_scho »

1) Screen overlay... I had wondered if this was possible as well:

dsb_dungeon_view(lev, x, y, dir, light) = bitmap
Return a rendering of the viewport, but you need to overwrite the viewport and not create an image from it.

dsb_override_floor(???) = ??? and dsb_override_roof(???) = ???
This functions are called when your view changes to a different level but don't know what they do. It won't be relative to the viewport though.

dsb_screen_bitmap
No idea

2) I had a go at this a while ago. Copied the concept from DM Java. I can pm you a few examples if you like. It's been ages though!
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Thanks, ian_scho. Could we post the examples openly? Part of the point of what I'm trying to do is to build some shared libraries for DSB that others can use as well.

Meanwhile I've been busily creating doors, keys, keyholes and wallitems, which is a bit slower than the monsters because of the need to figure out offsets. (DSB doesn't seem to need offsets for monsters and "things"--it seems to know where to put them on the screen--but wallitems don't seem to be quite so straightforward.) I'll post an updated file a bit later on.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Okay, here it is:

(removed -- use a later file version please)
Last edited by Mon Ful Ir on Tue Dec 07, 2010 7:26 pm, edited 1 time in total.
User avatar
Joramun
Mon Master
Posts: 925
Joined: Thu May 25, 2006 7:05 pm
Location: The Universe

Re: How to... ?

Post by Joramun »

Very nice !

I'll use that to add a set of new monsters and items.

PS: I looked at your code, and I think you could save some time by using the clone_arch() function to create new objects (and modify only relevent fields).
What Is Your Quest ?
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

It's still a work in progress at the moment, though, Joramun. :) I'll let you know when everything's in the file and working as intended.
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:Underwater levels, with an "underwater" screen overlay
ian_scho wrote:1) Screen overlay... I had wondered if this was possible as well
Take a look at this post. The title is a bit deceptive but the mechanic is actually exactly what you're looking for:
http://www.dungeon-master.com/forum/vie ... 53&t=27711
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Thank you. How can I set C_UNDERWATER so that it applies to a whole dungeon level?
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:How can I set C_UNDERWATER so that it applies to a whole dungeon level?
Well, there are a couple of different approaches. You could write a couple of quick functions to set and clear the condition, and use triggers and a "function_caller" on triggers near where you enter and leave the underwater level. However, provided you're not doing anything hugely fancy, a better way may be to override sys_enter_level, which is called every time the party changes level. For example, if the underwater level is level 6:

Code: Select all

function sys_enter_level(level)
   if (level == 6) then
      dsb_set_condition(PARTY, C_UNDERWATER, 1)
   else
      dsb_set_condition(PARTY, C_UNDERWATER, 0)
   end
end
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

I'm sorry, Amber, but I can't make it work.

I've set up underwater.lua like this:-

Code: Select all

C_UNDERWATER = dsb_add_condition(PARTY, gfx.water_overlay, nil, 0, nil)

function sys_enter_level(level)
   if (level == 1) then
      dsb_set_condition(PARTY, C_UNDERWATER, 1)
   else
      dsb_set_condition(PARTY, C_UNDERWATER, 0)
   end
end
I've added this to graphics.lua:-

Code: Select all

gfx.water_overlay = dsb_get_bitmap("WATER_OVERLAY", "mfi_graphics/misc/MISC_WATER_OVERLAY.png")
And I've added it to startup.lua:-

Code: Select all

lua_manifest = {
    "graphics.lua",
    "attacks.lua",
    "underwater.lua"
}
No viewport overlay. What am I doing wrong?
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Sorry, I guess I made a mistake in the function parameters. The proper call is:

Code: Select all

C_UNDERWATER = dsb_add_condition(PARTY, nil, gfx.water_overlay, 0, nil)
That is, the gfx.water_overlay parameter should be the third one, not the second.

Once I did this, the overlay displays fine after I go down to level 1 (DSB internally starts counting at 0)
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Perfect, thank you. Now I've got a level that looks like it's underwater. :)

The "running out of air" code is probably a bit more challenging...
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:The "running out of air" code is probably a bit more challenging...
Well, the advantage to making it a condition is that even though we're not currently using the strength and the update functions, there's nothing saying we can't. Just like in the paralysis function, an update frequency and an update function could very well be assigned. By setting the initial strength (in sys_enter_level for example) to greater than 1, this can denote a starting air supply.

An example function would look something like:

Code: Select all

function underwater_air_func(strength)
   -- No "who" parameter because this is a PARTY condition.
   strength = strength - 1
   if (strength == 5) then
      dsb_write(system_color, "THE PARTY IS RUNNING OUT OF AIR!")
   elseif (strength <= 1) then
      dsb_write(system_color, "THE PARTY HAS DROWNED!")
      for ppos=0,3 do
         local char = dsb_ppos_char(ppos)
         if (valid_and_alive(char)) then dsb_set_bar(char, HEALTH, 0) end
      end
   end
   return strength
end

This can be invoked by something like:

Code: Select all

C_UNDERWATER = dsb_add_condition(PARTY, nil, gfx.water_overlay, 5, underwater_air_func)
There are prettier and more complex ways to do it, of course, but this is a simple one. :)
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Thank you. I wanted to change the underwater code such that characters underwater don't die quite so quickly, and also such that being underwater stops you casting magic. So I wrote:

Code: Select all

function underwater_air_func(strength)
   strength = strength - 1
   if (strength == 10) then
      dsb_write(system_color, "THE PARTY IS RUNNING OUT OF AIR!")
   elseif (strength <= 1) then
      dsb_write(system_color, "THE PARTY HAS DROWNED!")
      for ppos=0,3 do
         local char = dsb_ppos_char(ppos)
         if (valid_and_alive(char)) then dsb_set_bar(char, HEALTH, 0) end
      end
   end
end

C_UNDERWATER = dsb_add_condition(PARTY, nil, gfx.water_overlay, 60, underwater_air_func)

function sys_enter_level(level)
   if (level == 1) then
      dsb_set_condition(PARTY, C_UNDERWATER, 1)
   else
      dsb_set_condition(PARTY, C_UNDERWATER, 0)
   end
end

function sys_forbid_magic(ppos, who)
   if (level == 1) then
      return true
   end
   return false
end
Unfortunately this isn't exactly working right because when I test, my test character no longer gets a warning when about to drown. Also, I'm concerned that we've already used sys_forbid_magic in your paralysis code, and I wonder if using it again will cause any problems.

Then I'll also need a "water breathing" effect, which ought to put a dotted line round the character portrait like fireshield does. For the duration of the effect it needs to stop function underwater_air_func from being called.

Meanwhile I'll find some underwater monsters! :)
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:Unfortunately this isn't exactly working right because when I test, my test character no longer gets a warning when about to drown.
The problem is that there is no "return strength" at the bottom of your function. This might be my fault, partially, because I noticed I forgot it later on, and you probably already copied my code by then. I edited my post. Anyway, add that and see if it works. :)
Mon Ful Ir wrote:Also, I'm concerned that we've already used sys_forbid_magic in your paralysis code, and I wonder if using it again will cause any problems.
It will cause a problem because you're just overriding the function. We just have to combine everything into one function to use both paralysis and also allow no magic underwater.

Code: Select all

function sys_forbid_magic(ppos, who)
   if (level == 1) then
      return true
   end

   local paralyzed = dsb_get_condition(who, C_PARALYSIS)
   if (paralyzed) then return true end

   return false
end
Mon Ful Ir wrote:Then I'll also need a "water breathing" effect, which ought to put a dotted line round the character portrait like fireshield does. For the duration of the effect it needs to stop function underwater_air_func from being called.
If the "water breathing" is applied to each character individually, like a fireshield, it will complicate the underwater_air_func function because some party members will be able to get air and some won't.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Yes, I see that. Can I do a similar thing with a whole-party effect? I'm concerned to ensure that the player has some visible signal that the water breathing's in effect.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

I'm sorry, but I'm afraid the warning text still isn't appearing -- it's just straight to drowned -- and my character can cast spells underwater now too. I've done something wrong.

Here's the actual file I'm using:-

(removed -- use a later file version please)
Last edited by Mon Ful Ir on Tue Dec 07, 2010 7:27 pm, edited 1 time in total.
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Oh, the problem is in this line:

Code: Select all

dsb_set_condition(PARTY, C_UNDERWATER, 1)
I mentioned this but perhaps I wasn't clear enough. It goes straight to drowned because the initial strength is 1, which is already drowning. Something like this will fix the issue:

Code: Select all

dsb_set_condition(PARTY, C_UNDERWATER, 50)
The reason you can cast spells underwater is because I need to stop copying and pasting code when I'm tired. :shock: :(
It's using a variable called "level" which isn't actually defined anywhere. We need to figure out what level the party is actually on.

Code: Select all

function sys_forbid_magic(ppos, who)
   local level = dsb_party_coords() -- Added this line
   if (level == 1) then
      return true
   end

   local paralyzed = dsb_get_condition(who, C_PARALYSIS)
   if (paralyzed) then return true end

   return false
end
Sorry about that.
User avatar
ian_scho
High Lord
Posts: 2806
Joined: Fri Apr 07, 2006 8:30 am
Location: Zaragoza, Spain

Re: How to... ?

Post by ian_scho »

Can I ask you Mon Ful Ir to save underwater, and then reload? Does it maintain "state"? I've just reviewed the documentation (thanks Sophia!) and you may well have more work to do :(
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Thanks a billion, Amber, that code is working beautifully.

ian_scho, I could solve that! Or at least, I could crack a nut with a sledgehammer... I added sys_forbid_save to underwater.lua. :)

It may be possible to solve it more elegantly, using the code in system.lua that gets called when you save or load a game. That would be preferable if it's not technically difficult, as someone using this graphics/code pack might well want to make quite a large underwater level.
User avatar
Gambit37
Should eat more pies
Posts: 13719
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: How to... ?

Post by Gambit37 »

I need to do underwater in my forthcoming game, so this will be very handy if I switch to DSB :-)
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

I think I've got you to thank for a lot of the ripped graphics, haven't I, Gambit37?

I've read your post in the Developers & Designers' Forum, and I think one of the things that you want going underwater to do is to put out all the party's torches. The way I was originally planning to do it was to have the entrance square to the underwater level operating a trigger that replaces all the torches with a new item (soaked torch, that clones burnt out torch)... but I think your underwater areas are going to use the code for pits in such a way that you can either swim on the surface of the water or underneath, so it would need an awful lot of triggers. In order to help Gambit37 wonder if it's possible to make C_UNDERWATER call a function that replaces all the torches instead.

As for the "air breathing" graphic, reading the documentation tells me that you can only put the graphic on an individual condition but at the moment C_UNDERWATER is a party condition. So I think C_UNDERWATER also needs to create up to four individual conditions with the graphic.
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:Okay, I'll put petrifaction in the "difficult" box for the moment and await improvements in the mechanics. :)
Since I had to make a new release anyway to fix some ugly bugs, I slipped a few improvements here in as well.

The main thing that is that you can now replace the top "hands", "portrait background" and "death" images, with the new dsb_replace_topimages command. It takes four parameters: a character id, and then the replacements for those three images. Pass it nil to leave the image alone, or 0 to go back to the default.

If you have loaded a gfx.top_dead_statue to replace the skull image for when a character has been turned to stone, you can assert it like so:

Code: Select all

dsb_replace_topimages(char, nil, nil, "top_dead_statue")
To go back to the default skull:

Code: Select all

dsb_replace_topimages(char, nil, nil, 0)
Note: DSB has no way to save a reference to an arbitrary object. So, in order to allow this change to be saved, we have to specify the graphic as a string that is used as a member of the gfx table instead. Just keep this in mind. :)

If you want reference images to build your replacements, you can grab them here.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

Thank you!

I'm now struggling because in DSB 0.46, ESB will no longer load my dungeon. :( It gives the following error message:-

dsb_add_champion requires 13 parameters

When I comment out dsb_add_champion, it gives a different error:-

dsb_spawn requires int in param 3

Sorry to be a pain...
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Oh, you're not a pain. I'm sorry for the bugs. :)

The problem is that you somehow got a broken ESB that was expecting 0.45's data structures but was linked with code from 0.46-- DSB and ESB have a lot of code in common. I have no idea how this happened.

I rebuilt everything and now it's fine.

So if you download DSB 0.46 again then it should work.
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

First error is now fixed. Second still gives:-

dsb_spawn requires int in param 3
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

I'm pretty sure that one is because you've commented out the call to dsb_add_champion, so the integer that isn't being found is the champion's id... and that id isn't being found because you've commented out the line of code that initializes that champion.

So, unless I'm mistaken, it's not a bug. You just need to uncomment the code you commented out. :)
Mon Ful Ir
Adept
Posts: 221
Joined: Sat Jan 07, 2006 1:54 am
Location: Britain

Re: How to... ?

Post by Mon Ful Ir »

I'm pretty sure you're right! :) Thank you.

I realise there's a bit of a backlog of questions here. Is it okay to ask more?
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: How to... ?

Post by Sophia »

Mon Ful Ir wrote:I realise there's a bit of a backlog of questions here. Is it okay to ask more?
Go right ahead. In fact, you might want to re-assert any previously opened questions that you'd still like answers to... I've been trying to get to issues as I can, but I may have missed some.
Post Reply