Can I dynamically change the gfx of a creature instance?

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.
Post Reply
User avatar
Gambit37
Should eat more pies
Posts: 13714
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Can I dynamically change the gfx of a creature instance?

Post by Gambit37 »

Can I dynamically change the gfx of a creature instance? If so, please could you share the right way to do this?

I tried a few things trying to reassign front and attack of the instance to no avail... I'm not really sure if it's even possible?
User avatar
Gambit37
Should eat more pies
Posts: 13714
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Gambit37 »

In addition, how would I do a "one-shot" change of a creature's images? For example:

Code: Select all

function obj.screamer:on_spawn(self, id)
	self.front = gfx.screamer2_base
	self.attack = gfx.screamer2_attack
end
I've tried the above with variations of id, exvar[id] etc in place of self, but can't get anything to work.
User avatar
Sophia
Concise and Honest
Posts: 4239
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Sophia »

Changing the images in obj won't generally work because the images are cached, and you don't really want to do this anyway because you're changing the image for the whole archetype.

Using different images for different attack methods is well-supported in DSB. Basically, you just specify an array of attack images instead of a single one, and your function that selects which attack method to use also returns an index of that array. See multivexirk.lua in the test dungeon for an example.

Changing the other graphics of a monster is not currently supported, but there's a simple enough workaround-- just make different clones with clone_arch of the monster with different images, make sure they all have the same group_type (which is just an integer) so monster grouping doesn't get messed up, and dsb_qswap between the monster's different appearances as needed. As a side benefit this can also give the different forms slightly different behavior if that's what you want.
User avatar
Gambit37
Should eat more pies
Posts: 13714
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Gambit37 »

I did start with using dsb_qswap on a cloned screamer, but the grouping didn't work (I ended up with 5 creatures on a tile, 4 originals on the sub-tiles, and 1 cloned in the center)... so I thought it didn't work. I didn't realise the group_type had to be set, and I also didn't realise that group_type isn't set for screamers by default.

What's the expected behaviour for monsters that don't have a group type set?

Anyway, I'll try your suggestion which sounds like it'll solve the issue. Should I set both the original screamer and cloned screamer to group type GT_SELF_ONLY? Or use a unique +ve integer not already used?

Going back to the original question though, the reason I asked is I wanted to programmatically create some colour variations of creatures, and randomly apply that variation on spawn. Is there no way to do this...? Do I need to pre-prepare all those variations and create multiple clones instead?
User avatar
Sophia
Concise and Honest
Posts: 4239
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Sophia »

If a group type isn't set, it's assumed to be GT_SELF_ONLY, which means that the monster will only group with itself. If you want different archetypes to be able to group up, that isn't what you want, so no, you'll have to set your own group type. Numbers above 100 aren't used by the core code and never will be, so that's a good enough place to start.

You can certainly programmatically create some color variations and apply that variation on spawn. The only difference is that it's handled at the archetype level. But you can execute all sorts of Lua code in objects.lua to generate different objects, so you can just automatically create different archetypes and swap to a random one on spawn; this leads to a certain degree of inflation of your object list, but certainly nothing that DSB can't handle, and with a good naming scheme it shouldn't be that much of a hassle in ESB, either.
User avatar
Gambit37
Should eat more pies
Posts: 13714
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Gambit37 »

OK, cool, thanks. I used this code and it seems to work fine:

Code: Select all

GT_SCREAMER = 110 
obj.screamer.group_type = GT_SCREAMER

obj.screamer2 = clone_arch(obj.screamer, {
   front = gfx.screamer2_base,
   side = gfx.screamer2_base,
   back = gfx.screamer2_base,
   attack = gfx.screamer2_attack
})

obj.screamer.on_spawn = function(arch, id)
   if (dsb_rand(1, 4) == 1) then
      dsb_qswap(id, "screamer2")
   end
end
I did also try using the other function format, but this causes errors when I close DSB:

Code: Select all

function obj.screamer:on_spawn(arch, id)
   if (dsb_rand(1, 4) == 1) then
      dsb_qswap(id, "screamer2")
   end
end
The errors are:

Code: Select all

PROGRAM CRASH!
Location: 1 22 43
Reason: Segmentation Fault
Stack Dump:
DSBmain
destroy_dungeon
destroy_dungeon.inst_table
inst_destroy
destroyed_monster
Location 1 22 43 is the party start position, facing the group of 4 screamers.

What's the difference between these two methods, and why does the second one cause errrors?
User avatar
Sophia
Concise and Honest
Posts: 4239
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Can I dynamically change the gfx of a creature instance?

Post by Sophia »

The short answer is that the first one is right and the second one is wrong... but you probably already knew that, since it makes DSB crash.

The colon tells Lua to create a self parameter that refers to whatever table the function belongs to. It's just a handy shorthand. However, if the calling code doesn't actually call the function with that parameter (and on_spawn does not) then it creates all sorts of problems. I'm amazed it didn't crash sooner, to be honest.
Post Reply