Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • 0
Misty

How to port Decorate to EDF?

Question

I would like to use some decorative items and one monster from realm667 page for my upcoming eternity map, but they come as zdoom's decorate and I'm not sure how to port those items and monster into EDF even after reading eternity's wiki several times. I could replace some base items and unused nazi and keen frames, but this is the last option which I would choose. Anyone could explain this into simpler manner? 

Share this post


Link to post

Recommended Posts

  • 0

Well there's no panacea for converting DECORATE to EDF, and in some cases it might be impossible. What monster and items do you wish to port? I can give specific guidance if I'm provided with that.

Share this post


Link to post
  • 0
Posted (edited)

I want use annihilator as boss monster and for decorative items would be evil eye varations, fire piliars(doom paletted) and marble urns. Nothing much hard, besides that cyber monster.

  https://realm667.com/index.php/en/prop-stop-mainmenu-163-64831/hell-a-magic-mainmenu-168-40302#preview-19

https://realm667.com/index.php/en/beastiary-mainmenu-136-69621/doom-style-mainmenu-105-73113

Share this post


Link to post
  • 0
Posted (edited)

OK so I'll break this down, starting with the marble urns, then moving on to the Annihilator.

 

In the global WAD namespace (not between some FOO_START FOO_END tags) you'll want a lump called EDFROOT. The contents of that lump should be fair simple to start off with.

stdinclude("root.edf")

setdialect("ALFHEIM") // This enables using : for inheritance and doomednum setting

lumpinclude("EURNS")    // You can call the lump whatever you want, but EURNS seems like a sensible name
lumpinclude("EANILATR") // Again, call it whatever you want

Now let's create the EURNS and EANILATR lumps. If we look at the DECORATE we see the first actor, "ACTOR MarbleUrn 13571". In EDF this translates to "thingtype MarbleUrn : Mobj, 13571". This syntax in general means "thingtype NameOfThing : ThingItInheritsFrom, DoomEdNum". "Mobj" is just a dummy value, meaning that it inherits from nothing.

 

Now let's break down the properties one by one. It's worth noting that property names are case insensitive, so the property "radius" and the property "rAdIuS" are the same thing

  • Radius 16: This line is an easy translation, turning to "radius 16.0". The ".0" isn't necessary, but I like keeping it there as it reminds me that it's not strictly a whole number
  • Height 40: Same thing as radius, it goes to "height 40.0"
  • +SOLID: OK, so flags are handled different in EDF, there's a few flags properties, but also one more important "cflags" property which lets you combine all other flags. Thankfully this is rather simple in this case, and just translates to "cflags SOLID". Alternatively you could use "basictype SolidDecor", which does the same thing. The idea behind basictype is that it's a pre-defined set of flags that commonly crop up (so SolidDector is just SOLID, but other ones are more complex).
  • States (stuff): OK so states isn't different at all really, but you have to replace '{' with '@"' and '}' with '"@'. Everything else can stay the same if you want. You should end up with something like this:
thingtype MarbleUrn : Mobj, 13571
{
  radius 16.0
  height 40.0
  cflags SOLID // using cflags instead of basictype as it's the closer thing to directly copying from the DECORATE
  states
  @"
  Spawn:
    MURN A -1
    Stop
  "@
}

Now that we've got the first one defined, the rest are a doddle. I trust you to figure out how to do Red/Black/Tan/Blue if I provide you with the steps to do the red one.

 

So not much has changed here. We just want to make MarbleUrnGrey which inherits from MarbleUrn, and has DoomEdNum 13572 This can just go below the MarbleUrn in the same file. Additionally the states will be different. Changing properties from their inherited values in EDF is much the same as it is in DECORATE. The only thing we need to remember is to place the dummy "Mobj" field in the definition with the thingtype we're inheriting from, which in this case is "MarbleUrn". Ultimately this is the result.

 

... // Pretend that the entirety of MarbleUrn is up here
}


thingtype MarbleUrnGrey : MarbleUrn, 13572
{
  states
  @"
  Spawn:
    MURN B -1
    Stop
  "@
}

 

OK let's shift gears to the Annihilator. Go to the EANILATR lump we made earlier. This one's a bit less obvious, especially since we have to define new sounds and two whole projectiles! Let's sort out the sounds first.  Note that you can't have ogg vorbis sounds in EE currently, so you'll need to turn them into mono WAVs (or actual Doom sounds). I don't remember if EE would be capable of parsing the Annihilator SNDINFO, so you'll need to get back to me on if the sounds actually work.

 

Now let's define the Annihilator. Like before, the first line should be "thingtype Annihilator : Mobj, 30111". Now we have to deal with the obituary. A limitation of EDF obituaries as of current is that the obituaries always start with "Playername ", which is then put before the obituary string. So in this case we could rework the line to be "obituary_normal "was blown away by the Cyber Annihilator's rockets."". Health , radius, height, mass, speed, and painchance all can just be used verbatim.

 

Now we get to MONSTER. This is the DECORATE version of a basictype. If we look at the EDF thing reference and go to basictype we can see that the nearest match is "basictype Monster". Now for the rest of the flags, we want to add them with the addflags property. In this case it should be "addflags". Looking at documentation the closest thing to NOTARGET is DMGIGNORED, FLOORCLIP goes to FOOTCLIP, NORADIUSDMG remains the same, BOSS remains the same, and MISSILEEVENMORE doesn't have a direct correlation to any flag, the closest being HIGHERMPROB. This results in the following:

"addflags DMGIGNORED|FOOTCLIP|NORADIUSDMG|BOSS|HIGHERMPROB".

The sound properties might work as-is, so that's fine.

 

Moving on the the states. Copy them verbatim, swapping out the '{' for '@"' and '}' for '"@'. Now we need to look at the list of codepointers on the wiki to see which codepointers exist. Looking at (A_)PlaySound we see that it uses misc1 and misc2 parameters, meaning it can't be used in DECORATE states, but it says that we can use A_PlaySoundEx instead. A_Jump works the same, so that can stay as-is. Now we get to A_CustomMissile, which isn't present in Eternity. Under "AI attack" > "Parameterized" there's MissileAttack. Looking at the parameters we see that there's no equivalent for the x/y offset (which makes me think that I should try and at least partially adapt A_SpawnProjectile to Eternity for convenience), but it roughly translates to "A_MissileAttack("Rocket2", normal, 40)", you might want to add another parameter after to define the angle offset though.

 

TODO: More

 

Edited by Altazimuth

Share this post


Link to post
  • 0

I tried to create "EURNS" lump, but eternity says this:

Error at EURNS:1:
missing title for section 'thingtype'

What I'm doing wrong here?

Share this post


Link to post
  • 0

I just included first urn code in "EURNS" lump and nothing more. I know, maybe it's a wrong thing to do, but I'm still a bit confused. Sorry for that. 

Share this post


Link to post
  • 0
Posted (edited)
thingtype MarbleUrn: Mobj , 13571
{
radius 16
height 40
cflags SOLID
states
@"
Spawn:
MURN A -1
Stop
"@
}

Same as yours now when I compared this. I think, switching between slade and port made code not saved. Well, it happens sometimes.

About Annihilator guy - maybe it could use cyberdemon sounds? where's not much difference between them, besides one doesn't have proper arms.

Share this post


Link to post
  • 0

Well, it needs some test. I checked eternity's wiki for EDF sound reference and seems where's no such example with "/" in wiki. I guess it will need a new SNDINFO for cyberguy. 

Share this post


Link to post
  • 0

Note that the / characters in ZDoom SNDINFO are functionally meaningless. They're here just for user convenience, because that way you can have a convention of monster/action sounds, like cyber/death or caco/pain. But you could just as well use underscore, for example, for the engine it doesn't matter whether you call the sound cyber/death, cyberDeath, cyber_death, or fjgdhjhdqs.

Share this post


Link to post
  • 0

Alright, I did a very rough sketch of annihilator's code and now I'm confused about states, so I left them blank for a while:
 

thingtype Annihilator : Mobj, 30111
basictype Monster
addflags DMGIGNORED|FOOTCLIP|NORADIUSDMG|BOSS|HIGHERMPROB

spawnhealth 7000
painchance 10
speed 16

radius 40
height 110

seesound DSCYBSIT
attacksound DSDMACT
painsound DSDMPAIN
deathsound DSCYBDTH
activesound DSHOOF/DSMETAL

obituary_normal "was blown away by the Annihilator's rockets"

 states                                       
   @" 
   Spawn:

For sounds, I used cyberdemon's one, but I think, I'll use provided ones after conversion, but learning sake, I want use what id guys provided 25 years ago. 

Share this post


Link to post
  • 0
Posted (edited)

Based on what I said it should look something like this. This probably won't work, but might?

 

thingtype Annihilator : Mobj, 30111
{
  obituary_normal "was blown away by The Cyber Annihilator's rockets."
  spawnhealth 7000
  radius 40.0
  height 110.0
  mass 1000
  speed 16
  painchance 16
  
  basictype Mosnter
  addflags "DMGIGNORED|FOOTCLIP|NORADIUSDMG|BOSS|HIGHERMPROB"

  seesound "monster/annsit"
  painsound "cyber/pain"
  deathsound "monster/anndth"
  activesound "cyber/active"

  states
  @"
  Spawn:
    ANNI AB 10 A_Look
	Loop
  See:
    ANNI A 3 A_PlaySoundEx("monster/anhoof")
	ANNI ABBCC 3 A_Chase
	ANNI D 3 A_PlaySoundEx("monster/anhoof")
	ANNI D 3 A_Chase
	Loop
  Missile:
    ANNI E 0 A_Jump(128,11)
    ANNI E 6 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 0 A_Jump(128,1)
    Goto See
  ShootMore: // If memory serves labels must be after gotos in EDF
    ANNI E 6 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40) 
	Goto See
  Pain:
    ANNI G 10 A_Pain
    Goto See
  Death:
    ANNI H 10 Bright
	ANNI I 10 Bright A_Scream
	ANNI JKL 10 Bright
    ANNI M 10 Bright A_Fall
    ANNI NO 10 Bright
    ANNI P 30
	ANNI P -1 A_BossDeath
  "@
}

I'll try get this done before the end of the day, editing the tutorial-of-sorts up above.

Edited by Altazimuth

Share this post


Link to post
  • 0
Posted (edited)

I decided to test your code and eternity returns me with this code error, which is "@ at the end of code:
 

Error at EANILATR:65:
no such option '’╗┐'

Also, it doesn't recognise "health" keyword, unless you add "spawnhealth". 

Share this post


Link to post
  • 0

For some reason the ASCII for the annihilator was really really screwed up. Sorted it out, copy the code above, which is updated.

Share this post


Link to post
  • 0
11 hours ago, Altazimuth said:

For some reason the ASCII for the annihilator was really really screwed up. Sorted it out, copy the code above, which is updated.

I have never coded for Eternity. Is it supposed to have the @" and "@ surrounding the states?

Share this post


Link to post
  • 0

Seems code works perfectly without any problems. Now one of the last question would be extradata - should it reflect those unique numbers given in marble code and main boss monster or it's defined a bit differently? Recordnum is one which gives me trouble, anything else is understandable for me. 

Share this post


Link to post
  • 0
Posted (edited)
2 hours ago, Empyre said:

I have never coded for Eternity. Is it supposed to have the @" and "@ surrounding the states?

Yes. Decorate has a rather unfortunate requirement that everything gets parsed as strings, so the start and ends of the states block needs to be clearly marked. However you can't just have quotes, because you can also have quotes inside the states block that designate strings as well, so the @ symbols are used to clear designate the the parser the key quotes for the block.

Share this post


Link to post
  • 0

Bogged down with university work. Still no excuse for being lazy and not responding. To make up for this I'll try implement a codepointer for you that should make porting the Annihilator easier: A_SpawnProjectile, the successor to A_CustomMissile. Shouldn't be too hard?

Share this post


Link to post
  • 0

Sure, take your time. Map is almost done, but without cyber annihilator I can't progress further and finish map proper way. ExtraData doesn't work for me, even if I used example from eternity wiki. 

Share this post


Link to post
  • 0

Because I started map eternity in doom format to test eternity port and my mapping skills for it.  My extradata lump looks like this, not sure what I'm doing wrong:
 

mapthing
{
recordnum = 30111
type{ Annihilator }
mapthing { options "EASY NORMAL HARD" }
}



 

Share this post


Link to post
  • 0

Fair enough. Was just wondering why when UDMF is a thing. Here's an example wad that uses ExtraData (I ported it to UDMF for the final idgames release).

e2l11.zip

Share this post


Link to post
  • 0
4 hours ago, Myst.Haruko said:

 


mapthing
{
recordnum = 30111
type{ Annihilator }
mapthing { options "EASY NORMAL HARD" }
}


This looks in your map for an ExtraData thing (doomednum 5004) with a tag of 30111, and replaces it with thingtype 'annihilator' with the options provided.

 

Since you mentioned you're working within the Doom format, you can't give a tag to the ExtraData thing. Use the commandline tool CLED to do so. 
 

 

Share this post


Link to post
  • 0

I think the ExtraData lump is entirely superfluous here. Apparently you're trying to use it to give an editor number to the Annihilator.

Share this post


Link to post
  • 0

Now, I'm a bit confused more. I just want defined decorations and monster to appear in game. I guess, should port map(but keep original one just in case) to udmf to avoid further confusion and readjust map for udmf action lines. 

Share this post


Link to post
  • 0

Alright, I'm bumping in this to tell that I finally understood how to bring custom things in map, solution was in front of me - I had only type thing's defined number manually from code start in builder. I wish it was stated a bit earlier or a bit more clearly, so it would saved some unnecessary confusion. I guess it's better later than never. 

Anyway, I have another problem - annihilator doesn't make any sounds and his rockets don't appear when he shoots. Other animations work as intended - he walks, chases, shoots, but no rockets and sounds when he gets hurts or sees player. I did video to show that, but if it will needed, I can put map here too. 

Edit: also he's like ghost, you can walk through him as would you do with "noclip" code.
 

Spoiler

 

 

Edited by Misty

Share this post


Link to post
  • 0
15 hours ago, Misty said:

Anyway, I have another problem

 

 

Please post the full EDF definitions of monster/projectile.

Share this post


Link to post
  • 0

I forgot to put code. My bad. Here:
 

thingtype Annihilator : Mobj, 30111
{
  doomednum   30002 
  obituary_normal "was blown away by The Cyber Annihilator's rockets."
  spawnhealth 7000
  radius 40.0
  height 110.0
  mass 1000
  speed 16
  painchance 16
  
  basictype Mosnter
  addflags "DMGIGNORED|FOOTCLIP|NORADIUSDMG|BOSS|HIGHERMPROB"

  seesound "monster/annsit"
  painsound "cyber/pain"
  deathsound "monster/anndth"
  activesound "cyber/active"

acs_spawndata 
  { 
    num   255;
    modes doom 
  }

  states
  @"
  Spawn:
    ANNI AB 10 A_Look
	Loop
  See:
    ANNI A 3 A_PlaySoundEx("monster/anhoof")
	ANNI ABBCC 3 A_Chase
	ANNI D 3 A_PlaySoundEx("monster/anhoof")
	ANNI D 3 A_Chase
	Loop
  Missile:
    ANNI E 0 A_Jump(128,11)
    ANNI E 6 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI F 12 Bright A_MissileAttack("Rocket2", normal, 40)
    ANNI E 0 A_Jump(128,1)
    Goto See
  ShootMore: // If memory serves labels must be after gotos in EDF
    ANNI E 6 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI E 12 A_FaceTarget
    ANNI F 0 Bright A_MissileAttack("HomRocket1", normal, 40)
    ANNI F 12 Bright A_MissileAttack("HomRocket1", normal, 40) 
	Goto See
  Pain:
    ANNI G 10 A_Pain
    Goto See
  Death:
    ANNI H 10 Bright
	ANNI I 10 Bright A_Scream
	ANNI JKL 10 Bright
    ANNI M 10 Bright A_Fall
    ANNI NO 10 Bright
    ANNI P 30
	ANNI P -1 A_BossDeath
  "@
}

 

Share this post


Link to post
  • 0

You're using Alfheim+ syntax ( "thingtype Annihilator : Mobj, 30111" ) but haven't expressly told EDF to use that syntax ("setdialect("ALFHEIM")" above your monster declaration). So, it will be ignored. Your monster's doomednum ("map editor id") is thus 30002, not 30111. There's a spelling mistake in "basictype Mosnter", which ought to read "basictype Monster"... that's what you get from copying @Altazimuth 's example verbatim :P

 

The latter explains your 'ghost' thing, as your monster is missing the basic 'monster' flags. You haven't posted the EDF of your custom rockets, so I can't tell what's wrong there.

 

As for sounds, you're probably pointing to a location that does not exist. Try using the 'vanilla' way of defining monster's sounds, eg "seesound = dswhatever", and having a "dswhatever" in your wad and see if that works, and go from there.

 

Also, you should always end a label with a 'stop', 'goto...' or whatever, because it can get messy if you start to use inheritance. So, a "stop" after AMNI P -1 A_BossDeath". Personally I would also end on a frame that has no codepointer, but that's just me.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×