SP Tutorial Other How to add Zombies and place them on the map.

Users who are viewing this thread

Hi.

FINISHED!

If any one of you find out that something doesn't work please tell me and I'll do my best to help.
Note that I'm not a master coder and there may be flaws. I have tested and tested, but I haven't encountered any.

Constructive feedback is more then welcome.




After some tricking and fiddling I finaly got it to work.
Here you will learn how to add zombies to your mod, using the module system. I will add the zombies to the native module.
There are about five zillion twists and turns on how to add them. This is one of them.

Before we move on you should take a look at JIK's module tutorial
As far as I know, the tutorial doesn't cover this part but it will help you understand the structuring of scripts.


Now, get the undead pack from Keedo420
I assume that you already have the module system and are ready to go. If not LOOK HERE


When you have downloaded Keedo420's undead pack. Unpack it and look through the folder. You should see 4 different files:

  • Install
  • Undead.brf
  • Undeadbody.dds
  • Undeadface.dds

These files are necessary to implement the zombies.




Now, where do we start?
First of all you should take a look at the INSTALL note first but I'll post it here as well.

From Keedos install notes


1) Place undead.brf in your mod's resource folder.

2) Place undeadbody.dds and undeadface.dds in your mod's textures folder.

3) Open your mod's module.ini file and search for the following line:
  limit_hair_colors = 1
  Change to 1 to a 0 so the line looks like this:
  limit_hair_colors = 0

4) Look for the following line in module.ini:
  scan_module_textures = 0
  Change to 0 to a 1 so the line looks like this:
  scan_module_textures = 1

5) Add the following line to your mod's module.ini file:
  load_mod_resource = undead



Now we have made it so that the game will scan the model and the dds files when launching.
Let's move to the part where we actually make the magic happen.

Open you module_skins.py (Edit with Idle) or use notepad++

There isn't very much in this file, so this will be easy.
First of, paste this into the tuple that says: undead_face_keys = []

Between the brackets so that it looks like this

Code:
undead_face_keys = [
(20,0, 0.7,-0.6, "Chin Size"),
(260,0, -0.6,1.4, "Chin Shape"),
(10,0,-0.5,0.9, "Chin Forward"),
(240,0,0.9,-0.8, "Jaw Width"),
(210,0,-0.5,1.0, "Jaw Position"),
(250,0,0.8,-1.0, "Mouth-Nose Distance"),
(200,0,-0.3,1.0, "Mouth Width"),
(50,0,-1.5,1.0, "Cheeks"),

(60,0,-0.4,1.35, "Nose Height"),
(70,0,-0.6,0.7, "Nose Width"),
(80,0,1.0,-0.1, "Nose Size"),
(270,0,-0.5,1.0, "Nose Shape"),
(90,0,-0.2,1.4, "Nose Bridge"),

(100,0,-0.3,1.5, "Cheek Bones"),
(150,0,-0.2,3.0, "Eye Width"),
(110,0,1.5,-0.9, "Eye to Eye Dist"),
(120,0,1.9,-1.0, "Eye Shape"),
(130,0,-0.5, 1.1, "Eye Depth"),
(140,0,1.0,-1.2, "Eyelids"),

(160,0,1.3,-0.2, "Eyebrow Position"),
(170,0,-0.1,1.9, "Eyebrow Height"),
(220,0,-0.1,0.9, "Eyebrow Depth"),
(180,0,-1.1,1.6, "Eyebrow Shape"),
(230,0,1.2,-0.7, "Temple Width"),

(30,0,-0.6,0.9, "Face Depth"),
(40,0,0.9,-0.6, "Face Ratio"),
(190,0,0.0,0.95, "Face Width"),

(280,0,0.0,1.0, "Post-Edit"),
]


Now go to the very bottom of the file and paste this BEFORE the last bracket, but below the female skin.
You will see an already existing undead tuple here that has been commented out using ## . I pasted over it, but I'm sure you can just ignore it and paste it below.


Module_Skins.py
Code:
(
    "undead", 0,
    "undead_body", "undead_calf_l", "undead_handL",
    "undead_head1", man_face_keys,
 ["man_hair_s","man_hair_m","man_hair_n","man_hair_o", "man_hair_y10", "man_hair_y12","man_hair_p","man_hair_r","man_hair_q","man_hair_v","man_hair_t","man_hair_y6","man_hair_y3","man_hair_y7","man_hair_y9","man_hair_y11","man_hair_u","man_hair_y","man_hair_y2","man_hair_y4"], #man_hair_meshes ,"man_hair_y5","man_hair_y8",
    ["beard_e","beard_d","beard_k","beard_l","beard_i","beard_j","beard_z","beard_m","beard_n","beard_y","beard_p","beard_o",   "beard_v", "beard_f", "beard_b", "beard_c","beard_t","beard_u","beard_r","beard_s","beard_a","beard_h","beard_g",], #beard meshes ,"beard_q"
    ["hair_blonde"], #hair textures
    ["beard_blonde"], #beard_materials
    [("undeadface",0xffffffff,["hair_blonde"],[0xffffffff, 0xffb04717, 0xff502a19, 0xff19100c]),
     ], #undead_face_textures
[(voice_die,"snd_man_die"),(voice_hit,"snd_man_hit"),(voice_grunt,"snd_man_grunt"),(voice_grunt_long,"snd_man_grunt_long"),(voice_yell,"snd_man_yell"),(voice_warcry,"snd_man_warcry"),(voice_victory,"snd_man_victory")], #voice sounds
    "skel_human", 1.0,
    psys_game_blood,psys_game_blood_2,
  ),

]  <------ This is the last bracket.



Now move on to Module_Troops.py and search for bandit_face2  = man_face_older_2. Just below it you will see:

Module_Troops.py
Code:
undead_face1  = 0x00000000002000000000000000000000
undead_face2  = 0x000000000020010000001fffffffffff

You see all those numbers? Those numbers determine the looks of the Zombies. Replace it with this:

Module_Troops.py
Code:
undead_face1  = 0x0000000000000000000000000000000000000000000000000000000000000000
undead_face2  = 0x000000003f000493000000000000000000000000000000000000000000000000

Now we need to make a new troop. If you search for: Player history array and look above you will see alot that is commented out. And just below
you will see:  ["quick_battle_6_player",    .... etc. In between those paste this:


Module_Troops.py
Code:
#Zombies Begin
["zombie","Zombie","Zombies",tf_undead|tf_allways_fall_dead|tf_guarantee_boots|tf_guarantee_gloves|tf_undead|tf_allways_fall_dead,0,0,fac_outlaws,
   [itm_hide_boots,itm_leather_gloves],lord_attrib|
   str_29|agi_6|level(1),wp(80),knows_warrior_npc,undead_face1,undead_face2],
#Zombies End 

so that it looks just like below.

Module_Troops.py
Code:
##  ["noble_refugee","Noble Refugee","Noble Refugees",tf_guarantee_boots|tf_guarantee_armor,0,0,fac_noble_refugees,
##   [itm_sword,itm_leather_jacket,itm_hide_boots, itm_saddle_horse, itm_leather_jacket, itm_leather_cap],
##   def_attrib|level(9),wp(100),knows_common,swadian_face1, swadian_face2],
##  ["noble_refugee_woman","Noble Refugee Woman","Noble Refugee Women",tf_female|tf_guarantee_armor|tf_guarantee_boots,0,0,fac_noble_refugees,
##   [itm_knife,itm_dagger,itm_hunting_crossbow,itm_dress,itm_robe,itm_woolen_dress, itm_headcloth, itm_woolen_hood, itm_wrapping_boots],
##   def_attrib|level(3),wp(45),knows_common,refugee_face1,refugee_face2],

#Zombies Begin
["zombie","Zombie","Zombies",tf_undead|tf_allways_fall_dead|tf_guarantee_boots|tf_guarantee_gloves|tf_undead|tf_allways_fall_dead,0,0,fac_outlaws,
   [itm_hide_boots,itm_leather_gloves],
   str_29|agi_6|level(8),wp(80),knows_warrior_npc,undead_face1,undead_face2],
#Zombies End   


  ["quick_battle_6_player", "quick_battle_6_player", "quick_battle_6_player", tf_hero, 0, reserved,  fac_player_faction, [itm_padded_cloth,itm_nomad_boots, itm_splinted_leather_greaves, itm_skullcap, itm_sword_medieval_b,  itm_crossbow, itm_bolts, itm_plate_covered_round_shield],    knight_attrib_1,wp(130),knight_skills_1, 0x000000000008010b01f041a9249f65fd],


#Player history array
  ["log_array_entry_type",            "Local Merchant","Local Merchant",tf_guarantee_boots|tf_guarantee_armor, 0,0, fac_commoners,[itm_leather_apron,itm_leather_boots,itm_butchering_knife],def_attrib|level(5),wp(40),knows_power_strike_1, merchant_face_1, merchant_face_2],
  ["log_array_entry_time",            "Local Merchant","Local Merchant",tf_guarantee_boots|tf_guarantee_armor, 0,0, fac_commoners,[itm_leather_apron,itm_leather_boots,itm_butchering_knife],def_attrib|level(5),wp(40),knows_power_strike_1, merchant_face_1, merchant_face_2],
  ["log_array_actor",                 "Local Merchant","Local Merchant",tf_guarantee_boots|tf_guarantee_armor, 0,0, fac_commoners,[itm_leather_apron,itm_leather_boots,itm_butchering_knife],def_attrib|level(5),wp(40),knows_power_strike_1, merchant_face_1, merchant_face_2],

Now that you have the unit ready we just need to place it somewhere.
Search for: sea_raider_spawn_point_2  . Just below it paste this:

Module_Parties.py
Code:
#Zombies Begin
  ("zombies_spawn_points"   ,"zombies_sp",pf_disabled|pf_is_static, no_menu, pt_none, fac_outlaws,0,ai_bhvr_hold,0,(48, 87),[(trp_looter,15,0)]),
#Zombies End

It should now look like this.

Module_Parties.py
Code:
("sea_raider_spawn_point_2"   ,"sea_raider_sp",pf_disabled|pf_is_static, no_menu, pt_none, fac_outlaws,0,ai_bhvr_hold,0,(47, 86),[(trp_looter,15,0)]),
#Zombies Begin
  ("zombies_spawn_points"   ,"zombies_sp",pf_disabled|pf_is_static, no_menu, pt_none, fac_outlaws,0,ai_bhvr_hold,0,(48, 87),[(trp_looter,15,0)]),
#Zombies End 
# add extra towns before this point 
  ("spawn_points_end"                  ,"last_spawn_point",    pf_disabled|pf_is_static, no_menu, pt_none, fac_commoners,0,ai_bhvr_hold,0,(0., 0),[(trp_looter,15,0)]),

In Module_Party_Templates.py search for this: ("sea_raiders","Sea Raiders"    .... etc.
Below it paste this:

Module_Party_Templates.py
Code:
#Zombies Begin
("zombies","Zombies",icon_peasant|carries_goods(2),0,fac_outlaws,bandit_personality,[(trp_zombie,50,75)]),
#Zombies End


It should now look like this:

Module_Party_Templates.py
Code:
("forest_bandits","Forest Bandits",icon_axeman|carries_goods(2),0,fac_forest_bandits,bandit_personality,[(trp_forest_bandit,5,52)]),
  ("mountain_bandits","Mountain Bandits",icon_axeman|carries_goods(2),0,fac_mountain_bandits,bandit_personality,[(trp_mountain_bandit,5,60)]),
  ("sea_raiders","Sea Raiders",icon_axeman|carries_goods(2),0,fac_outlaws,bandit_personality,[(trp_sea_raider,5,50)]),
  #Zombies Begin
  ("zombies","Zombies",icon_peasant|carries_goods(2),0,fac_outlaws,bandit_personality,[(trp_zombie,50,75)]),
  #Zombies End

  ("deserters","Deserters",icon_vaegir_knight|carries_goods(3),0,fac_deserters,bandit_personality,[]),

  ("merchant_caravan","Merchant Caravan",icon_gray_knight|carries_goods(20)|pf_auto_remove_in_town|pf_quest_party,0,fac_commoners,escorted_merchant_personality,[(trp_caravan_master,1,1),(trp_caravan_guard,5,25)]),


In Module_Scripts.py search for this: #script_spawn_bandits
Under the mountain bandits tuple paste this:

Module_Scripts.py
Code:
##Zombies Begin
	 (try_begin),
       (store_num_parties_of_template, ":num_parties", "pt_zombies"),
       (lt,":num_parties",1),
       (store_random,":spawn_point",num_zombies_spawn_points),
       (val_add,":spawn_point","p_zombies_spawn_points"),
       (spawn_around_party,":spawn_point","pt_zombies"),
     (try_end),
##Zombies End

It should now look like this.

Module_Scripts.py
Code:
#script_spawn_bandits
  # INPUT: none
  # OUTPUT: none
  ("spawn_bandits",
    [(set_spawn_radius,1),
     (try_begin),
       (store_num_parties_of_template, ":num_parties", "pt_mountain_bandits"),
       (lt,":num_parties",14),
       (store_random,":spawn_point",num_mountain_bandit_spawn_points),
       (val_add,":spawn_point","p_mountain_bandit_spawn_point"),
       (spawn_around_party,":spawn_point","pt_mountain_bandits"),
     (try_end),
##Zombies Begin
	 (try_begin),
       (store_num_parties_of_template, ":num_parties", "pt_zombies"),
       (lt,":num_parties",1),
       (store_random,":spawn_point",num_zombies_spawn_points),
       (val_add,":spawn_point","p_zombies_spawn_points"),
       (spawn_around_party,":spawn_point","pt_zombies"),
     (try_end),
##Zombies End
     (try_begin),
       (store_num_parties_of_template, ":num_parties", "pt_forest_bandits"),
       (lt,":num_parties",14),
       (store_random,":spawn_point",num_mountain_bandit_spawn_points),
       (val_add,":spawn_point","p_forest_bandit_spawn_point"),
       (spawn_around_party,":spawn_point","pt_forest_bandits"),
     (try_end),

Now that we have created the troop we need a dialogue for them. We will create them in Module_dialogues.py

Search for: I will drink from your skull!
Under that tuple you can add this:

Module_Dialogues.py
Code:
[anyone,"start", [(eq,"$talk_context", tc_party_encounter),(store_encountered_party, reg(5)),(party_get_template_id,reg(7),reg(5)),(eq,reg(7),"pt_zombies")],
   "Growl!", "battle_reason_stated",[(play_sound,"snd_encounter_zombies")]],

It should now look like this:

Module_Dialogues.py
Code:
[anyone,"start", [(eq,"$talk_context", tc_party_encounter),(store_encountered_party, reg(5)),(party_get_template_id,reg(7),reg(5)),(eq,reg(7),"pt_sea_raiders")],
   "I will drink from your skull!", "battle_reason_stated",[(play_sound,"snd_encounter_sea_raiders")]],
   
   [anyone,"start", [(eq,"$talk_context", tc_party_encounter),(store_encountered_party, reg(5)),(party_get_template_id,reg(7),reg(5)),(eq,reg(7),"pt_zombies")],
   "Growl!", "battle_reason_stated",[(play_sound,"snd_encounter_zombies")]],
  
######################################
# GENERIC MEMBER CHAT
######################################

NOTE:

Observe that I have added a new sound to the Zombie encountering: [(play_sound,"snd_encounter_zombies")]
This sound will not work and you will get an error trying to compile, IF you haven't already added it.

If you haven't, replace it with this: [(play_sound,"snd_encounter_sea_raiders")]


You can easily add a new sound by:

1. place a new sound in your mod's sound folder. Mine is named encounter_zombies and is of the file format .ogg
2. Add a new entry in Module_sounds.py
3. EXAMPLE: ("encounter_zombies",sf_2d|sf_vol_5, ["encounter_zombies.ogg"]),
4. Open your module.ini file and change the line

scan_module_sounds = 0

to this

scan_module_sounds = 1

That's all. Then you just have to use it.


And now, the last thing we'll do is add a simple entry in Module_Constant.py

Search for: num_sea_raider_spawn_points = 2

And paste this below

Module_Constant.py
Code:
num_zombies_spawn_points = 1

It should look like this

Module_Constant.py
Code:
num_forest_bandit_spawn_points = 1
num_mountain_bandit_spawn_points = 1
num_steppe_bandit_spawn_points = 1
num_black_khergit_spawn_points = 1
num_sea_raider_spawn_points = 2
num_zombies_spawn_points = 1

peak_prisoner_trains = 4
peak_kingdom_caravans = 12
peak_kingdom_messengers = 3


AND WE ARE DONE!!

Compile and run. At Wercheg you should now see Zombies running around "disguised" as farmers.

You can tweak and twist this as much as you want. Just look through the forum for info about how to do it.


In-game Pics below

ZombiePreview2.jpg

ZombiePreview1.jpg

ZombiePreview3.jpg

ZombiePreview4.jpg

ZombiePreview5.jpg

ZombiePreview6.jpg

ZombiePreview7.jpg

ZombiePreview8.jpg

 
It looks everything correct to me...

Maybe this is nonsense, but once someone was getting this unable to find object and it was a bad downloaded file.
 
You've got to be ****ing me?

I changed it and it worked perfectly.
When this stuff happens I just wish I stuck with map editing and scene making.

Thanks alot for your help.

Hey, now someone else can use this to their own mod.

Just gonna correct it and then it'll be ready to use.

-EDIT-

Ok they spawn OK and they have the right icon on the map and everything works fine, but...

When I try to go to battle with them the game crashes.
Can it be because of the number of enemies? Corrupt mesh, bad texture?

Any more ideas?
 
NaglFaar said:
Ok they spawn OK and they have the right icon on the map and everything works fine, but...

When I try to go to battle with them the game crashes.
Can it be because of the number of enemies? Corrupt mesh, bad texture?
Check your rgl_log.txt in the game's root folder.  Asset errors tend to show up there.  Is it a hard crash or just a windows bonk sound with a dialog and exit?
 
Do they have a ready dialogue? I crashed the game sometimes when there was something wrong with a troop and when you clicked the soldier it crashed, maybe the first of your soldiers has got an error.
 
kt0 said:
NaglFaar said:
Ok they spawn OK and they have the right icon on the map and everything works fine, but...

When I try to go to battle with them the game crashes.
Can it be because of the number of enemies? Corrupt mesh, bad texture?
Check your rgl_log.txt in the game's root folder.  Asset errors tend to show up there.  Is it a hard crash or just a windows bonk sound with a dialog and exit?

It' just windows with no sound and then the ordinary: windows has encountered a problem and must exit. It's not a RGL error.

I checked the log but could only find this:
Loading Resource  ani_run_sideways
Loading Module Resource  undead
Loading Resource  uni_jump
Loading Resource  uni_stances
Loading Resource  uni_equip
Loading Resource  uni_strike
Loading Resource  uni_throws
Loading Resource  uni_fistswing
Loading Resource  uni_lord_stand
Loading Resource  uni_defence
Loading Resource  uni_sideways
Loading Music...
WARNING: UNABLE TO MAP GAME PRESENTATION CODE:  prsnt_game_start
WARNING: UNABLE TO MAP GAME PRESENTATION CODE:  prsnt_game_escape
WARNING: UNABLE TO MAP GAME SCRIPT CODE:  game_check_party_sees_party
WARNING: UNABLE TO MAP GAME SCRIPT CODE:  game_get_party_speed_multiplier

Loading Module...
Loading item kinds...
Loading dialogs...
Loading mission templates...
Loading party templates...

Doesn't the zombies have a dialouge?


Blankin said:
Do they have a ready dialogue? I crashed the game sometimes when there was something wrong with a troop and when you clicked the soldier it crashed, maybe the first of your soldiers has got an error.

I just thought of that.

Anyone have a link to a tutorial if that's the problem?


-EDIT-

I gave the zombies a dialouge but that didn't help. So I thought that it must be the resource.
In troops.py I added the option to upgrade Hired blade to a zombie. When I tested it ingame it crashed.

I'm gonna try and contact keedo and see if this has happened before. Then I'll come back and share my knowledge.
 
NaglFaar said:
It' just windows with no sound and then the ordinary: windows has encountered a problem and must exit. It's not a RGL error.

I checked the log but could only find this:
Loading Resource  ani_run_sideways
Loading Module Resource  undead
Loading Resource  uni_jump
Loading Resource  uni_stances
Loading Resource  uni_equip
Loading Resource  uni_strike
Loading Resource  uni_throws
Loading Resource  uni_fistswing
Loading Resource  uni_lord_stand
Loading Resource  uni_defence
Loading Resource  uni_sideways
Loading Music...
WARNING: UNABLE TO MAP GAME PRESENTATION CODE:  prsnt_game_start
WARNING: UNABLE TO MAP GAME PRESENTATION CODE:  prsnt_game_escape
WARNING: UNABLE TO MAP GAME SCRIPT CODE:  game_check_party_sees_party
WARNING: UNABLE TO MAP GAME SCRIPT CODE:  game_get_party_speed_multiplier

Loading Module...
Loading item kinds...
Loading dialogs...
Loading mission templates...
Loading party templates...
Those warnings are normal; I get them too (and it annoys me that they're there). 

I'd double check that the face codes are proper.  I've seen some weird crashes hacking those kinds of things up before.  After that I'd check for corrupted textures and meshes like you said but I'm guessing that if it's not obviously wrong, that it's not the issue.  Beyond that I have no idea.  I'd probably hit it with windbg at that point but that's not exactly a simple tool to use. 
 
kt0 said:
Those warnings are normal; I get them too (and it annoys me that they're there). 

I'd double check that the face codes are proper.  I've seen some weird crashes hacking those kinds of things up before.  After that I'd check for corrupted textures and meshes like you said but I'm guessing that if it's not obviously wrong, that it's not the issue.  Beyond that I have no idea.  I'd probably hit it with windbg at that point but that's not exactly a simple tool to use.

What if I used the native meshes and textures for the undead?
I saw that there is for some horribly weird reason some native stuff for undeads.

Are they usable? I mean, as long as I set the limit_hair_colors correctly they should work, right?

-EDIT-

I looked a little more and found that the skinns exist but are commented out with #.
Will it work if I just remove the # ?
 
I remember in Keedo's thread for the zombie kit he mentioned that the native zombie face texture is missing so it would work but the face would be untextured. Keedo's thread mentioned some fixes to the various errors I think?
 
Ok. I solved the problem now.

The problem was that I had put this ?tuple? wrong:

Code:
(
    "undead", 0,
    "undead_body", "undead_calf_l", "undead_handL",
    "undead_head1", man_face_keys,
 ["man_hair_s","man_hair_m","man_hair_n","man_hair_o", "man_hair_y10", "man_hair_y12","man_hair_p","man_hair_r","man_hair_q","man_hair_v","man_hair_t","man_hair_y6","man_hair_y3","man_hair_y7","man_hair_y9","man_hair_y11","man_hair_u","man_hair_y","man_hair_y2","man_hair_y4"], #man_hair_meshes ,"man_hair_y5","man_hair_y8",
    ["beard_e","beard_d","beard_k","beard_l","beard_i","beard_j","beard_z","beard_m","beard_n","beard_y","beard_p","beard_o",   "beard_v", "beard_f", "beard_b", "beard_c","beard_t","beard_u","beard_r","beard_s","beard_a","beard_h","beard_g",], #beard meshes ,"beard_q"
    ["hair_blonde"], #hair textures
    ["beard_blonde"], #beard_materials
    [("undeadface",0xffffffff,["hair_blonde"],[0xffffffff, 0xffb04717, 0xff502a19, 0xff19100c]),
     ], #undead_face_textures
[(voice_die,"snd_man_die"),(voice_hit,"snd_man_hit"),(voice_grunt,"snd_man_grunt"),(voice_grunt_long,"snd_man_grunt_long"),(voice_yell,"snd_man_yell"),(voice_warcry,"snd_man_warcry"),(voice_victory,"snd_man_victory")], #voice sounds
    "skel_human", 1.0,
    psys_game_blood,psys_game_blood_2,
  ),

At first I had placed it with the undead_face_keys = [etc...
Howerver, that was awfully wrong.

Well I'll just update the first post to a tutorial. (might aswell use it if others want to try.)
If someone has a good reason for me NOT to make this tut, please tell me.



 
Nice job, you're getting the hang of it.  Just make sure to run a full test before posting the code, or post it as test code (v0.2 etc.).  I've done the same a few times... a  bit embarrassing... :wink:

I'm sure this will help a lot of fantasy/undead modders out there.
 
Thanks for making this into a tutorial especially the spawn script I always forget how to do that. I made me some warrior zombies.
 
Well one when I changed the limit hair colours but that seemed to give all the normal people in my game white untextured hair. So I changed it back and just made sure in the face codes of each troop ie I gave them two bald facecode options.  The zombies never get hair. And everything worked fine again, both zombies and people. Why does limit_hair_colours have to be changed?
 
Back
Top Bottom