Tutorial for Scripting Battles a la the Den Gang War

JimTheDinosaur

Vault Dweller
Modder
Again the set up for this is the same as for the previous tutorial. When I began (and immediately stopped) modding fallout a few years ago I wanted to do two things: make new party members and put together fights like the one in the Den. Especially the latter completely baffled me (I couldn't even get critters to move I remember) and without any tutorials around I soon gave up. Because, in case you hadn't noticed, checking to see what the developers did with the Den battle is extremely disheartening (just open den.h and prepare for sensory overload). So here's a barebones tutorial on how to do more or less the same thing.

As with the previous tutorial, I note up front that I'm a beginner myself and hopefully veterans will show up to explain all the things I did wrong/could have done easier/should have done to avoid the game breaking. Also, again, it's assumed that you know the absolute basics.

Okay, so suppose I want to set things up so that salvatore's gang can either attack Bishop's Casino or Mordino's Casino en masse (the latter is included to demonstrate how cross-map attacks, like the ones in the Den and the Ghost Farm, take place).

1) Make a new global variable called SALVATORE_ATTACK, which will be the basis for our two attacks (value 1 will be the attack on Bishop, 2 the one on Mordino). Now have these triggered through whichever conversation options which make sense to you.

2) open the map scripts for the two maps we're going to use (newr1.ssl and newr2.ssl) and add these lines to the latter:

Code:
export variable bouncer1;
export variable bouncer2;

and this one to the former:

Code:
export variable bouncer3;
export variable bouncer4;

We will need these variables to give our brave Salvatore troopers something to attack in a minute (at least, if I understood things right, you can only have scripts attack *individual* objects, but if it's somehow possible to attack a random critter with a certain script or on a certain team, I'd love to hear about it).

3: open the Salvatore grunt script (salmen.ssl) and add the lines

Code:
import variable bouncer1;
import variable bouncer2;
import variable bouncer3;
import variable bouncer4;

Now, let's start with moving towards the Bishop casino. Unless I'm a particularly stupid person, scripting movement in Fallout 2 is a pain in the ass. Critters constantly get stuck in other animations which they won't get out of, so it's important to cancel these out. So here's what we do; we add this line to critter_p_proc:

Code:
    if (global_var(GVAR_SALVATORE_ATTACK) == 1) and (local_var(LVAR_Attack_1) == 0) then begin   
         	animate_run_to_tile(19899);      
		if art_anim(ANIM_stand) then begin  
			reg_anim_clear(self_obj);
         	animate_run_to_tile(19899);
         end

Ignore the LVAR for the moment. What's important is that everytime the critter is being an asshole and standing still because somebody went through the door before him, the script forces him to stop being an asshole and get moving again. The tile number is just in front of the casino entrance (it can't be much further; for some reason npc's don't like being forced to move very far, so if you want to get further you need to script it in babysteps).

Now, before we script the actual attack we want the Salvatore grunts to have some backup from their two pals upstairs, so we add the line underneath:

Code:
         	if (self_elevation != 0) then begin
   			critter_attempt_placement(self_obj, 16535, 0);
   			end

which puts them neatly beneath the stairs. Now to have them attack the bouncers, add this beneath the previous line:

Code:
if 
         	(self_tile == 19899) then begin
         		attack(bouncer1);
				set_local_var(LVAR_Attack_1, 1);
         	end
end

The LVAR just makes sure that they don't move back to tile 19899 after the battle like a bunch of idiots, but you can leave it out if you want. Of course, nothing happens yet because "bouncer1" doesn't exist yet. So now we go to step

4: Open the bouncer script (nccasbou.ssl), import the same variables (bouncer1, bouncer2, etc.) as in the Salvatore script and add the following line to map_enter_p_proc:

Code:
   if (map_first_run) and (cur_map_index == MAP_NEW_RENO_2) then begin
         if (bouncer1 == 0) then begin
            bouncer1 := self_obj;
            set_local_var(LVAR_Bouncer_Num, 1);
         end else if (bouncer2 == 0) then begin
            bouncer2 := self_obj;
            set_local_var(LVAR_Bouncer_Num, 2);
      	 end
   end else if (local_var(LVAR_Bouncer_Num) == 1) then begin
      bouncer1 := self_obj;
   end else if (local_var(LVAR_Bouncer_Num) == 2) then begin
      bouncer2 := self_obj;
   end

Here I just copied the system used for the "junkie_talker"s in the Den.

(Now, just a note if you want to script using the New Reno bouncers specifically; they have this weird thing (maybe it's just in the mapper) where the team allocation system (the Mordino and Bishop bouncers have the same script) doesn't really work. So unless you want to end up having the Salvatore boys fighting prostitutes, add extra team lines for Bishop in the one map and Mordino in the other just for good measure.)

Et voila, F8 and the Bishop attack should work swimmingly.

5: Now for the Mordino attack; the bouncers just need an extra line similar to the previous one (remember that the bouncers for both casinos share the same script):

Code:
else if (map_first_run) and (cur_map_index == MAP_NEW_RENO_1) then begin
         if (bouncer3 == 0) then begin
            bouncer3 := self_obj;
            set_local_var(LVAR_Bouncer_Num, 3);
         end else if (bouncer4 == 0) then begin
            bouncer4 := self_obj;
            set_local_var(LVAR_Bouncer_Num, 4);
         end
   end else if (local_var(LVAR_Bouncer_Num) == 3) then begin
      bouncer3 := self_obj;
   end else if (local_var(LVAR_Bouncer_Num) == 4) then begin
      bouncer4 := self_obj;
   end

6: Now it's time in the mapper to go to the Mordino casino map and put copies of all the Salvatore grunts somewhere near the exit grid. Now give these copies each the salmen.int script and fill up their inventories the same way as their alter egos in the other map.

7: Now add the following line in the Salvatore men script beneath map_enter_p_proc:

Code:
   if (cur_map_index == MAP_NEW_RENO_2) and (global_var(GVAR_SALVATORE_ATTACK) == 2) then begin
   		set_obj_visibility(self_obj,1);
   end
   if (cur_map_index == MAP_NEW_RENO_2) and (global_var(GVAR_SALVATORE_ATTACK) != 2) then begin
   		set_obj_visibility(self_obj,0);
   end
   if (cur_map_index == MAP_NEW_RENO_1) and (global_var(GVAR_SALVATORE_ATTACK) != 2) then begin
   		set_obj_visibility(self_obj,1);
  		end 
   if (cur_map_index == MAP_NEW_RENO_1) and (global_var(GVAR_SALVATORE_ATTACK) == 2) then begin
   		set_obj_visibility(self_obj,0);
  		end

This makes sure that the Salvatore men in the Mordino casino map stay safely nonexistent until the Mordino attack sequence fires, and that the men in Salvatore's bar dissappear when this happens. Of course you can make this more sophisticated by transporting the player along with them like in the Den gang war, but none of that is strictly necessary: what's important is that whenever one alter ego is visible the other is invisible.

Finally, just add these lines to the critter_p_proc beneath the others for the second attack to become possible:

Code:
   	     if (global_var(GVAR_SALVATORE_ATTACK) == 2) and (local_var(LVAR_Attack_2) == 0) and (cur_map_index == MAP_NEW_RENO_1) then begin   
         	animate_run_to_tile(17495);      
				if art_anim(ANIM_stand) then begin  
					reg_anim_clear(self_obj);
         			animate_run_to_tile(17495);    
         			end if 
         				(self_tile == 17495) then begin
         				attack(bouncer3);
						set_local_var(LVAR_Attack_2, 1);
         	   end
   	end

And there you have it! It took me a lot of tinkering and a couple of the errors I'm not even a hundred percent clear on how I got past them, but it *seems* to work well now. Of course, I'll undoubtedly be set straight on this account.

After this I think the only other tutorial I'll make is for setting up new caravans (because you can always use more caravans).


EDIT: I forgot to mention that the most important way this approach differs from the ones used for the Den and the Ghost Farm is that you start out as an observer (like in the random encounter fights). To change that, just insert a line somewhere that (temporarily) changes the team of the Salvatore men to TEAM_PLAYER)
 
Back
Top