How does one make a simple invasion mission?

Users who are viewing this thread

Xaphan

Banned
I have long been trying to make a simple server side invasion mod.

How does one create a mission that spawns a certain amount of bots per active players, in rounds.

I tried the broken old OSP code to try and give me an idea on how an invasion system would work (by Arch3r).  His code just sends non stop waves, there is no end of the round, no point to playing it.

I'm not looking for someone to write code for me, I just need help figuring out where to start.

I'm decent at modding, and have been looking for a new project to work on. 

I'm not bothering with any Persistent World sub mods because they always fail, and well that exact system is over played.

I have two different mods I would like to make but first I would like to start with this simple Invasion mod. 
 
Well actually you are kinda lucky since im working on one and its like 2 weeks or 3 weeks away from release date so i could help you about these things.
You can define a global wave number variable for example before the mission starts trigger, and a variable to check if the current wave is in progress or not.
then make a trigger that checks every second what wave number it is and if it started already or not... if not - spawn the bots, if it did - ignore.
And then you could check on the trigger agent_wounded_or_killed if all agents are dead on the bots team and then increase the wave number value.
Thats a part of it. Hope i helped
 
Yes thank you, how would I go about creating waves?  Also no one has ever answered my questions about creating timers. 

They are not documented in header operations well if at all. 

Assuming in order to spawn a wave you would need to create a timer.  xD

Like rules for the wave and a command to spawn the AI.  Such as spawn 5 bots per player sort of thing.

Or would that be like a difficulty condition check.  Scan for number of players, at +1 to difficulty, store difficulty, add check in wave spawn for difficulty level?
 
Well for a timer you can just have a global variable that increments/decrements by one in a trigger that activates every one second.

For example

Code:
(1, 0, 0, [], [
     (val_sub, "$timer", 1),

     (try_begin),
          (le, "$timer", 0),
          <check to ensure all enemies are dead>
          <spawn some enemies based on number of players, using spawn_agent or set_visitors perhaps>
          (assign, "$timer", 60),
     (try_end),

]),
 
Ohhhh, I had no idea the modding system used global variables.  Big help thank you.  "Makes sense now because every language i have been learning lately uses them".

Now about the actual process of spawning said amount of bots.  I would need to write a difficulty check script maybe?  Possibly create a slot to store the difficulty? 

custom slots are another thing I am unsure of.  I created a slot in module constants, which did not work for storage. 

but in theory i would some how store the difficulty number, and use it when calling for the wave. 

I am just unsure how to actually spawn the wave is the thing. 

 
About the timers: a timer = a trigger. The structure is:
Code:
(<check_interval>, <delay_interval>, <rearm_interval>, [
<conditional_block>
], [
<execution_block>
])
It is placed inside a mission template's trigger list.
<check_interval>, <delay_interval> and <rearm_interval> are numbers that represents the time in seconds (it is a float number; if it is 0, then it means each game frame)

Each <check_interval> seconds the <conditional_block> is run. If it returns false (one operation failed at level 0 (it is not in any try_* loop)) then nothing happens ( the <conditional_block> will run after another <check_interval> seconds). If it returns true then, after <delay_interval>, <execution_block> is run. After <execution_block> ends, the trigger will wait <rearm_interval> seconds before it will start over again (rerun <conditional_block> each <check_interval>...).

Example:
Code:
(5, 2, 10,[
     (eq, "$need_to_show_test", 1),
],[
    (assign, "$need_to_show_test", 0),
    (display_message, "@Test!"),
]),
In the example above the condition will be executed each 5 seconds. If "$need_to_show_test" is 1, after 2 seconds it will become 0 and the message "Test!" will pop in game. After the message "Test!" shows, the trigger will wait 10 seconds before it will start again to run the condition each 5 seconds.


Now the invasion part.
You need some global variables to store the current wave number, if it was spawned, when the last wave ended and so on.
Here is a very simple invasion example:

Code:
(ti_before_mission_start, 0, 0, [],
       [
         (assign, "$wave_number", 0),
         (assign, "$wave_is_spawned", 0),
         (assign, "$wave_end_time", 0),
]),

(ti_on_agent_killed_or_wounded, 0, 0, [],
 [
  (store_trigger_param_1, ":dead_agent_no"), 
  (store_trigger_param_2, ":killer_agent_no"), 
   
  (try_begin),
    (agent_is_human, ":dead_agent_no"),
    (assign, ":team1_living_players", 0),
    (assign, ":team2_living_players", 0),
    (try_for_agents, ":cur_agent"),
      (agent_is_human, ":cur_agent"),         
      (try_begin),
        (agent_is_alive, ":cur_agent"),  
        (agent_get_team, ":cur_agent_team", ":cur_agent"),
        (try_begin),
          (eq, ":cur_agent_team", 0),
            (val_add, ":team1_living_players", 1),
        (else_try),
          (eq, ":cur_agent_team", 1),
            (val_add, ":team2_living_players", 1),
        (try_end),
      (try_end),
    (try_end),        
    (try_begin),
      (eq, ":team2_living_players", 0),
      (eq, ":dead_agent_team", 1),
        (store_mission_timer_a, "$wave_end_time"),
        (assign, "$wave_is_spawned", 0),
    (try_end),
 (try_end),
]),



(1, 0, 0, [
  (eq, "$wave_is_spawned", 0),
  (store_mission_timer_a, ":round_time"),
  (val_sub, ":round_time", "$wave_end_time"),
  (ge, ":round_time", 5),                        ### 5 means how many seconds needs to pass between waves to spawn
    (val_add, "$wave_number", 1),
],[
  (try_begin), ### choose our wave troop to spawn (this is only a simple way of choosing the troop (I would not recommend using this way))
    (eq, "$wave_number", 1),
      (assign, ":troop_to_spawn", "trp_hired_assassin"),
  (else_try),
    (eq, "$wave_number", 2),
      (assign, ":troop_to_spawn", "trp_sword_sister"),
  (else_try),
    (eq, "$wave_number", 3),
      (assign, ":troop_to_spawn", "trp_hired_blade"),
  (else_try),
      (assign, ":troop_to_spawn", "trp_belligerent_drunk"),
  (try_end),
  
  (assign, ":num_troops_to_spawn", 10),           ### if you want dificulty, then modify this value based on how many players are (count the players, then do whatever you want)
  
  (store_current_scene, ":cur_scene"), 
  (modify_visitors_at_site, ":cur_scene"),
  
  (add_visitors_to_current_scene, 1, ":troop_to_spawn", ":num_troops_to_spawn", 1, 0),
                                                  ## the first 1 represents the entry point at which we will spawn the troops
                                                  ## the second 1 represents the team ( 0 - first team; 1 - second team)
                                                  ## the last 0 represents the player that will control the troops ( 0 is the server)
  (assign, "$wave_is_spawned", 1),
]),

Put the above triggers in a mission template and you will have a nice unending invasion (it doesn't have the ending conditions: all players dies or all waves ends). (in theory the above code should work; haven't tested it).
 
You are a master, thank you so much for your help.  Your code line by line makes much more sense to me than what I have tried to work with, i should be able to fix it if it doesn't work.  "where is the fun in copy and pasting".

I have one last modding question, I see "$variablename", instead of ":variablename",  a lot in the module system.  are the ones beginning with $ global variables? 

 
okay thank for you clearing that up, i hope they put real work into explaining bannerlord's functions, it is a miracle anyone ever made warband mods in the beginning. 
 
I guess I have one last question, since this is my first time starting a new mod.

Can I use a blank mission template, and use blank scripts ect...  filled with only things I will be using?

Or do I need some of native mission templates and scripts functions? 
 
If you want to make a server side invasion mode (or whatever else that is just server side native compatible) then you need to edit a preexisting mission template.
Making a new blank one is harder in both ways: it is not native compatible anymore (because the clients will need your mod for using the new mission template) and you need to add some bunch stuffs for player spawning handling and such.
You can add/remove how many scripts you want because the scripts are local (the server knows about it's scripts; client has no idea what scripts a server is using (because the client has it's own scripts too)).
 
Well i'm starting to feel like I want to make a more robust mod with website php system for buying and selling items.  Though I have had luck in the past with equipping items from a database server side.  Also i'm unsure how to handle ammo refilling and hp regeneration server side, though eragon did it in his server side invasion mod.

I was thinking hp could be auto regan with a timer. 

Okay I must ponder.  If I can keep it server side it would be a plus.  I was looking for for the missions, I would need to remake a mission which already exists such as battle?

EDIT: Now that I have pondered on it more, I assume I could do anything server side I was able to do server side for persistent world.  (Server side modding for PW is how I got started)
 
So now that, that is settled, I would need to edit for example, the battle mission?  And use battle config?

Re guarding your example invasion script? 

It looks like you just set a few global variables than start a timer, but how would the server know to use that mission?
 
Xaphan said:
but how would the server know to use that mission?

It doesn't. You need to start the server with that mission template.

Xaphan said:
I would need to remake a mission which already exists such as battle?

Yes. Basically you can go into the battle mission template and start removing the stuffs that you don't want (there are a lot of triggers).

Xaphan said:
Well i'm starting to feel like I want to make a more robust mod with website php system for buying and selling items.

First make the core of the mod, then add extra stuffs like external saving and such. That is easy to add, so it can be added later.

Xaphan said:
Also i'm unsure how to handle ammo refilling and hp regeneration server side, though eragon did it in his server side invasion mod.

You mean in 27 days mod?
The player was healing only when he was standing on a bed (actually he was standing on an invisible barrier). There is a trigger that runs each second or so, and for each player it checks if it is standing on a "healing" barrier (scene_prop_has_agent_on_it) and if it does, then it refills a little bit of health (via store_agent_hit_points and agent_set_hit_points).
As for the ammo refilling you can use this "agent_refill_ammo" (however this will refill the javelins and throwing axes too (27 days was using the code from full invasion mod and was refilling only certain types of ammo)).
 
okay I tested it, the first wave works, and it does not continually spawn so the timer seems to be working.  Though when you beat the first wave, the second wave never spawns.

And if you die, its game over and admin has to reset mission. 

Hmmmph, time to dig. 

EDIT:: I might of fixed most things, but not sure how to restart the mission once every human is dead. 
 
This is how to restart the mission:
Code:
(call_script, "script_game_multiplayer_get_game_type_mission_template", "$g_multiplayer_game_type"),
(start_multiplayer_mission, reg0, "$g_multiplayer_selected_map", 0),
 
Back
Top Bottom