OSP Kit Campaign Sea Battles Mk. II & Misc Scenes

Users who are viewing this thread

So what with Wülf going cold, I thought I might share some of the more generalized features that someone might want to use in their own mod. The first (and what I assume will be the most wanted) is Sea Battles. Some of you might remember that I made a guide for some sea travel/fights for M&B 1.011. I'm going to start off by saying that this isn't just a ported version of that, and if you prefer the old one to this one (I'll explain the differences between the two soonish) the old code should basically work the same.

Now, the differences between the old sea travel I made and this one is that the old one was AI friendly, in that AI parties could go over the water themselves and it was all very nice - mostly. But it had some major drawbacks; it caused some pretty bad lag on lower-end PCs, you had to sacrifice a map texture, the water wouldn't move, and the code needed a fair bit of love and care from whoever was implementing it for it to work right, and you'd have to change it every time you added a new party template. Or something. It wasn't exactly the cleanest code in history, basically. The scenes weren't too good either. In this one, it only allows the player to go on water (as well as any parties that you specifically spawn on water as ships.)


The second thing in here are "three" misc scenes that someone might want. The scenes are WIP's, but they're mostly done. The first one is an island, which mostly looks totally abandoned, but has some traces of civilization. Further exploration brings you to some caves which lead inside the mountain to a room that holds a valuable treasure (what exactly the treasure is you can decide.) But once you take the treasure, you get ambushed by some nasty savages. The next is a huge mountain pass defended by a wall and some towers. Past the wall is a little village, and there's even a snowy path up the mountain that takes you to an old stone passageway, which leads to moar treasure! Most of the pass etc is AI meshed, but the path leading to the treasure chest and the mountains around there aren't AI meshed or blocked off or anything, so one could theoretically go around the defenses and the AI probably wouldn't be able to get at you. The other scene is a huge Sarranid town in the middle of nowhere. Sadly this scene isn't really anywhere near being finished, it still needs detailing and an AI mesh, but it's still pretty awesome, so I imagine someone might want it for something.


Sea Battles
Alright, keeping in mind that these codes are only mostly finished and would need some additions/changes depending on what your mod is (If you have a new map you might have to change which cities you can buy ships from etc) this should basically cover everything you would need to get these sea battles working in game.

First of all, let's add the new scenes. Download this:
http://www.mbrepository.com/file.php?id=2258
It includes the ship scenes, and the scenes for the island, the mountain pass, and Sarranid city. Right now, you only need to pay attention to the scenes named "sea_scene_X". Extract those three scenes (ignoring that they go 1, 2, then 4, as sea scene 3 was too lolzy to include) to your mod's SceneObj folder, and we'll just let those sit there for now.

With that done, you can actually add those scenes into the game. So open up module_scenes, and at the bottom add:
Code:
#Wulf begin
  ("sea_1",sf_generate,"none", "none", (0,0),(240,240),-0.5,"0x0000000030000000c00d2348000000008000000000000000",
   [],[]),
  ("sea_4",sf_generate,"none", "none", (0,0),(240,240),-0.5,"0x0000000030000000c00d2348000000008000000000000000",
   [],[]),
  ("sea_2",sf_generate,"none", "none", (0,0),(240,240),-0.5,"0x0000000030000000c00d2348000000008000000000000000",
   [],[]),
#Wulf end
Easy-peasy. Now, we want to be able to buy a ship and sail around. So save and close module_scenes and open up module_game_menus, and seach (Ctrl+F) the "sail_from_port" code. Delete that and replace it with this:
#Wulf begin
      ("sail_from_port",[(this_or_next|eq,"$current_town","p_town_1"),
                        (this_or_next|eq,"$current_town","p_town_2"),
                        (this_or_next|eq,"$current_town","p_town_6"),
                        (this_or_next|eq,"$current_town","p_town_12"),
                        (this_or_next|eq,"$current_town","p_town_19"),
                        (this_or_next|eq,"$current_town","p_town_13"),
                        (eq,"$current_town","p_town_15"),
#                          (eq, "$cheat_mode", 1),
#                        (party_slot_eq,"$current_town",slot_town_near_shore, 1),
                        ], "Buy a ship (5000 denars)",
      [(store_troop_gold,":money","trp_player"),
      (try_begin),
        (ge,":money",5000),
        (troop_remove_gold,"trp_player",5000),
        (assign, "$g_player_icon_state", pis_ship),
        (party_set_flags, "p_main_party", pf_is_ship, 1),
        (party_get_position, pos1, "p_main_party"),
        (map_get_water_position_around_position, pos2, pos1, 6),
        (party_set_position, "p_main_party", pos2),
        (assign, "$g_main_ship_party", -1),
        (change_screen_return),
      (else_try),
        (display_message,"@You don't have enough money"),
      (try_end),
        ]),
#Wulf end
This one might be a bit harder to follow. First of all, do a quick check to make sure that you copied over the right code. Do that by getting rid of the last bracket (the green one) and then typing it back in. That should "select" the code from the "(sail_from_port" to the last bracket. If it selects more, you must have gotten rid of an extra bracket that you weren't supposed to. (If you didn't completely understand that, it's fine, you probably didn't make a mistake, but this is just to be sure.) Next, pay attention to the 5000s. All those are the amount of money it costs to buy a ship, so you can change those three numbers to whatever you like to raise/lower the price of a ship. Save the file (but leave it open as we need it again soon) and compile your mod to check for errors. Fix any errors that may have appeared, and continue.

Now that you can get a ship and sail around, you need to actually be able to fight someone on those ships. So, (still in module_game_menus) search for "encounter attack". Delete that code and replace it with this:
Code:
("encounter_attack",[
          (eq, "$encountered_party_friendly", 0),
          (neg|troop_is_wounded, "trp_player"),
          #Wulf
          (party_get_current_terrain,":terrain","p_main_party"),
         (neq,":terrain",0),
          #Wulf end
          ],
                            "Charge the enemy.",[
                                (assign, "$g_battle_result", 0),
                                (assign, "$g_engaged_enemy", 1),
                                (call_script, "script_calculate_renown_value"),
                                (call_script, "script_calculate_battle_advantage"),
                                (set_battle_advantage, reg0),
                                (set_party_battle_mode),
                                (try_begin),
                                  (eq, "$g_encounter_type", enctype_fighting_against_village_raid),
                                  (assign, "$g_village_raid_evil", 0),
                                  (set_jump_mission,"mt_village_raid"),
                                  (party_get_slot, ":scene_to_use", "$g_encounter_is_in_village", slot_castle_exterior),
                                  (jump_to_scene, ":scene_to_use"),
                                (else_try),
                                  (eq, "$g_encounter_type", enctype_catched_during_village_raid),
                                  (assign, "$g_village_raid_evil", 0),
                                  (set_jump_mission,"mt_village_raid"),
                                  (party_get_slot, ":scene_to_use", "$g_encounter_is_in_village", slot_castle_exterior),
                                  (jump_to_scene, ":scene_to_use"),
                                (else_try),
                                  (set_jump_mission,"mt_lead_charge"),
                                  (call_script, "script_setup_random_scene"),
                                (try_end),
                                (assign, "$g_next_menu", "mnu_simple_encounter"),
                                (jump_to_menu, "mnu_battle_debrief"),
                                (change_screen_mission),
                                ]),
      ("encounter_attack",[
          (eq, "$encountered_party_friendly", 0),
          (neg|troop_is_wounded, "trp_player"),
          #Wulf
          (party_get_current_terrain,":terrain","p_main_party"),
         (eq,":terrain",0),
          #Wulf end
          ],
                            "Close in and board the enemy.",[
                                (assign, "$g_battle_result", 0),
                                (assign, "$g_engaged_enemy", 1),
                                (call_script, "script_calculate_renown_value"),
                                (call_script, "script_calculate_battle_advantage"),
                                (set_battle_advantage, reg0),
                                (set_party_battle_mode),
                                (try_begin),
                                  (eq, "$g_encounter_type", enctype_fighting_against_village_raid),
                                  (assign, "$g_village_raid_evil", 0),
                                  (set_jump_mission,"mt_village_raid"),
                                  (party_get_slot, ":scene_to_use", "$g_encounter_is_in_village", slot_castle_exterior),
                                  (jump_to_scene, ":scene_to_use"),
                                (else_try),
                                  (eq, "$g_encounter_type", enctype_catched_during_village_raid),
                                  (assign, "$g_village_raid_evil", 0),
                                  (set_jump_mission,"mt_village_raid"),
                                  (party_get_slot, ":scene_to_use", "$g_encounter_is_in_village", slot_castle_exterior),
                                  (jump_to_scene, ":scene_to_use"),
                                (else_try),
                                #Wulf
                                  (set_jump_mission,"mt_ship_battle"),
                                 (try_begin),
                                   (val_add,reg10,reg11),
                                   (gt,reg10,60),
                                   (jump_to_scene, "scn_sea_4"),
                                 (else_try),
                                   (val_add,reg10,reg11),
                                   (gt,reg10,30),
                                   (jump_to_scene, "scn_sea_2"),
                                 (else_try),
                                   (jump_to_scene, "scn_sea_1"),
                                   (end_try),
                                   #Wulf end
                                (try_end),
                                (assign, "$g_next_menu", "mnu_simple_encounter"),
                                (jump_to_menu, "mnu_battle_debrief"),
                                (change_screen_mission),
                                ]),

Now we're going to do something similar to the "join_attack" menu. So find "join_attack" and replace it with this:
Code:
      ("join_attack",[(party_get_current_terrain,":terrain","p_main_party"),
         (neq,":terrain",0),
#          (neq, "$encountered_party_hostile", 0),
           (neg|troop_is_wounded, "trp_player"),
##          (store_troop_health,reg(5),"trp_player"),
##          (ge,reg(5),20),
          ],
                            "Charge the enemy.",[
                                (party_set_next_battle_simulation_time, "$g_encountered_party", -1),
                                (assign, "$g_battle_result", 0),
                                (call_script, "script_calculate_renown_value"),
                                (call_script, "script_calculate_battle_advantage"),
                                (set_battle_advantage, reg0),
                                (set_party_battle_mode),
                                (set_jump_mission,"mt_lead_charge"),
                                (call_script, "script_setup_random_scene"),
                                (assign, "$g_next_menu", "mnu_join_battle"),
                                (jump_to_menu, "mnu_battle_debrief"),
                                (change_screen_mission),
                                ]),

            ("join_attack",[(party_get_current_terrain,":terrain","p_main_party"),
         (eq,":terrain",0),
#          (neq, "$encountered_party_hostile", 0),
           (neg|troop_is_wounded, "trp_player"),
##          (store_troop_health,reg(5),"trp_player"),
##          (ge,reg(5),20),
          ],
                            "Board the enemy",[
                                (party_set_next_battle_simulation_time, "$g_encountered_party", -1),
                                (assign, "$g_battle_result", 0),
                                (call_script, "script_calculate_renown_value"),
                                (call_script, "script_calculate_battle_advantage"),
                                (set_battle_advantage, reg0),
                                (set_party_battle_mode),
                                (set_jump_mission,"mt_ship_battle"),
                                (try_begin),
                                   (val_add,reg10,reg11),
                                   (gt,reg10,60),
                                   (jump_to_scene, "scn_sea_4"),
                                 (else_try),
                                   (val_add,reg10,reg11),
                                   (gt,reg10,30),
                                   (jump_to_scene, "scn_sea_2"),
                                 (else_try),
                                   (jump_to_scene, "scn_sea_1"),
                                   (end_try),
                                (assign, "$g_next_menu", "mnu_join_battle"),
                                (jump_to_menu, "mnu_battle_debrief"),
                                (change_screen_mission),
                                ]),

Those codes make you jump to the ship scenes when you're fighting someone on the water. Which leads to the next issue; getting someone to fight. Save and exit module_game_menus and open up module_mission_templates. Go to the bottom of the page and add this code:
Code:
        #Wulf begin
    (
    "ship_battle",mtf_battle_mode,-1,
    "You close in and board the enemy ships",
    [(0,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (1,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (2,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (3,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (4,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (5,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (6,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),     
    (7,mtef_attackers|mtef_team_1,af_override_horse,aif_start_alarmed,4,[]),
    (10,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (11,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (8,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (9,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (12,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (13,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (14,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
    (15,mtef_defenders|mtef_team_0,af_override_horse,aif_start_alarmed,4,[]),
     ],
    [
      (ti_on_agent_spawn, 0, 0, [],
       [
         (store_trigger_param_1, ":agent_no"),
         (call_script, "script_agent_reassign_team", ":agent_no"),
         ]),
    

      
      (0, 0, ti_once, [], [(assign,"$battle_won",0),
                           (assign,"$defender_reinforcement_stage",0),
                           (assign,"$attacker_reinforcement_stage",0),
                           (assign,"$g_presentation_battle_active", 0),
                           (call_script, "script_place_player_banner_near_inventory"),
                           (call_script, "script_combat_music_set_situation_with_culture"),
                           ]),
      common_music_situation_update,
      common_battle_check_friendly_kills,

      (1, 0, 5, [(lt,"$defender_reinforcement_stage",2),
                 (store_mission_timer_a,":mission_time"),
                 (ge,":mission_time",10),
                 (store_normalized_team_count,":num_defenders", 0),
                 (lt,":num_defenders",6),
#                 (assign, reg2, ":num_defenders"),
#                 (display_message,"@num_defenders = {reg2}")
                 ],
           [(add_reinforcements_to_entry,0,7),(val_add,"$defender_reinforcement_stage",1)]),
      
      (1, 0, 5, [(lt,"$attacker_reinforcement_stage",2),
                 (store_mission_timer_a,":mission_time"),
                 (ge,":mission_time",10),
                 (store_normalized_team_count,":num_attackers", 1),
                 (lt,":num_attackers",6),
#                 (assign, reg2, ":num_attackers"),
#                 (display_message,"@num_attackers = {reg2}")
                 ],
           [(add_reinforcements_to_entry,3,7),(val_add,"$attacker_reinforcement_stage",1)]),
      
      common_battle_check_victory_condition,
      common_battle_victory_display,
      common_battle_tab_press,

      (1, 4, ti_once, [(main_hero_fallen)],
          [
              (assign, "$pin_player_fallen", 1),
              (str_store_string, s5, "str_retreat"),
              (call_script, "script_simulate_retreat", 10, 20),
              (assign, "$g_battle_result", -1),
              (set_mission_result,-1),
              (call_script, "script_count_mission_casualties_from_agents"),
              (finish_mission,0)]),
#Wulf end
      ]),

With that there, we can actually go fight someone. Save and exit, compile your mod to check for errors, then open module_party_templates. Look for a small code called "sea_raider", and underneath it, put:
Code:
#wulf
  ("sea_raiders_ships","Sea Raiders",icon_ship|pf_is_ship|carries_goods(2),0,fac_outlaws,bandit_personality,[(trp_sea_raider,5,50)]),
#wulf end
What this is is a party of Sea Raiders, but on a ship. You can change the number of troops and the type of troop by editing the last box in the tuple, the "trp_sea_raider,5,50". trp_sea_raider (obviously) means Sea Raider troops. The 5 is the minimum number of Sea Raiders in a party, and 50 is the maximum. Now we need somewhere for them to spawn from, so open up module_parties and look for "Bridge 14". Underneath it, paste this code:
Code:
#Wulf
 ("ship_raider_spawn_point_1"   ,"the_ocean",pf_disabled|pf_is_static, no_menu, pt_none, fac_outlaws,0,ai_bhvr_hold,0,(-5.23,90.26),[(trp_looter,15,0)]),
#Wulf
This makes an invisible party which is on the water between Sargoth and Wercheg. You can easily add more parties to use as spawn points if you'd like, a great guide can be found here.

Now close module_parties and open module_scripts.
Search for "spawn_bandits", and scroll down just a bit and look for a code that looks like this:
    (try_begin),
      (store_num_parties_of_template, ":num_parties", "pt_mountain_bandits"),
      (lt,":num_parties",1:cool:, #was 14 at mount&blade, 18 in warband
      (store_random,":spawn_point",num_mountain_bandit_spawn_points),
      (val_add,":spawn_point","p_mountain_bandit_spawn_point"),
      (set_spawn_radius, 25),
      (spawn_around_party,":spawn_point","pt_mountain_bandits"),
    (try_end),
Now, just leave that one alone, but right underneath the (try_end), add this:
Code:
     #Wulf
     (try_begin),
       (store_num_parties_of_template, ":num_parties", "pt_sea_raiders_ships"),
       (lt,":num_parties",25),
       (store_random,":spawn_point",num_mountain_bandit_spawn_points),
       (val_add,":spawn_point","p_ship_raider_spawn_point_1"),
       (spawn_around_party,":spawn_point","pt_sea_raiders_ships"),
     (try_end),
     #Wulf end         

Save, exit, and compile. Now start up your game, go to Sargoth and buy a ship, and go fight some Sea Raiders in some fancy new ships. It's probably worth knowing that the three different scenes get picked based on the size of all the troops in the battle. If there are under 30, it uses the smallest scene. If there are 30 or more it uses the mid sized scene, and if there are 60 or more troops it uses the largest scene. Enjoy!














mb21.jpg


Sarranid city:





















 
Wouldn't it be much easier to modify script_setup_random_scene? You'd need to change the menu option text separately, but there shouldn't be a need for a separate option.
Code:
            (else_try),
              (eq, ":terrain_type", rt_water),
              # (assign, ":scene_to_use", "scn_water"),
              (set_jump_mission, "mt_ship_battle"),
              (store_add, ":size", reg10, reg11),
              (assign, ":scene_to_use", "scn_sea_1"),
              (try_begin),
                (gt, ":size", 60),
                (assign, ":scene_to_use", "scn_sea_4"),
              (else_try),
                (gt, ":size", 30),
                (assign, ":scene_to_use", "scn_sea_2"),
              (try_end),
 
this is really sweet, the only thing missing is some kind of trade caravan ships for our pirates to pray on, and the player too if he wants to be a pirate.

did you hear about the latest pirate movie? it's rated ARR.
 
Somebody said:
Wouldn't it be much easier to modify script_setup_random_scene? You'd need to change the menu option text separately, but there shouldn't be a need for a separate option.
Code:
            (else_try),
              (eq, ":terrain_type", rt_water),
              # (assign, ":scene_to_use", "scn_water"),
              (set_jump_mission, "mt_ship_battle"),
              (store_add, ":size", reg10, reg11),
              (assign, ":scene_to_use", "scn_sea_1"),
              (try_begin),
                (gt, ":size", 60),
                (assign, ":scene_to_use", "scn_sea_4"),
              (else_try),
                (gt, ":size", 30),
                (assign, ":scene_to_use", "scn_sea_2"),
              (try_end),
You could do that, but with this setup it's easier to add/remove scenes quickly, IMO. Your way is probably better, I just liked having all my scene stuff in game_menus. (I had a few camp options that dealt with jumping to different scenes.)

Arch3r said:
Nice, I might write some OS AI codes for it later, so that Lords and other parties will use the sea for travelling too.
That would be unbelievably awesome. If/when you get around to it, post the codes here and I'll put them in the first post. (And credit you for them, of course.)

Vincenzo said:
Is it OK, if I convert some of these scenes to multiplayer battle?
Or are they ready for MP already?

Would be cool MP battles  :smile:
All you'd have to do to make them work in MP is add a few entry points, but keep in mind that if a bunch of people spawn on horses on the ship scenes it could end up badly. You'd also probably want a script that kills people when they go underwater.
 
Well, wow. Certainly gonna use the ship codes, I'm pretty sure of that. Too bad lords can't go a-boating, though.

And the city. Wow. You're not gonna use it yourself? Because I can damn well use it for SulSuc. :grin:
 
FrisianDude said:
Well, wow. Certainly gonna use the ship codes, I'm pretty sure of that. Too bad lords can't go a-boating, though.

And the city. Wow. You're not gonna use it yourself? Because I can damn well use it for SulSuc. :grin:
I would use it myself if I planned on finishing the mod it was for.

EDIT: I'll have to postpone putting up the rest of the stuff until tomorrow or the day after, as I'm a bit sick and I want to finish up the whole code for the island thing.
 
Fine, fine scenes, Ruthven. I can see them appearing in many soon-to-be-released mods  :grin:

I too would like to use them if that's ok; I'm introducing an overarching quest line to NE and was wracking my brains about the Sarranid part.

Gotta love that city. 
 
I had a walk through the city last night and it's brilliant. Pity you didn't get to use it as you liked, Ruthven.

It's absolutely made for funnelling troops through bloody streets while attempting to reach that citadel in the middle.  :grin:
 
FrisianDude said:
Oh, by the way Ruthven, did you get around to making an AI mesh for the town?
Not even close. If someone else does it, It'd be nice if they'd let me use an AI meshed version. Only thing with this is that some people might want to have roofs AI meshed, and others might not.

And a bit of an interesting li'l thing you might want to know about the city, is that I actually planned it to be sort of hidden and secret, and the only way to get into it would be by going through one end of this archway in the middle of the desert. Through the arch, the city is there. If you don't go through the arch, no city. Similar to the Doors of Time in Legend of Zelda: Twilight Princess, for a very accurate yet nerdy comparison.
 
Ruthven said:
FrisianDude said:
Oh, by the way Ruthven, did you get around to making an AI mesh for the town?
Not even close. If someone else does it, It'd be nice if they'd let me use an AI meshed version. Only thing with this is that some people might want to have roofs AI meshed, and others might not.

I'll do the AI meshing and post it back up. However given my current development schedule, it will possibly be 6-8 weeks before I get to this. If someone else wants to do it in the meantime be my guest. Ideally I'll do two versions, only streets and also streets & roofs.

I'm assuming AI Meshing (especially for something this size) is a proper bastard to get right?  :smile:

 
Jesus Christ, the Sarranid city is beautiful... and I actually like the idea of having it as a hidden location.  It's always tempting to put all the most spectacular stuff right up front, but it's often better to let the player stumble on it themselves.  Then it becomes something that they remember and talk about, and people who hear of it will seek it out.  It's like rare loot, the size of a city.

I kind of want to volunteer to AI mesh it, but it's a big job... and people have some funny ideas about what makes a good AI mesh.  A lot of folk insist on having every single square millimetre mapped, even under all those balconies and around the pillars, despite the fact that the NPCs will happily negotiate those areas on their own for the most part.

It looks a lot like the cities from Assassin's Creed, obviously, but unlike those cities, this one has the potential to have an amazing game set into it.

 
 
Back
Top Bottom