MODDING Step by Step Tutorial

Discussion forum for Devil Whiskey 3rd Party MODS.

Moderator: Admin

User avatar
Growler
Necrolord
Posts: 1740
Joined: Mon Feb 14, 2005 10:37 pm
Location: Sputnik
Contact:

Post by Growler »

dragonbait wrote:..allows the Gelationous Cube to do much more damage via a Wild Pummel Skill, Entangle Skill, and Drown Spell. Will need to test it out...
Have you had a chance to test yet?
Now if someone could merge 'entangle' with 'drown' (then throw in 'wild pummel' for goodly measure), that would severely hamper (dampen?) one's day. :cry:
No Contraries : No Progression.
Opposition is true friendship, unless one is opposed to true friendship or (try) Resisting here http://www.cafepress.com/notheresistor
User avatar
dragonbait
Stalker
Posts: 775
Joined: Mon Apr 10, 2006 3:07 pm

Post by dragonbait »

I haven't tested the GCube yet. I got tripped up for a while over why one of my maps wasn't loading but that's been fixed now. One little typo can create so much chaos. :(

Step 4: EVENTS and TRAPS

Since this gets into some minor scripting, check out the...
Scripting Tutorial

Anyways, what good dungeon crawler doesn't contain some wraparound magic?

It is fairly simple to use in DW. All you need is wrap.py which is in the data/scripts folder

Code: Select all

#Wrap Around
from eventAPI import *
from APIUtils import *

def fireEvent(e):
   return 0
Now we go to the events file of the map that we want to use the wraparound in.

The Format is
<triggerX> <triggerY> <event Processor>
<reboundX> <reboundY> <reboundFaceAngle> <scriptName>

Code: Select all

#zzshrine1Events.cfg
13 15 2000
27 15 90 wrap
Line 1:
triggerX – the x location that triggers this event
triggerY – the y location that triggers this event
eventProcessor – this is the number of the event to trigger, and will most
commonly be 2000 – which is the python interpreter that handles scripted
combats, stairs or other map changes, messages to player, plot
advancement, etc. Other event numbers are listed in the next section

Line 2:
reboundX – the x location the character is rebounded to once the script
terminates with a false (0) result
reboundY – the y location the character is rebounded to once the script exits
with a false (0) result
reboundFaceAngle – the angle the character is facing on rebound –
0 = north, 90 = west, 180 = south, 270 = east
scriptName – the name of the python file to invoke without the .py extension,
ie – if we wanted to call wrap.py from this location, we would use
wrap for the script name.

You can use multiple wrap events so that when walking north, you reach an event that wraps you around to the south area of the map, south to the north, east to the west, west to the east. etc.

Like so.

Code: Select all

#zzshrine1Events.cfg
#
#14 22 2000
#15 22 270 zzshrine1out 
#Western wraparounds
13 15 2000
27 15 90 wrap
13 17 2000
27 17 90 wrap
13 19 2000
27 19 90 wrap
13 21 2000
27 21 90 wrap
13 23 2000
27 23 90 wrap
13 25 2000
27 25 90 wrap
13 27 2000
27 27 90 wrap
#Southern and Northern wraparounds
15 13 2000
15 27 180 wrap
15 29 2000
15 15 0 wrap
17 13 2000
17 27 180 wrap
17 29 2000
17 15 0 wrap
19 13 2000
19 27 180 wrap
19 29 2000
19 15 0 wrap
21 13 2000
21 27 180 wrap
21 29 2000
21 15 0 wrap
23 13 2000
23 27 180 wrap
23 29 2000
23 15 0 wrap
25 13 2000
25 27 180 wrap
25 29 2000
25 15 0 wrap
27 13 2000
27 27 180 wrap
27 29 2000
27 15 0 wrap
#Eastern wraparounds
29 15 2000
15 15 270 wrap
29 17 2000
15 17 270 wrap
29 19 2000
15 19 270 wrap
29 21 2000
15 21 270 wrap
29 23 2000
15 23 270 wrap
29 25 2000
15 25 270 wrap
29 27 2000
15 27 270 wrap
When using wraparounds on your maps it is important to make the map a bit larger than the area that you will wraparound, and put walls, doors etc. outside of the wraparound zone so to resemble the same walls, doors on each of the opposite sides.
Last edited by dragonbait on Sun Feb 05, 2012 8:55 pm, edited 3 times in total.
User avatar
dragonbait
Stalker
Posts: 775
Joined: Mon Apr 10, 2006 3:07 pm

Post by dragonbait »

Now that we have some wraparound magic set, its time to throw down some traps.

We need to modify the SPECCELL line within our map config file. (zzshrine1.cfg)
SPECCELL 14 22 28

The first 2 numbers to the right of SPECCELL are the (x) and (y) coordinates of the map's entry stairs.
The third number is the number of traps contained within the zzshrine1 map.

The number of traps on the SPECCELL line MUST match the number of traps listed below in the following format.

<trapX><trapY><trapType><trapNum>
Trap Lines:
<trapX> – the x location of the trap
<trapY> – the y location of the trap
<trapType> – the type of trap,
1 for normal (script based),
2 for spinners,
4 for anti-magic,
8 for darkness traps
<trapNum> – needed if trap is of type 1, calls the corresponding numbered trap
script (trap000x) so setting this to 2 would call script: trap0002.py
Trap types 2, 4, + 8 work each and every time the party steps on their trap location.

Trap type #1 (script based) will trigger once, and then will not trigger again if the party re-enters the square. Perhaps there might be a way to script trap type 1 so that the trap can re-trigger, but none of the current scripted traps do that and I haven't been able to get them to either.

The workaround for getting traps to trigger every time the party walks on the square is to create a trap event and place that trap event in the events file (zzshrine1Events.cfg) in the same way that we placed the wraparound event in my previous post.

Code: Select all

#zzshrine1Events.cfg
15 24 2000
15 24 0 trap0092

Code: Select all

#trap0092.py   Trap #92 - Heat damage Physical+Mental
# No Saving throw
# 4d6+2
# Added for Shrine of the Fire God 
from eventAPI import *
from APIUtils import *
 

def fireEvent&#40;e&#41;&#58;
    lFlagS = getTag&#40;e, "lFlagS"&#41;
    if &#40;not issetany&#40;lFlagS, 0x00000300&#41;&#41;&#58;
        return 0
    if &#40;isclearall&#40;lFlagS, 0x00000002&#41;&#41;&#58;
        showMessage&#40;e, &#91;"The heat of this place begins to physically and mentally drain you!"&#93;, optionInput&#41;
        for partyIdx in range&#40;getPartyCount&#40;e&#41;&#41;&#58;
         dmg = dice&#40;4, 6, 2&#41;
         modifyHP&#40;e, partyIdx, -dmg&#41;
         modifySP&#40;e, partyIdx, -dmg&#41;               
    return 0
The above trap script will do 4d6+2 damage to both HP and SP, and using it as an event will trigger the trap every time the party steps on or even turns in direction on the square. :twisted:
User avatar
dragonbait
Stalker
Posts: 775
Joined: Mon Apr 10, 2006 3:07 pm

Post by dragonbait »

Step 5: COMBAT (Random encounters versus Scripted encounters)

There are 2 ways to get monsters to attack the party.

1.) Random Encounters - You can set random encounters for each levels monster files.
For example the file zzshrineMon.cfg currently has the following information

Code: Select all

#zzshrineMon.cfg
# <Number of monsters> <chance attack <out of 1000>
5 30
#<Name><group size><group variance><group range><base occur><extra occur><start hour><stop hour>
Gelatinous_Cube 1 1 10 40 30 0 23
Glowing_Cube 1 2 10 35 20 0 23
Skeleton 2 8 30 20 15 0 23
Senrat 1 2 10 15 10 0 23
Giant_Spider 1 2 30 20 15
The number of monsters needs to match up with the number of monsters listed in the file so we currently have 5 monsters (2 cubes, skeleton, senrat, spider)

You can set the number of monsters contained within a group of monsters, and whether or not multiple groups of monsters can attack the party, and also the hours that monsters will appear.

A quick vid (though youtube compressed the hell out of it)of a random encounter...
http://www.youtube.com/watch?v=S9VZEnCkSEs


The other way for monsters to attack is via

2.) Scripted Encounters

A sample scripted encounter below details what text or images can be displayed either prior to battle or after battle (if the party defeats the monster, if the party is defeated by the monster and also if the party runs away......

Code: Select all

#glowcube battle
from eventAPI import *
from APIUtils import *

glowcube=0

def fireEvent&#40;e&#41;&#58;
   global glowcube
   glowcube = getTag&#40;e, "glowcube"&#41;
   if &#40;glowcube == 1&#41;&#58;
      return 1
   else&#58;
      showPicture&#40;e, "glowcube"&#41;
      showMessage&#40;e, &#91;"The bright illumination of Glow Cubes assault your well being."&#93;, optionInput&#41;
   fightThem&#40;e&#41;
   if &#40;glowcube == 1&#41;&#58;
      return 1
   else&#58;
      return 0

def fightThem&#40;e&#41;&#58;
   combatRet = combat&#40;e, &#91;&#40;"Glowing Cube", 1, 4, 10&#41;&#93;&#41;
   if &#40;combatRet == 1&#41;&#58;
      wonFight&#40;e&#41;
   elif &#40;combatRet == 3&#41;&#58;
      lostFight&#40;e&#41;
   else&#58;
      ranAwayFight&#40;e&#41;

def wonFight&#40;e&#41;&#58;
   global glowcube
   showMessage&#40;e, &#91;"The glow of the destroyed cubes fade into darkness."&#93;&#41;
   glowcube = 1
   setTag&#40;e, "glowcube", glowcube&#41;

def lostFight&#40;e&#41;&#58;
   showMessage&#40;e, &#91;"The cubes overpower you, their glowing embodyment burns and melts your flesh away."&#93;&#41;

def ranAwayFight&#40;e&#41;&#58;
   global glowcube
   showMessage&#40;e, &#91;"Lets get the hell out of here!"&#93;&#41;
   glowcube = 0
   setTag&#40;e, "glowcube", glowcube&#41;
   setExit&#40;e, "maps/zzshrine1.cfg", 17, 23, 90&#41;

Code: Select all

combatRet = combat&#40;e, &#91;&#40;"Glowing Cube", 1, 4, 10&#41;&#93;&#41;
will cause 1-5 Glowing Cubes to appear at 10’ range. Range must be divisible by 10. Multiple groups of the same type at the same range will be automatically combined.
-Returns an integer indicating the outcome of the combat: 1 indicates a party win, 2
indicates that the party ran, and 3 indicates that the entire party perished.

& you can set the exit location direction of the party if they run away.

Other useful commands including giveItems and chest and their descriptions...
giveItems(eventPtr, itemList)
chest(eventPtr, chestType, difficulty, gold, itemList, randItemCount, text)

can be viewed on the Scripting Tutorial previously linked above.

A bit longer vid (I changed the video display size from 1024x768 to 512 x384, after recording so youtube doesn't go all compression crazy) of a scripted encounter...
http://www.youtube.com/watch?v=ZQq6RlTnQTs
User avatar
Growler
Necrolord
Posts: 1740
Joined: Mon Feb 14, 2005 10:37 pm
Location: Sputnik
Contact:

Post by Growler »

Nice work there! (even tho yer party got totally gcube'd ;)

If weren't focused on dev'ing me own game, would be cool to mod-dev alongside here.. as it is, it's fun+interesting to read thru your descriptions and watch your vids.
No Contraries : No Progression.
Opposition is true friendship, unless one is opposed to true friendship or (try) Resisting here http://www.cafepress.com/notheresistor
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

What Video?

Post by jykler »

chaney wrote:That Video is absolutely kick arse!! Are you making this a starting party mod, or high level? I really like the red fog effect.
I'm brain dead, I didn't see a video?
-Jykler
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

Re: What Video?

Post by jykler »

jykler wrote:
chaney wrote:That Video is absolutely kick arse!! Are you making this a starting party mod, or high level? I really like the red fog effect.
I'm brain dead, I didn't see a video?
Nevermind. I found them on the last post.
-Jykler
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

Dumb question

Post by jykler »

I am thinking of this right now, and don't have the DW manual. I was playing last night (I actually had like 2-3 fights and LIVED) but I didn't like the order of my party. HOW IN THE HECK do you change the order of your party without having to do it each time during combat?
-Jykler
User avatar
chaney
Stalker
Posts: 683
Joined: Tue Nov 08, 2005 9:51 am
Location: San Diego

Post by chaney »

T for 1 position, Shift + T for redoing the whole party
Bring on the Dancing Horses!
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

THANKS!!

Post by jykler »

chaney wrote:T for 1 position, Shift + T for redoing the whole party
Thanks a lot, I'll do that as soon as I get home. Hmm, how to remember T? TO Reorder? The party reorder button? parTy order? Hmmm It will better for my casters to be in the back row (is that 4 in front and 4 in back? I have only 6 so 4 in front and 2 in back or 3/3?)
Sorry for all the questions, it's been years since I played :)
-Jykler
User avatar
chaney
Stalker
Posts: 683
Joined: Tue Nov 08, 2005 9:51 am
Location: San Diego

Post by chaney »

Questions are fun. :D
Bring on the Dancing Horses!
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

what about answers?

Post by jykler »

What about an answer, or did you not know?
-Jykler
User avatar
chaney
Stalker
Posts: 683
Joined: Tue Nov 08, 2005 9:51 am
Location: San Diego

Post by chaney »

Well,
If your question is about spellcaster positioning, then definitely the rear. If you had another unanswered question, I didn't see it.
Bring on the Dancing Horses!
User avatar
dragonbait
Stalker
Posts: 775
Joined: Mon Apr 10, 2006 3:07 pm

Post by dragonbait »

[t]oss party. Summons a large angry troll to toss the party around in the air creating a different party order.

But I think it was actually [t]rade or [t]ransfer?
User avatar
jykler
Site Admin
Posts: 82
Joined: Sun Jan 30, 2005 11:53 pm

Toss Party

Post by jykler »

dragonbait wrote:[t]oss party. Summons a large angry troll to toss the party around in the air creating a different party order.

But I think it was actually [t]rade or [t]ransfer?
I like Toss Party :)
Trade/transfer, my brain hasn't been working and it's obvious..
What I was REALLY asking was:

It will better for my casters to be in the back row (is that 4 in front and 4 in back? I have only 6 so 4 in front and 2 in back or 3/3?)
-Jykler
Post Reply