How to Add a BCNM

From DSP Wiki
Jump to: navigation, search

In this page we will learn how to add BCNMs (duh)

Adding the BCNM to the list

To start off, navigate to your dsp folder and then to /scripts/globals/ and open bcnm.lua

Inside you'll see something like this:

itemid_bcnmid_map = { 6,{0,0},--Bearclaw_Pinnacle
                      8,{0,0},--Boneyard_Gully
                     10,{0,0},--The_Shrouded_Maw
		     13,{0,0},--Mine_Shaft_2716
                     17,{0,0},--spire of holla
		     19,{0,0},--spire of dem
		     21,{0,0},--spire of mea

Unless you're adding a BCNM that requires an item trade, the above will be of no use. You should scroll down to this instead:

bcnmid_param_map = { 6,{640,0},
                     8,{672,0},
                    10,{704,0,706,2},
                    13,{736,0},
                    17,{768,0},
		    19,{800,0},
		    21,{832,0},
                    23,{864,0},

This may seem confusing at first glance but it's not! Here's a breakdown of it:

bcnmid_param_map = {
                    6,{640,0},

The first number (in our case 6) is the ZoneID. The first pair of numbers after the ZoneID are the bcnmid and paramid (which must always be in pairs).

6, <- Zone ID {640 <- bcnmid , 0 <- paramid }

The bcnmid can be found in the bcnm_info sql file / table.

The paramid can usually be found commented in the BCNM zone's Burning_Circle.lua file e.g.

-----------------------------------
-- Area: Balga's Dais
-- NPC:  Burning Circle
-- Balga's Dais Burning Circle
-- @pos 299 -123 345 146
-------------------------------------
package.loaded["scripts/zones/Balgas_Dais/TextIDs"] = nil;
package.loaded["scripts/globals/bcnm"] = nil;
-------------------------------------
........................
........................

	---- 0: Rank 2 Final Mission for Bastok "The Emissary" and Sandy "Journey Abroad" <--- This line <---
	---- 1: Steamed Sprouts (BCNM 40, Star Orb)
	---- 2: Divine Punishers (BCNM 60, Moon Orb)
	---- 3: Saintly Invitation (Windurst mission 6-2)
	---- 4: Treasure and Tribulations (BCNM 50, Comet Orb)

In our case, if the BCNM we were adding was for Rank 2 Final Mission in Balga's Dais, we could use the information from bcnm_info:

[bcnmid | zoneId |      name      ]
[  96   |   146  | rank_2_mission ]

In bcnm.lua with 96 being bcnmid and 0 being the paramid.

bcnm_param_map = {
                  146,{96,0},
                 }

IMPORTANT: You do not need to create another line for an existing zone's bcnm, simply add the bcnmid and paramid at the end of the zone's array (don't include the -->'s, they're there simply to make things easier to understand)

bcnm_param_map = {
                  146,{bcnmid --> 96, paramid --> 0, bcnmid --> 99, paramid --> 3},
                  }

Just a summary of this section;

bcnm_param_map = {
                 146, {  96  ,   0   ,   99  ,   3    },
         --   zoneid, {bcnmid,paramid, bcnmid, paramid},
                 }



Adding mobs to the BCNM

In this section we'll be adding mobs to the BCNM. To do this you'll need to have the monsterId which you can find from the mobid column mob_spawn_points table/sql file. Add this into the bcnm_battlefield table/sql file so it looks like this (if it were for Rank 2 Mission)

[ bcnmId | battlefieldNumber | monsterId | conditions ]
|   0    |       1        | 17346561  |     3      |

For the mob to show up, you'll need the mob's x,y,z,rotation pos in the mob_spawn_points table/sql file: NOTE: The mob MUST have a value greater than 0 in pos_x, pos_y, pos_z and pos_rot! This can even be '0.001' just as long as it's not '0'

[   mobid   |     mobname     | groupid |    pos_x   |    pos_y   |    pos_z  |   pos_rot  ]
|  17375233 |	Black_Dragon  |	  7900  |    -138    |	   56	  |    -224   |     189    |  
                                             ~X^           Y^           Z^        rotation^ ~                             

To set the pos you'll need access to a retail FFXI where you can pull the @pos co-ordinates. If you don't have access to retail FFXI, you can find a video with the BCNM fight and estimate the pos for the bcnm mobs.

When attempting to estimate the co-ordinates (x,y,z,rotation) you'll first need to assign a mob to the bcnmid and then go to the BCNM. Once you've entered the BCNM place your character at each of the mob's estimated spawn points and type @where. The [ x,y,z,(rotation) ] co-ordinates shown from @where need to go in mob_spawn_points table/sql file.

NOTE: You'll need 3 chars, one to enter each instance and find the co-ordinates of that BCNM so you can add the pos for mobs in each instance. (mobids for BCNMs are usually grouped together in mob_spawn_points.sql)

When all the information needed is added to bcnm_battlefield table/sql, re-import the sql file or save changes to table and reboot DSGameServer. Make sure you've added all mobs that need to be in the BCNM and got the correct co-ordinates.

Adding requirements to the BCNM

In this section we'll be adding requirements such as Key Item or Mission requirements to the BCNM. This is the easiest and least time consuming part of adding a BCNM. Simply add the condition you need in bcnm.lua under

function checkNonTradeBCNM(player,npc)

Here you can see the bcnm first checks the Zone, if the player has the Key Item required for it, sets the id, mask and sets the var needed.

elseif(Zone == 146) then -- Balga's Dais
		if(player:hasKeyItem(DARK_KEY)) then -- Mission 2-3
			mask = GetBattleBitmask(96,Zone,1);
			player:setVar("trade_bcnmid",96);
		end

You don't need another 'elseif(Zone == )' if adding another bcnm to a zone that already has one. Just add the check like so:

elseif(Zone == 146) then -- Balga's Dais
		if(player:hasKeyItem(DARK_KEY)) then -- Mission 2-3
			mask = GetBattleBitmask(96,Zone,1);
			player:setVar("trade_bcnmid",96);
		elseif(player:hasKeyItem(HOLY_ONES_INVITATION)) then -- Mission 6-2
			mask = GetBattleBitmask(99,Zone,1);
			player:setVar("trade_bcnmid",99);
		end



Finishing off the BCNM

Now that our BCNM has mobs, can be entered and can be won; we need to tell it what to do upon winning the BCNM. To make things simple, copy an existing script from scripts/zones/ZONE_NAME/bcnms (ZONE_NAME being the name of the zone you're scripting the bcnm for). Make a copy of that script and rename it to the BCNM's name which can be found in the bcnm_info table/sql file.

For this part we'll make a copy of the rank_2_mission script (Balga's Dais). When opening the script you'll see this:

function OnBcnmRegister(player,instance)
end;

-- Physically entering the BCNM via bcnmEnter(bcnmid)
function OnBcnmEnter(player,instance)
end;

In most cases you do NOT need to touch these.

Scroll down to onBcnmLeave and you'll see this:

function OnBcnmLeave(player,instance,leavecode)
-- print("leave code "..leavecode);
	
	if(leavecode == 2) then -- play end CS. Need time and battle id for record keeping + storage
		if(player:hasCompletedMission(player:getNation(),5)) then
			player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,1);
		else
			player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,0);
		end

Here's a quick breakdown of it;

if(leavecode == 2) then
line is saying "If player has won BCNM then" do something.

The next 4 lines;

if(player:hasCompletedMission(player:getNation(),5)) then

   player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,1);
		
 else
   player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,0);
 end

Check to see if the player has completed the mission or not. If they have then display the cutscene with a 'skip' option;

player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,1) -- <-- This last '1' determines if it can be skipped or not.

if not then display the regular cutscene without an option to skip it.

player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,0,0) -- <-- This last '0' means "stfu you cant skip".

To choose which cutscene to show it's pretty simple, all you have to do is get the paramid for the bcnm (in our case it's 0) and have that as the parameter before the 'skip' option parameter e.g. if the cutscene was for Mission 6-2, then this is what we'd see: IMPORTANT: The csid(in our case 0x7d01) will ALWAYS be the same. To show the correct cutscene you change the second to last parameter for player:startEvent to the BCNMs paramid.

player:startEvent(0x7d01,1,1,1,instance:getTimeInside(),1,      3       ,    1            );
                                                                ^paramid,    ^no skip(1) skip(0)


Now that we've got the BCNM showing the correct cutscene, we need to tell the BCNM what to do when that cutscene is finished. All you have to do is scroll down to onEventFinish and do what you gotta do. The csid will be the same as it was for the other BCNMs already in the zone e.g. for Balgas Dais the csid for the BCNM will always be 0x7d01.

function onEventFinish(player,csid,option)
-- print("bc finish csid "..csid.." and option "..option);
	
	if(csid == 0x7d01) then
		if(player:hasKeyItem(DARK_KEY)) then
			player:addKeyItem(KINDRED_CREST);
			player:messageSpecial(KEYITEM_OBTAINED,KINDRED_CREST);
			player:setVar("MissionStatus",9);
			player:delKeyItem(DARK_KEY);
		end
	end
	
end;

Adding Treasure Chests

Fill in the required values in bcnm_loot table remembering to add the items needed to each group under lootGroupId. Make sure there isn't an existing LootDropId with the same value as the one you're trying to add as you'll end up adding the drop to another BCNM which doesnt need this. In order to do this, simply add 1 to the highest LootDropId and set that as yours e.g. If you were adding a Treasure Chest to Horns of War (Horlais Peak) and there was already a BCNM with items with LootDropId's value of 10, you'd put: bcnm_loot

[LootDropId | itemId | rolls | lootGroupId ]
|    10     |  1234  |  123  |      0      | <-- previous LootDropId item ( read comment below )
|    10     |  1235  |  123  |      0      | <-- previous LootDropId item (both are in LootDropId 10, Group 0)
|    11	    |  1441  |	169  |      0      | <-- our NEW LootDropId items ( read comment below ) 
|    11     |  1442  |  169  |      0      | <-- our NEW LootDropId items (both are in LootDropId 11, Group 0)

If the items are part of the same BCNM drop, assign them the same LootDropId. The lootGroupIds are for BCNMs that drop random loot

You then go in to bcnm_info and add the LootDropId value into that BCNMs LootDropId column e.g.

[bcnmid |  zoneid  |     name     | fastestName | fastestTime | timeLimit | levelCap |  partySize | lootDropId | rules ]
|   11	|    139   | horns_of_war |	        |             |   1800    |	0    |	    18	  |     11     |  15   |
                                                                                                        ^
                                                                                                    this 

So as you can see, the LootDropId in both tables match.

Get the Treasure Chest's NPC ID (usually goes up in BCNM order e.g. 17375282 for the first BCNM and 17375284 for the second), and put the info required in bcnm_treasure_chests table.

bcnm_treasure_chests

[bcnmId | battlefieldNumber |  npcId   ]
|  107	|        1       | 17375282 |
|  107	|        2       | 17375284 | <-- same bcnm, different battlefieldNumber, different npcId
|  107	|        3       | 17375286 |

Once all the required information is in the tables (including the Treasure Chests spawn co-ordinates in npc_list) the Treasure Chest should show upon wiping all enemies in that BCNM unless i screwed up in the guide somewhere. TODO: (For demo) Explain winconditions in BCNM instance (pets / summons shouldnt be 3)